janusweb 1.5.32 → 1.5.36

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 (56) hide show
  1. package/CHANGELOG +39 -0
  2. package/media/assets/webui/apps/avatar/avatar.js +2 -1
  3. package/media/assets/webui/apps/buttons/buttons.html +2 -2
  4. package/media/assets/webui/apps/buttons/buttons.js +2 -2
  5. package/media/assets/webui/apps/comms/voip.js +2 -4
  6. package/media/assets/webui/apps/editor/codemirror/addon/hint/javascript-hint.js +162 -0
  7. package/media/assets/webui/apps/editor/codemirror/addon/hint/show-hint.css +36 -0
  8. package/media/assets/webui/apps/editor/codemirror/addon/hint/show-hint.js +529 -0
  9. package/media/assets/webui/apps/editor/codemirror/addon/hint/xml-hint.js +140 -0
  10. package/media/assets/webui/apps/editor/codemirror/keymap/vim.js +5734 -0
  11. package/media/assets/webui/apps/editor/codemirror/lib/codemirror.css +350 -0
  12. package/media/assets/webui/apps/editor/codemirror/lib/codemirror.js +9800 -0
  13. package/media/assets/webui/apps/editor/codemirror/lib/jmldark.css +33 -0
  14. package/media/assets/webui/apps/editor/codemirror/mode/css/css.js +864 -0
  15. package/media/assets/webui/apps/editor/codemirror/mode/htmlmixed/htmlmixed.js +153 -0
  16. package/media/assets/webui/apps/editor/codemirror/mode/javascript/javascript.js +942 -0
  17. package/media/assets/webui/apps/editor/codemirror/mode/xml/xml.js +413 -0
  18. package/media/assets/webui/apps/editor/editor.css +3 -0
  19. package/media/assets/webui/apps/editor/editor.js +407 -9
  20. package/media/assets/webui/apps/editor/editor.json +6 -3
  21. package/media/assets/webui/apps/inventory/inventory.js +2 -2
  22. package/media/assets/webui/apps/locomotion/teleporter.js +8 -7
  23. package/media/assets/webui/apps/navigation/navigation.js +12 -12
  24. package/media/assets/webui/apps/vfs/browserfs/browserfs.js +8 -0
  25. package/media/assets/webui/apps/vfs/vfs.css +52 -0
  26. package/media/assets/webui/apps/vfs/vfs.js +452 -0
  27. package/media/assets/webui/apps/vfs/vfs.json +10 -0
  28. package/media/assets/webui/default.json +2 -1
  29. package/media/assets/webui/themes/default.css +29 -2
  30. package/media/lib/physx/physx.release.js +21 -0
  31. package/media/lib/physx/physx.release.wasm +0 -0
  32. package/media/manifest.json +5 -5
  33. package/media/service-worker.js +7 -0
  34. package/package.json +2 -9
  35. package/scripts/client.js +65 -45
  36. package/scripts/config.js +2 -0
  37. package/scripts/elements/linesegments.js +5 -2
  38. package/scripts/image.js +7 -1
  39. package/scripts/janusbase.js +28 -11
  40. package/scripts/janusghost.js +4 -3
  41. package/scripts/janusparagraph.js +5 -3
  42. package/scripts/janusparticle.js +25 -14
  43. package/scripts/janusplayer.js +25 -10
  44. package/scripts/janusweb.js +22 -3
  45. package/scripts/janusxrplayer.js +4 -1
  46. package/scripts/multiplayermanager.js +3 -3
  47. package/scripts/object.js +172 -82
  48. package/scripts/portal.js +12 -10
  49. package/scripts/room.js +113 -54
  50. package/scripts/sound.js +0 -1
  51. package/scripts/text.js +10 -2
  52. package/scripts/translators/janusvfs.js +20 -0
  53. package/scripts/video.js +1 -1
  54. package/scripts/websurface.js +11 -2
  55. package/utils/build.sh +3 -0
  56. package/utils/init.sh +1 -1
package/scripts/object.js CHANGED
@@ -5,6 +5,36 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
5
5
  'front': THREE.BackSide,
6
6
  'none': THREE.DoubleSide
7
7
  };
8
+ this.depthFuncMap = {
9
+ 'never': THREE.NeverDepth,
10
+ 'always': THREE.AlwaysDepth,
11
+ 'equal': THREE.EqualDepth,
12
+ 'less': THREE.LessDepth,
13
+ 'lessequal': THREE.LessEqualDepth,
14
+ 'greaterequal': THREE.GreaterEqualDepth,
15
+ 'greater': THREE.GreaterDepth,
16
+ 'notequal': THREE.NotEqualDepth,
17
+ };
18
+ this.blendModeMap = {
19
+ 'normal': THREE.NormalBlending,
20
+ 'no': THREE.NoBlending,
21
+ 'additive': THREE.AdditiveBlending,
22
+ 'subtractive': THREE.SubtractiveBlending,
23
+ 'multiply': THREE.MultiplyBlending,
24
+ 'custom': THREE.CustomBlending,
25
+ };
26
+ this.blendFactorsMap = {
27
+ 'zero': THREE.ZeroFactor,
28
+ 'one': THREE.OneFactor,
29
+ 'src_color': THREE.SrcColorFactor,
30
+ 'dst_color': THREE.DstColorFactor,
31
+ 'src_alpha': THREE.SrcAlphaFactor,
32
+ 'dst_alpha': THREE.DstAlphaFactor,
33
+ 'one_minus_src_color': THREE.OneMinusSrcColorFactor,
34
+ 'one_minus_src_alpha': THREE.OneMinusSrcAlphaFactor,
35
+ 'one_minus_dst_color': THREE.OneMinusDstColorFactor,
36
+ 'one_minus_dst_alpha': THREE.OneMinusDstAlphaFactor,
37
+ };
8
38
  this.postinit = function() {
9
39
  elation.engine.things.janusobject.extendclass.postinit.call(this);
10
40
  this.defineProperties({
@@ -15,7 +45,7 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
15
45
  video_id: { type: 'string', set: this.updateVideo, comment: 'Video texture ID' },
16
46
  shader_id: { type: 'string', set: this.updateMaterial, comment: 'Shader ID' },
17
47
  shader_chunk_replace: { type: 'object' },
18
- url: { type: 'string' },
48
+ url: { type: 'string', set: this.updateWebsurfaceURL },
19
49
  loop: { type: 'boolean' },
20
50
  websurface_id: { type: 'string', set: this.updateWebsurface, comment: 'WebSurface ID' },
21
51
  shadow: { type: 'boolean', default: true, set: this.updateMaterial },
@@ -26,10 +56,14 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
26
56
  lights: { type: 'boolean', default: false, comment: 'Load lights from model' },
27
57
  lighting: { type: 'boolean', default: true, set: this.updateMaterial, comment: 'Object reacts to scene lighting' },
28
58
  cull_face: { type: 'string', default: 'back', set: this.updateMaterial, comment: 'Hide face sides (back, front, or none)' },
29
- blend_src: { type: 'string', default: 'src_alpha', set: this.updateMaterial, comment: 'Blend mode (source)' },
30
- blend_dest: { type: 'string', default: 'one_minus_src_alpha', set: this.updateMaterial, comment: 'Blend mode (destination)' },
59
+ blend_src: { type: 'string', set: this.updateMaterial, comment: 'Blend mode (source)' },
60
+ blend_dest: { type: 'string', set: this.updateMaterial, comment: 'Blend mode (destination)' },
61
+ blend_mode: { type: 'string', default: 'normal', set: this.updateMaterial, comment: 'Blend mode' },
31
62
  depth_write: { type: 'boolean', default: null, set: this.updateMaterial },
32
63
  depth_test: { type: 'boolean', default: null, set: this.updateMaterial },
64
+ depth_offset: { type: 'float', default: null, set: this.updateMaterial },
65
+ depth_func: { type: 'string', default: null, set: this.updateMaterial },
66
+ color_write: { type: 'boolean', default: null, set: this.updateMaterial },
33
67
  envmap_id: { type: 'string', set: this.updateMaterial, comment: 'Environment map texture ID (overrides skybox reflections)' },
34
68
  normalmap_id: { type: 'string', set: this.updateMaterial, comment: 'Normal map texture ID' },
35
69
  bumpmap_id: { type: 'string', set: this.updateMaterial, comment: 'Bumpmap texture ID' },
@@ -111,6 +145,8 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
111
145
  //this.properties.collidable = false;
112
146
 
113
147
  //this.updateColliderFromGeometry(new THREE.BoxGeometry(1,1,1));
148
+
149
+ elation.events.add(this.room, 'skybox_update', ev => this.updateSkybox());
114
150
  }
115
151
  this.createForces = function() {
116
152
  elation.engine.things.janusobject.extendclass.createForces.call(this);
@@ -183,7 +219,7 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
183
219
  var videoasset = this.getAsset('video', videoid);
184
220
  if (videoasset) {
185
221
  this.videoasset = videoasset;
186
- texture = videoasset.getInstance();
222
+ let texture = videoasset.getInstance();
187
223
  if (!texture.image) {
188
224
  videoasset.load();
189
225
  }
@@ -235,6 +271,8 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
235
271
  url = this.room.baseurl + url;
236
272
  }
237
273
  this.url = url;
274
+ } else {
275
+ this.url = this.websurface_id;
238
276
  }
239
277
  /*
240
278
  this.pickable = false;
@@ -272,6 +310,11 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
272
310
  if (n.material) n.material = blankmaterial;
273
311
  });
274
312
  }
313
+ this.updateWebsurfaceURL = function() {
314
+ if (this.websurface) {
315
+ this.websurface.url = this.url;
316
+ }
317
+ }
275
318
  this.setTextureDirty = function() {
276
319
  this.textureNeedsUpdate = true;
277
320
  }
@@ -313,7 +356,11 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
313
356
  blend_src = false,
314
357
  blend_dest = false,
315
358
  side = this.sidemap[this.properties.cull_face],
316
- textureasset;
359
+ textureasset,
360
+ lightmaptextureasset,
361
+ emissivetextureasset,
362
+ roughnesstextureasset,
363
+ metalnesstextureasset;
317
364
 
318
365
  this.textureNeedsUpdate = false;
319
366
 
@@ -360,10 +407,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
360
407
  if (textureasset) {
361
408
  texture = textureasset.getInstance();
362
409
  this.textureasset = textureasset;
363
- if (!this.assetloadhandlers[image_id]) {
364
- this.assetloadhandlers[image_id] = true;
410
+ if (!this.assetloadhandlers[texture.uuid]) {
411
+ this.assetloadhandlers[texture.uuid] = true;
365
412
  elation.events.add(textureasset, 'asset_load', this.refresh);
366
- elation.events.add(texture, 'update', this.refresh);
413
+ elation.events.add(texture, 'asset_update', this.refresh);
367
414
  }
368
415
 
369
416
  //texture.offset.copy(this.texture_offset);
@@ -389,10 +436,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
389
436
  let normaltextureasset = this.getAsset('image', normal_image_id, true);
390
437
  if (normaltextureasset) {
391
438
  textureNormal = normaltextureasset.getInstance();
392
- if (!this.assetloadhandlers[normal_image_id]) {
393
- this.assetloadhandlers[normal_image_id] = true;
439
+ if (!this.assetloadhandlers[textureNormal.uuid]) {
440
+ this.assetloadhandlers[textureNormal.uuid] = true;
394
441
  elation.events.add(textureNormal, 'asset_load', elation.bind(this, this.refresh));
395
- elation.events.add(textureNormal, 'update', elation.bind(this, this.refresh));
442
+ elation.events.add(textureNormal, 'asset_update', elation.bind(this, this.refresh));
396
443
  }
397
444
 
398
445
  if (normaltextureasset.sbs3d) {
@@ -411,10 +458,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
411
458
  let bumptextureasset = this.getAsset('image', bump_image_id, true);
412
459
  if (bumptextureasset) {
413
460
  textureBump = bumptextureasset.getInstance();
414
- if (!this.assetloadhandlers[bump_image_id]) {
415
- this.assetloadhandlers[bump_image_id] = true;
461
+ if (!this.assetloadhandlers[textureBump.uuid]) {
462
+ this.assetloadhandlers[textureBump.uuid] = true;
416
463
  elation.events.add(bumptextureasset, 'asset_load', elation.bind(this, this.refresh));
417
- elation.events.add(textureBump, 'update', elation.bind(this, this.refresh));
464
+ elation.events.add(textureBump, 'asset_update', elation.bind(this, this.refresh));
418
465
  }
419
466
  if (bumptextureasset.sbs3d) {
420
467
  textureBump.repeat.set(0.5, 1);
@@ -432,10 +479,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
432
479
  let alphatextureasset = this.getAsset('image', alpha_image_id, true);
433
480
  if (alphatextureasset) {
434
481
  textureAlpha = alphatextureasset.getInstance();
435
- if (!this.assetloadhandlers[alpha_image_id]) {
436
- this.assetloadhandlers[alpha_image_id] = true;
482
+ if (!this.assetloadhandlers[textureAlpha.uuid]) {
483
+ this.assetloadhandlers[textureAlpha.uuid] = true;
437
484
  elation.events.add(alphatextureasset, 'asset_load', elation.bind(this, this.refresh));
438
- elation.events.add(textureAlpha, 'update', elation.bind(this, this.refresh));
485
+ elation.events.add(textureAlpha, 'asset_update', elation.bind(this, this.refresh));
439
486
  }
440
487
  if (alphatextureasset.sbs3d) {
441
488
  textureAlpha.repeat.set(0.5, 1);
@@ -453,10 +500,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
453
500
  }
454
501
  if (displacementtextureasset) {
455
502
  textureDisplacement = displacementtextureasset.getInstance();
456
- if (!this.assetloadhandlers[displacement_image_id]) {
457
- this.assetloadhandlers[displacement_image_id] = true;
503
+ if (!this.assetloadhandlers[textureDisplacement.uuid]) {
504
+ this.assetloadhandlers[textureDisplacement.uuid] = true;
458
505
  elation.events.add(displacementtextureasset, 'asset_load', elation.bind(this, this.refresh));
459
- elation.events.add(textureDisplacement, 'update', elation.bind(this, this.refresh));
506
+ elation.events.add(textureDisplacement, 'asset_update', elation.bind(this, this.refresh));
460
507
  }
461
508
  if (displacementtextureasset.sbs3d) {
462
509
  textureDisplacement.repeat.set(0.5, 1);
@@ -474,10 +521,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
474
521
  lightmaptextureasset = this.getAsset('image', lightmap_image_id);
475
522
  if (lightmaptextureasset) {
476
523
  textureLightmap = lightmaptextureasset.getInstance();
477
- if (!this.assetloadhandlers[lightmap_image_id]) {
478
- this.assetloadhandlers[lightmap_image_id] = true;
524
+ if (!this.assetloadhandlers[textureLightmap.uuid]) {
525
+ this.assetloadhandlers[textureLightmap.uuid] = true;
479
526
  elation.events.add(lightmaptextureasset, 'asset_load', elation.bind(this, this.setTextureDirty));
480
- elation.events.add(textureLightmap, 'update', elation.bind(this, this.refresh));
527
+ elation.events.add(textureLightmap, 'asset_update', elation.bind(this, this.refresh));
481
528
  }
482
529
 
483
530
  if (textureLightmap) {
@@ -492,10 +539,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
492
539
  }
493
540
  if (emissivetextureasset) {
494
541
  textureEmissive = emissivetextureasset.getInstance();
495
- if (!this.assetloadhandlers[emissive_image_id]) {
496
- this.assetloadhandlers[emissive_image_id] = true;
542
+ if (!this.assetloadhandlers[textureEmissive.uuid]) {
543
+ this.assetloadhandlers[textureEmissive.uuid] = true;
497
544
  elation.events.add(emissivetextureasset, 'asset_load', elation.bind(this, this.setTextureDirty));
498
- elation.events.add(textureEmissive, 'update', elation.bind(this, this.refresh));
545
+ elation.events.add(textureEmissive, 'asset_update', elation.bind(this, this.refresh));
499
546
  }
500
547
 
501
548
  if (textureEmissive) {
@@ -507,10 +554,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
507
554
  roughnesstextureasset = this.getAsset('image', roughness_image_id);
508
555
  if (roughnesstextureasset) {
509
556
  textureRoughness = roughnesstextureasset.getInstance();
510
- if (!this.assetloadhandlers[roughness_image_id]) {
511
- this.assetloadhandlers[roughness_image_id] = true;
557
+ if (!this.assetloadhandlers[textureRoughness.uuid]) {
558
+ this.assetloadhandlers[textureRoughness.uuid] = true;
512
559
  elation.events.add(roughnesstextureasset, 'asset_load', elation.bind(this, this.setTextureDirty));
513
- elation.events.add(textureRoughness, 'update', elation.bind(this, this.refresh));
560
+ elation.events.add(textureRoughness, 'asset_update', elation.bind(this, this.refresh));
514
561
  }
515
562
 
516
563
  if (textureRoughness) {
@@ -522,10 +569,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
522
569
  metalnesstextureasset = this.getAsset('image', metalness_image_id);
523
570
  if (metalnesstextureasset) {
524
571
  textureMetalness = metalnesstextureasset.getInstance();
525
- if (!this.assetloadhandlers[metalness_image_id]) {
526
- this.assetloadhandlers[metalness_image_id] = true;
572
+ if (!this.assetloadhandlers[textureMetalness.uuid]) {
573
+ this.assetloadhandlers[textureMetalness.uuid] = true;
527
574
  elation.events.add(metalnesstextureasset, 'asset_load', elation.bind(this, this.setTextureDirty));
528
- elation.events.add(textureMetalness, 'update', elation.bind(this, this.refresh));
575
+ elation.events.add(textureMetalness, 'asset_update', elation.bind(this, this.refresh));
529
576
  }
530
577
 
531
578
  if (textureMetalness) {
@@ -565,18 +612,7 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
565
612
  //color.setRGB(col.x, col.y, col.z);
566
613
  }
567
614
  */
568
- var srcfactors = {
569
- 'zero': THREE.ZeroFactor,
570
- 'one': THREE.OneFactor,
571
- 'src_color': THREE.SrcColorFactor,
572
- 'dst_color': THREE.DstColorFactor,
573
- 'src_alpha': THREE.SrcAlphaFactor,
574
- 'dst_alpha': THREE.DstAlphaFactor,
575
- 'one_minus_src_color': THREE.OneMinusSrcColorFactor,
576
- 'one_minus_src_alpha': THREE.OneMinusSrcAlphaFactor,
577
- 'one_minus_dst_color': THREE.OneMinusDstColorFactor,
578
- 'one_minus_dst_alpha': THREE.OneMinusDstAlphaFactor,
579
- }
615
+ let srcfactors = this.blendFactorsMap;
580
616
  if (srcfactors[this.properties.blend_src]) {
581
617
  blend_src = srcfactors[this.properties.blend_src];
582
618
  }
@@ -617,6 +653,9 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
617
653
  if (this.depth_test !== null) {
618
654
  shadermaterial.depthTest = this.depth_test;
619
655
  }
656
+ if (this.color_write !== null) {
657
+ shadermaterial.colorWrite = this.color_write;
658
+ }
620
659
  this.traverseObjects((n) => {
621
660
  if (n.material) {
622
661
  if (Array.isArray(n.material)) {
@@ -683,13 +722,16 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
683
722
  //if (!color) m.color.setHex(0xffffff);
684
723
  m.map = texture;
685
724
  texture.encoding = THREE.sRGBEncoding;
686
- elation.events.add(texture, 'asset_update', (ev) => {
687
- m.map = ev.data;
688
- this.updateTextureOffsets();
689
- this.refresh();
690
- });
725
+ if (false && !this.assetloadhandlers[texture.uuid]) {
726
+ this.assetloadhandlers[texture.uuid] = true;
727
+ elation.events.add(texture, 'asset_update', (ev) => {
728
+ m.map = ev.data;
729
+ this.updateTextureOffsets();
730
+ this.refresh();
731
+ });
732
+ }
691
733
 
692
- m.transparent = (textureasset && textureasset.hasalpha) || m.opacity < 1;
734
+ m.transparent = (this.transparent !== null ? this.transparent : (textureasset && textureasset.hasalpha) || m.opacity < 1);
693
735
  } else if (m.map && m.map.sourceFile) {
694
736
  var imagesrc = m.map.sourceFile;
695
737
  var asset = this.getAsset('image', imagesrc, true);
@@ -700,18 +742,21 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
700
742
  }
701
743
  m.map = asset.getInstance();
702
744
  m.map.encoding = THREE.sRGBEncoding;
703
- elation.events.add(m.map, 'asset_update', elation.bind(this, function(ev) {
704
- m.map = ev.data;
705
- this.updateTextureOffsets();
706
- }));
707
- elation.events.add(asset, 'asset_load', elation.bind(this, function(m, asset, ev) {
708
- if (asset.hasalpha && !m.transparent) {
709
- m.transparent = true;
710
- m.alphaTest = this.alphatest;
711
- //m.needsUpdate = true;
712
- }
713
- this.refresh();
714
- }, m, asset));
745
+ if (!this.assetloadhandlers[m.map.uuid]) {
746
+ this.assetloadhandlers[m.map.uuid] = true;
747
+ elation.events.add(m.map, 'asset_update', elation.bind(this, function(ev) {
748
+ m.map = ev.data;
749
+ this.updateTextureOffsets();
750
+ }));
751
+ elation.events.add(asset, 'asset_load', elation.bind(this, function(m, asset, ev) {
752
+ if (asset.hasalpha && !m.transparent) {
753
+ m.transparent = true;
754
+ m.alphaTest = this.alphatest;
755
+ //m.needsUpdate = true;
756
+ }
757
+ this.refresh();
758
+ }, m, asset));
759
+ }
715
760
  }
716
761
  if (m.map) {
717
762
  this.assignTextureParameters(m.map, modelasset, asset);
@@ -723,11 +768,14 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
723
768
  if (asset) {
724
769
  m.normalMap = asset.getInstance();
725
770
  m.normalMap = asset.getInstance();
726
- elation.events.add(m.normalMap, 'asset_update', elation.bind(this, function(ev) {
727
- m.normalMap = ev.data; this.refresh();
728
- this.updateTextureOffsets();
729
- }));
730
- elation.events.add(asset, 'asset_load', elation.bind(this, function(ev) { m.normalMap = ev.data; this.refresh(); }));
771
+ if (!this.assetloadhandlers[m.normalMap.uuid]) {
772
+ this.assetloadhandlers[m.normalMap.uuid] = true;
773
+ elation.events.add(m.normalMap, 'asset_update', elation.bind(this, function(ev) {
774
+ m.normalMap = ev.data; this.refresh();
775
+ this.updateTextureOffsets();
776
+ }));
777
+ elation.events.add(asset, 'asset_load', elation.bind(this, function(ev) { m.normalMap = ev.data; this.refresh(); }));
778
+ }
731
779
  }
732
780
  } else if (textureBump) {
733
781
  m.bumpMap = textureBump;
@@ -738,13 +786,16 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
738
786
  if (asset) {
739
787
  m.normalMap = asset.getInstance();
740
788
  m.normalMap = asset.getInstance();
741
- elation.events.add(m.bumpMap, 'asset_update', elation.bind(this, function(ev) {
742
- m.normalMap = ev.data; this.refresh();
743
- m.normalMap.offset.copy(this.texture_offset);
744
- m.normalMap.repeat.copy(this.texture_repeat);
745
- m.normalMap.rotation = this.texture_rotation * THREE.Math.DEG2RAD;
746
- }));
747
- elation.events.add(asset, 'asset_load', elation.bind(this, function(ev) { m.normalMap = ev.data; this.refresh(); }));
789
+ if (!this.assetloadhandlers[m.normalMap.uuid]) {
790
+ this.assetloadhandlers[m.normalMap.uuid] = true;
791
+ elation.events.add(m.bumpMap, 'asset_update', elation.bind(this, function(ev) {
792
+ m.normalMap = ev.data; this.refresh();
793
+ m.normalMap.offset.copy(this.texture_offset);
794
+ m.normalMap.repeat.copy(this.texture_repeat);
795
+ m.normalMap.rotation = this.texture_rotation * THREE.Math.DEG2RAD;
796
+ }));
797
+ elation.events.add(asset, 'asset_load', elation.bind(this, function(ev) { m.normalMap = ev.data; this.refresh(); }));
798
+ }
748
799
  }
749
800
  }
750
801
  if (textureNormal) {
@@ -754,8 +805,11 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
754
805
  var asset = this.getAsset('image', imagesrc, {id: imagesrc, src: imagesrc, hasalpha: false});
755
806
  if (asset) {
756
807
  m.normalMap = asset.getInstance();
757
- elation.events.add(m.normalMap, 'asset_update', elation.bind(this, function(ev) { m.normalMap = ev.data; this.refresh(); }));
758
- elation.events.add(asset, 'asset_load', elation.bind(this, function(ev) { m.normalMap = ev.data; this.refresh(); }));
808
+ if (!this.assetloadhandlers[m.normalMap.uuid]) {
809
+ this.assetloadhandlers[m.normalMap.uuid] = true;
810
+ elation.events.add(m.normalMap, 'asset_update', elation.bind(this, function(ev) { m.normalMap = ev.data; this.refresh(); }));
811
+ elation.events.add(asset, 'asset_load', elation.bind(this, function(ev) { m.normalMap = ev.data; this.refresh(); }));
812
+ }
759
813
  }
760
814
  }
761
815
 
@@ -764,14 +818,20 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
764
818
  m.lightMap = textureLightmap;
765
819
  } else {
766
820
  }
767
- elation.events.add(textureLightmap, 'asset_update', elation.bind(m, function(ev) { m.lightMap = ev.data; this.refresh(); }));
821
+ if (!this.assetloadhandlers[m.lightMap.uuid]) {
822
+ this.assetloadhandlers[m.lightMap.uuid] = true;
823
+ elation.events.add(textureLightmap, 'asset_update', elation.bind(m, function(ev) { m.lightMap = ev.data; this.refresh(); }));
824
+ }
768
825
  } else if (m.lightMap) {
769
826
  var imagesrc = m.lightMap.sourceFile;
770
- var asset = this.getAsset('image', imagesrc, {id: imagesrc, src: imagesrc, hasalpha: false});
771
- if (asset) {
772
- m.lightMap = asset.getInstance();
773
- elation.events.add(asset, 'asset_load', elation.bind(this, function(ev) { m.lightMap = ev.data; this.refresh();}));
774
- elation.events.add(m.lightMap, 'asset_update', elation.bind(this, function(ev) { m.lightMap = ev.data; this.refresh(); }));
827
+ if (!this.assetloadhandlers[m.lightMap.uuid]) {
828
+ this.assetloadhandlers[m.lightMap.uuid] = true;
829
+ var asset = this.getAsset('image', imagesrc, {id: imagesrc, src: imagesrc, hasalpha: false});
830
+ if (asset) {
831
+ m.lightMap = asset.getInstance();
832
+ elation.events.add(asset, 'asset_load', elation.bind(this, function(ev) { m.lightMap = ev.data; this.refresh();}));
833
+ elation.events.add(m.lightMap, 'asset_update', elation.bind(this, function(ev) { m.lightMap = ev.data; this.refresh(); }));
834
+ }
775
835
  }
776
836
  }
777
837
  if (textureDisplacement) {
@@ -829,6 +889,21 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
829
889
  if (this.depth_test !== null) {
830
890
  m.depthTest = this.depth_test;
831
891
  }
892
+ if (this.depth_func !== null) {
893
+ m.depthFunc = this.depthFuncMap[this.depth_func];
894
+ } else {
895
+ m.depthFunc = this.depthFuncMap['lessequal'];
896
+ }
897
+ if (this.depth_offset !== null) {
898
+ m.polygonOffset = true;
899
+ m.polygonOffsetUnits = 1;
900
+ m.polygonOffsetFactor = -this.depth_offset;
901
+ } else {
902
+ m.polygonOffset = false;
903
+ }
904
+ if (this.color_write !== null) {
905
+ m.colorWrite = this.color_write;
906
+ }
832
907
  // If our diffuse texture has an alpha channel, set up a customDepthMaterial / customDistanceMaterial to allow shadows to work
833
908
  if (m.map) { //this.shadow && m.transparent && m.map) {
834
909
  if (!n.customDepthMaterial) {
@@ -990,6 +1065,17 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
990
1065
  }
991
1066
  return m;
992
1067
  }
1068
+ this.updateSkybox = function() {
1069
+ let envMap = (this.isUsingPBR() ? this.getEnvmap() : null);
1070
+ this.traverseObjects(n => {
1071
+ if (n.material) {
1072
+ let materials = (elation.utils.isArray(n.material) ? n.material : [n.material]);
1073
+ materials.forEach(m => {
1074
+ m.envMap = envMap;
1075
+ });
1076
+ }
1077
+ });
1078
+ }
993
1079
  this.updateColor = function() {
994
1080
  elation.engine.things.janusobject.extendclass.updateColor.call(this);
995
1081
 
@@ -1348,8 +1434,12 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
1348
1434
  cull_face: [ 'property', 'cull_face' ],
1349
1435
  blend_src: [ 'property', 'blend_src' ],
1350
1436
  blend_dest: [ 'property', 'blend_dest' ],
1437
+ blend_mode: [ 'property', 'blend_mode' ],
1351
1438
  depth_write: [ 'property', 'depth_write' ],
1352
1439
  depth_test: [ 'property', 'depth_test' ],
1440
+ depth_offset: [ 'property', 'depth_offset' ],
1441
+ depth_func: [ 'property', 'depth_func' ],
1442
+ color_write: [ 'property', 'color_write' ],
1353
1443
 
1354
1444
  wireframe: [ 'property', 'wireframe'],
1355
1445
  fog: [ 'property', 'fog'],
package/scripts/portal.js CHANGED
@@ -2,17 +2,15 @@ elation.require(['janusweb.janusbase'], function() {
2
2
  elation.component.add('engine.things.janusportal', function() {
3
3
  this.postinit = function() {
4
4
  this.defineProperties({
5
- 'url': { type: 'string' },
6
- 'title': { type: 'string' },
5
+ 'url': { type: 'string', set: this.updateTitle },
6
+ 'title': { type: 'string', set: this.updateTitle },
7
7
  'janus': { type: 'object' },
8
8
  'room': { type: 'object' },
9
9
  //'color': { type: 'color', default: new THREE.Color(0xffffff), set: this.updateMaterial },
10
10
  'size': { type: 'vector3', default: new THREE.Vector3(1.4,2.2,1), set: this.updateGeometry },
11
- 'url': { type: 'string', set: this.updateTitle },
12
11
  'open': { type: 'boolean', default: false },
13
12
  'collision_id': { type: 'string', default: 'cube', set: this.updateCollider },
14
13
  'collision_scale': { type: 'vector3', set: this.updateCollider },
15
- 'title': { type: 'string', set: this.updateTitle },
16
14
  'seamless': { type: 'boolean', default: false },
17
15
  'draw_text': { type: 'boolean', default: true, set: this.updateTitle },
18
16
  'draw_glow': { type: 'boolean', default: true, refreshGeometry: true},
@@ -26,6 +24,8 @@ elation.require(['janusweb.janusbase'], function() {
26
24
  'target': { type: 'string', default: '' },
27
25
  'round': { type: 'boolean', default: false },
28
26
  'cooldown': { type: 'float', default: 1000 },
27
+ 'font': { type: 'string', default: 'impact' },
28
+ 'font_weight': { type: 'string', default: 'bold' },
29
29
  });
30
30
  this.addTag('usable');
31
31
  elation.engine.things.janusportal.extendclass.postinit.call(this);
@@ -75,8 +75,8 @@ elation.require(['janusweb.janusbase'], function() {
75
75
  collidable: false,
76
76
  pickable: false,
77
77
  background: 'rgba(255,255,255,.4)',
78
- font: 'impact',
79
- fontWeight: 'bold',
78
+ font: this.font,
79
+ fontWeight: this.font_weight,
80
80
  textShadowBlur: 5,
81
81
  textShadowColor: 'black',
82
82
  height: .1,
@@ -94,7 +94,7 @@ elation.require(['janusweb.janusbase'], function() {
94
94
  elation.events.add(this, 'click', elation.bind(this, this.activate));
95
95
  elation.events.add(this, 'mouseover', elation.bind(this, this.hover));
96
96
  elation.events.add(this, 'mouseout', elation.bind(this, this.unhover));
97
- elation.events.add(this, 'collide', (ev) => this.handleCollide());
97
+ elation.events.add(this, 'collide', (ev) => this.handleCollide(ev));
98
98
  }
99
99
  }
100
100
  this.createMaterial = function() {
@@ -331,7 +331,7 @@ elation.require(['janusweb.janusbase'], function() {
331
331
  console.log('load that room', this.portalroom);
332
332
 
333
333
  var scene = new THREE.Scene();
334
- scene.background = this.portalroom.skyboxtexture
334
+ scene.background = this.portalroom.skyboxtexture;
335
335
  scene.add(this.portalroom.objects['3d']);
336
336
  this.scene = scene;
337
337
  this.scene.updateMatrixWorld(true);
@@ -615,14 +615,16 @@ elation.require(['janusweb.janusbase'], function() {
615
615
  }
616
616
  this.handleFrameUpdates = function(ev) {
617
617
  elation.engine.things.janusportal.extendclass.handleFrameUpdates.call(this, ev);
618
- if (this.shader) {
618
+ if (this.shader && this.shader.uniforms) {
619
619
  if (this.shader.uniforms.time) {
620
620
  this.shader.uniforms.time.value = performance.now() / 1000;
621
621
  this.refresh();
622
622
  }
623
623
  }
624
624
  }
625
- this.handleCollide = function() {
625
+ this.handleCollide = function(ev) {
626
+ // TODO - we could potentially handle sending other physical objects through portals here, but for now we only care about the player
627
+ if (ev.data.other !== player._target) return;
626
628
  // Only activate portal if the player is walking towards it
627
629
  let fwd = this.localToWorld(V(0,0,1)).sub(this.localToWorld(V(0,0,0)));
628
630
  let dot = fwd.dot(normalized(player.vel));