janusweb 1.5.30 → 1.5.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CHANGELOG +39 -0
  2. package/LICENSE +1 -1
  3. package/media/assets/janus-avatar-animations.glb +0 -0
  4. package/media/assets/janus-avatar-base.glb +0 -0
  5. package/media/assets/webui/apps/avatar/avatar.css +6 -2
  6. package/media/assets/webui/apps/avatar/avatar.js +99 -11
  7. package/media/assets/webui/apps/buttons/buttons.html +2 -2
  8. package/media/assets/webui/apps/buttons/buttons.js +3 -3
  9. package/media/assets/webui/apps/comms/comms.js +7 -4
  10. package/media/assets/webui/apps/comms/voip.js +133 -57
  11. package/media/assets/webui/apps/editor/codemirror/addon/hint/javascript-hint.js +162 -0
  12. package/media/assets/webui/apps/editor/codemirror/addon/hint/show-hint.css +36 -0
  13. package/media/assets/webui/apps/editor/codemirror/addon/hint/show-hint.js +529 -0
  14. package/media/assets/webui/apps/editor/codemirror/addon/hint/xml-hint.js +140 -0
  15. package/media/assets/webui/apps/editor/codemirror/keymap/vim.js +5734 -0
  16. package/media/assets/webui/apps/editor/codemirror/lib/codemirror.css +350 -0
  17. package/media/assets/webui/apps/editor/codemirror/lib/codemirror.js +9800 -0
  18. package/media/assets/webui/apps/editor/codemirror/lib/jmldark.css +33 -0
  19. package/media/assets/webui/apps/editor/codemirror/mode/css/css.js +864 -0
  20. package/media/assets/webui/apps/editor/codemirror/mode/htmlmixed/htmlmixed.js +153 -0
  21. package/media/assets/webui/apps/editor/codemirror/mode/javascript/javascript.js +942 -0
  22. package/media/assets/webui/apps/editor/codemirror/mode/xml/xml.js +413 -0
  23. package/media/assets/webui/apps/editor/editor.css +3 -0
  24. package/media/assets/webui/apps/editor/editor.js +409 -9
  25. package/media/assets/webui/apps/editor/editor.json +6 -3
  26. package/media/assets/webui/apps/inventory/inventory.html +7 -4
  27. package/media/assets/webui/apps/inventory/inventory.js +2 -2
  28. package/media/assets/webui/apps/locomotion/teleporter.js +10 -9
  29. package/media/assets/webui/apps/navigation/navigation.js +12 -12
  30. package/media/assets/webui/apps/settings/settings.html +1 -1
  31. package/media/assets/webui/apps/vfs/browserfs/browserfs.js +8 -0
  32. package/media/assets/webui/apps/vfs/vfs.css +52 -0
  33. package/media/assets/webui/apps/vfs/vfs.js +452 -0
  34. package/media/assets/webui/apps/vfs/vfs.json +10 -0
  35. package/media/assets/webui/apps/virtualgamepad/virtualgamepad.js +9 -7
  36. package/media/assets/webui/apps/xrmenu/xrmenu.js +13 -4
  37. package/media/assets/webui/default.json +2 -1
  38. package/media/assets/webui/none.json +1 -0
  39. package/media/assets/webui/themes/default.css +29 -2
  40. package/media/assets.json +2 -1
  41. package/media/index.html +1 -1
  42. package/media/lib/draco/README.md +32 -0
  43. package/media/lib/draco/draco_decoder.js +52 -0
  44. package/media/lib/draco/draco_decoder.wasm +0 -0
  45. package/media/lib/draco/draco_encoder.js +33 -0
  46. package/media/lib/draco/draco_wasm_wrapper.js +104 -0
  47. package/media/lib/draco/gltf/draco_decoder.js +48 -0
  48. package/media/lib/draco/gltf/draco_decoder.wasm +0 -0
  49. package/media/lib/draco/gltf/draco_encoder.js +33 -0
  50. package/media/lib/draco/gltf/draco_wasm_wrapper.js +104 -0
  51. package/media/lib/physx/physx.release.js +21 -0
  52. package/media/lib/physx/physx.release.wasm +0 -0
  53. package/media/manifest.json +5 -5
  54. package/media/service-worker.js +7 -0
  55. package/package.json +2 -9
  56. package/scripts/client.js +67 -46
  57. package/scripts/config.js +2 -0
  58. package/scripts/elements/linesegments.js +10 -3
  59. package/scripts/external/JanusFireboxParser.js +1 -0
  60. package/scripts/image.js +7 -1
  61. package/scripts/janusbase.js +104 -43
  62. package/scripts/janusghost.js +314 -16
  63. package/scripts/januslight.js +11 -2
  64. package/scripts/janusparagraph.js +8 -6
  65. package/scripts/janusparticle.js +26 -16
  66. package/scripts/janusplayer.js +126 -37
  67. package/scripts/janusweb.js +26 -2
  68. package/scripts/janusxrplayer.js +5 -3
  69. package/scripts/multiplayermanager.js +6 -4
  70. package/scripts/object.js +246 -88
  71. package/scripts/portal.js +23 -14
  72. package/scripts/remoteplayer.js +1 -25
  73. package/scripts/room.js +199 -77
  74. package/scripts/sound.js +8 -6
  75. package/scripts/text.js +13 -5
  76. package/scripts/translators/janusvfs.js +20 -0
  77. package/scripts/video.js +1 -1
  78. package/scripts/websurface.js +17 -3
  79. package/utils/build.sh +3 -0
  80. package/utils/init.sh +2 -2
  81. package/scripts/chat.js +0 -80
  82. package/scripts/ui.js +0 -265
  83. package/scripts/urlbar.js +0 -93
  84. package/templates/janusweb.tpl +0 -3
package/scripts/room.js CHANGED
@@ -3,7 +3,7 @@ elation.require([
3
3
  'engine.things.generic', 'engine.things.label', 'engine.things.skybox',
4
4
  'janusweb.object', 'janusweb.portal', 'janusweb.image', 'janusweb.video', 'janusweb.text', 'janusweb.janusparagraph',
5
5
  'janusweb.sound', 'janusweb.januslight', 'janusweb.janusparticle', 'janusweb.janusghost',
6
- 'janusweb.translators.bookmarks', 'janusweb.translators.reddit', 'janusweb.translators.error', 'janusweb.translators.blank', 'janusweb.translators.default', 'janusweb.translators.dat'
6
+ 'janusweb.translators.bookmarks', 'janusweb.translators.reddit', 'janusweb.translators.error', 'janusweb.translators.blank', 'janusweb.translators.default', 'janusweb.translators.dat', 'janusweb.translators.janusvfs'
7
7
  ], function() {
8
8
  elation.component.add('engine.things.janusroom', function() {
9
9
  this.postinit = function() {
@@ -26,13 +26,14 @@ elation.require([
26
26
  'corsproxy': { type: 'string', default: false },
27
27
  'baseurl': { type: 'string', default: false },
28
28
  'source': { type: 'string' },
29
- 'skybox': { type: 'boolean', default: true },
30
- 'skybox_left': { type: 'string' },
31
- 'skybox_right': { type: 'string' },
32
- 'skybox_up': { type: 'string' },
33
- 'skybox_down': { type: 'string' },
34
- 'skybox_front': { type: 'string' },
35
- 'skybox_back': { type: 'string' },
29
+ 'skybox': { type: 'boolean', default: true, set: this.toggleSkybox },
30
+ 'skybox_equi': { type: 'string', set: this.setSkybox },
31
+ 'skybox_left_id': { type: 'string', set: this.setSkybox },
32
+ 'skybox_right_id': { type: 'string', set: this.setSkybox },
33
+ 'skybox_up_id': { type: 'string', set: this.setSkybox },
34
+ 'skybox_down_id': { type: 'string', set: this.setSkybox },
35
+ 'skybox_front_id': { type: 'string', set: this.setSkybox },
36
+ 'skybox_back_id': { type: 'string', set: this.setSkybox },
36
37
  'cubemap_irradiance_id': { type: 'string' },
37
38
  'cubemap_radiance_id': { type: 'string' },
38
39
  'fog': { type: 'boolean', default: false, set: this.setFog },
@@ -75,11 +76,13 @@ elation.require([
75
76
  'className': { type: 'string', default: '', set: this.setClassName },
76
77
  'gazetime': { type: 'float', default: 1000 },
77
78
  'selfavatar': { type: 'boolean', default: false },
78
- 'requirescripts': { type: 'string' },
79
+ 'requires': { type: 'string' },
79
80
  'onload': { type: 'string' },
80
81
  'sync': { type: 'boolean', default: false },
82
+ 'pointerlock': { type: 'boolean', default: true },
81
83
  });
82
84
  this.translators = {
85
+ '^janus-vfs:': elation.janusweb.translators.janusvfs({janus: this.janus}),
83
86
  '^about:blank$': elation.janusweb.translators.blank({janus: this.janus}),
84
87
  '^bookmarks$': elation.janusweb.translators.bookmarks({janus: this.janus}),
85
88
  '^dat:': elation.janusweb.translators.dat({janus: this.janus}),
@@ -225,15 +228,15 @@ elation.require([
225
228
  // Reparent player to the room if necessary
226
229
  this.appendChild(player.getProxyObject());
227
230
  }
231
+ player.reset_position();
228
232
  player.position.copy(pos);
229
233
  player.orientation.copy(orientation);
230
- //player.reset_position();
231
234
  player.properties.movestrength = 80 * this.properties.walk_speed;
232
235
  player.properties.runstrength = 80 * this.properties.run_speed;
233
236
  player.cursor_visible = (!janus.hmd ? elation.utils.any(this.cursor_visible, true) : false);
234
237
  player.cursor_opacity = elation.utils.any(this.cursor_opacity, .8);
235
238
  // FIXME - for some reason the above call sometimes orients the player backwards. Doing it on a delay fixes it...
236
- setTimeout(elation.bind(player, player.reset_position), 0);
239
+ //setTimeout(elation.bind(player, player.reset_position), 0);
237
240
  }
238
241
  this.setHash = function(hash) {
239
242
  this.urlhash = hash;
@@ -255,7 +258,15 @@ elation.require([
255
258
  if (links[i].url == referrer) {
256
259
  //spawnpoint.position = links[i].position;
257
260
  spawnpoint.position = links[i].localToWorld(V(0,0,player.fatness*2));
258
- spawnpoint.orientation = links[i].orientation.clone().multiply(new THREE.Quaternion().setFromEuler(new THREE.Euler(0, Math.PI, 0))); // Flip 180 degrees from portal orientation
261
+ spawnpoint.orientation = links[i].orientation.clone();
262
+ let node = links[i];
263
+ let roomproxy = this.getProxyObject();
264
+ while (node.parent && node.parent != roomproxy) {
265
+ node = node.parent;
266
+ node.handleFrameUpdates({});
267
+ spawnpoint.orientation.multiply(node.orientation);
268
+ }
269
+ spawnpoint.orientation.multiply(new THREE.Quaternion().setFromEuler(new THREE.Euler(0, Math.PI, 0))); // Flip 180 degrees from portal orientation
259
270
  break;
260
271
  }
261
272
  }
@@ -286,22 +297,32 @@ elation.require([
286
297
  }
287
298
  if (this.skyboxtexture) {
288
299
  this.skyboxobj.setTexture(this.skyboxtexture);
289
- return;
300
+ //return;
290
301
  }
291
302
 
292
- var hasSkybox = (this.skybox_left || this.skybox_right || this.skybox_top || this.skybox_bottom || this.skybox_left || this.skybox_right) != undefined;
293
- if (hasSkybox) {
294
- var assets = [
295
- this.getAsset('image', this.skybox_right || 'black'),
296
- this.getAsset('image', this.skybox_left || 'black'),
297
- this.getAsset('image', this.skybox_up || 'black'),
298
- this.getAsset('image', this.skybox_down || 'black'),
299
- this.getAsset('image', this.skybox_front || 'black'),
300
- this.getAsset('image', this.skybox_back || 'black')
303
+ var hasSkybox = (this.skybox_left_id || this.skybox_right_id || this.skybox_top_id || this.skybox_bottom_id || this.skybox_left_id || this.skybox_right_id) != undefined;
304
+ var assets = [];
305
+ if (this.skybox_equi) {
306
+ let equi = this.getAsset('image', this.skybox_equi);
307
+ elation.events.add(equi, 'asset_load', ev => {
308
+ this.skyboxtexture = ev.target._texture;
309
+ if (this.janus.currentroom === this) {
310
+ this.skyboxobj.setTexture(this.skyboxtexture);
311
+ }
312
+ });
313
+ equi.getInstance();
314
+ } else if (hasSkybox) {
315
+ assets = [
316
+ this.getAsset('image', this.skybox_right_id || 'black'),
317
+ this.getAsset('image', this.skybox_left_id || 'black'),
318
+ this.getAsset('image', this.skybox_up_id || 'black'),
319
+ this.getAsset('image', this.skybox_down_id || 'black'),
320
+ this.getAsset('image', this.skybox_front_id || 'black'),
321
+ this.getAsset('image', this.skybox_back_id || 'black')
301
322
  ];
302
323
  } else {
303
324
  var skyboxname = 'dayskybox';
304
- var assets = [
325
+ assets = [
305
326
  this.getAsset('image', skyboxname + '_right'),
306
327
  this.getAsset('image', skyboxname + '_left'),
307
328
  this.getAsset('image', skyboxname + '_up'),
@@ -328,6 +349,12 @@ elation.require([
328
349
  assets.forEach(elation.bind(this, function(asset) {
329
350
  if (asset) {
330
351
  var n = asset.getInstance();
352
+ if (asset.loaded) {
353
+ loaded++;
354
+ if (loaded + errored == 6) {
355
+ this.processSkybox(assets);
356
+ }
357
+ } else {
331
358
  elation.events.add(n, 'asset_load,asset_error', elation.bind(this, function(ev) {
332
359
  if (ev.type == 'asset_load') loaded++;
333
360
  else errored++;
@@ -336,6 +363,7 @@ elation.require([
336
363
  }
337
364
  }));
338
365
  }
366
+ }
339
367
  }));
340
368
  return false;
341
369
  }
@@ -386,10 +414,26 @@ elation.require([
386
414
  if (this.janus.currentroom === this) {
387
415
  this.skyboxobj.setTexture(this.skyboxtexture);
388
416
  }
417
+ elation.events.fire({element: this, type: 'skybox_update'});
389
418
  return true;
390
419
  }
391
420
  }
392
421
  }
422
+ this.toggleSkybox = function() {
423
+ if (this.skybox) {
424
+ this.engine.systems.render.renderer.setClearAlpha(1);
425
+ if (this.skyboxtexture) {
426
+ this.skyboxobj.setTexture(this.skyboxtexture);
427
+ } else {
428
+ this.setSkybox();
429
+ }
430
+ } else {
431
+ this.engine.systems.render.renderer.setClearAlpha(0);
432
+ if (this.skyboxobj) {
433
+ this.skyboxobj.setTexture(null);
434
+ }
435
+ }
436
+ }
393
437
  this.setFog = function() {
394
438
  if (this.fog) {
395
439
  var fogcol = this.properties.fog_col || 0;
@@ -663,11 +707,12 @@ elation.require([
663
707
  this.fullsource = data;
664
708
  var titlere = /<title>([\s\S]*?)<\/title>/mi;
665
709
  var re = /<fireboxroom>[\s\S]*?<\/fireboxroom>/mi;
710
+ var re2 = /<janus-viewer[^>]*>[\s\S]*?<\/janus-viewer>/mi;
666
711
  var mtitle = data.match(titlere);
667
712
  var parsed = {
668
713
  title: 'Untitled Room',
669
714
  source: false
670
- }
715
+ };
671
716
  if (mtitle) {
672
717
  parsed.title = mtitle[1];
673
718
  this.setTitle(mtitle[1]);
@@ -677,15 +722,56 @@ elation.require([
677
722
  var m = data.match(re);
678
723
  if (m) {
679
724
  parsed.source = m[0];
725
+ } else {
726
+ let m2 = data.match(re2);
727
+ if (m2) {
728
+ parsed.source = m2[0].replaceAll('janus-viewer', 'fireboxroom');
729
+ }
680
730
  }
681
731
  return parsed;
682
732
  }
733
+ this.updateSource = function(source) {
734
+ var datapath = elation.config.get('janusweb.datapath', '/media/janusweb');
735
+ try {
736
+ var roomdata = this.janus.parser.parse(source, this.baseurl, datapath);
737
+ } catch (e) {
738
+ }
739
+ console.log('updated roomdata!', roomdata);
740
+ if (roomdata && roomdata.room) {
741
+ for (let k in roomdata.room) {
742
+ let val = roomdata.room[k];
743
+ if (val !== null && room[k] != val) {
744
+ console.log('update room value', k, room[k], val);
745
+ room[k] = val;
746
+ }
747
+ }
748
+ if (roomdata.object) {
749
+ for (let i = 0; i < roomdata.object.length; i++) {
750
+ let objdata = roomdata.object[i];
751
+ let roomobj = room.objects[objdata.js_id];
752
+ if (roomobj) {
753
+ for (let k in objdata) {
754
+ let val = objdata[k];
755
+ if (roomobj[k] != objdata[k] && val !== null) {
756
+ roomobj[k] = val;
757
+ }
758
+ }
759
+ } else {
760
+ objdata.persist = true;
761
+ this.createObject('object', objdata);
762
+ }
763
+ }
764
+ }
765
+ }
766
+ }
683
767
 
684
768
  this.loadRoomAssets = function(roomdata) {
685
769
  if (roomdata && roomdata.assets && roomdata.assets.assetlist && roomdata.assets.assetlist.length > 0) {
686
770
  var assetlist = roomdata.assets.assetlist;
687
771
  if (roomdata.assets.websurfaces) {
688
772
  elation.utils.merge(roomdata.assets.websurfaces, this.websurfaces);
773
+ if (!this.roomassets.websurface) this.roomassets.websurface = {};
774
+ elation.utils.merge(roomdata.assets.websurfaces, this.roomassets.websurface);
689
775
  }
690
776
 
691
777
  if (roomdata.assets.ghosts) {
@@ -787,8 +873,8 @@ elation.require([
787
873
  links.forEach(link => {
788
874
  let url = this.getFullRoomURL(link.url);
789
875
  if (url == this.referrer) {
790
- this.spawnpoint.quaternion.copy(link.orientation.inverse());
791
- this.spawnpoint.position.fromArray(link.pos);
876
+ this.spawnpoint.quaternion.copy(link.orientation).invert();
877
+ this.spawnpoint.position.copy(link.pos);
792
878
  this.spawnpoint.position.add(this.spawnpoint.localToWorld(V(0,0,-player.fatness)));
793
879
  hasReciprocalLink = true;
794
880
  }
@@ -812,15 +898,18 @@ elation.require([
812
898
  });
813
899
  }
814
900
  }
815
- setTimeout(() => this.setPlayerPosition(), 0);
901
+ if (this.active) {
902
+ setTimeout(() => this.setPlayerPosition(), 0);
903
+ }
816
904
 
817
905
  if (typeof room.skybox != 'undefined') this.properties.skybox = room.skybox;
818
- if (room.skybox_left_id) this.properties.skybox_left = room.skybox_left_id;
819
- if (room.skybox_right_id) this.properties.skybox_right = room.skybox_right_id;
820
- if (room.skybox_up_id) this.properties.skybox_up = room.skybox_up_id;
821
- if (room.skybox_down_id) this.properties.skybox_down = room.skybox_down_id;
822
- if (room.skybox_front_id) this.properties.skybox_front = room.skybox_front_id;
823
- if (room.skybox_back_id) this.properties.skybox_back = room.skybox_back_id;
906
+ if (room.skybox_equi) this.properties.skybox_equi = room.skybox_equi;
907
+ if (room.skybox_left_id) this.properties.skybox_left_id = room.skybox_left_id;
908
+ if (room.skybox_right_id) this.properties.skybox_right_id = room.skybox_right_id;
909
+ if (room.skybox_up_id) this.properties.skybox_up_id = room.skybox_up_id;
910
+ if (room.skybox_down_id) this.properties.skybox_down_id = room.skybox_down_id;
911
+ if (room.skybox_front_id) this.properties.skybox_front_id = room.skybox_front_id;
912
+ if (room.skybox_back_id) this.properties.skybox_back_id = room.skybox_back_id;
824
913
 
825
914
  if (room.cubemap_radiance_id) this.properties.cubemap_radiance_id = room.cubemap_radiance_id;
826
915
  if (room.cubemap_irradiance_id) this.properties.cubemap_irradiance_id = room.cubemap_irradiance_id;
@@ -859,6 +948,7 @@ elation.require([
859
948
  this.gravity = elation.utils.any(room.gravity, 0);
860
949
  this.flying = elation.utils.any(room.flying, true);
861
950
  this.teleport = elation.utils.any(room.teleport, true);
951
+ this.pointerlock = elation.utils.any(room.pointerlock, true);
862
952
  //if (room.col) this.properties.col = room.col;
863
953
 
864
954
  this.properties.walk_speed = room.walk_speed || 1.8;
@@ -881,10 +971,12 @@ elation.require([
881
971
  this.pendingScriptMap = {};
882
972
  this.loadScripts(assets.scripts);
883
973
  }
884
- if (room.require) {
974
+
975
+ let requires = room.requires || room.require;
976
+ if (requires) {
885
977
  let roomproxy = this.getProxyObject();
886
- roomproxy.require(room.require);
887
- this.requirescripts = room.require;
978
+ roomproxy.require(requires);
979
+ this.requires = requires;
888
980
  }
889
981
  }
890
982
  this.applyingEdits = false;
@@ -896,6 +988,7 @@ elation.require([
896
988
  }
897
989
  this.loadScripts = function(scripts) {
898
990
  scripts.forEach(s => {
991
+ this.loadNewAsset('script', { src: s.src, override: { room: this.getProxyObject() } });
899
992
  let scriptasset = this.getAsset('script', s.src);
900
993
  let script = scriptasset.getInstance();
901
994
  if (scriptasset.loaded) {
@@ -912,6 +1005,10 @@ elation.require([
912
1005
  if (!this.pendingScriptMap[s.src]) {
913
1006
  this.pendingScripts++;
914
1007
  this.pendingScriptMap[s.src] = true;;
1008
+ elation.events.add(scriptasset, 'asset_error', (ev) => {
1009
+ console.error('Failed to load Janus room script', scriptasset);
1010
+ this.doScriptOnload();
1011
+ });
915
1012
  elation.events.add(script, 'asset_load', () => {
916
1013
  script.onload = () => this.doScriptOnload();
917
1014
  document.head.appendChild(script);
@@ -947,9 +1044,9 @@ elation.require([
947
1044
  elation.events.add(window, 'click', this.onClick);
948
1045
  elation.events.add(window, 'keydown', this.onKeyDown);
949
1046
  elation.events.add(window, 'keyup', this.onKeyUp);
950
- elation.events.add(this.engine.client.container, 'mousedown,touchstart', this.onMouseDown);
951
- elation.events.add(this.engine.client.container, 'mouseup,touchend', this.onMouseUp);
952
- elation.events.add(this.engine.client.container, 'mousemove', this.onMouseMove);
1047
+ //elation.events.add(this, 'mousedown,touchstart', this.onMouseDown);
1048
+ //elation.events.add(this, 'mouseup,touchend', this.onMouseUp);
1049
+ //elation.events.add(this, 'mousemove', this.onMouseMove);
953
1050
  elation.events.add(this, 'click', this.onObjectClick);
954
1051
  /*
955
1052
  elation.events.add(this, 'dragenter', this.handleDragOver);
@@ -965,9 +1062,10 @@ elation.require([
965
1062
  console.log('connect room audio to graph', this.audionodes.gain, this.audionodes.listener.getInput(), this);
966
1063
  this.fadeAudioIn(2);
967
1064
  }
968
- }
969
- if (this.engine.systems.admin) {
970
- elation.events.add(this.engine.systems.admin, 'admin_edit_change', elation.bind(this, this.onRoomEdit));
1065
+ this.engine.systems.controls.pointerLockEnabled = this.pointerlock;
1066
+ if (this.engine.systems.admin) {
1067
+ elation.events.add(this.engine.systems.admin, 'admin_edit_change', elation.bind(this, this.onRoomEdit));
1068
+ }
971
1069
  }
972
1070
  //this.showDebug();
973
1071
  }
@@ -1015,6 +1113,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1015
1113
  console.log('disconnect room audio from graph', this.audionodes.gain, this.audionodes.listener.getInput(), this);
1016
1114
  }, 1500);
1017
1115
  }
1116
+ //this.engine.systems.controls.pointerLockEnabled = this.pointerlock;
1018
1117
  }
1019
1118
  }
1020
1119
  this.setTitle = function(title) {
@@ -1226,7 +1325,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1226
1325
  objectargs.ghost_id = args.id;
1227
1326
  //objectargs.ghost_scale = args.scale;
1228
1327
  //objectargs.scale = new THREE.Vector3(1,1,1);
1229
- objectargs.orientation = new THREE.Quaternion()
1328
+ objectargs.orientation = new THREE.Quaternion();
1230
1329
  break;
1231
1330
  }
1232
1331
  //console.log('spawn it', realtype, args, objectargs);
@@ -1345,6 +1444,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1345
1444
  hasalpha: args.hasalpha,
1346
1445
  maxsize: args.maxsize,
1347
1446
  preload: args.preload,
1447
+ proxy: args.proxy,
1348
1448
  baseurl: this.baseurl
1349
1449
  };
1350
1450
  assetlist.push(assetargs);
@@ -1385,6 +1485,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1385
1485
  format: args.format,
1386
1486
  hls: args.hls,
1387
1487
  preload: args.preload,
1488
+ proxy: args.proxy,
1388
1489
  baseurl: this.baseurl
1389
1490
  });
1390
1491
  } else if (args.video) {
@@ -1413,11 +1514,14 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1413
1514
  src: src,
1414
1515
  buffer: args.buffer,
1415
1516
  rate: args.rate,
1517
+ proxy: args.proxy,
1416
1518
  baseurl: this.baseurl
1417
1519
  });
1418
1520
  } else if (type == 'websurface') {
1419
1521
  if (args.id) {
1420
1522
  this.websurfaces[args.id] = args;
1523
+ if (!this.roomassets.websurface) this.roomassets.websurface = {};
1524
+ this.roomassets.websurface[args.id] = args;
1421
1525
  }
1422
1526
  } else if (type == 'script') {
1423
1527
  var src = (args.src.match(/^file:/) ? args.src.replace(/^file:/, datapath) : args.src);
@@ -1425,7 +1529,8 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1425
1529
  assettype:'script',
1426
1530
  name: src,
1427
1531
  src: src,
1428
- baseurl: this.baseurl
1532
+ baseurl: this.baseurl,
1533
+ override: { room: this.getProxyObject() }
1429
1534
  });
1430
1535
  } else if (type == 'object' || type == 'model') {
1431
1536
  var src, mtlsrc, srcparts = [];
@@ -1461,7 +1566,8 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1461
1566
  tex0: args.tex || args.tex0 || srcparts[1],
1462
1567
  tex1: args.tex1 || srcparts[2],
1463
1568
  tex2: args.tex2 || srcparts[3],
1464
- tex3: args.tex3 || srcparts[4]
1569
+ tex3: args.tex3 || srcparts[4],
1570
+ proxy: args.proxy,
1465
1571
  });
1466
1572
  } else if (type == 'ghost') {
1467
1573
  var src = (args.src.match(/^file:/) ? args.src.replace(/^file:/, datapath) : args.src);
@@ -1535,9 +1641,13 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1535
1641
  }
1536
1642
  this.playSound = function(name, properties) {
1537
1643
  if (!this.sounds[name]) {
1538
- this.sounds[name] = this.createObject('Sound', {
1539
- id: name
1540
- });
1644
+ if (room.objects[name]) {
1645
+ this.sounds[name] = room.objects[name];
1646
+ } else {
1647
+ this.sounds[name] = this.createObject('Sound', {
1648
+ id: name
1649
+ });
1650
+ }
1541
1651
  }
1542
1652
  if (this.sounds[name]) {
1543
1653
  if (properties) {
@@ -1710,14 +1820,20 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1710
1820
  }
1711
1821
  }
1712
1822
  this.onThingChange = function(ev) {
1713
- var thing = ev.target;
1714
- if (!this.applyingEdits && thing.js_id && this.jsobjects[thing.js_id]) {
1715
- var proxy = this.jsobjects[thing.js_id];
1716
- if (proxy.sync) {
1717
- if (!this.appliedchanges[thing.js_id]) {
1718
- this.changes[thing.js_id] = proxy;
1823
+ if (this.applyingEdits) return;
1824
+
1825
+ let thing = ev.target,
1826
+ js_id = thing.properties.js_id;
1827
+
1828
+ if (!js_id) return;
1829
+
1830
+ let proxy = this.jsobjects[js_id];
1831
+ if (proxy) {
1832
+ if (thing.properties.sync) {
1833
+ if (!this.appliedchanges[js_id]) {
1834
+ this.changes[js_id] = proxy;
1719
1835
  }
1720
- proxy.sync = proxy.autosync;
1836
+ thing.properties.sync = proxy.autosync;
1721
1837
  }
1722
1838
  }
1723
1839
  }
@@ -1743,8 +1859,8 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1743
1859
  }
1744
1860
  }
1745
1861
  this.onScriptTick = function(ev) {
1746
- this.engine.systems.world.scene['world-3d'].updateMatrix();
1747
- this.engine.systems.world.scene['world-3d'].updateMatrixWorld();
1862
+ //this.engine.systems.world.scene['world-3d'].updateMatrix();
1863
+ //this.engine.systems.world.scene['world-3d'].updateMatrixWorld();
1748
1864
  /*
1749
1865
  for (var k in this.jsobjects) {
1750
1866
  var realobj = this.getObjectFromProxy(this.jsobjects[k]);
@@ -1934,19 +2050,20 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
1934
2050
  locked: ['property', 'locked'],
1935
2051
  private: ['property', 'private'],
1936
2052
  selfavatar: ['property', 'selfavatar'],
1937
- requirescripts:['property', 'requirescripts'],
2053
+ requires: ['property', 'requires'],
1938
2054
  pos: ['property', 'spawnpoint.position'],
1939
2055
  sync: ['property', 'sync'],
1940
2056
  js_id: ['property', 'roomid'],
1941
2057
  pickable: ['property', 'pickable'],
1942
2058
 
1943
2059
  skybox: ['property', 'skybox'],
1944
- skybox_left_id: ['property', 'skybox_left'],
1945
- skybox_right_id:['property', 'skybox_right'],
1946
- skybox_up_id: ['property', 'skybox_up'],
1947
- skybox_down_id: ['property', 'skybox_down'],
1948
- skybox_front_id:['property', 'skybox_front'],
1949
- skybox_back_id: ['property', 'skybox_back'],
2060
+ skybox_equi: ['property', 'skybox_equi'],
2061
+ skybox_left_id: ['property', 'skybox_left_id'],
2062
+ skybox_right_id:['property', 'skybox_right_id'],
2063
+ skybox_up_id: ['property', 'skybox_up_id'],
2064
+ skybox_down_id: ['property', 'skybox_down_id'],
2065
+ skybox_front_id:['property', 'skybox_front_id'],
2066
+ skybox_back_id: ['property', 'skybox_back_id'],
1950
2067
 
1951
2068
  pendingScripts: ['property', 'pendingScripts'],
1952
2069
  pendingCustomElements: ['property', 'pendingCustomElements'],
@@ -2000,10 +2117,10 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
2000
2117
  onColliderEnter: ['callback', 'janus_room_collider_enter'],
2001
2118
  onColliderExit: ['callback', 'janus_room_collider_exit'],
2002
2119
  onClick: ['callback', 'click,touchstart', 'engine.client.container'],
2003
- onMouseDown: ['callback', 'janus_room_mousedown'],
2004
- onMouseUp: ['callback', 'janus_room_mouseup'],
2005
- onMouseMove: ['callback', 'janus_room_mousemove'],
2006
- onMouseDrag: ['callback', 'janus_room_mousedrag'],
2120
+ onMouseDown: ['callback', 'mousedown'],
2121
+ onMouseUp: ['callback', 'mouseup'],
2122
+ onMouseMove: ['callback', 'mousemove'],
2123
+ onMouseDrag: ['callback', 'mousedrag'],
2007
2124
  onKeyDown: ['callback', 'janus_room_keydown'],
2008
2125
  onKeyUp: ['callback', 'janus_room_keyup']
2009
2126
  });
@@ -2037,7 +2154,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
2037
2154
  var real = this.getObjectFromProxy(change);
2038
2155
  if (real) {
2039
2156
  var xmltype = typemap[real.type] || 'Object';
2040
- xmlnode = xmldoc.createElement(xmltype);
2157
+ let xmlnode = xmldoc.createElement(xmltype);
2041
2158
 
2042
2159
  var attrs = Object.keys(change);
2043
2160
  for (var i = 0; i < attrs.length; i++) {
@@ -2232,7 +2349,9 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
2232
2349
  var asset = this.roomassets[type][assetname];
2233
2350
 
2234
2351
  let defaultasset = (janus.assetpack.assetmap[type] ? janus.assetpack.assetmap[type][assetname] : undefined);
2235
- if (assetname != asset.src && asset !== defaultasset) {
2352
+ if (type == 'script') {
2353
+ assetsrc += ' <assetscript src="' + asset.src + '" />\n';
2354
+ } else if (assetname != asset.src && asset !== defaultasset) {
2236
2355
  assetsrc += ' <asset' + (assettypemap[type] || type) + ' id="' + assetname + '" src="' + asset.src + '" />\n';
2237
2356
  }
2238
2357
  }
@@ -2249,7 +2368,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
2249
2368
  val = elation.utils.arrayget(this.properties, def[1]);
2250
2369
 
2251
2370
  if (k == 'url' || !propdef) continue;
2252
- if (k == 'requirescripts') k = 'require';
2371
+ if (k == 'requires') k = 'require';
2253
2372
 
2254
2373
  let defaultval = propdef.default;
2255
2374
  if (val instanceof THREE.Vector2) {
@@ -2463,14 +2582,14 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
2463
2582
  }
2464
2583
  }
2465
2584
  });
2466
- if (this.pendingScripts) {
2585
+ if (!this.loaded && this.pendingScripts) {
2467
2586
  // We're still waiting for the room to finish loading, so wait for the room_load_complete event before checking if we need to load anything else
2468
2587
  this.addEventListener('room_load_complete', (ev) => {
2469
2588
  // Room and all of its assets have finished loading. If our required component still isn't available, check the master package list and autoload if possible
2470
2589
  if (!finished) {
2471
2590
  this.loadComponentList().then(components => {
2472
2591
  if (components[k]) {
2473
- this.loadNewAsset('script', { src: components[k].url });
2592
+ this.loadNewAsset('script', { src: components[k].url, override: { room: this.getProxyObject() } });
2474
2593
  this._target.loadScripts([{src: components[k].url}]);
2475
2594
  }
2476
2595
  });
@@ -2480,7 +2599,7 @@ console.log('connect room audio to graph', this.audionodes.gain, this.audionodes
2480
2599
  // Room is already loaded and scripts are processed - we still don't know about this component, so load it up
2481
2600
  this.loadComponentList().then(components => {
2482
2601
  if (components[k]) {
2483
- this.loadNewAsset('script', { src: components[k].url });
2602
+ this.loadNewAsset('script', { src: components[k].url, override: { room: this.getProxyObject() } });
2484
2603
  this._target.loadScripts([{src: components[k].url}]);
2485
2604
  }
2486
2605
  });
@@ -2534,7 +2653,7 @@ console.log('dispatch to parent', event, this, event.target);
2534
2653
  if (!url) url = this.url;
2535
2654
  if (url[0] == '/') {
2536
2655
  url = this.baseurl.replace(/^(https?:\/\/[^\/]+)\/.*$/, '$1') + url;
2537
- } else if (!url.match(/https?:\/\//i)) {
2656
+ } else if (!url.match(/:\/\//i)) {
2538
2657
  url = this.baseurl + url;
2539
2658
  }
2540
2659
  return url;
@@ -2546,9 +2665,12 @@ console.log('dispatch to parent', event, this, event.target);
2546
2665
  this.loaded = false;
2547
2666
  }
2548
2667
  this.contains = function(obj) {
2668
+ if (obj._target) obj = obj._target;
2669
+ let room = this;
2670
+ if (this._target) room = this._target;
2549
2671
  let ptr = obj;
2550
2672
  while (ptr.parent) {
2551
- if (ptr.parent == this) return true;
2673
+ if (ptr.parent == room) return true;
2552
2674
  ptr = ptr.parent;
2553
2675
  }
2554
2676
  return false;
@@ -2612,7 +2734,7 @@ console.log('dispatch to parent', event, this, event.target);
2612
2734
  this.fadeAudioOut = function(time=4, value=0) {
2613
2735
  if (this.audionodes) {
2614
2736
  let gain = this.audionodes.gain,
2615
- ctx = this.audionodes.listener.context;
2737
+ ctx = this.audionodes.listener.context,
2616
2738
  currentgain = gain.gain.value;
2617
2739
 
2618
2740
  gain.gain.cancelScheduledValues(ctx.currentTime);
package/scripts/sound.js CHANGED
@@ -14,7 +14,7 @@ elation.require(['janusweb.janusbase'], function() {
14
14
  pitch: { type: 'float', default: 1.0, set: this.updateSound },
15
15
  gain: { type: 'float', default: 1.0, set: this.updateSound },
16
16
  starttime: { type: 'float', default: 0.0, set: this.updateSound },
17
- distanceModel: { type: 'string', set: this.updateSound },
17
+ distancemodel: { type: 'string', default: 'inverse', set: this.updateSound },
18
18
  rolloff: { type: 'float', default: 1.0, set: this.updateSound },
19
19
  rect: { type: 'string', set: this.updateSound }
20
20
  });
@@ -36,7 +36,7 @@ elation.require(['janusweb.janusbase'], function() {
36
36
  }
37
37
  }
38
38
  this.createAudio = async function(src, audionodes) {
39
- var sound = this.getAsset('sound', this.sound_id);
39
+ var sound = this.getAsset('sound', this.sound_id, true);
40
40
  if (!src) {
41
41
  this.currentsound = this.sound_id;
42
42
  if (sound && sound.src) {
@@ -58,8 +58,8 @@ elation.require(['janusweb.janusbase'], function() {
58
58
  this.audio = new THREE.Audio(audionodes.listener);
59
59
  } else {
60
60
  this.audio = new THREE.PositionalAudio(audionodes.listener);
61
- if (this.properties.distanceModel) {
62
- this.audio.panner.distanceModel = this.properties.distanceModel;
61
+ if (this.properties.distancemodel) {
62
+ this.audio.panner.distanceModel = this.properties.distancemodel;
63
63
  }
64
64
  //this.audio.panner.maxDistance = this.properties.distance;
65
65
  if (this.dist) {
@@ -131,6 +131,9 @@ elation.require(['janusweb.janusbase'], function() {
131
131
  await this.createAudio();
132
132
  }
133
133
  if (this.audio && this.audio.buffer) { //this.audio.source && this.audio.source.buffer) {
134
+ if (this.audio.source) {
135
+ this.audio.stop();
136
+ }
134
137
  this.audio.setVolume(this.gain);
135
138
  if (this.audio.isPlaying) {
136
139
  this.audio.source.currentTime = 0;
@@ -173,7 +176,7 @@ elation.require(['janusweb.janusbase'], function() {
173
176
  if (this.audio instanceof THREE.PositionalAudio) {
174
177
  this.audio.setRolloffFactor(this.rolloff);
175
178
  this.audio.setRefDistance(this.dist);
176
- this.audio.setDistanceModel(this.distanceModel);
179
+ this.audio.setDistanceModel(this.distancemodel);
177
180
  }
178
181
  }
179
182
  if (this.rect) {
@@ -220,7 +223,6 @@ elation.require(['janusweb.janusbase'], function() {
220
223
  playing: [ 'property', 'playing', 'sound.isPlaying'],
221
224
  pitch: [ 'property', 'pitch'],
222
225
  auto_play: [ 'property', 'auto_play'],
223
- playing: [ 'property', 'playing'],
224
226
  play: [ 'function', 'play'],
225
227
  pause: [ 'function', 'pause'],
226
228
  stop: [ 'function', 'stop'],