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
@@ -2,7 +2,18 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
2
2
  elation.requireCSS('janusweb.janusplayer');
3
3
 
4
4
  elation.component.add('engine.things.janusplayer', function() {
5
- this.defaultavatar = '<FireBoxRoom>\n <Assets>\n <AssetObject id="screen" src="https://web.janusxr.org/media/assets/hoverscreen.obj" mtl="https://web.janusxr.org/media/assets/hoverscreen.mtl" />\n </Assets>\n <Room>\n <Ghost id="januswebuser" col="#ffffff" lighting="true" head_pos="0 1.4 0" body_id="" eye_pos="0 1.6 0" userid_pos="0 0.5 0" cull_face="back" screen_name="screen_Cube.004">\n <Object id="screen" js_id="head" />\n </Ghost>\n </Room>\n</FireBoxRoom>'
5
+ //this.defaultavatar = '<FireBoxRoom>\n <Assets>\n <AssetObject id="screen" src="https://web.janusxr.org/media/assets/hoverscreen.obj" mtl="https://web.janusxr.org/media/assets/hoverscreen.mtl" />\n </Assets>\n <Room>\n <Ghost id="januswebuser" col="#ffffff" lighting="true" head_pos="0 1.4 0" body_id="" eye_pos="0 1.6 0" userid_pos="0 0.5 0" cull_face="back" screen_name="screen_Cube.004">\n <Object id="screen" js_id="head" />\n </Ghost>\n </Room>\n</FireBoxRoom>'
6
+ this.defaultavatar = `
7
+ <FireBoxRoom>
8
+ <assets>
9
+ <assetobject id="body" src="http://www.baicoianu.com/~bai/janusweb/test/janus-avatar-base.glb" />
10
+ <assetobject id="avatar_animations" src="http://www.baicoianu.com/~bai/janusweb/test/janus-avatar-animations.glb" />
11
+ </assets>
12
+ <room>
13
+ <ghost scale=".01 .01 .01" col="#e0d5a1" body_id="body" bone_head="head" />
14
+ </room>
15
+ </FireBoxRoom>
16
+ `;
6
17
 
7
18
  this.postinit = function() {
8
19
  elation.engine.things.janusplayer.extendclass.postinit.call(this);
@@ -15,9 +26,12 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
15
26
  cursor_visible: {type: 'boolean', default: true, set: this.toggleCursorVisibility},
16
27
  cursor_opacity: {type: 'float', default: 1.0, set: this.toggleCursorVisibility},
17
28
  usevoip: {type: 'boolean', default: false },
29
+ defaultanimation: {type: 'string', default: 'idle' },
18
30
  collision_radius: {type: 'float', default: .25, set: this.updateCollider},
19
31
  party_mode: { type: 'boolean', set: this.updatePartyMode },
20
32
  avatarsrc: { type: 'string' },
33
+ cameraview: { type: 'string', default: 'firstperson' },
34
+ decouplehead: { type: 'boolean', default: false },
21
35
  });
22
36
 
23
37
  var controllerconfig = this.getSetting('controls.settings');
@@ -32,7 +46,9 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
32
46
  elation.events.add(this.engine.client.view.container, 'touchend', elation.bind(this, this.handleTouchEnd));
33
47
 
34
48
  this.controlstate2 = this.engine.systems.controls.addContext('janusplayer', {
35
- 'voip_active': ['keyboard_v,keyboard_shift_v', elation.bind(this, this.activateVOIP)],
49
+ 'toggle_view': ['keyboard_v,keyboard_shift_v', elation.bind(this, this.toggleCamera)],
50
+ 'zoom_out': ['mouse_wheel_down', ev => this.zoomView(-1)],
51
+ 'zoom_in': ['mouse_wheel_up', ev => this.zoomView(1)],
36
52
  //'browse_back': ['gamepad_any_button_4', elation.bind(this, this.browseBack)],
37
53
  //'browse_forward': ['gamepad_any_button_5', elation.bind(this, this.browseForward)],
38
54
  });
@@ -100,7 +116,7 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
100
116
  elation.events.add(this.engine.client.container, 'mousedown', elation.bind(this, this.updateMouseStatus));
101
117
  elation.events.add(this.engine.client.container, 'mouseup', elation.bind(this, this.updateMouseStatus));
102
118
 
103
- elation.events.add(this.room, 'mouseover,mouseout', elation.bind(this, this.updateCursorStyle));
119
+ this.updateCursorStyle = elation.bind(this, this.updateCursorStyle);
104
120
 
105
121
  this.touchcache = {
106
122
  positions: []
@@ -122,11 +138,13 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
122
138
 
123
139
  this.getAvatarData().then(avatar => {;
124
140
  if (avatar && false) { // FIXME - self avatar is buggy so it's disabled
141
+ /*
125
142
  this.ghost = this.createObject('ghost', {
126
143
  ghost_id: this.getUsername(),
127
144
  avatar_src: 'data:text/plain,' + encodeURIComponent(avatar),
128
145
  showlabel: false
129
146
  });
147
+ */
130
148
  }
131
149
  });
132
150
 
@@ -264,14 +282,11 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
264
282
  }
265
283
  }
266
284
  }
267
- if (this.ghost) {
285
+ if (this.ghost && !this.decouplehead) {
286
+ this.ghost.setHeadOrientation(this.head.orientation, true);
268
287
  if (this.ghost._target.head) {
269
288
  //this.ghost._target.face.position.copy(this.head.position);
270
- this.ghost.head.orientation.copy(this.head.orientation);
271
- }
272
- if (this.ghost._target.body) {
273
- //this.ghost._target.body.position.copy(this.body.position);
274
- //this.ghost._target.body.orientation.copy(this.body.orientation);
289
+ this.ghost.head.orientation.copy(this.head.orientation).invert();
275
290
  }
276
291
  }
277
292
  }
@@ -280,6 +295,10 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
280
295
  if (this.lookAtLERPtime) {
281
296
  this.updateLookAtLERP();
282
297
  }
298
+ if (this.ghost && this.ghost.body) {
299
+ let animid = this.getAnimationID();
300
+ this.ghost.body.anim_id = animid;
301
+ }
283
302
  }
284
303
  this.updateCursor = (function() {
285
304
  var _tmpvec = new THREE.Vector3();
@@ -349,10 +368,10 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
349
368
  if (typeof playerpos.z == 'undefined' || isNaN(playerpos.z)) playerpos.z = 0;
350
369
  this.objects['3d'].updateMatrix();
351
370
  this.objects['3d'].updateMatrixWorld();
352
- this.objects['3d'].matrixWorld.extractBasis(v.xdir, v.ydir, v.zdir)
371
+ this.objects['3d'].matrixWorld.extractBasis(v.xdir, v.ydir, v.zdir);
353
372
  }
354
373
  if (this.head) {
355
- this.head.objects['3d'].matrixWorld.extractBasis(v.view_xdir, v.view_ydir, v.view_zdir)
374
+ this.head.objects['3d'].matrixWorld.extractBasis(v.view_xdir, v.view_ydir, v.view_zdir);
356
375
  v.head_pos.setFromMatrixPosition(this.head.objects['3d'].matrixWorld);
357
376
  v.view_zdir.negate();
358
377
  }
@@ -375,6 +394,21 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
375
394
  this.gaze.fired = true;
376
395
  }
377
396
  }
397
+ if (this.controlstate.jump && !this.jumping) {
398
+ let jumptime = 1;
399
+ if (this.ghost && this.ghost.body.animations && this.ghost.body.animations.jump) {
400
+ let jumpanim = this.ghost.body.animations.jump;
401
+ let jumpclip = jumpanim.getClip();
402
+
403
+ jumpanim.loop = THREE.LoopOnce;
404
+
405
+ if (jumpclip) {
406
+ jumptime = jumpclip.duration;
407
+ }
408
+ this.jumping = true;
409
+ setTimeout(() => this.jumping = false, (jumptime * 1000) * .8);
410
+ }
411
+ }
378
412
  }
379
413
  this.updateMouseStatus = function(ev) {
380
414
  if (ev.type == 'mousedown' && ev.button === 0) {
@@ -412,10 +446,15 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
412
446
  }
413
447
  this.setRoom = function(newroom) {
414
448
  if (this.room) {
449
+ let oldroomproxy = this.room.getProxyObject();
450
+ oldroomproxy.removeEventListener('mouseover', this.updateCursorStyle);
451
+ oldroomproxy.removeEventListener('mouseout', this.updateCursorStyle);
415
452
  this.room.part();
416
453
  }
417
454
  this.room = newroom;
418
455
  this.room.join();
456
+
457
+ /*
419
458
  if (!this.gazecaster) {
420
459
  this.gazecaster = newroom.createObject('raycaster', {persist: false});
421
460
  this.head.add(this.gazecaster._target);
@@ -426,6 +465,11 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
426
465
  } else {
427
466
  this.gazecaster.setRoom(newroom);
428
467
  }
468
+ */
469
+ let newroomproxy = newroom.getProxyObject();
470
+ newroomproxy.addEventListener('mouseover', this.updateCursorStyle);
471
+ newroomproxy.addEventListener('mouseout', this.updateCursorStyle);
472
+
429
473
  if (!this.cursors) {
430
474
  this.cursors = {
431
475
  'default': janus.getAsset('image', 'cursor_crosshair'),
@@ -435,25 +479,27 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
435
479
  'dot_active': janus.getAsset('image', 'cursor_dot_active'),
436
480
  };
437
481
  }
438
- if (!this.room.selfavatar && this.ghost) {
439
- this.ghost.die();
440
- this.ghost = false;
441
- this.visible = false;
442
- } else if (!this.ghost && this.room.selfavatar) {
482
+ newroom.appendChild(this.getProxyObject());
483
+ if (this.ghost) {
484
+ this.ghost.setRoom(newroom);
485
+ } else if (!this.ghost) { // && this.room.selfavatar) {
443
486
  // FIXME - self avatar is buggy so it's disabled
444
487
  this.getAvatarData().then(avatar => {
445
488
  if (avatar) {
446
489
  this.ghost = this.createObject('ghost', {
447
490
  ghost_id: this.getUsername(),
448
491
  avatar_src: 'data:text/plain,' + encodeURIComponent(avatar),
449
- showlabel: false
492
+ showlabel: false,
493
+ //pos: V(0, -this.fatness, 0),
494
+ rotation: V(0, 180, 0),
495
+ renderorder: 101,
450
496
  });
497
+ this.ghost.orientation.set(0,1,0,0);
451
498
  }
452
499
  });
453
500
  this.visible = true;
454
501
  }
455
502
 
456
- newroom.appendChild(this.getProxyObject());
457
503
  for (let k in this.children) {
458
504
  if (this.children[k].setRoom) {
459
505
  this.children[k].setRoom(room);
@@ -553,6 +599,9 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
553
599
 
554
600
  collision_radius: ['property', 'collision_radius'],
555
601
 
602
+ currentavatar: ['property', 'currentavatar'],
603
+ defaultanimation: ['property', 'defaultanimation'],
604
+
556
605
  localToWorld: ['function', 'localToWorld'],
557
606
  worldToLocal: ['function', 'worldToLocal'],
558
607
  appendChild: ['function', 'appendChild'],
@@ -601,15 +650,13 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
601
650
  if (this.ghost) {
602
651
  this.ghost.die();
603
652
  }
604
- this.getAvatarData().then(avatardata => {
605
- // FIXME - self avatar is broken and weird right now, so it's disabled
606
- if (avatardata && this.room.selfavatar) {
607
- this.ghost = this.createObject('ghost', {
608
- ghost_id: this.getUsername(),
609
- avatar_src: 'data:text/plain,' + encodeURIComponent(avatardata),
610
- showlabel: false
611
- });
612
- }
653
+ this.ghost = this.createObject('ghost', {
654
+ ghost_id: this.getUsername(),
655
+ avatar_src: 'data:text/plain,' + encodeURIComponent(avatar),
656
+ showlabel: false,
657
+ //pos: V(0, -this.fatness, 0),
658
+ rotation: V(0, 180, 0),
659
+ renderorder: 101,
613
660
  });
614
661
 
615
662
  return setting;
@@ -632,17 +679,19 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
632
679
  return voipdata;
633
680
  }
634
681
  this.getAnimationID = function() {
635
- var animid = 'idle';
636
- if (this.controlstate.run) {
637
- animid = 'run';
638
- } else if (this.controlstate.move_forward) {
639
- animid = 'walk';
682
+ var animid = this.defaultanimation;
683
+ let running = this.controlstate.run;
684
+
685
+ if (this.jumping) {
686
+ animid = 'jump';
640
687
  } else if (this.controlstate.move_left) {
641
- animid = 'walk_left';
688
+ animid = (running ? 'run' : 'walk_left');
642
689
  } else if (this.controlstate.move_right) {
643
- animid = 'walk_right';
690
+ animid = (running ? 'run' : 'walk_right');
691
+ } else if (this.controlstate.move_forward) {
692
+ animid = (running ? 'run' : 'walk');
644
693
  } else if (this.controlstate.move_backward) {
645
- animid = 'walk_back';
694
+ animid = (running ? 'run' : 'walk_back');
646
695
  } else if (document.activeElement && this.properties.janus.chat && document.activeElement === this.properties.janus.chat.input.inputelement) {
647
696
  animid = 'type';
648
697
  } else if (this.hasVoipData()) {
@@ -737,10 +786,9 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
737
786
  }
738
787
  this.updateCursorStyle = function(ev) {
739
788
  var vrdisplay = this.engine.systems.render.views.main.vrdisplay;
740
- var obj = ev.target || ev.element;
789
+ var obj = ev.element;
741
790
  var proxyobj = (obj.getProxyObject ? obj.getProxyObject() : obj);
742
791
 
743
-
744
792
  if (obj && proxyobj && (ev.type == 'mouseover' || ev.type == 'mousemove') && (
745
793
  obj.onclick ||
746
794
  elation.events.hasEventListener(obj, 'click') ||
@@ -793,8 +841,15 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
793
841
  this.updateCollider = function() {
794
842
  if (this.objects['dynamics']) {
795
843
  if (this.collision_radius > 0) {
844
+ /*
796
845
  this.setCollider('sphere', {
797
846
  radius: this.collision_radius,
847
+ });
848
+ */
849
+ this.pickable = false;
850
+ this.setCollider('capsule', {
851
+ radius: this.collision_radius,
852
+ length: 1,
798
853
  offset: V(0, this.collision_radius, 0)
799
854
  });
800
855
  } else {
@@ -1036,6 +1091,40 @@ elation.require(['engine.things.player', 'janusweb.external.JanusVOIP', 'ui.butt
1036
1091
  round: true,
1037
1092
  shader_id: 'defaultportal',
1038
1093
  });
1094
+
1095
+ // FIXME - should only set this if we have an active portal animation, and we should use the animation's duration for our timeout
1096
+ this.defaultanimation = 'portal';
1097
+ setTimeout(() => this.defaultanimation = 'idle', 3000);
1098
+ }
1099
+ this.toggleCamera = function(ev) {
1100
+ if (ev.value == 1) {
1101
+ if (this.cameraview == 'firstperson') {
1102
+ this.cameraview = 'thirdperson';
1103
+ this.camera.position.z = 2;
1104
+ } else {
1105
+ this.cameraview = 'firstperson';
1106
+ this.camera.position.z = 0;
1107
+ }
1108
+ }
1109
+ }
1110
+ this.zoomView = function(amount) {
1111
+ if (this.cameraview == 'thirdperson') {
1112
+ this.camera.position.z -= amount / 10;
1113
+ }
1114
+ }
1115
+ this.setAnimationSequence = function(sequence) {
1116
+ let t = 0;
1117
+ let currentanimation = this.defaultanimation;
1118
+ let body = this.ghost.body;
1119
+ sequence.forEach(clipname => {
1120
+ let anim = body.animations[clipname];
1121
+ if (anim) {
1122
+ let clip = anim.getClip();
1123
+ setTimeout(() => { this.defaultanimation = clipname; }, t * 1000);
1124
+ t += clip.duration;
1125
+ }
1126
+ });
1127
+ setTimeout(() => { this.defaultanimation = currentanimation; }, t * 1000);
1039
1128
  }
1040
1129
  }, elation.engine.things.player);
1041
1130
  });
@@ -101,7 +101,7 @@ elation.require([
101
101
  if (this.urltemplate) {
102
102
  dust.filters.stripunsafe = function(s) {
103
103
  return s.replace(/:\//g, '');
104
- }
104
+ };
105
105
  elation.template.add('janusweb.url', this.urltemplate);
106
106
  }
107
107
  this.initScripting();
@@ -157,6 +157,7 @@ elation.require([
157
157
  userid: ['property', 'userId'],
158
158
  avatarlighting: ['property', 'settings.avatarlighting'],
159
159
  ui: ['property', 'engine.client.ui'],
160
+ currentroom: ['property', 'currentroom'],
160
161
 
161
162
  hmd: ['accessor', 'isVRActive'],
162
163
 
@@ -170,6 +171,9 @@ elation.require([
170
171
  navback: ['function', 'navigateBack'],
171
172
  navforward: ['function', 'navigateForward'],
172
173
  load: ['function', 'navigateTo'],
174
+ setActiveRoom: ['function', 'setActiveRoom'],
175
+ preload: ['function', 'preload'],
176
+ createRoom: ['function', 'createRoom'],
173
177
  navhome: ['function', 'navigateHome'],
174
178
  chatsend: ['function', 'sendChatMessage'],
175
179
  sync: ['function', 'currentroom.sync'],
@@ -407,6 +411,26 @@ elation.require([
407
411
  this.load(url, true, null, referrer === false);
408
412
  }
409
413
  }
414
+ this.preload = function(url, stripreferrer) {
415
+ return this.load(url, false, null, stripreferrer);
416
+ }
417
+ this.createRoom = function(url, makeactive=true) {
418
+ let newroom = this.spawn('janusroom', url, {
419
+ url: url,
420
+ janus: this,
421
+ corsproxy: this.corsproxy,
422
+ deferload: true
423
+ });
424
+
425
+ this.rooms[newroom.roomid] = newroom;
426
+ //console.log('made new room', url, room);
427
+ this.loading = false;
428
+ if (newroom && makeactive) {
429
+ this.setActiveRoom(newroom);
430
+ }
431
+ this.initScripting();
432
+ return newroom.getProxyObject();
433
+ }
410
434
  this.getFixedURL = function(url) {
411
435
  // Our 'clean' client URLs don't contain a : because many services have problems parsing them
412
436
  var m = url.match(/^(https?)\/\/?(.*)$/i);
@@ -506,7 +530,7 @@ elation.require([
506
530
  }
507
531
  this.handleRoomEditOther = function(data) {
508
532
  var roomId = data.roomId,
509
- movedata = data.position;
533
+ movedata = data.position,
510
534
  edit = movedata.room_edit,
511
535
  del = movedata.room_delete;
512
536
 
@@ -316,10 +316,9 @@ elation.require(['engine.things.generic', 'janusweb.external.webxr-input-profile
316
316
  const minNode = motionControllerRoot.getObjectByName(visualResponse.minNodeName);
317
317
  const maxNode = motionControllerRoot.getObjectByName(visualResponse.maxNodeName);
318
318
 
319
- THREE.Quaternion.slerp(
319
+ valueNode.quaternion.slerp(
320
320
  minNode.quaternion,
321
321
  maxNode.quaternion,
322
- valueNode.quaternion,
323
322
  visualResponse.value
324
323
  );
325
324
 
@@ -563,6 +562,7 @@ elation.require(['engine.things.generic', 'janusweb.external.webxr-input-profile
563
562
  lighting: false,
564
563
  opacity: .5,
565
564
  cull_face: 'none',
565
+ billboard: 'y',
566
566
  });
567
567
  this.raycaster = this.createObject('raycaster', {});
568
568
  this.raycaster.addEventListener('raycastenter', (ev) => this.handleRaycastEnter(ev));
@@ -573,8 +573,10 @@ elation.require(['engine.things.generic', 'janusweb.external.webxr-input-profile
573
573
  this.worldToLocal(this.laser.positions[1].copy(endpoint));
574
574
  this.laser.updateLine();
575
575
  this.cursor.pos.copy(endpoint);
576
+ let cursorscale = player.head.distanceTo(endpoint) / 12;
577
+ this.cursor.scale.set(cursorscale, cursorscale, cursorscale);
576
578
  //this.cursor.zdir = normal;
577
- if (this.cursor.room !== room) room.appendChild(this.cursor);
579
+ if (this.cursor.room !== room._target) room.appendChild(this.cursor);
578
580
  //this.cursor.zdir.copy(player.view_dir).multiplyScalar(-1);
579
581
  //this.cursor.zdir = normal;
580
582
  this.cursor.visible = true;
@@ -180,7 +180,7 @@ console.log('[MultiplayerManager] set active room:', room, this.activeroom);
180
180
  dir: (-tmpVecZ.x) + ' ' + (-tmpVecZ.y) + ' ' + (-tmpVecZ.z),
181
181
  up_dir: '0 1 0',
182
182
  //view_dir: this.tmpVecZ.toArray().join(' ')
183
- }
183
+ };
184
184
  if (head) {
185
185
  //this.tmpMat.makeRotationFromQuaternion(head.properties.orientation);
186
186
  tmpMat.copy(head.objects['3d'].matrixWorld);
@@ -230,8 +230,8 @@ console.log('[MultiplayerManager] set active room:', room, this.activeroom);
230
230
  //console.log('[MultiplayerManager] player update', moveData);
231
231
  if (this.avatarNeedsUpdate || player.avatarNeedsUpdate) {
232
232
  moveData.avatar = player.getCurrentAvatarData().replace(/"/g, "^");
233
- this.avatarNeedsUpdate = false
234
- player.avatarNeedsUpdate = false
233
+ this.avatarNeedsUpdate = false;
234
+ player.avatarNeedsUpdate = false;
235
235
  } else if (moveData.avatar) {
236
236
  delete moveData.avatar;
237
237
  }
@@ -319,9 +319,9 @@ console.log('[MultiplayerManager] part', room.url);
319
319
  var roomId = data.roomId;
320
320
 
321
321
  var room = this.rooms[roomId] || this.activeroom;
322
- console.log('[MultiplayerManager] spawn remote guy', userId, roomId, room);
323
322
 
324
323
  var spawnpos = (data.position && data.position.pos ? data.position.pos.split(" ").map(parseFloat) : [0,0,0]);
324
+ //console.log('[MultiplayerManager] spawn remote guy', userId, roomId, room, spawnpos);
325
325
  this.remoteplayers[userId] = room.spawn('remoteplayer', userId, { position: spawnpos, player_id: userId, player_name: userId, pickable: false, collidable: false, janus: this.janusweb, room: room});
326
326
  var remote = this.remoteplayers[userId];
327
327
 
@@ -330,6 +330,7 @@ console.log('[MultiplayerManager] spawn remote guy', userId, roomId, room);
330
330
 
331
331
  // If a new player spawned, let's send an avatar update ASAP
332
332
  this.updateAvatar();
333
+ remote.start();
333
334
  return remote;
334
335
  }
335
336
  this.updateAvatar = function() {
@@ -390,6 +391,7 @@ console.log('[MultiplayerManager] spawn remote guy', userId, roomId, room);
390
391
 
391
392
  if (remote.room !== room) {
392
393
  remote.setRoom(room);
394
+ remote.start();
393
395
  }
394
396
 
395
397
  remote.updateData(movedata);