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/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);
@@ -150,6 +186,13 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
150
186
  }), 0);
151
187
  this.jsparts.updateParts();
152
188
  this.assetloaded = true;
189
+ if (this.modelasset) {
190
+ this.initAnimations(this.modelasset.animations);
191
+ if (this.animations && this.anim_id && this.animations[this.anim_id]) {
192
+ console.log('start animation', this);
193
+ this.animations[this.anim_id].play();
194
+ }
195
+ }
153
196
  if (this.loadingindicator) {
154
197
  this.loadingindicator.die();
155
198
  }
@@ -176,7 +219,7 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
176
219
  var videoasset = this.getAsset('video', videoid);
177
220
  if (videoasset) {
178
221
  this.videoasset = videoasset;
179
- texture = videoasset.getInstance();
222
+ let texture = videoasset.getInstance();
180
223
  if (!texture.image) {
181
224
  videoasset.load();
182
225
  }
@@ -228,6 +271,8 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
228
271
  url = this.room.baseurl + url;
229
272
  }
230
273
  this.url = url;
274
+ } else {
275
+ this.url = this.websurface_id;
231
276
  }
232
277
  /*
233
278
  this.pickable = false;
@@ -265,6 +310,11 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
265
310
  if (n.material) n.material = blankmaterial;
266
311
  });
267
312
  }
313
+ this.updateWebsurfaceURL = function() {
314
+ if (this.websurface) {
315
+ this.websurface.url = this.url;
316
+ }
317
+ }
268
318
  this.setTextureDirty = function() {
269
319
  this.textureNeedsUpdate = true;
270
320
  }
@@ -279,6 +329,11 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
279
329
  this.refresh();
280
330
  }
281
331
  }
332
+ if (this.animationmixer) {
333
+ //this.animationmixer.setTime(new Date().getTime() / 1000);
334
+ this.animationmixer.update(ev.data);
335
+ this.refresh();
336
+ }
282
337
  }
283
338
  this.assignTextures = function() {
284
339
  //console.log('assign textures', this.name, this.objects['3d']);
@@ -301,7 +356,11 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
301
356
  blend_src = false,
302
357
  blend_dest = false,
303
358
  side = this.sidemap[this.properties.cull_face],
304
- textureasset;
359
+ textureasset,
360
+ lightmaptextureasset,
361
+ emissivetextureasset,
362
+ roughnesstextureasset,
363
+ metalnesstextureasset;
305
364
 
306
365
  this.textureNeedsUpdate = false;
307
366
 
@@ -319,6 +378,18 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
319
378
  if (!modelasset || modelasset.name != this.janusid) {
320
379
  modelasset = this.getAsset('model', this.janusid, true);
321
380
  this.modelasset = modelasset;
381
+
382
+ if (modelasset.animations) {
383
+ this.initAnimations(modelasset.animations);
384
+ if (this.anim_id) {
385
+ if (modelasset && modelasset.loaded) {
386
+ this.setAnimation(this.anim_id);
387
+ } else {
388
+ elation.events.add(modelasset, 'asset_load', () => this.setAnimation(this.anim_id));
389
+ }
390
+ }
391
+ }
392
+
322
393
  }
323
394
  if (modelasset.tex) {
324
395
  image_id = modelasset.tex;
@@ -336,10 +407,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
336
407
  if (textureasset) {
337
408
  texture = textureasset.getInstance();
338
409
  this.textureasset = textureasset;
339
- if (!this.assetloadhandlers[image_id]) {
340
- this.assetloadhandlers[image_id] = true;
410
+ if (!this.assetloadhandlers[texture.uuid]) {
411
+ this.assetloadhandlers[texture.uuid] = true;
341
412
  elation.events.add(textureasset, 'asset_load', this.refresh);
342
- elation.events.add(texture, 'update', this.refresh);
413
+ elation.events.add(texture, 'asset_update', this.refresh);
343
414
  }
344
415
 
345
416
  //texture.offset.copy(this.texture_offset);
@@ -365,10 +436,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
365
436
  let normaltextureasset = this.getAsset('image', normal_image_id, true);
366
437
  if (normaltextureasset) {
367
438
  textureNormal = normaltextureasset.getInstance();
368
- if (!this.assetloadhandlers[normal_image_id]) {
369
- this.assetloadhandlers[normal_image_id] = true;
439
+ if (!this.assetloadhandlers[textureNormal.uuid]) {
440
+ this.assetloadhandlers[textureNormal.uuid] = true;
370
441
  elation.events.add(textureNormal, 'asset_load', elation.bind(this, this.refresh));
371
- elation.events.add(textureNormal, 'update', elation.bind(this, this.refresh));
442
+ elation.events.add(textureNormal, 'asset_update', elation.bind(this, this.refresh));
372
443
  }
373
444
 
374
445
  if (normaltextureasset.sbs3d) {
@@ -387,10 +458,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
387
458
  let bumptextureasset = this.getAsset('image', bump_image_id, true);
388
459
  if (bumptextureasset) {
389
460
  textureBump = bumptextureasset.getInstance();
390
- if (!this.assetloadhandlers[bump_image_id]) {
391
- this.assetloadhandlers[bump_image_id] = true;
461
+ if (!this.assetloadhandlers[textureBump.uuid]) {
462
+ this.assetloadhandlers[textureBump.uuid] = true;
392
463
  elation.events.add(bumptextureasset, 'asset_load', elation.bind(this, this.refresh));
393
- elation.events.add(textureBump, 'update', elation.bind(this, this.refresh));
464
+ elation.events.add(textureBump, 'asset_update', elation.bind(this, this.refresh));
394
465
  }
395
466
  if (bumptextureasset.sbs3d) {
396
467
  textureBump.repeat.set(0.5, 1);
@@ -408,10 +479,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
408
479
  let alphatextureasset = this.getAsset('image', alpha_image_id, true);
409
480
  if (alphatextureasset) {
410
481
  textureAlpha = alphatextureasset.getInstance();
411
- if (!this.assetloadhandlers[alpha_image_id]) {
412
- this.assetloadhandlers[alpha_image_id] = true;
482
+ if (!this.assetloadhandlers[textureAlpha.uuid]) {
483
+ this.assetloadhandlers[textureAlpha.uuid] = true;
413
484
  elation.events.add(alphatextureasset, 'asset_load', elation.bind(this, this.refresh));
414
- elation.events.add(textureAlpha, 'update', elation.bind(this, this.refresh));
485
+ elation.events.add(textureAlpha, 'asset_update', elation.bind(this, this.refresh));
415
486
  }
416
487
  if (alphatextureasset.sbs3d) {
417
488
  textureAlpha.repeat.set(0.5, 1);
@@ -429,10 +500,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
429
500
  }
430
501
  if (displacementtextureasset) {
431
502
  textureDisplacement = displacementtextureasset.getInstance();
432
- if (!this.assetloadhandlers[displacement_image_id]) {
433
- this.assetloadhandlers[displacement_image_id] = true;
503
+ if (!this.assetloadhandlers[textureDisplacement.uuid]) {
504
+ this.assetloadhandlers[textureDisplacement.uuid] = true;
434
505
  elation.events.add(displacementtextureasset, 'asset_load', elation.bind(this, this.refresh));
435
- elation.events.add(textureDisplacement, 'update', elation.bind(this, this.refresh));
506
+ elation.events.add(textureDisplacement, 'asset_update', elation.bind(this, this.refresh));
436
507
  }
437
508
  if (displacementtextureasset.sbs3d) {
438
509
  textureDisplacement.repeat.set(0.5, 1);
@@ -450,10 +521,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
450
521
  lightmaptextureasset = this.getAsset('image', lightmap_image_id);
451
522
  if (lightmaptextureasset) {
452
523
  textureLightmap = lightmaptextureasset.getInstance();
453
- if (!this.assetloadhandlers[lightmap_image_id]) {
454
- this.assetloadhandlers[lightmap_image_id] = true;
524
+ if (!this.assetloadhandlers[textureLightmap.uuid]) {
525
+ this.assetloadhandlers[textureLightmap.uuid] = true;
455
526
  elation.events.add(lightmaptextureasset, 'asset_load', elation.bind(this, this.setTextureDirty));
456
- elation.events.add(textureLightmap, 'update', elation.bind(this, this.refresh));
527
+ elation.events.add(textureLightmap, 'asset_update', elation.bind(this, this.refresh));
457
528
  }
458
529
 
459
530
  if (textureLightmap) {
@@ -468,10 +539,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
468
539
  }
469
540
  if (emissivetextureasset) {
470
541
  textureEmissive = emissivetextureasset.getInstance();
471
- if (!this.assetloadhandlers[emissive_image_id]) {
472
- this.assetloadhandlers[emissive_image_id] = true;
542
+ if (!this.assetloadhandlers[textureEmissive.uuid]) {
543
+ this.assetloadhandlers[textureEmissive.uuid] = true;
473
544
  elation.events.add(emissivetextureasset, 'asset_load', elation.bind(this, this.setTextureDirty));
474
- elation.events.add(textureEmissive, 'update', elation.bind(this, this.refresh));
545
+ elation.events.add(textureEmissive, 'asset_update', elation.bind(this, this.refresh));
475
546
  }
476
547
 
477
548
  if (textureEmissive) {
@@ -483,10 +554,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
483
554
  roughnesstextureasset = this.getAsset('image', roughness_image_id);
484
555
  if (roughnesstextureasset) {
485
556
  textureRoughness = roughnesstextureasset.getInstance();
486
- if (!this.assetloadhandlers[roughness_image_id]) {
487
- this.assetloadhandlers[roughness_image_id] = true;
557
+ if (!this.assetloadhandlers[textureRoughness.uuid]) {
558
+ this.assetloadhandlers[textureRoughness.uuid] = true;
488
559
  elation.events.add(roughnesstextureasset, 'asset_load', elation.bind(this, this.setTextureDirty));
489
- elation.events.add(textureRoughness, 'update', elation.bind(this, this.refresh));
560
+ elation.events.add(textureRoughness, 'asset_update', elation.bind(this, this.refresh));
490
561
  }
491
562
 
492
563
  if (textureRoughness) {
@@ -498,10 +569,10 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
498
569
  metalnesstextureasset = this.getAsset('image', metalness_image_id);
499
570
  if (metalnesstextureasset) {
500
571
  textureMetalness = metalnesstextureasset.getInstance();
501
- if (!this.assetloadhandlers[metalness_image_id]) {
502
- this.assetloadhandlers[metalness_image_id] = true;
572
+ if (!this.assetloadhandlers[textureMetalness.uuid]) {
573
+ this.assetloadhandlers[textureMetalness.uuid] = true;
503
574
  elation.events.add(metalnesstextureasset, 'asset_load', elation.bind(this, this.setTextureDirty));
504
- elation.events.add(textureMetalness, 'update', elation.bind(this, this.refresh));
575
+ elation.events.add(textureMetalness, 'asset_update', elation.bind(this, this.refresh));
505
576
  }
506
577
 
507
578
  if (textureMetalness) {
@@ -541,18 +612,7 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
541
612
  //color.setRGB(col.x, col.y, col.z);
542
613
  }
543
614
  */
544
- var srcfactors = {
545
- 'zero': THREE.ZeroFactor,
546
- 'one': THREE.OneFactor,
547
- 'src_color': THREE.SrcColorFactor,
548
- 'dst_color': THREE.DstColorFactor,
549
- 'src_alpha': THREE.SrcAlphaFactor,
550
- 'dst_alpha': THREE.DstAlphaFactor,
551
- 'one_minus_src_color': THREE.OneMinusSrcColorFactor,
552
- 'one_minus_src_alpha': THREE.OneMinusSrcAlphaFactor,
553
- 'one_minus_dst_color': THREE.OneMinusDstColorFactor,
554
- 'one_minus_dst_alpha': THREE.OneMinusDstAlphaFactor,
555
- }
615
+ let srcfactors = this.blendFactorsMap;
556
616
  if (srcfactors[this.properties.blend_src]) {
557
617
  blend_src = srcfactors[this.properties.blend_src];
558
618
  }
@@ -560,8 +620,6 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
560
620
  blend_dest = srcfactors[this.properties.blend_dest];
561
621
  }
562
622
 
563
- this.extractAnimations(this.objects['3d']);
564
-
565
623
  var scene = this.engine.systems.world.scene['world-3d'];
566
624
  if (!this.hasalpha) this.hasalpha = {};
567
625
  var hasalpha = this.hasalpha;
@@ -595,6 +653,9 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
595
653
  if (this.depth_test !== null) {
596
654
  shadermaterial.depthTest = this.depth_test;
597
655
  }
656
+ if (this.color_write !== null) {
657
+ shadermaterial.colorWrite = this.color_write;
658
+ }
598
659
  this.traverseObjects((n) => {
599
660
  if (n.material) {
600
661
  if (Array.isArray(n.material)) {
@@ -661,13 +722,16 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
661
722
  //if (!color) m.color.setHex(0xffffff);
662
723
  m.map = texture;
663
724
  texture.encoding = THREE.sRGBEncoding;
664
- elation.events.add(texture, 'asset_update', (ev) => {
665
- m.map = ev.data;
666
- this.updateTextureOffsets();
667
- this.refresh();
668
- });
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
+ }
669
733
 
670
- m.transparent = (textureasset && textureasset.hasalpha) || m.opacity < 1;
734
+ m.transparent = (this.transparent !== null ? this.transparent : (textureasset && textureasset.hasalpha) || m.opacity < 1);
671
735
  } else if (m.map && m.map.sourceFile) {
672
736
  var imagesrc = m.map.sourceFile;
673
737
  var asset = this.getAsset('image', imagesrc, true);
@@ -678,18 +742,21 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
678
742
  }
679
743
  m.map = asset.getInstance();
680
744
  m.map.encoding = THREE.sRGBEncoding;
681
- elation.events.add(m.map, 'asset_update', elation.bind(this, function(ev) {
682
- m.map = ev.data;
683
- this.updateTextureOffsets();
684
- }));
685
- elation.events.add(asset, 'asset_load', elation.bind(this, function(m, asset, ev) {
686
- if (asset.hasalpha && !m.transparent) {
687
- m.transparent = true;
688
- m.alphaTest = this.alphatest;
689
- //m.needsUpdate = true;
690
- }
691
- this.refresh();
692
- }, 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
+ }
693
760
  }
694
761
  if (m.map) {
695
762
  this.assignTextureParameters(m.map, modelasset, asset);
@@ -701,11 +768,14 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
701
768
  if (asset) {
702
769
  m.normalMap = asset.getInstance();
703
770
  m.normalMap = asset.getInstance();
704
- elation.events.add(m.normalMap, 'asset_update', elation.bind(this, function(ev) {
705
- m.normalMap = ev.data; this.refresh();
706
- this.updateTextureOffsets();
707
- }));
708
- 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
+ }
709
779
  }
710
780
  } else if (textureBump) {
711
781
  m.bumpMap = textureBump;
@@ -716,13 +786,16 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
716
786
  if (asset) {
717
787
  m.normalMap = asset.getInstance();
718
788
  m.normalMap = asset.getInstance();
719
- elation.events.add(m.bumpMap, 'asset_update', elation.bind(this, function(ev) {
720
- m.normalMap = ev.data; this.refresh();
721
- m.normalMap.offset.copy(this.texture_offset);
722
- m.normalMap.repeat.copy(this.texture_repeat);
723
- m.normalMap.rotation = this.texture_rotation * THREE.Math.DEG2RAD;
724
- }));
725
- 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
+ }
726
799
  }
727
800
  }
728
801
  if (textureNormal) {
@@ -732,8 +805,11 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
732
805
  var asset = this.getAsset('image', imagesrc, {id: imagesrc, src: imagesrc, hasalpha: false});
733
806
  if (asset) {
734
807
  m.normalMap = asset.getInstance();
735
- elation.events.add(m.normalMap, 'asset_update', elation.bind(this, function(ev) { m.normalMap = ev.data; this.refresh(); }));
736
- 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
+ }
737
813
  }
738
814
  }
739
815
 
@@ -742,14 +818,20 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
742
818
  m.lightMap = textureLightmap;
743
819
  } else {
744
820
  }
745
- 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
+ }
746
825
  } else if (m.lightMap) {
747
826
  var imagesrc = m.lightMap.sourceFile;
748
- var asset = this.getAsset('image', imagesrc, {id: imagesrc, src: imagesrc, hasalpha: false});
749
- if (asset) {
750
- m.lightMap = asset.getInstance();
751
- elation.events.add(asset, 'asset_load', elation.bind(this, function(ev) { m.lightMap = ev.data; this.refresh();}));
752
- 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
+ }
753
835
  }
754
836
  }
755
837
  if (textureDisplacement) {
@@ -807,6 +889,21 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
807
889
  if (this.depth_test !== null) {
808
890
  m.depthTest = this.depth_test;
809
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
+ }
810
907
  // If our diffuse texture has an alpha channel, set up a customDepthMaterial / customDistanceMaterial to allow shadows to work
811
908
  if (m.map) { //this.shadow && m.transparent && m.map) {
812
909
  if (!n.customDepthMaterial) {
@@ -910,6 +1007,8 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
910
1007
  if (oldmat.color) {
911
1008
  m.color.copy(oldmat.color);
912
1009
  }
1010
+ m.transmission = oldmat.transmission;
1011
+ m.transmissionMap = oldmat.transmissionMap;
913
1012
  m.transparent = m.opacity < 1;
914
1013
  m.alphaTest = oldmat.alphaTest;
915
1014
  m.skinning = oldmat.skinning;
@@ -918,10 +1017,18 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
918
1017
  if (oldmat.metalnessMap !== undefined) m.metalnessMap = oldmat.metalnessMap;
919
1018
  if (oldmat.roughness !== undefined) m.roughness = oldmat.roughness;
920
1019
  if (oldmat.roughnessMap !== undefined) m.roughnessMap = oldmat.roughnessMap;
921
- if (oldmat.clearCoat !== undefined) m.clearCoat = oldmat.clearCoar;
922
- if (oldmat.clearCoatRoughness !== undefined) m.clearCoatRoughness = oldmat.clearCoatRoughness;
1020
+ if (oldmat.clearcoat !== undefined) m.clearcoat = oldmat.clearcoat;
1021
+ if (oldmat.clearcoatMap !== undefined) m.clearcoatMap = oldmat.clearcoatMap;
1022
+ if (oldmat.clearcoatRoughness !== undefined) m.clearcoatcoughness = oldmat.clearcoatRoughness;
1023
+ if (oldmat.clearcoatRoughnessMap !== undefined) m.clearcoatRoughnessMap = oldmat.clearcoatRoughnessMap;
1024
+ if (oldmat.clearcoatNormalMap !== undefined) m.clearcoatNormalMap = oldmat.clearcoatNormalMap;
1025
+ if (oldmat.clearcoatNormalScale !== undefined) m.clearcoatNormalScale = oldmat.clearcoatNormalScale;
1026
+ if (oldmat.attenuationTint !== undefined) m.attenuationTint = oldmat.attenuationTint;
1027
+ if (oldmat.attenuationDistance !== undefined) m.attenuationDistance = oldmat.attenuationDistance;
1028
+ if (oldmat.thickness !== undefined) m.thickness = oldmat.thickness;
1029
+ if (oldmat.thicknessMap !== undefined) m.thicknessMap = oldmat.thicknessMap;
923
1030
 
924
- m.reflectivity = (oldmat.reflectivity !== undefined ? oldmat.reflectivity : .5);
1031
+ //m.reflectivity = (oldmat.reflectivity !== undefined ? oldmat.reflectivity : .5);
925
1032
 
926
1033
  if (oldmat.roughnessMap !== undefined) {
927
1034
  m.roughnessMap = oldmat.roughnessMap;
@@ -946,17 +1053,29 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
946
1053
  */
947
1054
 
948
1055
  if (this.shader_chunk_replace) {
949
- let chunkreplace = this.shader_chunk_replace;
1056
+ let chunkreplace = (elation.utils.isString(this.shader_chunk_replace) ? JSON.parse(this.shader_chunk_replace) : this.shader_chunk_replace);
950
1057
  m.onBeforeCompile = function(shader) {
951
1058
  for (let oldchunkname in chunkreplace) {
952
1059
  let newchunkname = chunkreplace[oldchunkname];
953
1060
  shader.vertexShader = shader.vertexShader.replace('#include <' + oldchunkname + '>', '#include <' + newchunkname + '>');
1061
+ shader.fragmentShader = shader.fragmentShader.replace('#include <' + oldchunkname + '>', '#include <' + newchunkname + '>');
954
1062
  }
955
1063
  }
956
1064
  }
957
1065
  }
958
1066
  return m;
959
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
+ }
960
1079
  this.updateColor = function() {
961
1080
  elation.engine.things.janusobject.extendclass.updateColor.call(this);
962
1081
 
@@ -1253,6 +1372,41 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
1253
1372
  this.video.volume = this.gain;
1254
1373
  }
1255
1374
  }
1375
+ this.extractMorphTargets = function() {
1376
+ this.objects['3d'].traverse(n => {
1377
+ if (n.morphTargetDictionary && n.morphTargetInfluences && n.morphTargetInfluences.length > 0) {
1378
+ this.morphtargets = n.morphTargetDictionary;
1379
+ this.morphtargetInfluences = n.morphTargetInfluences;
1380
+ }
1381
+ });
1382
+ }
1383
+ this.setMorphTargetInfluence = function(name, value) {
1384
+ if (typeof this.morphtargets == 'undefined') {
1385
+ this.extractMorphTargets();
1386
+ }
1387
+
1388
+ if (this.morphtargets && name in this.morphtargets) {
1389
+ this.morphtargetInfluences[this.morphtargets[name]] = value;
1390
+ }
1391
+ }
1392
+ this.applyPosition = function(pos) {
1393
+ if (!this.modelasset) this.assignTextures();
1394
+
1395
+ let mat4 = new THREE.Matrix4().makeTranslation(+pos.x, +pos.y, +pos.z);
1396
+ if (this.modelasset && this.modelasset.loaded) {
1397
+ // FIXME - should we handle the case where the object is already loaded and we want to modify its origin?
1398
+ // Currently we do nothing, so we don't double-apply
1399
+ } else {
1400
+ elation.events.add(this.modelasset, 'asset_load', ev => {
1401
+ this.objects['3d'].traverse(n => {
1402
+ if (n instanceof THREE.Mesh) {
1403
+ n.geometry.applyMatrix4(mat4);
1404
+ }
1405
+ });
1406
+ });
1407
+ }
1408
+
1409
+ }
1256
1410
  this.getProxyObject = function(classdef) {
1257
1411
  if (!this._proxyobject) {
1258
1412
  this._proxyobject = elation.engine.things.janusobject.extendclass.getProxyObject.call(this, classdef);
@@ -1280,8 +1434,12 @@ elation.require(['janusweb.janusbase', 'janusweb.websurface'], function() {
1280
1434
  cull_face: [ 'property', 'cull_face' ],
1281
1435
  blend_src: [ 'property', 'blend_src' ],
1282
1436
  blend_dest: [ 'property', 'blend_dest' ],
1437
+ blend_mode: [ 'property', 'blend_mode' ],
1283
1438
  depth_write: [ 'property', 'depth_write' ],
1284
1439
  depth_test: [ 'property', 'depth_test' ],
1440
+ depth_offset: [ 'property', 'depth_offset' ],
1441
+ depth_func: [ 'property', 'depth_func' ],
1442
+ color_write: [ 'property', 'color_write' ],
1285
1443
 
1286
1444
  wireframe: [ 'property', 'wireframe'],
1287
1445
  fog: [ 'property', 'fog'],