@combeenation/3d-viewer 12.2.0 → 12.3.0-beta1

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.
@@ -26,10 +26,19 @@ import { ArcRotateCamera } from '@babylonjs/core/Cameras/arcRotateCamera';
26
26
  import { Engine } from '@babylonjs/core/Engines/engine';
27
27
  import { DirectionalLight } from '@babylonjs/core/Lights/directionalLight';
28
28
  import { HemisphericLight } from '@babylonjs/core/Lights/hemisphericLight';
29
- import { PBRMaterial } from '@babylonjs/core/Materials/PBR/pbrMaterial';
30
- import { CubeTexture } from '@babylonjs/core/Materials/Textures/cubeTexture';
31
- import { DynamicTexture } from '@babylonjs/core/Materials/Textures/dynamicTexture';
32
- import { Texture } from '@babylonjs/core/Materials/Textures/texture';
29
+ import { BackgroundMaterial } from '@babylonjs/core/Materials/Background/backgroundMaterial';
30
+ import { NodeMaterial } from '@babylonjs/core/Materials/Node';
31
+ /**
32
+ * Importing from .../PBR covers all PBR material types, also the deprecated ones like `PBRMetallicRoughnessMaterial`.
33
+ * In this way we can also load models which contain these PBR materials.
34
+ * Still we only actively use `PBRMaterial` in the viewer code base and we also only want to expose this one to the
35
+ * consumer.
36
+ */
37
+ import { PBRMaterial } from '@babylonjs/core/Materials/PBR';
38
+ /**
39
+ * Same story as for PBR materials, we want to support also textures but only want to expose a few of them
40
+ */
41
+ import { CubeTexture, DynamicTexture, Texture } from '@babylonjs/core/Materials/Textures';
33
42
  import { Material } from '@babylonjs/core/Materials/material';
34
43
  import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';
35
44
  import { Color3, Color4 } from '@babylonjs/core/Maths/math.color';
@@ -51,4 +60,4 @@ import { EventEmitter } from 'eventemitter3';
51
60
  /**
52
61
  * Expose some frequently used babylon modules by our consumers.
53
62
  */
54
- export { AnimationManager, AnimationInterface, Variant, VariantInstanceManager, Viewer, ParameterObservable, Parameterizable, VariantParameterizable, ViewerLight, emitter as Emitter, EventEmitter, Event, Parameter, VariantInstance, Color3, Color4, Vector3, AbstractMesh, InstancedMesh, Mesh, TransformNode, Node, Material, PBRMaterial, StandardMaterial, Scene, Engine, ArcRotateCamera, DynamicTexture, CubeTexture, MeshBuilder, Texture, BabylonAnimation, HemisphericLight, DirectionalLight, Element, EventBroadcaster, SceneManager, PlacementAnimation, BabylonHelper, GltfExportManager, SpecStorage, TagManager, ViewerError, ViewerErrorIds, };
63
+ export { AnimationManager, AnimationInterface, Variant, VariantInstanceManager, Viewer, ParameterObservable, Parameterizable, VariantParameterizable, ViewerLight, emitter as Emitter, EventEmitter, Event, Parameter, VariantInstance, Color3, Color4, Vector3, AbstractMesh, InstancedMesh, Mesh, TransformNode, Node, Material, PBRMaterial, StandardMaterial, NodeMaterial, BackgroundMaterial, Scene, Engine, ArcRotateCamera, DynamicTexture, CubeTexture, MeshBuilder, Texture, BabylonAnimation, HemisphericLight, DirectionalLight, Element, EventBroadcaster, SceneManager, PlacementAnimation, BabylonHelper, GltfExportManager, SpecStorage, TagManager, ViewerError, ViewerErrorIds, };
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.ViewerErrorIds = exports.ViewerError = exports.TagManager = exports.SpecStorage = exports.GltfExportManager = exports.BabylonHelper = exports.PlacementAnimation = exports.SceneManager = exports.EventBroadcaster = exports.Element = exports.DirectionalLight = exports.HemisphericLight = exports.BabylonAnimation = exports.Texture = exports.MeshBuilder = exports.CubeTexture = exports.DynamicTexture = exports.ArcRotateCamera = exports.Engine = exports.Scene = exports.StandardMaterial = exports.PBRMaterial = exports.Material = exports.Node = exports.TransformNode = exports.Mesh = exports.InstancedMesh = exports.AbstractMesh = exports.Vector3 = exports.Color4 = exports.Color3 = exports.VariantInstance = exports.Parameter = exports.Event = exports.EventEmitter = exports.Emitter = exports.ViewerLight = exports.VariantParameterizable = exports.Parameterizable = exports.ParameterObservable = exports.Viewer = exports.VariantInstanceManager = exports.Variant = exports.AnimationManager = void 0;
26
+ exports.ViewerErrorIds = exports.ViewerError = exports.TagManager = exports.SpecStorage = exports.GltfExportManager = exports.BabylonHelper = exports.PlacementAnimation = exports.SceneManager = exports.EventBroadcaster = exports.Element = exports.DirectionalLight = exports.HemisphericLight = exports.BabylonAnimation = exports.Texture = exports.MeshBuilder = exports.CubeTexture = exports.DynamicTexture = exports.ArcRotateCamera = exports.Engine = exports.Scene = exports.BackgroundMaterial = exports.NodeMaterial = exports.StandardMaterial = exports.PBRMaterial = exports.Material = exports.Node = exports.TransformNode = exports.Mesh = exports.InstancedMesh = exports.AbstractMesh = exports.Vector3 = exports.Color4 = exports.Color3 = exports.VariantInstance = exports.Parameter = exports.Event = exports.EventEmitter = exports.Emitter = exports.ViewerLight = exports.VariantParameterizable = exports.Parameterizable = exports.ParameterObservable = exports.Viewer = exports.VariantInstanceManager = exports.Variant = exports.AnimationManager = void 0;
27
27
  const element_1 = require("./api/classes/element");
28
28
  Object.defineProperty(exports, "Element", { enumerable: true, get: function () { return element_1.Element; } });
29
29
  const event_1 = require("./api/classes/event");
@@ -76,14 +76,25 @@ const directionalLight_1 = require("@babylonjs/core/Lights/directionalLight");
76
76
  Object.defineProperty(exports, "DirectionalLight", { enumerable: true, get: function () { return directionalLight_1.DirectionalLight; } });
77
77
  const hemisphericLight_1 = require("@babylonjs/core/Lights/hemisphericLight");
78
78
  Object.defineProperty(exports, "HemisphericLight", { enumerable: true, get: function () { return hemisphericLight_1.HemisphericLight; } });
79
- const pbrMaterial_1 = require("@babylonjs/core/Materials/PBR/pbrMaterial");
80
- Object.defineProperty(exports, "PBRMaterial", { enumerable: true, get: function () { return pbrMaterial_1.PBRMaterial; } });
81
- const cubeTexture_1 = require("@babylonjs/core/Materials/Textures/cubeTexture");
82
- Object.defineProperty(exports, "CubeTexture", { enumerable: true, get: function () { return cubeTexture_1.CubeTexture; } });
83
- const dynamicTexture_1 = require("@babylonjs/core/Materials/Textures/dynamicTexture");
84
- Object.defineProperty(exports, "DynamicTexture", { enumerable: true, get: function () { return dynamicTexture_1.DynamicTexture; } });
85
- const texture_1 = require("@babylonjs/core/Materials/Textures/texture");
86
- Object.defineProperty(exports, "Texture", { enumerable: true, get: function () { return texture_1.Texture; } });
79
+ const backgroundMaterial_1 = require("@babylonjs/core/Materials/Background/backgroundMaterial");
80
+ Object.defineProperty(exports, "BackgroundMaterial", { enumerable: true, get: function () { return backgroundMaterial_1.BackgroundMaterial; } });
81
+ const Node_1 = require("@babylonjs/core/Materials/Node");
82
+ Object.defineProperty(exports, "NodeMaterial", { enumerable: true, get: function () { return Node_1.NodeMaterial; } });
83
+ /**
84
+ * Importing from .../PBR covers all PBR material types, also the deprecated ones like `PBRMetallicRoughnessMaterial`.
85
+ * In this way we can also load models which contain these PBR materials.
86
+ * Still we only actively use `PBRMaterial` in the viewer code base and we also only want to expose this one to the
87
+ * consumer.
88
+ */
89
+ const PBR_1 = require("@babylonjs/core/Materials/PBR");
90
+ Object.defineProperty(exports, "PBRMaterial", { enumerable: true, get: function () { return PBR_1.PBRMaterial; } });
91
+ /**
92
+ * Same story as for PBR materials, we want to support also textures but only want to expose a few of them
93
+ */
94
+ const Textures_1 = require("@babylonjs/core/Materials/Textures");
95
+ Object.defineProperty(exports, "CubeTexture", { enumerable: true, get: function () { return Textures_1.CubeTexture; } });
96
+ Object.defineProperty(exports, "DynamicTexture", { enumerable: true, get: function () { return Textures_1.DynamicTexture; } });
97
+ Object.defineProperty(exports, "Texture", { enumerable: true, get: function () { return Textures_1.Texture; } });
87
98
  const material_1 = require("@babylonjs/core/Materials/material");
88
99
  Object.defineProperty(exports, "Material", { enumerable: true, get: function () { return material_1.Material; } });
89
100
  const standardMaterial_1 = require("@babylonjs/core/Materials/standardMaterial");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,mDAAgD;AAwF9C,wFAxFO,iBAAO,OAwFP;AAvFT,+CAAqD;AA+DnD,sFA/DO,aAAK,OA+DP;AAFM,wFA7DG,eAAO,OA6DH;AA5DpB,qEAAkE;AAuFhE,iGAvFO,mCAAgB,OAuFP;AAtFlB,uDAAoD;AA8DlD,0FA9DO,qBAAS,OA8DP;AA7DX,2EAAwE;AAsDtE,oGAtDO,yCAAmB,OAsDP;AArDrB,mEAAgE;AAsD9D,gGAtDO,iCAAe,OAsDP;AArDjB,yEAAsE;AAqFpE,mGArFO,uCAAkB,OAqFP;AApFpB,mDAAgD;AAgD9C,wFAhDO,iBAAO,OAgDP;AA/CT,mEAAgE;AA0D9D,gGA1DO,iCAAe,OA0DP;AAzDjB,iFAA8E;AAmD5E,uGAnDO,+CAAsB,OAmDP;AAlDxB,iDAA8C;AA+C5C,uFA/CO,eAAM,OA+CP;AA9CR,2DAAwE;AAqFtE,4FArFO,yBAAW,OAqFP;AACX,+FAtFoB,4BAAc,OAsFpB;AArFhB,2DAAwD;AAiDtD,4FAjDO,yBAAW,OAiDP;AAhDb,qEAAkE;AAwChE,iGAxCO,mCAAgB,OAwCP;AAvClB,uEAAoE;AA+ElE,kGA/EO,qCAAiB,OA+EP;AA9EnB,6DAA0D;AA2ExD,6FA3EO,2BAAY,OA2EP;AA1Ed,yDAAsD;AA+EpD,2FA/EO,uBAAU,OA+EP;AA9EZ,iFAA8E;AAuC5E,uGAvCO,+CAAsB,OAuCP;AAtCxB,yDAAsD;AA4EpD,4FA5EO,yBAAW,OA4EP;AA3Eb,wEAA0D;AAyExD,sCAAa;AAxEf,oEAAqF;AAiEnF,iGAjEoB,qBAAgB,OAiEpB;AAhElB,6EAA0E;AA2DxE,gGA3DO,iCAAe,OA2DP;AA1DjB,2DAAwD;AAyDtD,uFAzDO,eAAM,OAyDP;AAxDR,8EAA2E;AAgEzE,iGAhEO,mCAAgB,OAgEP;AA/DlB,8EAA2E;AA8DzE,iGA9DO,mCAAgB,OA8DP;AA7DlB,2EAAwE;AAmDtE,4FAnDO,yBAAW,OAmDP;AAlDb,gFAA6E;AAwD3E,4FAxDO,yBAAW,OAwDP;AAvDb,sFAAmF;AAsDjF,+FAtDO,+BAAc,OAsDP;AArDhB,wEAAqE;AAwDnE,wFAxDO,iBAAO,OAwDP;AAvDT,iEAA8D;AA8C5D,yFA9CO,mBAAQ,OA8CP;AA7CV,iFAA8E;AA+C5E,iGA/CO,mCAAgB,OA+CP;AA9ClB,iEAAkE;AAoChE,uFApCO,mBAAM,OAoCP;AACN,uFArCe,mBAAM,OAqCf;AApCR,mEAA4D;AAqC1D,wFArCO,qBAAO,OAqCP;AApCT,sEAAmE;AAqCjE,6FArCO,2BAAY,OAqCP;AApCd,wEAAqE;AAqCnE,8FArCO,6BAAa,OAqCP;AApCf,sDAAmD;AAqCjD,qFArCO,WAAI,OAqCP;AApCN,oEAAiE;AA+C/D,4FA/CO,yBAAW,OA+CP;AA9Cb,wEAAqE;AAoCnE,8FApCO,6BAAa,OAoCP;AAlCf;;;;GAIG;AACH,yDAAuD;AACvD,+CAA4C;AA6B1C,qFA7BO,WAAI,OA6BP;AA5BN,iDAA8C;AAgC5C,sFAhCO,aAAK,OAgCP;AA/BP,iDAA6C;AAgB3C,6FAhBO,4BAAY,OAgBP"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,mDAAgD;AAqG9C,wFArGO,iBAAO,OAqGP;AApGT,+CAAqD;AA0EnD,sFA1EO,aAAK,OA0EP;AAFM,wFAxEG,eAAO,OAwEH;AAvEpB,qEAAkE;AAoGhE,iGApGO,mCAAgB,OAoGP;AAnGlB,uDAAoD;AAyElD,0FAzEO,qBAAS,OAyEP;AAxEX,2EAAwE;AAiEtE,oGAjEO,yCAAmB,OAiEP;AAhErB,mEAAgE;AAiE9D,gGAjEO,iCAAe,OAiEP;AAhEjB,yEAAsE;AAkGpE,mGAlGO,uCAAkB,OAkGP;AAjGpB,mDAAgD;AA2D9C,wFA3DO,iBAAO,OA2DP;AA1DT,mEAAgE;AAqE9D,gGArEO,iCAAe,OAqEP;AApEjB,iFAA8E;AA8D5E,uGA9DO,+CAAsB,OA8DP;AA7DxB,iDAA8C;AA0D5C,uFA1DO,eAAM,OA0DP;AAzDR,2DAAwE;AAkGtE,4FAlGO,yBAAW,OAkGP;AACX,+FAnGoB,4BAAc,OAmGpB;AAlGhB,2DAAwD;AA4DtD,4FA5DO,yBAAW,OA4DP;AA3Db,qEAAkE;AAmDhE,iGAnDO,mCAAgB,OAmDP;AAlDlB,uEAAoE;AA4FlE,kGA5FO,qCAAiB,OA4FP;AA3FnB,6DAA0D;AAwFxD,6FAxFO,2BAAY,OAwFP;AAvFd,yDAAsD;AA4FpD,2FA5FO,uBAAU,OA4FP;AA3FZ,iFAA8E;AAkD5E,uGAlDO,+CAAsB,OAkDP;AAjDxB,yDAAsD;AAyFpD,4FAzFO,yBAAW,OAyFP;AAxFb,wEAA0D;AAsFxD,sCAAa;AArFf,oEAAqF;AA8EnF,iGA9EoB,qBAAgB,OA8EpB;AA7ElB,6EAA0E;AAwExE,gGAxEO,iCAAe,OAwEP;AAvEjB,2DAAwD;AAsEtD,uFAtEO,eAAM,OAsEP;AArER,8EAA2E;AA6EzE,iGA7EO,mCAAgB,OA6EP;AA5ElB,8EAA2E;AA2EzE,iGA3EO,mCAAgB,OA2EP;AA1ElB,gGAA6F;AAiE3F,mGAjEO,uCAAkB,OAiEP;AAhEpB,yDAA8D;AA+D5D,6FA/DO,mBAAY,OA+DP;AA7Dd;;;;;GAKG;AACH,uDAA4D;AAqD1D,4FArDO,iBAAW,OAqDP;AAnDb;;GAEG;AACH,iEAA0F;AAwDxF,4FAxDO,sBAAW,OAwDP;AADX,+FAvDoB,yBAAc,OAuDpB;AAGd,wFA1DoC,kBAAO,OA0DpC;AAzDT,iEAA8D;AA8C5D,yFA9CO,mBAAQ,OA8CP;AA7CV,iFAA8E;AA+C5E,iGA/CO,mCAAgB,OA+CP;AA9ClB,iEAAkE;AAoChE,uFApCO,mBAAM,OAoCP;AACN,uFArCe,mBAAM,OAqCf;AApCR,mEAA4D;AAqC1D,wFArCO,qBAAO,OAqCP;AApCT,sEAAmE;AAqCjE,6FArCO,2BAAY,OAqCP;AApCd,wEAAqE;AAqCnE,8FArCO,6BAAa,OAqCP;AApCf,sDAAmD;AAqCjD,qFArCO,WAAI,OAqCP;AApCN,oEAAiE;AAiD/D,4FAjDO,yBAAW,OAiDP;AAhDb,wEAAqE;AAoCnE,8FApCO,6BAAa,OAoCP;AAlCf;;;;GAIG;AACH,yDAAuD;AACvD,+CAA4C;AA6B1C,qFA7BO,WAAI,OA6BP;AA5BN,iDAA8C;AAkC5C,sFAlCO,aAAK,OAkCP;AAjCP,iDAA6C;AAgB3C,6FAhBO,4BAAY,OAgBP"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@combeenation/3d-viewer",
3
- "version": "12.2.0",
3
+ "version": "12.3.0-beta1",
4
4
  "description": "Combeenation 3D Viewer",
5
5
  "homepage": "https://github.com/Combeenation/3d-viewer#readme",
6
6
  "bugs": {
@@ -48,7 +48,6 @@
48
48
  "dependencies": {
49
49
  "@babylonjs/core": "6.27.1",
50
50
  "@babylonjs/loaders": "6.27.1",
51
- "@babylonjs/materials": "6.27.1",
52
51
  "@babylonjs/serializers": "6.27.1",
53
52
  "eventemitter3": "4.0.7",
54
53
  "gsap": "3.11.2",
@@ -7,7 +7,7 @@ import { TagManager } from '../manager/tagManager';
7
7
  import { VariantInstanceManager } from '../manager/variantInstanceManager';
8
8
  import { SpecStorage } from '../store/specStorage';
9
9
  import { backgroundDomeName, envHelperMetadataName } from '../util/babylonHelper';
10
- import { hideWorldCoordinates, isWorldCoordinatesDebugNode, showWorldCoordinates } from '../util/debugHelper';
10
+ import { hideWorldCoordinates, showWorldCoordinates } from '../util/debugHelper';
11
11
  import { getIsScaledDownDevice } from '../util/deviceHelper';
12
12
  import { debounce, loadJson } from '../util/resourceHelper';
13
13
  import { getCustomCbnBabylonLoaderPlugin } from '../util/sceneLoaderHelper';
@@ -45,8 +45,6 @@ import { isString } from 'lodash-es';
45
45
  * The class does nothing on its own and needs to {@link bootstrap}
46
46
  */
47
47
  export class Viewer extends EventBroadcaster {
48
- public static readonly BOUNDING_BOX_NAME = '__bounding_box__';
49
-
50
48
  protected _scene: Scene | null = null;
51
49
 
52
50
  protected _animationManager: AnimationManager | null = null;
@@ -498,9 +496,9 @@ The inspector can only be used in development builds.`);
498
496
  }
499
497
 
500
498
  /**
501
- * Calculates the bounding box from all visible meshes on the scene.
499
+ * Calculates the bounding box information from all visible meshes on the scene.
502
500
  */
503
- public async calculateBoundingBox(excludeGeometry?: ExcludedGeometryList): Promise<Mesh> {
501
+ public calculateBoundingInfo(excludeGeometry?: ExcludedGeometryList): BoundingInfo {
504
502
  if (this.scene.meshes.length === 0) {
505
503
  throw new Error('There are currently no meshes on the scene.');
506
504
  }
@@ -508,24 +506,13 @@ The inspector can only be used in development builds.`);
508
506
  const { max, min } = this.scene.meshes
509
507
  .filter(mesh => {
510
508
  const isEnabled = mesh.isEnabled();
511
- // ignore the existing bounding box mesh for calculating the current one
512
- const isNotBBoxMesh = Viewer.BOUNDING_BOX_NAME !== mesh.name;
513
- // ignore debug world coordinates nodes
514
- const isNotWorldCoordinatesDebugNode = !isWorldCoordinatesDebugNode(mesh.name);
515
509
  // ignore meshes with invalid bounding infos
516
510
  const hasValidBBoxInfo = mesh.getBoundingInfo().boundingSphere.radius > 0;
517
511
  // ignore meshes with infinite distance, typically these are sky boxes
518
512
  const hasInfiniteDistance = mesh.infiniteDistance;
519
513
  // ignore excluded meshes
520
514
  const isExcluded = excludeGeometry ? isNodeIncludedInExclusionList(mesh, excludeGeometry) : false;
521
- return (
522
- isEnabled &&
523
- isNotBBoxMesh &&
524
- isNotWorldCoordinatesDebugNode &&
525
- hasValidBBoxInfo &&
526
- !hasInfiniteDistance &&
527
- !isExcluded
528
- );
515
+ return isEnabled && hasValidBBoxInfo && !hasInfiniteDistance && !isExcluded;
529
516
  })
530
517
  .reduce(
531
518
  (accBBoxMinMax, curMesh, idx) => {
@@ -538,12 +525,8 @@ The inspector can only be used in development builds.`);
538
525
  { max: new Vector3(), min: new Vector3() }
539
526
  );
540
527
 
541
- let boundingBox = this.scene.getMeshByName(Viewer.BOUNDING_BOX_NAME) as Mesh;
542
- if (!boundingBox) {
543
- boundingBox = new Mesh(Viewer.BOUNDING_BOX_NAME, this.scene);
544
- }
545
- boundingBox.setBoundingInfo(new BoundingInfo(min, max));
546
- return boundingBox;
528
+ const boundingInfo = new BoundingInfo(min, max);
529
+ return boundingInfo;
547
530
  }
548
531
 
549
532
  /**
@@ -575,10 +558,10 @@ The inspector can only be used in development builds.`);
575
558
  }
576
559
 
577
560
  // get bounding box of all visible meshes, this is the base for the autofocus algorithm
578
- const boundingBox = await this.calculateBoundingBox(exclude);
561
+ const boundingInfo = this.calculateBoundingInfo(exclude);
579
562
 
580
- const radius = boundingBox.getBoundingInfo().boundingSphere.radius;
581
- const center = boundingBox.getBoundingInfo().boundingSphere.center;
563
+ const radius = boundingInfo.boundingSphere.radius;
564
+ const center = boundingInfo.boundingSphere.center;
582
565
  const diameter = radius * 2;
583
566
 
584
567
  // set lower radius limit on edge of bounding sphere to make sure that we can't dive into the meshes
@@ -639,14 +622,14 @@ The inspector can only be used in development builds.`);
639
622
  * Show world coordinate system with given dimension (for debugging purpose).
640
623
  */
641
624
  public showWorldCoordinates(dimension: number) {
642
- showWorldCoordinates(this.scene, dimension);
625
+ showWorldCoordinates(dimension);
643
626
  }
644
627
 
645
628
  /**
646
629
  * Hide world coordinate system.
647
630
  */
648
631
  public hideWorldCoordinates() {
649
- hideWorldCoordinates(this.scene);
632
+ hideWorldCoordinates();
650
633
  }
651
634
 
652
635
  /**
@@ -1,6 +1,5 @@
1
1
  import { Viewer } from '../classes/viewer';
2
2
  import { injectMetadata } from '../util/babylonHelper';
3
- import { isWorldCoordinatesDebugNode } from '../util/debugHelper';
4
3
  import { getIsScaledDownDevice } from '../util/deviceHelper';
5
4
  import { bakeGeometryOfMesh, createMeshFromInstancedMesh, resetTransformation } from '../util/geometryHelper';
6
5
  import { isNodeIncludedInExclusionList } from '../util/structureHelper';
@@ -280,12 +279,6 @@ export class GltfExportManager {
280
279
  return false;
281
280
  }
282
281
  // TODO: think of adding "BackgroundHelper" and nodes with "infiniteDistance" here as well, at least in AR mode
283
- if (node.name === Viewer.BOUNDING_BOX_NAME) {
284
- return false;
285
- }
286
- if (isWorldCoordinatesDebugNode(node.name)) {
287
- return false;
288
- }
289
282
  if (!node.isEnabled()) {
290
283
  return false;
291
284
  }
@@ -299,10 +299,6 @@ export class TagManager {
299
299
  created means that there is no scenario where new nodes should get TagManager parameters applied.
300
300
  Instead, we check for the state to be enabled via the `onEnabledStateChangedObservable` below.
301
301
  */
302
- //if (node.name === Viewer.BOUNDING_BOX_NAME || !this.viewer.variantInstances.areAllDefinitionsCreated) {
303
- if (node.name === Viewer.BOUNDING_BOX_NAME) {
304
- return;
305
- }
306
302
  const onEnabledStateChangedObserver = node.onEnabledStateChangedObservable.add(async state => {
307
303
  if (!state) {
308
304
  // if the node is disabled, means ignoring also "ghost nodes"
@@ -1,10 +1,11 @@
1
- import { Vector3 } from '@babylonjs/core';
2
1
  import { AxesViewer } from '@babylonjs/core/Debug/axesViewer';
3
2
  import { DynamicTexture } from '@babylonjs/core/Materials/Textures/dynamicTexture';
4
3
  import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';
5
4
  import { Color3 } from '@babylonjs/core/Maths/math.color';
5
+ import { Vector3 } from '@babylonjs/core/Maths/math.vector';
6
6
  import { MeshBuilder } from '@babylonjs/core/Meshes/meshBuilder';
7
7
  import { TransformNode } from '@babylonjs/core/Meshes/transformNode';
8
+ import { UtilityLayerRenderer } from '@babylonjs/core/Rendering/utilityLayerRenderer';
8
9
 
9
10
  type DebugAxisKeys = 'X' | 'Y' | 'Z';
10
11
  type DebugAxisConfig = { color: Color3; position: Vector3 };
@@ -22,44 +23,38 @@ let _AXES_VIEWER: AxesViewer;
22
23
  * Create debug coordinate system located in world origin.
23
24
  * This function is based on Babylon.js `AxesViewer`, axis texts are added manually.
24
25
  */
25
- export function showWorldCoordinates(scene: Scene, dimension: number) {
26
+ export function showWorldCoordinates(dimension: number) {
26
27
  // make sure to remove already existing debug coordinate systems
27
- hideWorldCoordinates(scene);
28
+ hideWorldCoordinates();
28
29
 
29
- const worldCoordRoot = new TransformNode(_WORLD_COORD_ROOT_KEY, scene);
30
+ // draw in utility layer, so that there is no interaction with the actually scene content (eg: glb export, autofocus)
31
+ const utilityLayerScene = UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene;
32
+
33
+ const worldCoordRoot = new TransformNode('__world_coordinates__', utilityLayerScene);
30
34
  // axes viewer coordinate system is a bit too large
31
35
  // multiply with unify factor to create arrows which exactly match the length of the input dimension
32
36
  const factor = _getWorldCoordinatesAxesUnifyFactor();
33
- _AXES_VIEWER = new AxesViewer(scene, dimension * factor);
37
+ _AXES_VIEWER = new AxesViewer(utilityLayerScene, dimension * factor);
34
38
 
35
- _prepareWorldCoordinateAxis('X', _AXES_VIEWER.xAxis, worldCoordRoot, dimension, scene);
36
- _prepareWorldCoordinateAxis('Y', _AXES_VIEWER.yAxis, worldCoordRoot, dimension, scene);
37
- _prepareWorldCoordinateAxis('Z', _AXES_VIEWER.zAxis, worldCoordRoot, dimension, scene);
39
+ _prepareWorldCoordinateAxis('X', _AXES_VIEWER.xAxis, worldCoordRoot, dimension, utilityLayerScene);
40
+ _prepareWorldCoordinateAxis('Y', _AXES_VIEWER.yAxis, worldCoordRoot, dimension, utilityLayerScene);
41
+ _prepareWorldCoordinateAxis('Z', _AXES_VIEWER.zAxis, worldCoordRoot, dimension, utilityLayerScene);
38
42
  }
39
43
 
40
44
  /**
41
45
  * Remove meshes and materials that are associated with the debug world coordinates system
42
46
  */
43
- export function hideWorldCoordinates(scene: Scene) {
47
+ export function hideWorldCoordinates() {
48
+ const utilityLayerScene = UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene;
49
+
44
50
  _AXES_VIEWER?.dispose();
45
51
 
46
- const worldCoordRoot = scene.getTransformNodeByName(_WORLD_COORD_ROOT_KEY);
52
+ const worldCoordRoot = utilityLayerScene.getTransformNodeByName(_WORLD_COORD_ROOT_KEY);
47
53
  if (worldCoordRoot) {
48
54
  worldCoordRoot.dispose(false, true);
49
55
  }
50
56
  }
51
57
 
52
- /**
53
- * Checks if the node is generated by the `showWorldCoordinates` function.
54
- * These nodes need special treatment in certain cases, for example the `autofocusActiveCamera` function should ignore
55
- * the values and GLB exports should also not include the nodes.
56
- */
57
- export function isWorldCoordinatesDebugNode(nodeName: string) {
58
- // ATM this is a plain name check, as we have some reserved names in the viewer (see Viewer.BOUNDING_BOX_NAME)
59
- // Other solutions could be storing this info in the metadata or in a different global node store
60
- return nodeName.startsWith(_WORLD_COORD_ROOT_KEY);
61
- }
62
-
63
58
  /**
64
59
  * Adjust and enhance coordinate axes to fulfill our needs.
65
60
  * - moves nodes into common root
@@ -70,26 +65,29 @@ function _prepareWorldCoordinateAxis(
70
65
  axis: TransformNode,
71
66
  root: TransformNode,
72
67
  dimension: number,
73
- scene: Scene
68
+ utilityLayerScene: Scene
74
69
  ) {
75
70
  // create unique names
76
71
  axis.name = `${_WORLD_COORD_ROOT_KEY}.${text}`;
77
72
  axis.parent = root;
78
- axis.getChildMeshes().forEach((child, idx) => (child.name = `${_WORLD_COORD_ROOT_KEY}.${text}.cylinder_${idx}`));
79
73
 
80
74
  // create text mesh via dynamic texture
81
- const dynamicTexture = new DynamicTexture(`${_WORLD_COORD_ROOT_KEY}.${text}`, 50, scene, true);
75
+ const dynamicTexture = new DynamicTexture(`${_WORLD_COORD_ROOT_KEY}.${text}`, 50, utilityLayerScene, true);
82
76
  dynamicTexture.hasAlpha = true;
83
77
  // 42.5 is a magic offset, so that the text is vertically centered for font size 50px
84
78
  // horizontal centering works well with the standard behaviour of Babylon.js (setting "null" as "width")
85
79
  dynamicTexture.drawText(text, null, 42.5, 'bold 50px Arial', 'white', 'transparent', true);
86
80
 
87
- const material = new StandardMaterial(`${_WORLD_COORD_ROOT_KEY}.${text}`, scene);
81
+ const material = new StandardMaterial(`${_WORLD_COORD_ROOT_KEY}.${text}`, utilityLayerScene);
88
82
  material.disableLighting = true;
89
83
  material.emissiveColor = _DEBUG_AXIS_MAP[text].color;
90
84
  material.diffuseTexture = dynamicTexture;
91
85
 
92
- const plane = MeshBuilder.CreatePlane(`${_WORLD_COORD_ROOT_KEY}.${text}.TextPlane`, { size: dimension / 10 }, scene);
86
+ const plane = MeshBuilder.CreatePlane(
87
+ `${_WORLD_COORD_ROOT_KEY}.${text}.TextPlane`,
88
+ { size: dimension / 10 },
89
+ utilityLayerScene
90
+ );
93
91
  // make sure that text is located outside of arrow
94
92
  plane.position = _DEBUG_AXIS_MAP[text].position.multiplyByFloats(
95
93
  dimension * 1.05,
@@ -22,6 +22,8 @@ type Color4 = import('@babylonjs/core/Maths/math.color').Color4;
22
22
  type Material = import('@babylonjs/core/Materials/material').Material;
23
23
  type PBRMaterial = import('@babylonjs/core/Materials/PBR/pbrMaterial').PBRMaterial;
24
24
  type StandardMaterial = import('@babylonjs/core/Materials/standardMaterial').StandardMaterial;
25
+ type BackgroundMaterial = import('@babylonjs/core/Materials/Background/backgroundMaterial').BackgroundMaterial;
26
+ type NodeMaterial = import('@babylonjs/core/Materials/Node').NodeMaterial;
25
27
  type DynamicTexture = import('@babylonjs/core/Materials/Textures/dynamicTexture').DynamicTexture;
26
28
  type Mesh = import('@babylonjs/core/Meshes/mesh').Mesh;
27
29
  type AbstractMesh = import('@babylonjs/core/Meshes/abstractMesh').AbstractMesh;
@@ -11,6 +11,7 @@ import { AssetContainer } from '@babylonjs/core/assetContainer';
11
11
  import { Node as BjsNode } from '@babylonjs/core/node';
12
12
  import { Scene } from '@babylonjs/core/scene';
13
13
  import { Nullable } from '@babylonjs/core/types';
14
+ import { isArray, isString } from 'lodash-es';
14
15
  import has from 'lodash-es/has';
15
16
 
16
17
  // map for keeping track of active "node enable" observers
@@ -88,26 +89,59 @@ export const getMaterialPostLoadObserver = function (concerningMesh: Mesh) {
88
89
  };
89
90
  };
90
91
 
92
+ type InstanceData = {
93
+ name: string;
94
+ tags?: string;
95
+ };
96
+
97
+ function _isMeshInstanceData(data: any): data is InstanceData {
98
+ const hasName = isString(data.name);
99
+ const hasValidTags = !data.tags || isString(data.tags);
100
+ return hasName && hasValidTags;
101
+ }
102
+
103
+ type MeshData = {
104
+ name: string;
105
+ materialId?: string;
106
+ instances?: unknown[];
107
+ };
108
+
109
+ function _isMeshData(data: any): data is MeshData {
110
+ const hasName = isString(data.name);
111
+ const hasValidMaterialId = !data.materialId || isString(data.materialId);
112
+
113
+ return hasName && hasValidMaterialId;
114
+ }
115
+
116
+ type DataWithMeshes = { meshes: unknown[] };
117
+
118
+ function _isDataWithMeshes(data: any): data is DataWithMeshes {
119
+ return data && isArray(data.meshes);
120
+ }
121
+
91
122
  /**
92
123
  * Internal function that compares the original meshes on a .babylon file with what was loaded,
93
124
  * and tags missing materials with respective metadata on respective meshes.
94
125
  * @param dataParsed original data
95
126
  * @param container loaded data
96
127
  */
97
- export const addMissingMaterialMetadata = function (dataParsed: any, container: AssetContainer) {
98
- container.meshes.forEach(currMeshImported => {
99
- for (const currMeshOriginal of dataParsed.meshes) {
100
- if (currMeshOriginal.name !== currMeshImported.name) continue;
101
- // we're dealing with the original version of the current imported mesh now
102
- // first save original material id of the imported babylon or GLB file
103
- injectMetadata(currMeshImported, { [parsedMaterialIdMetadataName]: currMeshOriginal.materialId }, false);
104
- const materialOnImportedMesh = currMeshImported.material?.id;
105
- const materialOnOriginalMesh = currMeshOriginal.materialId;
106
- if (!materialOnOriginalMesh || materialOnImportedMesh === materialOnOriginalMesh) continue;
107
- // if we're here, the imported mesh has different material than original one
128
+ export const addMissingMaterialMetadata = function (dataParsed: unknown, container: AssetContainer) {
129
+ if (!_isDataWithMeshes(dataParsed)) return;
130
+
131
+ const validatedMeshes = dataParsed.meshes.filter(_isMeshData);
132
+
133
+ container.meshes.forEach(importedMesh => {
134
+ const parsedMesh = validatedMeshes.find(mesh => mesh.name === importedMesh.name);
135
+
136
+ // save original material id of the imported babylon or GLB file
137
+ injectMetadata(importedMesh, { [parsedMaterialIdMetadataName]: parsedMesh?.materialId }, false);
138
+
139
+ const materialOnImportedMesh = importedMesh.material?.id;
140
+ const materialOnOriginalMesh = parsedMesh?.materialId;
141
+
142
+ if (materialOnOriginalMesh && materialOnImportedMesh !== materialOnOriginalMesh) {
108
143
  window.Cbn?.Assets.assertMaterialExists(materialOnOriginalMesh);
109
- injectMetadata(currMeshImported, { [missingMaterialMetadataName]: materialOnOriginalMesh }, false);
110
- break;
144
+ injectMetadata(importedMesh, { [missingMaterialMetadataName]: materialOnOriginalMesh }, false);
111
145
  }
112
146
  });
113
147
  };
@@ -124,7 +158,11 @@ export const addMissingMaterialMetadata = function (dataParsed: any, container:
124
158
  * @param dataParsed original data
125
159
  * @param container loaded data
126
160
  */
127
- export const reconstructTagsForInstancedMeshes = function (dataParsed: any, container: AssetContainer) {
161
+ export const reconstructTagsForInstancedMeshes = function (dataParsed: unknown, container: AssetContainer) {
162
+ if (!_isDataWithMeshes(dataParsed)) return;
163
+
164
+ const validatedMeshes = dataParsed.meshes.filter(_isMeshData);
165
+
128
166
  container.meshes.forEach(importedMesh => {
129
167
  if (importedMesh instanceof InstancedMesh) {
130
168
  // remove all tags from the imported mesh if there are some, since these tags are probably coming from the
@@ -134,12 +172,9 @@ export const reconstructTagsForInstancedMeshes = function (dataParsed: any, cont
134
172
  Tags.RemoveTagsFrom(importedMesh, importedTags);
135
173
 
136
174
  // get tags of parsed instanced mesh and set them on the imported instanced mesh
137
- const parsedSourceMesh = dataParsed.meshes?.find(
138
- (parsedMesh: any) => parsedMesh.name === importedMesh.sourceMesh.name
139
- );
140
- const parsedInstancedMesh = parsedSourceMesh?.instances.find(
141
- (parsedMesh: any) => parsedMesh.name === importedMesh.name
142
- );
175
+ const parsedSourceMesh = validatedMeshes.find(mesh => mesh.name === importedMesh.sourceMesh.name);
176
+ const validatedSourceMeshInstances = parsedSourceMesh?.instances?.filter(_isMeshInstanceData);
177
+ const parsedInstancedMesh = validatedSourceMeshInstances?.find(mesh => mesh.name === importedMesh.name);
143
178
  const parsedTags = parsedInstancedMesh?.tags;
144
179
  if (parsedTags) {
145
180
  Tags.AddTagsTo(importedMesh, parsedTags);
package/src/index.ts CHANGED
@@ -27,10 +27,21 @@ import { ArcRotateCamera } from '@babylonjs/core/Cameras/arcRotateCamera';
27
27
  import { Engine } from '@babylonjs/core/Engines/engine';
28
28
  import { DirectionalLight } from '@babylonjs/core/Lights/directionalLight';
29
29
  import { HemisphericLight } from '@babylonjs/core/Lights/hemisphericLight';
30
- import { PBRMaterial } from '@babylonjs/core/Materials/PBR/pbrMaterial';
31
- import { CubeTexture } from '@babylonjs/core/Materials/Textures/cubeTexture';
32
- import { DynamicTexture } from '@babylonjs/core/Materials/Textures/dynamicTexture';
33
- import { Texture } from '@babylonjs/core/Materials/Textures/texture';
30
+ import { BackgroundMaterial } from '@babylonjs/core/Materials/Background/backgroundMaterial';
31
+ import { NodeMaterial } from '@babylonjs/core/Materials/Node';
32
+
33
+ /**
34
+ * Importing from .../PBR covers all PBR material types, also the deprecated ones like `PBRMetallicRoughnessMaterial`.
35
+ * In this way we can also load models which contain these PBR materials.
36
+ * Still we only actively use `PBRMaterial` in the viewer code base and we also only want to expose this one to the
37
+ * consumer.
38
+ */
39
+ import { PBRMaterial } from '@babylonjs/core/Materials/PBR';
40
+
41
+ /**
42
+ * Same story as for PBR materials, we want to support also textures but only want to expose a few of them
43
+ */
44
+ import { CubeTexture, DynamicTexture, Texture } from '@babylonjs/core/Materials/Textures';
34
45
  import { Material } from '@babylonjs/core/Materials/material';
35
46
  import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';
36
47
  import { Color3, Color4 } from '@babylonjs/core/Maths/math.color';
@@ -80,6 +91,8 @@ export {
80
91
  Material,
81
92
  PBRMaterial,
82
93
  StandardMaterial,
94
+ NodeMaterial,
95
+ BackgroundMaterial,
83
96
  Scene,
84
97
  Engine,
85
98
  ArcRotateCamera,