Needle Engine

Changes between version 3.41.0-alpha and 3.41.0-alpha.1
Files changed (13) hide show
  1. src/engine/dist/api.js +0 -73
  2. src/engine/dist/engine_networking_streams.js +0 -474
  3. src/engine/dist/api.js.meta +0 -7
  4. src/engine/dist/engine_networking_streams.js.meta +0 -7
  5. src/engine-components/postprocessing/Effects/Bloom.ts +11 -9
  6. src/engine-components/postprocessing/Effects/ColorAdjustments.ts +2 -17
  7. src/engine-components/postprocessing/Effects/DepthOfField.ts +0 -2
  8. src/engine/export/gltf/index.ts +8 -37
  9. src/engine-components/timeline/PlayableDirector.ts +3 -0
  10. src/engine-components/postprocessing/PostProcessingHandler.ts +14 -1
  11. src/engine-components/postprocessing/Effects/Tonemapping.ts +14 -6
  12. src/engine-components/webxr/WebXR.ts +13 -0
  13. src/engine/export/gltf/Writers.ts +35 -0
src/engine/dist/api.js DELETED
@@ -1,73 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
- for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
11
- };
12
- exports.__esModule = true;
13
- __exportStar(require("./extensions/index.js"), exports);
14
- __exportStar(require("./engine_addressables.js"), exports);
15
- __exportStar(require("./engine_application.js"), exports);
16
- __exportStar(require("./engine_assetdatabase.js"), exports);
17
- __exportStar(require("./engine_create_objects.js"), exports);
18
- __exportStar(require("./engine_components_internal.js"), exports);
19
- __exportStar(require("./engine_components.js"), exports);
20
- __exportStar(require("./engine_components_internal.js"), exports);
21
- __exportStar(require("./engine_context_registry.js"), exports);
22
- __exportStar(require("./engine_context.js"), exports);
23
- __exportStar(require("./engine_coroutine.js"), exports);
24
- __exportStar(require("./engine_constants.js"), exports);
25
- __exportStar(require("./debug/index.js"), exports);
26
- __exportStar(require("./engine_element.js"), exports);
27
- __exportStar(require("./engine_element_loading.js"), exports);
28
- __exportStar(require("./engine_element_attributes.js"), exports);
29
- var engine_gizmos_js_1 = require("./engine_gizmos.js");
30
- __createBinding(exports, engine_gizmos_js_1, "Gizmos");
31
- __exportStar(require("./engine_gltf.js"), exports);
32
- __exportStar(require("./engine_hot_reload.js"), exports);
33
- __exportStar(require("./engine_gameobject.js"), exports);
34
- __exportStar(require("./engine_networking.js"), exports);
35
- __exportStar(require("./engine_networking_types.js"), exports);
36
- var engine_networking_auto_js_1 = require("./engine_networking_auto.js");
37
- __createBinding(exports, engine_networking_auto_js_1, "syncField");
38
- __exportStar(require("./engine_networking_files.js"), exports);
39
- __exportStar(require("./engine_networking_instantiate.js"), exports);
40
- __exportStar(require("./engine_networking_streams.js"), exports);
41
- __exportStar(require("./engine_networking_utils.js"), exports);
42
- __exportStar(require("./engine_networking_peer.js"), exports);
43
- __exportStar(require("./engine_patcher.js"), exports);
44
- __exportStar(require("./engine_playerview.js"), exports);
45
- __exportStar(require("./engine_physics.js"), exports);
46
- __exportStar(require("./engine_physics.types.js"), exports);
47
- __exportStar(require("./engine_physics_rapier.js"), exports);
48
- __exportStar(require("./engine_scenelighting.js"), exports);
49
- __exportStar(require("./engine_input.js"), exports);
50
- __exportStar(require("./engine_math.js"), exports);
51
- __exportStar(require("./js-extensions/index.js"), exports);
52
- __exportStar(require("./engine_scenetools.js"), exports);
53
- __exportStar(require("./engine_serialization.js"), exports);
54
- var engine_serialization_core_js_1 = require("./engine_serialization_core.js");
55
- __createBinding(exports, engine_serialization_core_js_1, "type");
56
- __exportStar(require("./engine_texture.js"), exports);
57
- __exportStar(require("./engine_three_utils.js"), exports);
58
- __exportStar(require("./engine_time.js"), exports);
59
- __exportStar(require("./engine_types.js"), exports);
60
- __exportStar(require("./engine_utils_screenshot.js"), exports);
61
- __exportStar(require("./engine_web_api.js"), exports);
62
- __exportStar(require("./engine_utils.js"), exports);
63
- var engine_typestore_js_1 = require("./engine_typestore.js");
64
- __createBinding(exports, engine_typestore_js_1, "TypeStore");
65
- __createBinding(exports, engine_typestore_js_1, "registerType");
66
- var engine_instancing_js_1 = require("./engine_instancing.js");
67
- __createBinding(exports, engine_instancing_js_1, "InstancingUtil");
68
- var engine_util_decorator_js_1 = require("./engine_util_decorator.js");
69
- __createBinding(exports, engine_util_decorator_js_1, "validate");
70
- __createBinding(exports, engine_util_decorator_js_1, "prefix");
71
- var engine_license_js_1 = require("./engine_license.js");
72
- __createBinding(exports, engine_license_js_1, "hasProLicense");
73
- __createBinding(exports, engine_license_js_1, "hasIndieLicense");
src/engine/dist/engine_networking_streams.js DELETED
@@ -1,474 +0,0 @@
1
- "use strict";
2
- var __extends = (this && this.__extends) || (function () {
3
- var extendStatics = function (d, b) {
4
- extendStatics = Object.setPrototypeOf ||
5
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
7
- return extendStatics(d, b);
8
- };
9
- return function (d, b) {
10
- extendStatics(d, b);
11
- function __() { this.constructor = d; }
12
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13
- };
14
- })();
15
- exports.__esModule = true;
16
- exports.disposeStream = exports.NetworkedStreams = exports.PeerHandle = exports.ReceiveStreamEvent = exports.CallEndedEvent = exports.PeerEvent = void 0;
17
- var engine_networking_js_1 = require("../engine/engine_networking.js");
18
- var engine_networking_peer_js_1 = require("../engine/engine_networking_peer.js");
19
- var three_1 = require("three");
20
- var engine_utils_js_1 = require("./engine_utils.js");
21
- var debug = engine_utils_js_1.getParam("debugnetworkingstreams");
22
- var PeerEvent;
23
- (function (PeerEvent) {
24
- PeerEvent["Connected"] = "peer-user-connected";
25
- PeerEvent["ReceiveStream"] = "receive-stream";
26
- PeerEvent["CallEnded"] = "call-ended";
27
- PeerEvent["Disconnected"] = "peer-user-disconnected";
28
- PeerEvent["UserJoined"] = "user-joined";
29
- })(PeerEvent = exports.PeerEvent || (exports.PeerEvent = {}));
30
- var CallEndedEvent = /** @class */ (function () {
31
- function CallEndedEvent(userId, direction) {
32
- this.type = PeerEvent.CallEnded;
33
- this.userId = userId;
34
- this.direction = direction;
35
- }
36
- return CallEndedEvent;
37
- }());
38
- exports.CallEndedEvent = CallEndedEvent;
39
- var ReceiveStreamEvent = /** @class */ (function () {
40
- function ReceiveStreamEvent(stream, target) {
41
- this.type = PeerEvent.ReceiveStream;
42
- this.stream = stream;
43
- this.target = target;
44
- }
45
- return ReceiveStreamEvent;
46
- }());
47
- exports.ReceiveStreamEvent = ReceiveStreamEvent;
48
- var PeerUserConnectedModel = /** @class */ (function () {
49
- function PeerUserConnectedModel(handle, peerId) {
50
- // internal so server doesnt save it to persistent storage
51
- this.dontSave = true;
52
- this.guid = handle.id;
53
- this.peerId = peerId;
54
- }
55
- return PeerUserConnectedModel;
56
- }());
57
- var CallDirection;
58
- (function (CallDirection) {
59
- CallDirection["Incoming"] = "incoming";
60
- CallDirection["Outgoing"] = "outgoing";
61
- })(CallDirection || (CallDirection = {}));
62
- var CallHandle = /** @class */ (function (_super) {
63
- __extends(CallHandle, _super);
64
- function CallHandle(userId, call, direction) {
65
- var _this = _super.call(this) || this;
66
- _this._stream = null;
67
- _this._isDisposed = false;
68
- _this.userId = userId;
69
- _this.call = call;
70
- _this.direction = direction;
71
- _this._stream = null;
72
- call.on("stream", function (stream) {
73
- if (debug)
74
- console.log("Receive video", stream.getAudioTracks(), stream.getVideoTracks());
75
- _this._stream = stream;
76
- if (direction === CallDirection.Incoming) {
77
- var args = new ReceiveStreamEvent(stream, _this);
78
- _this.dispatchEvent(args);
79
- }
80
- });
81
- call.on("close", function () {
82
- _this.dispatchEvent(new CallEndedEvent(userId, direction));
83
- });
84
- return _this;
85
- }
86
- Object.defineProperty(CallHandle.prototype, "stream", {
87
- get: function () { return this._stream; },
88
- enumerable: false,
89
- configurable: true
90
- });
91
- ;
92
- CallHandle.prototype.close = function () {
93
- if (this._isDisposed)
94
- return;
95
- this._isDisposed = true;
96
- this.call.close();
97
- disposeStream(this._stream);
98
- };
99
- Object.defineProperty(CallHandle.prototype, "isOpen", {
100
- get: function () {
101
- var _a;
102
- return ((_a = this.call.peerConnection) === null || _a === void 0 ? void 0 : _a.connectionState) === "connected"; // && this._stream?.active;
103
- },
104
- enumerable: false,
105
- configurable: true
106
- });
107
- Object.defineProperty(CallHandle.prototype, "isOpening", {
108
- get: function () {
109
- var _a;
110
- return ((_a = this.call.peerConnection) === null || _a === void 0 ? void 0 : _a.connectionState) === "connecting";
111
- },
112
- enumerable: false,
113
- configurable: true
114
- });
115
- Object.defineProperty(CallHandle.prototype, "isClosed", {
116
- get: function () {
117
- return !this.isOpen;
118
- },
119
- enumerable: false,
120
- configurable: true
121
- });
122
- return CallHandle;
123
- }(three_1.EventDispatcher));
124
- var PeerHandle = /** @class */ (function (_super) {
125
- __extends(PeerHandle, _super);
126
- function PeerHandle(context, id) {
127
- var _this = _super.call(this) || this;
128
- _this._incomingCalls = [];
129
- _this._outgoingCalls = [];
130
- _this._enabled = false;
131
- _this._enabledPeer = false;
132
- _this.onConnectRoomFn = _this.onConnectRoom.bind(_this);
133
- // private onUserJoinedOrLeftRoomFn: Function = this.onUserJoinedOrLeftRoom.bind(this);
134
- _this.onPeerConnectFn = _this.onPeerConnect.bind(_this);
135
- _this.onPeerReceiveCallFn = _this.onPeerReceivingCall.bind(_this);
136
- _this.context = context;
137
- _this.id = id;
138
- _this.setupPeer();
139
- navigator["getUserMedia"] = (navigator["getUserMedia"] || navigator["webkitGetUserMedia"] ||
140
- navigator["mozGetUserMedia"] || navigator["msGetUserMedia"]);
141
- return _this;
142
- }
143
- PeerHandle.getOrCreate = function (context, guid) {
144
- // if (id === undefined) {
145
- // // randomId
146
- // id = Math.random().toFixed(5);
147
- // }
148
- if (PeerHandle.instances.has(guid))
149
- return PeerHandle.instances.get(guid);
150
- var peer = new PeerHandle(context, guid);
151
- PeerHandle.instances.set(guid, peer);
152
- return peer;
153
- };
154
- PeerHandle.prototype.getMyPeerId = function () {
155
- if (this.context.connection.connectionId)
156
- return this.getPeerIdFromUserId(this.context.connection.connectionId);
157
- return undefined;
158
- };
159
- PeerHandle.prototype.getPeerIdFromUserId = function (userConnectionId) {
160
- // we build the peer id ourselves so we dont need to wait for peer to report it
161
- return this.id + "-" + userConnectionId;
162
- };
163
- PeerHandle.prototype.getUserIdFromPeerId = function (peerId) {
164
- return peerId.substring(this.id.length + 1);
165
- };
166
- PeerHandle.prototype.makeCall = function (peerId, stream) {
167
- var _a;
168
- var opts = { metadata: { userId: this.context.connection.connectionId } };
169
- var call = (_a = this._peer) === null || _a === void 0 ? void 0 : _a.call(peerId, stream, opts);
170
- if (call)
171
- return this.registerCall(call, CallDirection.Outgoing);
172
- return undefined;
173
- };
174
- Object.defineProperty(PeerHandle.prototype, "peer", {
175
- get: function () { return this._peer; },
176
- enumerable: false,
177
- configurable: true
178
- });
179
- // private _connectionPeerIdMap : Map<string, string> = new Map();
180
- PeerHandle.prototype.enable = function () {
181
- if (this._enabled)
182
- return;
183
- this._enabled = true;
184
- this.context.connection.beginListen(engine_networking_js_1.RoomEvents.JoinedRoom, this.onConnectRoomFn);
185
- // this.context.connection.beginListen(RoomEvents.UserJoinedRoom, this.onUserJoinedOrLeftRoomFn);
186
- // this.context.connection.beginListen(RoomEvents.UserLeftRoom, this.onUserJoinedOrLeftRoomFn);
187
- this.subscribePeerEvents();
188
- };
189
- PeerHandle.prototype.disable = function () {
190
- if (!this._enabled)
191
- return;
192
- this._enabled = false;
193
- this.context.connection.stopListen(engine_networking_js_1.RoomEvents.JoinedRoom, this.onConnectRoomFn);
194
- // this.context.connection.stopListen(RoomEvents.UserJoinedRoom, this.onUserJoinedOrLeftRoomFn);
195
- // this.context.connection.stopListen(RoomEvents.UserLeftRoom, this.onUserJoinedOrLeftRoomFn);
196
- this.unsubscribePeerEvents();
197
- };
198
- PeerHandle.prototype.onConnectRoom = function () {
199
- this.setupPeer();
200
- };
201
- ;
202
- // private onUserJoinedOrLeftRoom(_: UserJoinedOrLeftRoomModel): void {
203
- // };
204
- PeerHandle.prototype.setupPeer = function () {
205
- if (!this.context.connection.connectionId)
206
- return;
207
- if (this._enabledPeer)
208
- return;
209
- this._enabledPeer = true;
210
- if (!this._peer) {
211
- var peerId = this.getMyPeerId();
212
- if (peerId)
213
- this._peer = engine_networking_peer_js_1.getPeerjsInstance(peerId);
214
- else
215
- console.error("Failed to setup peerjs because we dont have a connection id", this.context.connection.connectionId);
216
- }
217
- if (this._enabled)
218
- this.subscribePeerEvents();
219
- };
220
- PeerHandle.prototype.subscribePeerEvents = function () {
221
- if (!this._peer)
222
- return;
223
- this._peer.on("open", this.onPeerConnectFn);
224
- this._peer.on("call", this.onPeerReceiveCallFn);
225
- // this.context.connection.beginListen(PeerEvent.Connected, this.onRemotePeerConnect.bind(this));
226
- // TODO: make connection to all current active calls even if the user is not anymore in the needle room
227
- };
228
- PeerHandle.prototype.unsubscribePeerEvents = function () {
229
- if (!this._peer)
230
- return;
231
- this._peer.off("open", this.onPeerConnectFn);
232
- this._peer.off("call", this.onPeerReceiveCallFn);
233
- // this.context.connection.stopListen(PeerEvent.Connected, this.onRemotePeerConnect.bind(this));
234
- };
235
- PeerHandle.prototype.onPeerConnect = function (id) {
236
- if (debug)
237
- console.log("Peer connected as", id);
238
- this.context.connection.send(PeerEvent.Connected, new PeerUserConnectedModel(this, id));
239
- };
240
- PeerHandle.prototype.onPeerReceivingCall = function (call) {
241
- call.answer();
242
- this.registerCall(call, CallDirection.Incoming);
243
- };
244
- PeerHandle.prototype.registerCall = function (call, direction) {
245
- var _this = this;
246
- var meta = call.metadata;
247
- if (!meta || !meta.userId) {
248
- console.error("Missing call metadata", call);
249
- }
250
- var userId = meta.userId;
251
- if (direction === CallDirection.Incoming && debug)
252
- console.log("Receive call from", call.metadata);
253
- else if (debug)
254
- console.log("Make call to", call.metadata);
255
- var arr = direction === CallDirection.Incoming ? this._incomingCalls : this._outgoingCalls;
256
- var handle = new CallHandle(userId, call, direction);
257
- arr.push(handle);
258
- call.on("error", function (err) {
259
- console.error("Call error", err);
260
- });
261
- call.on("close", function () {
262
- if (debug)
263
- console.log("Call ended", call.metadata);
264
- call.close();
265
- var index = arr.indexOf(handle);
266
- if (index !== -1)
267
- arr.splice(index, 1);
268
- });
269
- handle.addEventListener(PeerEvent.CallEnded, function (e) {
270
- _this.dispatchEvent(e);
271
- });
272
- if (direction === CallDirection.Incoming) {
273
- handle.addEventListener(PeerEvent.ReceiveStream, function (e) {
274
- _this.dispatchEvent(e);
275
- });
276
- call.on("stream", function () {
277
- // workaround for https://github.com/peers/peerjs/issues/636
278
- var intervalCounter = 0;
279
- var closeInterval = setInterval(function () {
280
- var isFirstInterval = intervalCounter === 0;
281
- if (!handle.isOpen && isFirstInterval) {
282
- intervalCounter += 1;
283
- clearInterval(closeInterval);
284
- handle.close();
285
- }
286
- }, 2000);
287
- });
288
- }
289
- return handle;
290
- };
291
- PeerHandle.instances = new Map();
292
- return PeerHandle;
293
- }(three_1.EventDispatcher));
294
- exports.PeerHandle = PeerHandle;
295
- // type UserVideoCall = {
296
- // call: Peer.MediaConnection;
297
- // stream: MediaStream;
298
- // userId: string;
299
- // }
300
- // type IncomingStreamArgs = {
301
- // stream: MediaStream;
302
- // userId: string;
303
- // }
304
- var NetworkedStreams = /** @class */ (function (_super) {
305
- __extends(NetworkedStreams, _super);
306
- function NetworkedStreams(context, peer) {
307
- var _this = _super.call(this) || this;
308
- // private _receiveVideoStreamListeners: Array<(info: IncomingStreamArgs) => void> = [];
309
- _this._sendingStreams = new Map();
310
- // private onUserJoinedPeer = (evt) => {
311
- // if (!this.context.connection.isConnected && evt.userId) {
312
- // this.startCallWithUserIfNotAlready(evt.userId);
313
- // }
314
- // }
315
- // When either we ourselves OR someone else is joining the room we want to make sure to re-establish all calls
316
- // and if the user that joined is not yet receiving our video stream we want to start a stream with them
317
- // https://github.com/needle-tools/needle-tiny/issues/697#issuecomment-1510425539
318
- _this.onJoinedRoom = function (evt) {
319
- if (debug)
320
- console.log(evt.userId + " joined room and I'm currently sending " + _this._sendingStreams.size + " streams");
321
- if (_this._sendingStreams.size > 0)
322
- _this.updateSendingCalls();
323
- };
324
- _this.onReceiveStream = function (evt) {
325
- if (debug)
326
- console.log("RECEIVE VIDEO", evt);
327
- _this.dispatchEvent({ type: PeerEvent.ReceiveStream, target: _this, stream: evt.stream, userId: evt.userId });
328
- };
329
- _this.onCallEnded = function (evt) {
330
- _this.dispatchEvent(evt);
331
- };
332
- _this.onUserConnected = function (user) {
333
- // console.log(this.peer.id, user.guid)
334
- if (_this.peer.id === user.guid) {
335
- if (debug)
336
- console.log("USER CONNECTED", user.guid, user);
337
- var stream = _this._sendingStreams.keys().next().value;
338
- _this.peer.makeCall(user.peerId, stream);
339
- }
340
- };
341
- _this.context = context;
342
- _this.peer = peer;
343
- return _this;
344
- }
345
- NetworkedStreams.create = function (comp) {
346
- var peer = PeerHandle.getOrCreate(comp.context, comp.context.connection.connectionId);
347
- return new NetworkedStreams(comp.context, peer);
348
- };
349
- NetworkedStreams.prototype.startSendingStream = function (stream) {
350
- if (!this._sendingStreams.has(stream)) {
351
- this._sendingStreams.set(stream, []);
352
- this.updateSendingCalls();
353
- }
354
- ;
355
- };
356
- NetworkedStreams.prototype.stopSendingStream = function (_steam) {
357
- if (_steam) {
358
- var calls = this._sendingStreams.get(_steam);
359
- if (calls) {
360
- if (debug)
361
- console.log("Closing calls", calls);
362
- for (var _i = 0, calls_1 = calls; _i < calls_1.length; _i++) {
363
- var call = calls_1[_i];
364
- call.close();
365
- }
366
- }
367
- this._sendingStreams["delete"](_steam);
368
- if (calls && debug)
369
- console.log("Currently sending", this._sendingStreams);
370
- }
371
- };
372
- // private onConnectRoomFn: Function = this.onConnectRoom.bind(this);
373
- // private onUserConnectedFn: Function = this.onUserConnected.bind(this);
374
- // private onUserLeftFn: Function = this.onUserLeft.bind(this);
375
- NetworkedStreams.prototype.enable = function () {
376
- this.peer.enable();
377
- this.peer.addEventListener(PeerEvent.ReceiveStream, this.onReceiveStream);
378
- //@ts-ignore
379
- this.peer.addEventListener(PeerEvent.CallEnded, this.onCallEnded);
380
- // this.peer.addEventListener(PeerEvent.UserJoined, this.onUserJoinedPeer);
381
- this.context.connection.beginListen(PeerEvent.Connected, this.onUserConnected);
382
- this.context.connection.beginListen(engine_networking_js_1.RoomEvents.JoinedRoom, this.onJoinedRoom);
383
- this.context.connection.beginListen(engine_networking_js_1.RoomEvents.UserJoinedRoom, this.onJoinedRoom);
384
- this.context.connection.beginListen(engine_networking_js_1.RoomEvents.UserLeftRoom, this.onUserLeft);
385
- };
386
- NetworkedStreams.prototype.disable = function () {
387
- this.peer.disable();
388
- this.peer.removeEventListener(PeerEvent.ReceiveStream, this.onReceiveStream);
389
- //@ts-ignore
390
- this.peer.removeEventListener(PeerEvent.CallEnded, this.onCallEnded);
391
- // this.peer.removeEventListener(PeerEvent.UserJoined, this.onUserJoinedPeer);
392
- this.context.connection.stopListen(PeerEvent.Connected, this.onUserConnected);
393
- this.context.connection.stopListen(engine_networking_js_1.RoomEvents.JoinedRoom, this.onJoinedRoom);
394
- this.context.connection.stopListen(engine_networking_js_1.RoomEvents.UserJoinedRoom, this.onJoinedRoom);
395
- this.context.connection.stopListen(engine_networking_js_1.RoomEvents.UserLeftRoom, this.onUserLeft);
396
- };
397
- NetworkedStreams.prototype.onUserLeft = function (_) {
398
- this.stopCallsToUsersThatAreNotInTheRoomAnymore();
399
- };
400
- NetworkedStreams.prototype.updateSendingCalls = function () {
401
- var _a;
402
- var startedNewCall = false;
403
- var localUserId = this.context.connection.connectionId;
404
- for (var _i = 0, _b = this._sendingStreams.keys(); _i < _b.length; _i++) {
405
- var stream = _b[_i];
406
- var calls = this._sendingStreams.get(stream) || [];
407
- var _loop_1 = function (userId) {
408
- if (userId === localUserId)
409
- return "continue";
410
- var existing = calls.find(function (c) { return c.userId === userId; });
411
- if (!existing || ((_a = existing.stream) === null || _a === void 0 ? void 0 : _a.active) === false) {
412
- if (debug)
413
- console.log("Starting call to", userId, localUserId);
414
- var handle = this_1.peer.makeCall(this_1.peer.getPeerIdFromUserId(userId), stream);
415
- if (handle) {
416
- startedNewCall = true;
417
- calls.push(handle);
418
- }
419
- }
420
- };
421
- var this_1 = this;
422
- for (var _c = 0, _d = this.context.connection.usersInRoom(); _c < _d.length; _c++) {
423
- var userId = _d[_c];
424
- _loop_1(userId);
425
- }
426
- this._sendingStreams.set(stream, calls);
427
- }
428
- this.stopCallsToUsersThatAreNotInTheRoomAnymore();
429
- if (startedNewCall && debug) {
430
- console.log("Currently sending", this._sendingStreams);
431
- }
432
- };
433
- // private startCallWithUserIfNotAlready(userId: string) {
434
- // for (const stream of this._sendingVideoStreams.keys()) {
435
- // const calls = this._sendingVideoStreams.get(stream) || [];
436
- // const existing = calls.find(c => c.userId === userId);
437
- // if (!existing || existing.stream?.active === false) {
438
- // if (debug) console.log("Starting call to", userId)
439
- // const handle = this.peer.makeCall(this.peer.getPeerIdFromUserId(userId), stream);
440
- // if (handle) {
441
- // calls.push(handle);
442
- // return true;
443
- // }
444
- // }
445
- // }
446
- // return false;
447
- // }
448
- NetworkedStreams.prototype.stopCallsToUsersThatAreNotInTheRoomAnymore = function () {
449
- for (var _i = 0, _a = this._sendingStreams.keys(); _i < _a.length; _i++) {
450
- var stream = _a[_i];
451
- var calls = this._sendingStreams.get(stream);
452
- if (!calls)
453
- continue;
454
- for (var i = calls.length - 1; i >= 0; i--) {
455
- var call = calls[i];
456
- if (!this.context.connection.userIsInRoom(call.userId)) {
457
- call.close();
458
- calls.splice(i, 1);
459
- }
460
- }
461
- }
462
- };
463
- return NetworkedStreams;
464
- }(three_1.EventDispatcher));
465
- exports.NetworkedStreams = NetworkedStreams;
466
- function disposeStream(str) {
467
- if (!str)
468
- return;
469
- for (var _i = 0, _a = str.getTracks(); _i < _a.length; _i++) {
470
- var cap = _a[_i];
471
- cap.stop();
472
- }
473
- }
474
- exports.disposeStream = disposeStream;
src/engine/dist/api.js.meta DELETED
@@ -1,7 +0,0 @@
1
- fileFormatVersion: 2
2
- guid: f0e01709ea200b648a0c053c2c79f225
3
- DefaultImporter:
4
- externalObjects: {}
5
- userData:
6
- assetBundleName:
7
- assetBundleVariant:
src/engine/dist/engine_networking_streams.js.meta DELETED
@@ -1,7 +0,0 @@
1
- fileFormatVersion: 2
2
- guid: 48d3950534f4dae478088f839e8c1578
3
- DefaultImporter:
4
- externalObjects: {}
5
- userData:
6
- assetBundleName:
7
- assetBundleVariant:
src/engine-components/postprocessing/Effects/Bloom.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { BlendFunction, BloomEffect, SelectiveBloomEffect } from "postprocessing";
2
+ import { MathUtils } from "three";
2
3
 
3
4
  import { serializable } from "../../../engine/engine_serialization.js";
4
5
  import { PostProcessingEffect } from "../PostProcessingEffect.js";
@@ -35,8 +36,8 @@
35
36
  }
36
37
  else {
37
38
  this.threshold.valueProcessor = (v: number) => v;
38
- this.intensity.valueProcessor = (v: number) => v;// * 2.2;
39
- this.scatter.valueProcessor = (v: number) => 100 * (1 - v);
39
+ this.intensity.valueProcessor = (v: number) => v;
40
+ this.scatter.valueProcessor = (v: number) => 1 * Math.PI * (1 - v);
40
41
  }
41
42
  }
42
43
 
@@ -54,6 +55,7 @@
54
55
  mipmapBlur: true,
55
56
  luminanceThreshold: this.threshold.value,
56
57
  luminanceSmoothing: this.scatter.value,
58
+ radius: 0.85, // default value
57
59
  intensity: this.intensity.value,
58
60
  });
59
61
  selectiveBloom.inverted = true;
@@ -64,25 +66,25 @@
64
66
  mipmapBlur: true,
65
67
  luminanceThreshold: this.threshold.value,
66
68
  luminanceSmoothing: this.scatter.value,
69
+ radius: 0.85, // default value
67
70
  intensity: this.intensity.value,
68
71
  });
69
72
  }
70
73
 
71
-
72
- // const blur = bloom["mipmapBlurPass"];
73
- // if (typeof blur === "object") {
74
- // blur.radius = this.scatter.value;
75
- // }
76
-
77
74
  this.intensity.onValueChanged = newValue => {
78
75
  bloom!.intensity = newValue;
79
76
  };
80
77
  this.threshold.onValueChanged = newValue => {
81
- bloom!.luminanceMaterial.threshold = newValue;
78
+ // for some reason the threshold needs to be gamma-corrected
79
+ bloom!.luminanceMaterial.threshold = Math.pow(newValue, 2.2);
82
80
  };
83
81
  this.scatter.onValueChanged = newValue => {
84
82
  bloom!.luminancePass.enabled = true;
83
+ console.log("Scatter", newValue);
85
84
  bloom!.luminanceMaterial.smoothing = newValue;
85
+ if (bloom["mipmapBlurPass"])
86
+ // heuristic so it looks similar to "scatter" in other engines
87
+ bloom!["mipmapBlurPass"].radius = MathUtils.lerp(0.1, 0.9, 1 - newValue / Math.PI);
86
88
  };
87
89
 
88
90
  return bloom;
src/engine-components/postprocessing/Effects/ColorAdjustments.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { BrightnessContrastEffect, HueSaturationEffect, ToneMappingEffect, ToneMappingMode } from "postprocessing";
2
- import { ACESFilmicToneMapping, AgXToneMapping, LinearToneMapping, NeutralToneMapping, NoToneMapping } from "three";
2
+ import { ACESFilmicToneMapping, AgXToneMapping, LinearToneMapping, NeutralToneMapping, NoToneMapping, ReinhardToneMapping } from "three";
3
3
 
4
4
  import { serializable } from "../../../engine/engine_serialization.js";
5
5
  import { GameObject } from "../../Component.js";
@@ -69,6 +69,7 @@
69
69
  case ACESFilmicToneMapping: return ToneMappingMode.ACES_FILMIC;
70
70
  case AgXToneMapping: return ToneMappingMode.AGX;
71
71
  case NeutralToneMapping: return ToneMappingMode.NEUTRAL;
72
+ case ReinhardToneMapping: return ToneMappingMode.REINHARD;
72
73
  default: return ToneMappingMode.LINEAR;
73
74
  }
74
75
  }
@@ -120,21 +121,5 @@
120
121
 
121
122
  return effects;
122
123
  }
123
-
124
- // apply() {
125
- // this.postExposure!.onValueChanged = () => {
126
- // this.setExposure();
127
- // };
128
-
129
- // // unity range goes from -15..15
130
- // // three.js range goes from 0..inf
131
- // if (this.postExposure?.overrideState) {
132
- // this.setExposure();
133
- // }
134
- // }
135
- // private setExposure() {
136
- // const exposure = Math.pow(2, this.postExposure?.value ?? 0);
137
- // this.context.renderer.toneMappingExposure = exposure;
138
- // }
139
124
  }
140
125
  registerCustomEffectType("ColorAdjustments", ColorAdjustments);
src/engine-components/postprocessing/Effects/DepthOfField.ts CHANGED
@@ -43,8 +43,6 @@
43
43
  bokehScale?: VolumeParameter;
44
44
 
45
45
  init() {
46
- if (debug) console.log("DOF: INIT");
47
-
48
46
  this.focalLength.valueProcessor = v => {
49
47
  const t = v / 300;
50
48
  const max = 2;// this.context.mainCameraComponent?.farClipPlane ?? 10;
src/engine/export/gltf/index.ts CHANGED
@@ -1,10 +1,11 @@
1
- import { AnimationAction, AnimationClip, Material, Mesh, Object3D, Texture } from "three";
2
- import type { Context } from "../../engine_setup";
1
+ import { AnimationClip, Object3D } from "three";
2
+ import type { Context } from "../../engine_setup.js";
3
3
  import { GLTFExporter, GLTFExporterOptions } from "three/examples/jsm/exporters/GLTFExporter";
4
4
  import GLTFMeshGPUInstancingExtension from "../../../include/three/EXT_mesh_gpu_instancing_exporter";
5
- import { registerExportExtensions } from "../../extensions";
6
- import { AnimationUtils } from "../../engine_animation";
7
- import { __isExporting } from "../state";
5
+ import { registerExportExtensions } from "../../extensions/index.js";
6
+ import { AnimationUtils } from "../../engine_animation.js";
7
+ import { __isExporting } from "../state.js";
8
+ import { GizmoWriter as GLTFGizmoWriter, RenderTextureWriter as GLTFRenderTextureWriter } from "./Writers.js";
8
9
 
9
10
  declare type ExportOptions = {
10
11
  context: Context,
@@ -38,6 +39,8 @@
38
39
 
39
40
  const exporter = new GLTFExporter();
40
41
  exporter.register(writer => new GLTFMeshGPUInstancingExtension(writer));
42
+ exporter.register(writer => new GLTFGizmoWriter(writer));
43
+ exporter.register(writer => new GLTFRenderTextureWriter(writer));
41
44
  registerExportExtensions(exporter, opts.context);
42
45
 
43
46
  const exporterOptions: GLTFExporterOptions = {
@@ -82,8 +85,6 @@
82
85
  }
83
86
  }
84
87
 
85
-
86
-
87
88
  return res;
88
89
  }
89
90
 
@@ -107,38 +108,8 @@
107
108
  }
108
109
  mixer.update(0);
109
110
  })
110
-
111
- const objects = Array.isArray(opts.scene) ? opts.scene : [opts.scene];
112
- objects.forEach(obj => {
113
- if (!obj) return;
114
- obj.traverse(o => {
115
- if ((o as any).isMesh) {
116
- const material = (o as Mesh).material;
117
- if (Array.isArray(material)) {
118
- for (const mat of material) {
119
- this.fixMaterial(mat);
120
- }
121
- }
122
- else {
123
- this.fixMaterial(material);
124
- }
125
- }
126
- });
127
- });
128
111
  }
129
112
 
130
- private fixMaterial(mat: Material) {
131
- // enumerate textures and make sure we don't export a WebGLRenderTarget texture
132
- for (const prop in mat) {
133
- const tex = mat[prop] as Texture | null | undefined;
134
- if (!tex) continue;
135
- if (tex.isRenderTargetTexture) {
136
- mat[prop] = null;
137
- this._undo.push(() => { mat[prop] = tex; });
138
- }
139
- }
140
- }
141
-
142
113
  onAfterExport(_opts: Required<ExportOptions>) {
143
114
  this._undo.forEach(fn => fn());
144
115
  this._undo.length = 0;
src/engine-components/timeline/PlayableDirector.ts CHANGED
@@ -11,6 +11,7 @@
11
11
  import { SignalReceiver } from './SignalAsset.js';
12
12
  import * as Models from "./TimelineModels.js";
13
13
  import * as Tracks from "./TimelineTracks.js";
14
+ import { serializable } from '../../engine/engine_serialization.js';
14
15
 
15
16
  const debug = getParam("debugtimeline");
16
17
 
@@ -64,7 +65,9 @@
64
65
 
65
66
  playableAsset?: Models.TimelineAssetModel;
66
67
  /** Set to true to start playing the timeline when the scene starts */
68
+ @serializable()
67
69
  playOnAwake?: boolean;
70
+ @serializable()
68
71
  extrapolationMode: DirectorWrapMode = DirectorWrapMode.Loop;
69
72
 
70
73
  /** @returns true if the timeline is currently playing */
src/engine-components/postprocessing/PostProcessingHandler.ts CHANGED
@@ -7,6 +7,8 @@
7
7
  import type { Constructor } from "../../engine/engine_types.js";
8
8
  import { getParam, isMobileDevice } from "../../engine/engine_utils.js";
9
9
  import { Camera } from "../Camera.js";
10
+ import { ColorAdjustments } from "./Effects/ColorAdjustments.js";
11
+ import { ToneMapping } from "./Effects/Tonemapping.js";
10
12
  import { PostProcessingEffect } from "./PostProcessingEffect.js";
11
13
 
12
14
  const debug = getParam("debugpost");
@@ -75,6 +77,7 @@
75
77
  this._composer = null;
76
78
  }
77
79
 
80
+ private tempColorAdjustments: ColorAdjustments | null = null;
78
81
 
79
82
  private onApply(context: Context, components: PostProcessingEffect[]) {
80
83
 
@@ -90,7 +93,17 @@
90
93
  // const effects: Array<Effect | Pass> = [];
91
94
  this._effects.length = 0;
92
95
 
93
- for (const component of components) {
96
+ // Tonemapping is currently applied from the ColorAdjustments effect, so we need to check if that is present,
97
+ // and add a default ColorAdjustments effect if not.
98
+ const haveTonemappingComponent = components.some(c => c instanceof ToneMapping);
99
+ const haveColorAdjustmentsComponent = components.some(c => c instanceof ColorAdjustments && c.active);
100
+ if (haveTonemappingComponent && !haveColorAdjustmentsComponent) {
101
+ if (debug) console.log("Adding a default ColorAdjustments component to apply tonemapping.", ...components);
102
+ if (this.tempColorAdjustments === null) this.tempColorAdjustments = new ColorAdjustments();
103
+ this._lastVolumeComponents.push(this.tempColorAdjustments);
104
+ }
105
+
106
+ for (const component of this._lastVolumeComponents) {
94
107
  //@ts-ignore
95
108
  component.context = context;
96
109
  if (component.apply) {
src/engine-components/postprocessing/Effects/Tonemapping.ts CHANGED
@@ -1,20 +1,21 @@
1
- import { ACESFilmicToneMapping, LinearToneMapping, NeutralToneMapping, NoToneMapping, ReinhardToneMapping } from "three";
1
+ import { ACESFilmicToneMapping, AgXToneMapping, LinearToneMapping, NeutralToneMapping, NoToneMapping, ReinhardToneMapping } from "three";
2
2
 
3
3
  import { serializable } from "../../../engine/engine_serialization.js";
4
- import { type EffectProviderResult, PostProcessingEffect } from "../PostProcessingEffect.js";
4
+ import { PostProcessingEffect } from "../PostProcessingEffect.js";
5
5
  import { VolumeParameter } from "../VolumeParameter.js";
6
6
  import { registerCustomEffectType } from "../VolumeProfile.js";
7
7
 
8
8
 
9
9
  export enum TonemappingMode {
10
10
  None = 0,
11
- Neutral = 1, // Neutral tonemapper
11
+ Neutral = 1, // Neutral tonemapper, close to Reinhard
12
12
  ACES = 2, // ACES Filmic reference tonemapper (custom approximation)
13
+ AgX = 3, // AgX Filmic tonemapper
14
+ KhronosNeutral = 4, // PBR Neural tonemapper
13
15
  }
14
16
 
15
17
  export class ToneMapping extends PostProcessingEffect {
16
18
 
17
-
18
19
  get typeName() {
19
20
  return "ToneMapping";
20
21
  }
@@ -36,6 +37,9 @@
36
37
  }
37
38
 
38
39
  private _apply(v: TonemappingMode) {
40
+ // The renderer tonemapping mode is used when NO volume is in effect.
41
+ // It does not have an effect when a composer exists, and then tonemapping is applied as posteffect
42
+ // from ColodAdjustments.ts
39
43
  this.context.renderer.toneMapping = this.getThreeToneMapping(v);
40
44
  }
41
45
 
@@ -44,11 +48,15 @@
44
48
  case TonemappingMode.None:
45
49
  return LinearToneMapping;
46
50
  case TonemappingMode.Neutral:
47
- return NeutralToneMapping;
51
+ return ReinhardToneMapping;
48
52
  case TonemappingMode.ACES:
49
53
  return ACESFilmicToneMapping;
54
+ case TonemappingMode.AgX:
55
+ return AgXToneMapping;
56
+ case TonemappingMode.KhronosNeutral:
57
+ return NeutralToneMapping;
50
58
  default:
51
- return LinearToneMapping;
59
+ return NeutralToneMapping;
52
60
  }
53
61
  }
54
62
 
src/engine-components/webxr/WebXR.ts CHANGED
@@ -31,39 +31,52 @@
31
31
 
32
32
  // UI
33
33
  /** When enabled a button will be added to the UI to enter VR */
34
+ @serializable()
34
35
  createVRButton: boolean = true;
35
36
  /** When enabled a button will be added to the UI to enter AR */
37
+ @serializable()
36
38
  createARButton: boolean = true;
37
39
  /** When enabled a send to quest button will be shown if the device does not support VR */
40
+ @serializable()
38
41
  createSendToQuestButton: boolean = true;
39
42
  /** When enabled a QRCode will be created to open the website on a mobile device */
43
+ @serializable()
40
44
  createQRCode: boolean = true;
41
45
 
42
46
  // VR Settings
43
47
  /** When enabled default movement behaviour will be added */
48
+ @serializable()
44
49
  useDefaultControls: boolean = true;
45
50
  /** When enabled controller models will automatically be created and updated when you are using controllers in WebXR */
51
+ @serializable()
46
52
  showControllerModels: boolean = true;
47
53
  /** When enabled hand models will automatically be created and updated when you are using hands in WebXR */
54
+ @serializable()
48
55
  showHandModels: boolean = true;
49
56
 
50
57
  // AR Settings
51
58
  /** When enabled the scene must be placed in AR */
59
+ @serializable()
52
60
  usePlacementReticle: boolean = true;
53
61
  /** When enabled you can position, rotate or scale your AR scene with one or two fingers */
62
+ @serializable()
54
63
  usePlacementAdjustment: boolean = true;
55
64
  /** Used when `usePlacementReticle` is enabled */
65
+ @serializable()
56
66
  arSceneScale: number = 1;
57
67
  /** Experimental: When enabled an XRAnchor will be created for the AR scene and the position will be updated to the anchor position every few frames */
68
+ @serializable()
58
69
  useXRAnchor: boolean = false;
59
70
 
60
71
  /** When enabled a USDZExporter component will be added to the scene (if none is found) */
72
+ @serializable()
61
73
  useQuicklookExport: boolean = false;
62
74
 
63
75
 
64
76
  /** Preview feature enabling occlusion (when available: https://github.com/cabanier/three.js/commit/b6ee92bcd8f20718c186120b7f19a3b68a1d4e47)
65
77
  * Enables the 'depth-sensing' WebXR feature to provide realtime depth occlusion. Only supported on Oculus Quest right now.
66
78
  */
79
+ @serializable()
67
80
  useDepthSensing: boolean = false;
68
81
 
69
82
 
src/engine/export/gltf/Writers.ts ADDED
@@ -0,0 +1,35 @@
1
+
2
+ import { Object3D, Texture } from 'three';
3
+ import { GLTFExporterPlugin, GLTFWriter } from 'three/examples/jsm/exporters/GLTFExporter.js';
4
+ import { Gizmos } from '../../engine_gizmos.js';
5
+ import { createFlatTexture } from '../../engine_shaders.js';
6
+ import { RGBAColor } from '../../../engine-components/js-extensions/index.js';
7
+
8
+ declare type BeforeWriteArgs = { keep: boolean };
9
+
10
+ export abstract class BaseWriter implements GLTFExporterPlugin {
11
+ private readonly writer: GLTFWriter;
12
+ constructor(writer: GLTFWriter) {
13
+ this.writer = writer;
14
+ }
15
+ writeNode(_node: Object3D) { }
16
+ }
17
+
18
+ export class GizmoWriter extends BaseWriter {
19
+
20
+ beforeWriteNode(node: Object3D, args: BeforeWriteArgs) {
21
+ if (Gizmos.isGizmo(node)) {
22
+ args.keep = false;
23
+ }
24
+ }
25
+
26
+ }
27
+
28
+ export class RenderTextureWriter extends BaseWriter {
29
+
30
+ beforeWriteTexture(texture: Texture, args: BeforeWriteArgs & { newTexture?: Texture }) {
31
+ if (texture.isRenderTargetTexture) {
32
+ args.newTexture = createFlatTexture(new RGBAColor(1, 1, 1, 0))
33
+ }
34
+ }
35
+ }