@configura/babylon-view 1.3.0-alpha.1 → 1.3.0-alpha.5

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 (51) hide show
  1. package/dist/animation/coordinator/CoordinatorDropAndSpin.js +1 -1
  2. package/dist/animation/coordinator/CoordinatorPulseBounce.js +1 -1
  3. package/dist/animation/coordinator/CoordinatorPulseHighlight.js +1 -1
  4. package/dist/animation/coordinator/CoordinatorPulseInflate.js +1 -1
  5. package/dist/camera/CfgArcRotateCameraPointersInput.d.ts +16 -0
  6. package/dist/camera/CfgArcRotateCameraPointersInput.js +17 -15
  7. package/dist/camera/CfgOrbitalCamera.d.ts +5 -1
  8. package/dist/camera/CfgOrbitalCamera.js +24 -7
  9. package/dist/engine/EngineCreator.js +1 -1
  10. package/dist/geometry/CfgGeometry.d.ts +22 -5
  11. package/dist/geometry/CfgGeometry.js +131 -102
  12. package/dist/geometry/CfgMesh.d.ts +4 -1
  13. package/dist/geometry/CfgMesh.js +32 -2
  14. package/dist/geometry/stretch/CfgMorphTarget.d.ts +16 -0
  15. package/dist/geometry/stretch/CfgMorphTarget.js +65 -0
  16. package/dist/geometry/stretch/CfgStretchData.d.ts +115 -0
  17. package/dist/geometry/stretch/CfgStretchData.js +340 -0
  18. package/dist/geometry/stretch/CfgStretchMorphGeometry.d.ts +17 -0
  19. package/dist/geometry/stretch/CfgStretchMorphGeometry.js +95 -0
  20. package/dist/material/CfgMaterial.d.ts +19 -4
  21. package/dist/material/CfgMaterial.js +38 -30
  22. package/dist/material/material.js +3 -3
  23. package/dist/material/texture.js +10 -8
  24. package/dist/nodes/CfgDeferredMeshNode.d.ts +8 -1
  25. package/dist/nodes/CfgDeferredMeshNode.js +48 -18
  26. package/dist/nodes/CfgProductNode.d.ts +68 -3
  27. package/dist/nodes/CfgProductNode.js +130 -38
  28. package/dist/nodes/CfgSymNode.d.ts +14 -6
  29. package/dist/nodes/CfgSymNode.js +50 -17
  30. package/dist/nodes/CfgSymRootNode.d.ts +18 -6
  31. package/dist/nodes/CfgSymRootNode.js +62 -17
  32. package/dist/nodes/CfgTransformNode.d.ts +4 -0
  33. package/dist/nodes/CfgTransformNode.js +4 -2
  34. package/dist/utilities/CfgBoundingBox.d.ts +5 -0
  35. package/dist/utilities/CfgBoundingBox.js +18 -1
  36. package/dist/utilities/anchor/anchor.d.ts +52 -0
  37. package/dist/utilities/anchor/anchor.js +136 -0
  38. package/dist/utilities/anchor/anchorMap.d.ts +21 -0
  39. package/dist/utilities/anchor/anchorMap.js +111 -0
  40. package/dist/utilities/utilities3D.d.ts +44 -0
  41. package/dist/utilities/utilities3D.js +97 -19
  42. package/dist/utilities/utilitiesSymRootIdentifier.d.ts +3 -1
  43. package/dist/utilities/utilitiesSymRootIdentifier.js +10 -4
  44. package/dist/view/BaseView.d.ts +9 -1
  45. package/dist/view/BaseView.js +16 -10
  46. package/dist/view/RenderEnv.d.ts +6 -1
  47. package/dist/view/SingleProductDefaultCameraView.js +2 -1
  48. package/dist/view/SingleProductDefaultCameraViewConfiguration.d.ts +2 -0
  49. package/dist/view/SingleProductView.d.ts +8 -1
  50. package/dist/view/SingleProductView.js +1 -0
  51. package/package.json +5 -5
@@ -16,14 +16,16 @@ function findTexture(textures, texture) {
16
16
  const DBL = 1;
17
17
  const BTF = 2;
18
18
  const FLP = 4;
19
- /// A wrapper around Babylon.js PBRMaterial class.
20
- ///
21
- /// Also contains logic to create light weight "variants" of the main PBRMaterial to take into
22
- /// account that CmSym allows the meshes to have properties that affects the material currently
23
- /// applied to the mesh, such as double doubled sided or flipping the textures along the y-axis.
24
- ///
25
- /// The variants are created on demand if the request to getPBRMaterial specifies properties that
26
- /// does not match the main PBRMaterial. The variants are then cached.
19
+ /**
20
+ * A wrapper around Babylon.js PBRMaterial class.
21
+ *
22
+ * Also contains logic to create light weight "variants" of the main PBRMaterial to take into
23
+ * account that CmSym allows the meshes to have properties that affects the material currently
24
+ * applied to the mesh, such as double doubled sided or flipping the textures along the y-axis.
25
+ *
26
+ * The variants are created on demand if the request to getPBRMaterial specifies properties that
27
+ * does not match the main PBRMaterial. The variants are then cached.
28
+ */
27
29
  export class CfgMaterial {
28
30
  constructor(material, maxSimultaneousLights) {
29
31
  this.isTransparent = false;
@@ -41,13 +43,13 @@ export class CfgMaterial {
41
43
  this._variants = new Array(8);
42
44
  this._variants[this.indexFromMaterial(material)] = material;
43
45
  }
44
- /// This material is supposed to be rendered as double sided by default
46
+ /** This material is supposed to be rendered as double sided by default. */
45
47
  isDoubleSided() {
46
48
  return !this._material.backFaceCulling;
47
49
  }
48
- static fromTexture(renderEnvironment, texture, sourcePath) {
50
+ static makeFromTexture(renderEnvironment, texture, sourcePath) {
49
51
  var _a, _b;
50
- sourcePath.push("fromTexture");
52
+ sourcePath.push("makeFromTexture");
51
53
  let name = "(Img)";
52
54
  const fileName = (_b = (_a = texture.name) === null || _a === void 0 ? void 0 : _a.split("\\").pop()) === null || _b === void 0 ? void 0 : _b.split("/").pop();
53
55
  if (fileName) {
@@ -58,9 +60,9 @@ export class CfgMaterial {
58
60
  material.roughness = 1;
59
61
  material.metallic = 0;
60
62
  // TODO Babylon: What happens if the texture has an alpha map? Compare to Three.js and CET
61
- return new CfgMaterial(material, renderEnvironment.lightRig.lightCount);
63
+ return new this(material, renderEnvironment.lightRig.lightCount);
62
64
  }
63
- static compileFromGm(renderEnvironment, meta, gMaterial, textures) {
65
+ static makeFromGm(renderEnvironment, meta, gMaterial, textures) {
64
66
  var _a, _b;
65
67
  // Use the materials given name or fallback to the materialKey, if any.
66
68
  const miscName = (_a = gMaterial.misc) === null || _a === void 0 ? void 0 : _a.get("name");
@@ -68,16 +70,16 @@ export class CfgMaterial {
68
70
  ? miscName
69
71
  : (_b = gMaterial.materialKey) !== null && _b !== void 0 ? _b : "";
70
72
  const { material, transparent, doubleSided } = gMaterial instanceof GMaterialPBR
71
- ? this.compileFromGmPBR(renderEnvironment, meta, gMaterial, textures, name)
72
- : this.compileFromGmClassic(renderEnvironment, meta, gMaterial, textures, name);
73
+ ? this.makeFromGmPBR(renderEnvironment, meta, gMaterial, textures, name)
74
+ : this.makeFromGmClassic(renderEnvironment, meta, gMaterial, textures, name);
73
75
  makeMaterialDoubleSided(material, doubleSided);
74
- const cfgMaterial = new CfgMaterial(material, renderEnvironment.lightRig.lightCount);
76
+ const cfgMaterial = new this(material, renderEnvironment.lightRig.lightCount);
75
77
  cfgMaterial.isTransparent = transparent;
76
78
  return cfgMaterial;
77
79
  }
78
- static compileFromGmPBR(renderEnvironment, meta, gMaterial, textures, name) {
80
+ static makeFromGmPBR(renderEnvironment, meta, gMaterial, textures, name) {
79
81
  var _a;
80
- meta.sourcePath.push("compileFromGmPBR");
82
+ meta.sourcePath.push("makeFromGmPBR");
81
83
  name = "(PBR) " + name;
82
84
  const { doubleSided, base, emissive, metallic, normal, occlusion, opacity, refraction, roughness, } = gMaterial;
83
85
  const material = new PBRMaterial(name, renderEnvironment.scene);
@@ -225,8 +227,8 @@ export class CfgMaterial {
225
227
  }
226
228
  return { material, transparent, doubleSided };
227
229
  }
228
- static compileFromGmClassic(renderEnvironment, meta, gMaterial, textures, name) {
229
- meta.sourcePath.push("compileFromGmClassic");
230
+ static makeFromGmClassic(renderEnvironment, meta, gMaterial, textures, name) {
231
+ meta.sourcePath.push("makeFromGmClassic");
230
232
  name = "(GM) " + name;
231
233
  const { doubleSided, redCustomProperties: redEngineCustomProperties, reflection, bump, diffuse, specular, transparency, } = gMaterial;
232
234
  const bumpTexture = findTexture(textures, bump);
@@ -397,8 +399,10 @@ export class CfgMaterial {
397
399
  return clone;
398
400
  }
399
401
  }
400
- /// The exact changes this method makes depends on the material's separateCullingPass setting, so
401
- /// make sure make any changes to that property before calling this method.
402
+ /**
403
+ * The exact changes this method makes depends on the material's separateCullingPass setting, so
404
+ * make sure make any changes to that property before calling this method.
405
+ */
402
406
  export function makeMaterialDoubleSided(material, doubleSided) {
403
407
  if (doubleSided) {
404
408
  // SeparateCullingPass breaks twoSidedLightning by not flipping the normals when
@@ -414,11 +418,13 @@ export function makeMaterialDoubleSided(material, doubleSided) {
414
418
  material.forceNormalForward = false; // Don't change the normals to front facing
415
419
  }
416
420
  }
417
- /// Clones all the textures used in the material and flips them along the y-axis by inverting the
418
- /// texture's vScale, vOffset and wRotation.
419
- ///
420
- /// @note: The flipped state is not stored in the material it self, so calling this method twice on
421
- /// the same material will undo the flip.
421
+ /**
422
+ * Clones all the textures used in the material and flips them along the y-axis by inverting the
423
+ * texture's vScale, vOffset and wRotation.
424
+ *
425
+ * @note: The flipped state is not stored in the material it self, so calling this method twice on
426
+ * the same material will undo the flip.
427
+ */
422
428
  function flipMaterialTextures(material) {
423
429
  material.albedoTexture = cloneAndFlipTexture(material.albedoTexture);
424
430
  material.bumpTexture = cloneAndFlipTexture(material.bumpTexture);
@@ -438,9 +444,11 @@ function flipMaterialTextures(material) {
438
444
  material.reflectivityTexture = cloneAndFlipTexture(material.reflectivityTexture);
439
445
  material.microSurfaceTexture = cloneAndFlipTexture(material.microSurfaceTexture);
440
446
  }
441
- /// Returns undefined if texture is undefined.
442
- /// Returns original texture if it isn't of type "Texture".
443
- /// Otherwise, Clones and flips the texture along the y-axis by inverting vScale, vOffset and wAng.
447
+ /**
448
+ * Returns undefined if texture is undefined.
449
+ * Returns original texture if it isn't of type "Texture".
450
+ * Otherwise, Clones and flips the texture along the y-axis by inverting vScale, vOffset and wAng.
451
+ */
444
452
  function cloneAndFlipTexture(texture) {
445
453
  if (texture instanceof Texture) {
446
454
  texture = texture.clone();
@@ -58,7 +58,7 @@ function mtrlSourceUrlToCachedCfgMaterial(meta, renderEnvironment, mtrl) {
58
58
  if (getFileExtension(url) !== "gm") {
59
59
  const texture = yield loadTextureFromURL(url, renderEnvironment);
60
60
  innerMeta.sourcePath.push("image");
61
- result.material = CfgMaterial.fromTexture(renderEnvironment, texture, innerMeta.sourcePath);
61
+ result.material = CfgMaterial.makeFromTexture(renderEnvironment, texture, innerMeta.sourcePath);
62
62
  return result;
63
63
  }
64
64
  const multiGMaterial = yield loadMaterialFromUrl(innerMeta.logger, url, renderEnvironment.dexManager);
@@ -82,7 +82,7 @@ function bufferToCfgMaterial(renderEnvironment, meta, mtrl) {
82
82
  }
83
83
  meta.sourcePath.push("image");
84
84
  const texture = yield loadTextureFromURL(`data:image/${fileExtension};base64,${btoa(String.fromCharCode(...new Uint8Array(buffer)))}`, renderEnvironment);
85
- return CfgMaterial.fromTexture(renderEnvironment, texture, meta.sourcePath);
85
+ return CfgMaterial.makeFromTexture(renderEnvironment, texture, meta.sourcePath);
86
86
  }
87
87
  const multiGMaterial = makeMaterialFromBuffer(meta.logger, mtrl.buffer, renderEnvironment.dexManager);
88
88
  meta.sourcePath.push("gm");
@@ -100,7 +100,7 @@ export function gMaterialToCfgMaterial(meta, renderEnvironment, gMaterial) {
100
100
  innerMeta.sourcePath.push("cache_gMaterial");
101
101
  innerMeta.gMaterial = gMaterial;
102
102
  const textures = yield getTextures(innerMeta.logger, renderEnvironment, gMaterial);
103
- const material = CfgMaterial.compileFromGm(renderEnvironment, innerMeta, gMaterial, textures);
103
+ const material = CfgMaterial.makeFromGm(renderEnvironment, innerMeta, gMaterial, textures);
104
104
  return {
105
105
  material: material,
106
106
  meta: innerMeta,
@@ -116,12 +116,14 @@ export function loadTextureFromURL(url, renderEnvironment) {
116
116
  }, reject);
117
117
  });
118
118
  }
119
- /// Derives a normal map from a supplied height map. Both are used in CET for bump-maps but Babylon
120
- /// only supports normal maps.
121
- ///
122
- /// The derived normal map and the effect from `scale` is carefully crafted to be as similar to how
123
- /// the RedSDK 3D renderer in CET operates and match it's final output. Do not change this code to
124
- /// make it visually "better", the goal is instead to be as similar as possible.
119
+ /**
120
+ * Derives a normal map from a supplied height map (aka bump-map). Classic materials in CET can use
121
+ * both height maps and normal maps but Babylon.js only supports normal maps.
122
+ *
123
+ * The derived normal map and the effect from `scale` is carefully crafted to be as similar to how
124
+ * the RedSDK 3D renderer in CET operates and match it's final output. Do not change this code to
125
+ * make it visually "better", the goal is instead to be as similar as possible.
126
+ */
125
127
  function deriveNormalMapFromHeightMap(image, amount, logger) {
126
128
  const w = image.width;
127
129
  const h = image.height;
@@ -136,7 +138,7 @@ function deriveNormalMapFromHeightMap(image, amount, logger) {
136
138
  const data = imgData.data;
137
139
  // The scale conversion and default value comes from the CET source code.
138
140
  const scale = amount ? 15 * amount : 0.1;
139
- /// Number of components, canvas returns RGBA
141
+ // Number of components, canvas returns RGBA
140
142
  const c = 4;
141
143
  // Go through the image and calculate a gray scale version, storing it in the A channel.
142
144
  // Since this is legacy support code, we might as well support non-gray scale height maps,
@@ -186,7 +188,7 @@ function deriveNormalMapFromHeightMap(image, amount, logger) {
186
188
  context.putImageData(imgData, 0, 0);
187
189
  const convertedImage = new Image();
188
190
  convertedImage.src = canvas.toDataURL("image/png");
189
- logger.info(`Converting height based bump map`, `of size ${w}x${h} took ${Math.round(performance.now() - tick)}ms. For optimal performance, update all materials to use normal maps rather than height maps.`);
191
+ logger.info(`Converting height based bump map`, `of size ${w}x${h} took ${Math.round(performance.now() - tick)}ms. For optimal performance, update all classic materials to use normal maps rather than height maps or switch to PBR materials.`);
190
192
  return convertedImage;
191
193
  }
192
194
  return image;
@@ -6,17 +6,22 @@ import { DetailLevel, DetailMask } from "@configura/web-core/dist/cm/geometry/De
6
6
  import { Logger, LogObservable, LogProducer } from "@configura/web-utilities";
7
7
  import { AnimatableObject } from "../animation/AnimatableObject.js";
8
8
  import { CoordinatorWithMeta } from "../animation/coordinator/Coordinator.js";
9
+ import { CfgMesh } from "../geometry/CfgMesh.js";
10
+ import { CfgStretchData } from "../geometry/stretch/CfgStretchData.js";
9
11
  import { MaterialMetaData } from "../material/material.js";
10
12
  import { CfgBoundingBox } from "../utilities/CfgBoundingBox.js";
11
13
  import { RenderEnv } from "../view/RenderEnv.js";
14
+ import { CfgProductNode } from "./CfgProductNode.js";
12
15
  import { CfgTransformNode } from "./CfgTransformNode.js";
13
16
  export declare class CfgDeferredMeshNode extends CfgTransformNode implements LogProducer, AnimatableObject {
17
+ readonly cfgProductNodeParent: CfgProductNode;
14
18
  lod: DetailMask;
15
19
  private _gMaterial;
16
20
  private _meshDoubleSided;
17
21
  private _lowerLeftTextureOrigin;
18
22
  private _geo;
19
- static makeCfgDeferredMesh(logger: Logger, renderEnvironment: RenderEnv, detailLevel: DetailLevel, symNode: SymNode, gMaterial: SymGMaterial | undefined): Promise<CfgDeferredMeshNode | undefined>;
23
+ private _stretchDatas;
24
+ static makeCfgDeferredMesh(logger: Logger, renderEnvironment: RenderEnv, cfgProductNodeParent: CfgProductNode, detailLevel: DetailLevel, symNode: SymNode, gMaterial: SymGMaterial | undefined, stretchDatas: CfgStretchData[]): Promise<CfgDeferredMeshNode | undefined>;
20
25
  get cfgClassName(): string;
21
26
  private _material;
22
27
  private _dummyMaterial;
@@ -36,6 +41,8 @@ export declare class CfgDeferredMeshNode extends CfgTransformNode implements Log
36
41
  isAllMeshMaterialsReady: () => boolean;
37
42
  startSplitGeo: (force?: boolean) => Promise<void>;
38
43
  get boundingBox(): CfgBoundingBox;
44
+ getChildCfgMeshes(): CfgMesh[];
45
+ refreshStretch(): void;
39
46
  protected addInspectorProperties(): void;
40
47
  private get _inspectorLodLevels();
41
48
  private get _inspectorSourcePath();
@@ -13,6 +13,7 @@ import { logMtrlSourceWithMetaDataToConsole } from "@configura/web-api";
13
13
  import { SymBox } from "@configura/web-core/dist/cm/format/cmsym/components/SymBox.js";
14
14
  import { SymGfxMode } from "@configura/web-core/dist/cm/format/cmsym/components/SymComponent.js";
15
15
  import { SymMesh } from "@configura/web-core/dist/cm/format/cmsym/components/SymMesh.js";
16
+ import { SymPlane } from "@configura/web-core/dist/cm/format/cmsym/components/SymPlane.js";
16
17
  import { SymReps } from "@configura/web-core/dist/cm/format/cmsym/components/SymReps.js";
17
18
  import { SymSphere } from "@configura/web-core/dist/cm/format/cmsym/components/SymSphere.js";
18
19
  import { DetailMask } from "@configura/web-core/dist/cm/geometry/DetailMask.js";
@@ -20,9 +21,10 @@ import { LogObservable } from "@configura/web-utilities";
20
21
  import { CfgGeometry } from "../geometry/CfgGeometry.js";
21
22
  import { CfgMesh } from "../geometry/CfgMesh.js";
22
23
  import { splitIndexComplete, splitIndexQuick } from "../geometry/geoSplitter.js";
24
+ import { toStretchedPoint } from "../geometry/stretch/CfgStretchData.js";
23
25
  import { gMaterialToCfgMaterial, mtrlSourceToCfgMaterial, } from "../material/material.js";
24
26
  import { CfgBoundingBox } from "../utilities/CfgBoundingBox.js";
25
- import { aTriMeshBox, aTriMeshSphere } from "../utilities/utilities3D.js";
27
+ import { aTriMeshBox, aTriMeshPlane, aTriMeshSphere } from "../utilities/utilities3D.js";
26
28
  import { GeometryCacheEntry } from "../view/RenderEnv.js";
27
29
  import { CfgTransformNode } from "./CfgTransformNode.js";
28
30
  const QUICK_SPLIT_INDEX_SIZE_LIMIT = 20000;
@@ -50,9 +52,15 @@ function getDetailMask(symNode) {
50
52
  }
51
53
  return lod;
52
54
  }
53
- function symComponentToGeometry(logger, renderEnvironment, component) {
55
+ function symComponentToGeometry(logger, renderEnvironment, component, stretchDatas, uvMapper) {
56
+ var _a;
54
57
  return __awaiter(this, void 0, void 0, function* () {
55
- return renderEnvironment.geometryCache.get(component, () => __awaiter(this, void 0, void 0, function* () {
58
+ const identifierObject = {
59
+ component,
60
+ stretchDatasHash: stretchDatas.reduce((acc, stretchData) => acc + stretchData.hash, 0),
61
+ uvMapperHash: (_a = uvMapper === null || uvMapper === void 0 ? void 0 : uvMapper.env) === null || _a === void 0 ? void 0 : _a.hash,
62
+ };
63
+ return renderEnvironment.geometryCache.get(identifierObject, () => __awaiter(this, void 0, void 0, function* () {
56
64
  let mesh = undefined;
57
65
  if (component instanceof SymMesh) {
58
66
  mesh = component.mesh(logger, renderEnvironment.symMeshEnv);
@@ -63,22 +71,27 @@ function symComponentToGeometry(logger, renderEnvironment, component) {
63
71
  else if (component instanceof SymBox) {
64
72
  mesh = aTriMeshBox(component.p0, component.p1);
65
73
  }
74
+ else if (component instanceof SymPlane) {
75
+ mesh = aTriMeshPlane(component.vector, component.distance, 1);
76
+ }
66
77
  if (mesh === undefined) {
67
78
  logger.error("SymComponent did not return a mesh", component);
68
79
  return undefined;
69
80
  }
70
- return new GeometryCacheEntry(new CfgGeometry("(Geo) " + component.id, mesh, renderEnvironment.scene), mesh.doubleSided, mesh.lowerLeftTextureOrigin);
81
+ return new GeometryCacheEntry(CfgGeometry.fromATriMeshF(logger, "(Geo) " + component.id, mesh, renderEnvironment.scene, stretchDatas, uvMapper), mesh.doubleSided, mesh.lowerLeftTextureOrigin);
71
82
  }));
72
83
  });
73
84
  }
74
85
  export class CfgDeferredMeshNode extends CfgTransformNode {
75
- constructor(renderEnvironment, name, lod, _gMaterial, _meshDoubleSided, _lowerLeftTextureOrigin, _geo) {
86
+ constructor(renderEnvironment, cfgProductNodeParent, name, lod, _gMaterial, _meshDoubleSided, _lowerLeftTextureOrigin, _geo, _stretchDatas) {
76
87
  super(renderEnvironment, name);
88
+ this.cfgProductNodeParent = cfgProductNodeParent;
77
89
  this.lod = lod;
78
90
  this._gMaterial = _gMaterial;
79
91
  this._meshDoubleSided = _meshDoubleSided;
80
92
  this._lowerLeftTextureOrigin = _lowerLeftTextureOrigin;
81
93
  this._geo = _geo;
94
+ this._stretchDatas = _stretchDatas;
82
95
  this._materialIsDirty = false;
83
96
  this._mtrlSourceWithMetaData = null;
84
97
  this._splitGeoStatus = SplitGeoStatus.Idle;
@@ -127,7 +140,7 @@ export class CfgDeferredMeshNode extends CfgTransformNode {
127
140
  const material = this._material.getPBRMaterial(doubleSided, backToFront, flipTexture);
128
141
  this.clear(true);
129
142
  for (const geo of geos) {
130
- const mesh = new CfgMesh(labelSuffix, this._renderEnvironment, geo, material);
143
+ const mesh = new CfgMesh(labelSuffix, this._renderEnvironment, this.cfgProductNodeParent, geo, material);
131
144
  this.add(mesh);
132
145
  }
133
146
  };
@@ -147,9 +160,11 @@ export class CfgDeferredMeshNode extends CfgTransformNode {
147
160
  let groups;
148
161
  if (doCompleteSplit) {
149
162
  groups = splitIndexComplete(this.logger, geo, {
150
- maxFinalGroups: force ? Number.MAX_VALUE : COMPLETE_SPLIT_FINAL_GROUPS_COUNT_LIMIT,
163
+ maxFinalGroups: force
164
+ ? Number.POSITIVE_INFINITY
165
+ : COMPLETE_SPLIT_FINAL_GROUPS_COUNT_LIMIT,
151
166
  maxProgressGroups: force
152
- ? Number.MAX_VALUE
167
+ ? Number.POSITIVE_INFINITY
153
168
  : COMPLETE_SPLIT_PROGRESS_GROUPS_COUNT_LIMIT,
154
169
  acceptCoordinateMatch: true,
155
170
  });
@@ -175,22 +190,26 @@ export class CfgDeferredMeshNode extends CfgTransformNode {
175
190
  this._dummyMaterial = renderEnvironment.dummyMaterial;
176
191
  this.resetMaterial();
177
192
  }
178
- static makeCfgDeferredMesh(logger, renderEnvironment, detailLevel, symNode, gMaterial) {
179
- var _a, _b;
193
+ static makeCfgDeferredMesh(logger, renderEnvironment, cfgProductNodeParent, detailLevel, symNode, gMaterial, stretchDatas) {
194
+ var _a, _b, _c;
180
195
  return __awaiter(this, void 0, void 0, function* () {
181
196
  const lod = getDetailMask(symNode);
182
197
  if (lod === undefined || !lod.includes(detailLevel)) {
183
198
  return;
184
199
  }
185
- const component = (_b = (_a = symNode.symMesh()) !== null && _a !== void 0 ? _a : symNode.symSphere()) !== null && _b !== void 0 ? _b : symNode.symBox();
200
+ const component = (_c = (_b = (_a = symNode.symMesh()) !== null && _a !== void 0 ? _a : symNode.symSphere()) !== null && _b !== void 0 ? _b : symNode.symBox()) !== null && _c !== void 0 ? _c : symNode.symPlane();
186
201
  if (component === undefined) {
187
202
  return;
188
203
  }
189
- const entry = yield symComponentToGeometry(logger, renderEnvironment, component);
190
- if ((entry === null || entry === void 0 ? void 0 : entry.geometry) === undefined) {
204
+ const entry = yield symComponentToGeometry(logger, renderEnvironment, component, stretchDatas, symNode.symUVMapper(true).mapper);
205
+ if (entry === undefined) {
206
+ return undefined;
207
+ }
208
+ let geo = entry.geometry;
209
+ if (geo === undefined) {
191
210
  return undefined;
192
211
  }
193
- return new CfgDeferredMeshNode(renderEnvironment, "(Deferred Mesh) " + symNode.id, lod, gMaterial, entry.doubleSided, entry.lowerLeftTextureOrigin, entry.geometry);
212
+ return new this(renderEnvironment, cfgProductNodeParent, "(Deferred Mesh) " + symNode.id, lod, gMaterial, entry.doubleSided, entry.lowerLeftTextureOrigin, geo, stretchDatas);
194
213
  });
195
214
  }
196
215
  get cfgClassName() {
@@ -265,15 +284,26 @@ export class CfgDeferredMeshNode extends CfgTransformNode {
265
284
  });
266
285
  }
267
286
  get boundingBox() {
287
+ const stretchDatas = this._stretchDatas;
288
+ const stretchReferenceLengthsByMeasureParamCode = this.cfgProductNodeParent.product.configuration._internal
289
+ .stretchReferenceLengthsByMeasureParamCode;
268
290
  return this.getChildMeshes().reduce((a, m) => {
269
291
  const bb = m.getBoundingInfo().boundingBox;
270
- // Here we strip away the world matrix as we handle the transforms
271
- // manually, and the world matrix changes depending on if the has
272
- // been rendered to screen yet
273
- a.expand(new CfgBoundingBox(bb.minimum, bb.maximum));
292
+ const cfgBb = new CfgBoundingBox(bb.minimum, bb.maximum);
293
+ cfgBb.corners
294
+ .map((c) => toStretchedPoint(c, stretchDatas, stretchReferenceLengthsByMeasureParamCode))
295
+ .forEach((c) => {
296
+ a.expandWithPoint(c);
297
+ });
274
298
  return a;
275
299
  }, new CfgBoundingBox());
276
300
  }
301
+ getChildCfgMeshes() {
302
+ return this.getChildMeshes().filter((f) => f instanceof CfgMesh);
303
+ }
304
+ refreshStretch() {
305
+ this.getChildCfgMeshes().map((childMesh) => childMesh.refreshStretch());
306
+ }
277
307
  addInspectorProperties() {
278
308
  super.addInspectorProperties();
279
309
  this.addInspectableCustomProperty({
@@ -3,47 +3,112 @@ import { CfgMaterialMapping, CfgMtrlApplication, CfgProduct } from "@configura/w
3
3
  import { LogObservable, LogProducer } from "@configura/web-utilities";
4
4
  import { AnimatableObject } from "../animation/AnimatableObject.js";
5
5
  import { CoordinatorWithMeta } from "../animation/coordinator/Coordinator.js";
6
+ import { CfgAnchorableNode, CfgAnchorRef, CfgAnchorTargetNode } from "../utilities/anchor/anchor.js";
6
7
  import { CfgBoundingBox } from "../utilities/CfgBoundingBox.js";
7
8
  import { RenderEnv } from "../view/RenderEnv.js";
8
9
  import { CfgSymRootNode } from "./CfgSymRootNode.js";
9
10
  import { CfgTransformNode } from "./CfgTransformNode.js";
10
11
  export declare function isProductNode(value: unknown): value is CfgProductNode;
11
12
  export declare function isCfgSymRootNode(value: unknown): value is CfgSymRootNode;
13
+ export declare function isCfgAnchorableNode(value: unknown): value is CfgAnchorableNode;
12
14
  export declare class CfgProductNode extends CfgTransformNode implements AnimatableObject, LogProducer {
13
15
  private readonly _product;
14
16
  static make(renderEnvironment: RenderEnv, product: CfgProduct): CfgProductNode;
15
- logger: LogObservable;
17
+ readonly logger: LogObservable;
16
18
  private _destroyed;
17
19
  readonly key: string;
18
20
  _applicationAreas: CfgMtrlApplication[];
19
21
  private _mtrlApplications;
20
22
  private _configuration;
21
- private _debugMtrlApplications;
23
+ private readonly _debugMtrlApplications;
22
24
  _areasToMaterials: CfgMaterialMapping | undefined;
23
25
  _scheduledForRemoval: (CfgSymRootNode | CfgProductNode)[];
26
+ private _anchoredToAnchors;
24
27
  private _symRootLoadings;
28
+ private _modelMatrix;
29
+ private _originalMatrixWithModelTransform;
30
+ private _anchorTarget;
31
+ private _stretchedAnchorPointMatrix;
32
+ readonly anchorRef: CfgAnchorRef | undefined;
25
33
  private constructor();
26
34
  get cfgClassName(): string;
27
35
  destroy(): void;
28
36
  get product(): CfgProduct;
37
+ /**
38
+ * We want to be able to animate nodes that are on the way out.
39
+ * So we do not immediately remove them from the tree.
40
+ */
29
41
  private scheduleForRemoval;
30
42
  isDestroyed(): boolean;
43
+ /**
44
+ * The passed function is recursively applied on every descendant CfgProductNode in the tree.
45
+ * This node is included. Destroyed products are not included.
46
+ */
31
47
  _applyOnDescendantProductNodes: <T>(fn: (p: CfgProductNode) => T) => T[];
48
+ /**
49
+ * This function will apply either of tree passed functions on the additional products/ in the
50
+ * passed CfgProduct and the additional products in the CfgProductNode.
51
+ * It is not applied recursively.
52
+ */
32
53
  private _syncAdditionalProductNodes;
54
+ /**
55
+ * Application areas are essentially catalogue level material mappings.
56
+ * This function is recursively applied on additional products.
57
+ */
33
58
  setApplicationAreas(applicationAreas: CfgMtrlApplication[]): void;
59
+ /**
60
+ * Start loading the geometry, but do not yet show it.
61
+ * This function is recursively applied on additional products.
62
+ */
34
63
  loadGeo(coordinatorWithMeta?: CoordinatorWithMeta): Promise<void>;
35
64
  private _loadAdditionalProducts;
65
+ /**
66
+ * Run any animations and then permanently removes the nodes from the tree
67
+ * This function is recursively applied on additional products.
68
+ */
36
69
  flushScheduledForRemove(animationCoordinator?: CoordinatorWithMeta): Promise<void>;
70
+ /**
71
+ * Are all materials currently needed loaded and ready to be applied?
72
+ * This function does not take additional products into account.
73
+ */
37
74
  private _isAllMeshMaterialsReady;
75
+ /**
76
+ * Resolves when all materials currently needed have been loaded and are ready to be applied.
77
+ * This function does not take additional products into account.
78
+ */
38
79
  private _awaitAllMeshMaterialsReady;
80
+ /**
81
+ * Loads the materials needed.
82
+ * This function is recursively applied on additional products.
83
+ */
39
84
  loadMaterials(animationCoordinator?: CoordinatorWithMeta): Promise<void>;
85
+ /**
86
+ * Update the tag (area) to material mapping and gives them to sym children
87
+ * This function does not take additional products into account.
88
+ */
40
89
  private _aggregateMaterialsPushToChildrenAndLoad;
90
+ /**
91
+ * Starts loading the materials on the sym children (but does not apply)
92
+ * This function does not take additional products into account.
93
+ */
41
94
  private _pushMaterialToSymRootChildrenAndLoad;
42
95
  private _getSymRootChildren;
43
96
  private _getAdditionalProductNodes;
97
+ private _getAnchorableNodes;
98
+ /**
99
+ * Applies and thereby shows the geometry. Finally flushes scheduled for remove.
100
+ * This function is recursively applied on additional products.
101
+ */
44
102
  applyGeo(animationCoordinator?: CoordinatorWithMeta): Promise<void>;
103
+ /**
104
+ * Applies and thereby shows the right materials.
105
+ * This function is recursively applied on additional products.
106
+ */
45
107
  applyMaterials(): Promise<void>;
46
- readonly originalMatrix: Matrix;
108
+ setAnchorTarget(anchorTarget: CfgAnchorTargetNode | undefined): void;
109
+ refreshStretch(): void;
110
+ get originalMatrix(): Matrix;
111
+ protected initTransform(): void;
47
112
  _applyDebugSymRoots(symRootPromises: Promise<CfgSymRootNode | undefined>[]): Promise<void>;
48
113
  _addDebugMtrlApplication(debugMtrlApplication: CfgMtrlApplication): Promise<void>;
49
114
  get boundingBox(): CfgBoundingBox;