@configura/babylon-view 1.4.0-alpha.4 → 1.4.0

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 (125) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +1 -1
  3. package/dist/animation/AnimatableObject.d.ts +8 -8
  4. package/dist/animation/AnimatableObject.js +3 -3
  5. package/dist/animation/animator/Animator.d.ts +33 -33
  6. package/dist/animation/animator/Animator.js +58 -58
  7. package/dist/animation/animator/AnimatorEasing.d.ts +16 -16
  8. package/dist/animation/animator/AnimatorEasing.js +31 -31
  9. package/dist/animation/animator/AnimatorEasingMatrix.d.ts +14 -14
  10. package/dist/animation/animator/AnimatorEasingMatrix.js +16 -16
  11. package/dist/animation/animator/AnimatorHighlight.d.ts +16 -16
  12. package/dist/animation/animator/AnimatorHighlight.js +32 -32
  13. package/dist/animation/animator/AnimatorPointToPoint.d.ts +8 -8
  14. package/dist/animation/animator/AnimatorPointToPoint.js +14 -14
  15. package/dist/animation/animator/AnimatorQueue.d.ts +13 -13
  16. package/dist/animation/animator/AnimatorQueue.js +57 -57
  17. package/dist/animation/animator/AnimatorScale.d.ts +8 -8
  18. package/dist/animation/animator/AnimatorScale.js +13 -13
  19. package/dist/animation/animator/AnimatorSpin.d.ts +10 -10
  20. package/dist/animation/animator/AnimatorSpin.js +13 -13
  21. package/dist/animation/animator/EasingFunctions.d.ts +35 -35
  22. package/dist/animation/animator/EasingFunctions.js +137 -137
  23. package/dist/animation/coordinator/Coordinator.d.ts +28 -28
  24. package/dist/animation/coordinator/Coordinator.js +47 -47
  25. package/dist/animation/coordinator/CoordinatorDropAndSpin.d.ts +22 -22
  26. package/dist/animation/coordinator/CoordinatorDropAndSpin.js +133 -133
  27. package/dist/animation/coordinator/CoordinatorIdentity.d.ts +11 -11
  28. package/dist/animation/coordinator/CoordinatorIdentity.js +12 -12
  29. package/dist/animation/coordinator/CoordinatorNodeQueues.d.ts +18 -18
  30. package/dist/animation/coordinator/CoordinatorNodeQueues.js +50 -50
  31. package/dist/animation/coordinator/CoordinatorPulse.d.ts +21 -21
  32. package/dist/animation/coordinator/CoordinatorPulse.js +47 -47
  33. package/dist/animation/coordinator/CoordinatorPulseBounce.d.ts +14 -14
  34. package/dist/animation/coordinator/CoordinatorPulseBounce.js +40 -40
  35. package/dist/animation/coordinator/CoordinatorPulseHighlight.d.ts +13 -13
  36. package/dist/animation/coordinator/CoordinatorPulseHighlight.js +34 -34
  37. package/dist/animation/coordinator/CoordinatorPulseInflate.d.ts +14 -14
  38. package/dist/animation/coordinator/CoordinatorPulseInflate.js +30 -30
  39. package/dist/camera/CameraCreator.d.ts +5 -5
  40. package/dist/camera/CameraCreator.js +4 -4
  41. package/dist/camera/CfgArcRotateCameraPointersInput.d.ts +26 -26
  42. package/dist/camera/CfgArcRotateCameraPointersInput.js +264 -264
  43. package/dist/camera/CfgOrbitalCamera.d.ts +68 -68
  44. package/dist/camera/CfgOrbitalCamera.js +250 -250
  45. package/dist/camera/CfgOrbitalCameraControlProps.d.ts +6 -6
  46. package/dist/camera/CfgOrbitalCameraControlProps.js +3 -3
  47. package/dist/camera/GradingApplier.d.ts +3 -3
  48. package/dist/camera/GradingApplier.js +48 -48
  49. package/dist/engine/EngineCreator.d.ts +3 -3
  50. package/dist/engine/EngineCreator.js +10 -10
  51. package/dist/geometry/CfgGeometry.d.ts +29 -29
  52. package/dist/geometry/CfgGeometry.js +146 -146
  53. package/dist/geometry/CfgMesh.d.ts +10 -10
  54. package/dist/geometry/CfgMesh.js +38 -38
  55. package/dist/geometry/geoSplitter.d.ts +8 -8
  56. package/dist/geometry/geoSplitter.js +192 -192
  57. package/dist/geometry/stretch/CfgMorphTarget.d.ts +15 -15
  58. package/dist/geometry/stretch/CfgMorphTarget.js +65 -65
  59. package/dist/geometry/stretch/CfgStretchData.d.ts +114 -114
  60. package/dist/geometry/stretch/CfgStretchData.js +340 -340
  61. package/dist/geometry/stretch/CfgStretchMorphGeometry.d.ts +16 -16
  62. package/dist/geometry/stretch/CfgStretchMorphGeometry.js +95 -95
  63. package/dist/index.d.ts +13 -13
  64. package/dist/index.js +13 -13
  65. package/dist/light/CfgDirectionalLight.d.ts +8 -8
  66. package/dist/light/CfgDirectionalLight.js +18 -18
  67. package/dist/light/CfgHemisphericLight.d.ts +7 -7
  68. package/dist/light/CfgHemisphericLight.js +17 -17
  69. package/dist/light/CfgPointLight.d.ts +8 -8
  70. package/dist/light/CfgPointLight.js +18 -18
  71. package/dist/light/DefaultLightRig.d.ts +19 -19
  72. package/dist/light/DefaultLightRig.js +77 -77
  73. package/dist/light/LightRigCreator.d.ts +9 -9
  74. package/dist/light/LightRigCreator.js +3 -3
  75. package/dist/material/CfgMaterial.d.ts +68 -68
  76. package/dist/material/CfgMaterial.js +482 -482
  77. package/dist/material/DummyMaterialCreator.d.ts +4 -4
  78. package/dist/material/DummyMaterialCreator.js +15 -15
  79. package/dist/material/material.d.ts +18 -18
  80. package/dist/material/material.js +128 -128
  81. package/dist/material/texture.d.ts +14 -14
  82. package/dist/material/texture.js +306 -306
  83. package/dist/nodes/CfgContentRootNode.d.ts +19 -19
  84. package/dist/nodes/CfgContentRootNode.js +75 -75
  85. package/dist/nodes/CfgDeferredMeshNode.d.ts +55 -55
  86. package/dist/nodes/CfgDeferredMeshNode.js +377 -377
  87. package/dist/nodes/CfgProductNode.d.ts +126 -126
  88. package/dist/nodes/CfgProductNode.js +578 -578
  89. package/dist/nodes/CfgSymNode.d.ts +50 -50
  90. package/dist/nodes/CfgSymNode.js +249 -249
  91. package/dist/nodes/CfgSymRootNode.d.ts +45 -45
  92. package/dist/nodes/CfgSymRootNode.js +220 -220
  93. package/dist/nodes/CfgTransformNode.d.ts +33 -33
  94. package/dist/nodes/CfgTransformNode.js +83 -83
  95. package/dist/scene/SceneCreator.d.ts +6 -6
  96. package/dist/scene/SceneCreator.js +22 -22
  97. package/dist/utilities/CfgBoundingBox.d.ts +21 -21
  98. package/dist/utilities/CfgBoundingBox.js +81 -81
  99. package/dist/utilities/anchor/anchor.d.ts +51 -51
  100. package/dist/utilities/anchor/anchor.js +136 -136
  101. package/dist/utilities/anchor/anchorMap.d.ts +20 -20
  102. package/dist/utilities/anchor/anchorMap.js +111 -111
  103. package/dist/utilities/utilities3D.d.ts +70 -70
  104. package/dist/utilities/utilities3D.js +265 -265
  105. package/dist/utilities/utilitiesColor.d.ts +18 -18
  106. package/dist/utilities/utilitiesColor.js +48 -48
  107. package/dist/utilities/utilitiesImage.d.ts +6 -6
  108. package/dist/utilities/utilitiesImage.js +107 -107
  109. package/dist/utilities/utilitiesSymRootIdentifier.d.ts +7 -7
  110. package/dist/utilities/utilitiesSymRootIdentifier.js +26 -26
  111. package/dist/view/BaseView.d.ts +78 -78
  112. package/dist/view/BaseView.js +297 -297
  113. package/dist/view/BaseViewConfiguration.d.ts +32 -32
  114. package/dist/view/BaseViewConfiguration.js +8 -8
  115. package/dist/view/RenderEnv.d.ts +43 -43
  116. package/dist/view/RenderEnv.js +7 -7
  117. package/dist/view/SingleProductDefaultCameraView.d.ts +33 -33
  118. package/dist/view/SingleProductDefaultCameraView.js +141 -141
  119. package/dist/view/SingleProductDefaultCameraViewConfiguration.d.ts +46 -46
  120. package/dist/view/SingleProductDefaultCameraViewConfiguration.js +11 -11
  121. package/dist/view/SingleProductView.d.ts +42 -42
  122. package/dist/view/SingleProductView.js +206 -206
  123. package/dist/view/SingleProductViewConfiguration.d.ts +32 -32
  124. package/dist/view/SingleProductViewConfiguration.js +19 -19
  125. package/package.json +5 -5
@@ -1,377 +1,377 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { Matrix } from "@babylonjs/core/Maths/math.vector.js";
11
- import { InspectableType } from "@babylonjs/core/Misc/iInspectable.js";
12
- import { logMtrlSourceWithMetaDataToConsole } from "@configura/web-api";
13
- import { SymBox } from "@configura/web-core/dist/cm/format/cmsym/components/SymBox.js";
14
- import { SymGfxMode } from "@configura/web-core/dist/cm/format/cmsym/components/SymComponent.js";
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";
17
- import { SymReps } from "@configura/web-core/dist/cm/format/cmsym/components/SymReps.js";
18
- import { SymSphere } from "@configura/web-core/dist/cm/format/cmsym/components/SymSphere.js";
19
- import { DetailMask } from "@configura/web-core/dist/cm/geometry/DetailMask.js";
20
- import { LogObservable } from "@configura/web-utilities";
21
- import { CfgGeometry } from "../geometry/CfgGeometry.js";
22
- import { CfgMesh } from "../geometry/CfgMesh.js";
23
- import { splitIndexComplete, splitIndexQuick } from "../geometry/geoSplitter.js";
24
- import { toStretchedPoint } from "../geometry/stretch/CfgStretchData.js";
25
- import { gMaterialToCfgMaterial, mtrlSourceToCfgMaterial, } from "../material/material.js";
26
- import { CfgBoundingBox } from "../utilities/CfgBoundingBox.js";
27
- import { aTriMeshBox, aTriMeshPlane, aTriMeshSphere } from "../utilities/utilities3D.js";
28
- import { GeometryCacheEntry } from "../view/RenderEnv.js";
29
- import { CfgTransformNode } from "./CfgTransformNode.js";
30
- const QUICK_SPLIT_INDEX_SIZE_LIMIT = 20000;
31
- const COMPLETE_SPLIT_INDEX_SIZE_LIMIT = 5000;
32
- const COMPLETE_SPLIT_FINAL_GROUPS_COUNT_LIMIT = 20;
33
- const COMPLETE_SPLIT_PROGRESS_GROUPS_COUNT_LIMIT = 100;
34
- var SplitGeoStatus;
35
- (function (SplitGeoStatus) {
36
- SplitGeoStatus["Idle"] = "Idle";
37
- SplitGeoStatus["Splitting"] = "Splitting";
38
- SplitGeoStatus["Unapplied"] = "Unapplied";
39
- SplitGeoStatus["Done"] = "Done";
40
- })(SplitGeoStatus || (SplitGeoStatus = {}));
41
- function getDetailMask(symNode) {
42
- const symReps = symNode.symReps();
43
- if (!(symReps instanceof SymReps)) {
44
- return;
45
- }
46
- if (symReps._details === undefined) {
47
- return;
48
- }
49
- const lod = symReps._details.get(SymGfxMode.x3D);
50
- if (!(lod instanceof DetailMask)) {
51
- return;
52
- }
53
- return lod;
54
- }
55
- function symComponentToGeometry(logger, renderEnvironment, component, stretchDatas, uvMapper) {
56
- var _a;
57
- return __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* () {
64
- let mesh = undefined;
65
- if (component instanceof SymMesh) {
66
- mesh = component.mesh(logger, renderEnvironment.symMeshEnv);
67
- }
68
- else if (component instanceof SymSphere) {
69
- mesh = aTriMeshSphere(component.radius, component.center, component.segments);
70
- }
71
- else if (component instanceof SymBox) {
72
- mesh = aTriMeshBox(component.p0, component.p1);
73
- }
74
- else if (component instanceof SymPlane) {
75
- mesh = aTriMeshPlane(component.vector, component.distance, 1);
76
- }
77
- if (mesh === undefined) {
78
- logger.error("SymComponent did not return a mesh", component);
79
- return undefined;
80
- }
81
- return new GeometryCacheEntry(CfgGeometry.fromATriMeshF(logger, "(Geo) " + component.id, mesh, renderEnvironment.scene, stretchDatas, uvMapper), mesh.doubleSided, mesh.lowerLeftTextureOrigin);
82
- }));
83
- });
84
- }
85
- export class CfgDeferredMeshNode extends CfgTransformNode {
86
- constructor(renderEnvironment, cfgProductNodeParent, name, lod, _gMaterial, _meshDoubleSided, _lowerLeftTextureOrigin, _geo, _stretchDatas) {
87
- super(renderEnvironment, name);
88
- this.cfgProductNodeParent = cfgProductNodeParent;
89
- this.lod = lod;
90
- this._gMaterial = _gMaterial;
91
- this._meshDoubleSided = _meshDoubleSided;
92
- this._lowerLeftTextureOrigin = _lowerLeftTextureOrigin;
93
- this._geo = _geo;
94
- this._stretchDatas = _stretchDatas;
95
- this._materialIsDirty = false;
96
- this._mtrlSourceWithMetaData = null;
97
- this._splitGeoStatus = SplitGeoStatus.Idle;
98
- this.logger = new LogObservable();
99
- this.applyMaterial = () => {
100
- if (this._material === undefined ||
101
- (!this._materialIsDirty && this._splitGeoStatus !== SplitGeoStatus.Unapplied)) {
102
- return;
103
- }
104
- this._materialIsDirty = false;
105
- if (this._splitGeoStatus === SplitGeoStatus.Unapplied) {
106
- this._splitGeoStatus = SplitGeoStatus.Done;
107
- }
108
- let geos = [this._geo];
109
- let labelSuffix = this.name;
110
- if (this._splitGeos !== undefined) {
111
- geos = this._splitGeos;
112
- labelSuffix += " (geo split)";
113
- }
114
- let doubleSided = false;
115
- let backToFront = false;
116
- let flipTexture = !this._lowerLeftTextureOrigin;
117
- if (this._meshDoubleSided || this._material.isDoubleSided()) {
118
- // Double sided can be set both by the mesh and the material, but only the material
119
- // controls it during rendering. Ensure we are using a material that is double sided.
120
- doubleSided = true;
121
- if (this._material.isTransparent) {
122
- // Mesh will render double sided with possible transparent parts, this is tricky.
123
- //
124
- // Since we don't depth sort all triangles in the mesh relative to the camera (which
125
- // is not doable in the general case) we need to employ a trick to make sure the
126
- // inside of the object gets rendered before the outside skin.
127
- //
128
- // Otherwise, semi-transparent pixels in the outer skin would fully occlude pixels
129
- // from the inside of the object if they happen to be rendered first. That means
130
- // that sometimes your would not see the inside of the object through the "holes"
131
- // in it.
132
- //
133
- // A good workaround for correctly made objects (where "correct" is mostly related
134
- // to the normals) is to render the mesh twice, first the back sides ("inside"),
135
- // then the front sides ("outside") of the triangles. Babylon.js has such a feature
136
- // built in called separateCullingPass (or "back then front" below).
137
- backToFront = true;
138
- }
139
- }
140
- const material = this._material.getPBRMaterial(doubleSided, backToFront, flipTexture);
141
- this.clear(true);
142
- for (const geo of geos) {
143
- const mesh = new CfgMesh(labelSuffix, this._renderEnvironment, this.cfgProductNodeParent, geo, material);
144
- this.add(mesh);
145
- }
146
- };
147
- this.isAllMeshMaterialsReady = () => this.getChildMeshes().reduce((a, m) => a && (m.material === null || m.material.isReady(m)), true);
148
- this.startSplitGeo = (force = false) => __awaiter(this, void 0, void 0, function* () {
149
- if (!force && this._splitGeoStatus !== SplitGeoStatus.Idle) {
150
- return;
151
- }
152
- this._splitGeoStatus = SplitGeoStatus.Splitting;
153
- const geo = this._geo;
154
- const indexCount = geo.getTotalIndices();
155
- if (!force && QUICK_SPLIT_INDEX_SIZE_LIMIT < indexCount) {
156
- return;
157
- }
158
- const splitStart = performance.now();
159
- const doCompleteSplit = indexCount < COMPLETE_SPLIT_INDEX_SIZE_LIMIT || force;
160
- let groups;
161
- if (doCompleteSplit) {
162
- groups = splitIndexComplete(this.logger, geo, {
163
- maxFinalGroups: force
164
- ? Number.POSITIVE_INFINITY
165
- : COMPLETE_SPLIT_FINAL_GROUPS_COUNT_LIMIT,
166
- maxProgressGroups: force
167
- ? Number.POSITIVE_INFINITY
168
- : COMPLETE_SPLIT_PROGRESS_GROUPS_COUNT_LIMIT,
169
- acceptCoordinateMatch: true,
170
- });
171
- }
172
- else {
173
- groups = splitIndexQuick(this.logger, geo);
174
- }
175
- if (groups === undefined || groups.length === 1) {
176
- this._splitGeoStatus = SplitGeoStatus.Done;
177
- return;
178
- }
179
- const splitEnd = performance.now();
180
- this._splitGeos = groups.map((group) => geo.cloneWithSubset(group));
181
- const repackEnd = performance.now();
182
- this._splitGeoStatus = SplitGeoStatus.Unapplied;
183
- this.logger.info(`${doCompleteSplit ? "Complete" : "Quick"}-split`, `of ${indexCount / 3} triangles into ${groups.length} disjoint groups took ${(splitEnd - splitStart).toFixed(1)} ms, repack took ${(repackEnd - splitEnd).toFixed(1)} ms.`);
184
- // If material is dirty someone else is responsible for calling applyMaterial
185
- // at a later point
186
- if (!this._materialIsDirty) {
187
- this.applyMaterial();
188
- }
189
- });
190
- this._dummyMaterial = renderEnvironment.dummyMaterial;
191
- this.resetMaterial();
192
- }
193
- static makeCfgDeferredMesh(logger, renderEnvironment, cfgProductNodeParent, detailLevel, symNode, gMaterial, stretchDatas) {
194
- var _a, _b, _c;
195
- return __awaiter(this, void 0, void 0, function* () {
196
- const lod = getDetailMask(symNode);
197
- if (lod === undefined || !lod.includes(detailLevel)) {
198
- return;
199
- }
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();
201
- if (component === undefined) {
202
- return;
203
- }
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) {
210
- return undefined;
211
- }
212
- return new this(renderEnvironment, cfgProductNodeParent, "(Deferred Mesh) " + symNode.id, lod, gMaterial, entry.doubleSided, entry.lowerLeftTextureOrigin, geo, stretchDatas);
213
- });
214
- }
215
- get cfgClassName() {
216
- return "CfgDeferredMeshNode";
217
- }
218
- resetMaterial() {
219
- this._material = this._dummyMaterial;
220
- this._materialMetaData = undefined;
221
- this._materialIsDirty = true;
222
- this.applyMaterial();
223
- }
224
- get originalMatrix() {
225
- return Matrix.Identity();
226
- }
227
- setMaterialAndLoad(mtrlWithMetaData, animatorCoordinator) {
228
- return __awaiter(this, void 0, void 0, function* () {
229
- if (this._materialLoadedPromise !== undefined &&
230
- mtrlWithMetaData !== undefined &&
231
- this._mtrlSourceWithMetaData !== undefined &&
232
- this._mtrlSourceWithMetaData !== null &&
233
- mtrlWithMetaData.mtrl.isSame(this._mtrlSourceWithMetaData.mtrl)) {
234
- return this._materialLoadedPromise;
235
- }
236
- this._mtrlSourceWithMetaData = mtrlWithMetaData;
237
- this._materialLoadedPromise = this.loadMaterial();
238
- if (animatorCoordinator !== undefined && mtrlWithMetaData !== undefined) {
239
- const c = animatorCoordinator.coordinator;
240
- c.prepareForMaterialChange.bind(c)(this, animatorCoordinator.isNewProduct);
241
- }
242
- return this._materialLoadedPromise;
243
- });
244
- }
245
- loadMaterial() {
246
- return __awaiter(this, void 0, void 0, function* () {
247
- let material;
248
- const meta = {
249
- logger: this.logger,
250
- sourcePath: ["loadMaterial"],
251
- };
252
- if (this._mtrlSourceWithMetaData === null) {
253
- // null === has not yet been set
254
- return;
255
- }
256
- try {
257
- if (this._mtrlSourceWithMetaData !== undefined) {
258
- material = yield mtrlSourceToCfgMaterial(meta, this._mtrlSourceWithMetaData, this._renderEnvironment);
259
- if (material === undefined) {
260
- this.logger.error("Failed to load material from mtrlSource");
261
- }
262
- }
263
- else if (this._gMaterial !== undefined && this._gMaterial.gm !== undefined) {
264
- meta.sourcePath.push("embedded");
265
- material = yield gMaterialToCfgMaterial(meta, this._renderEnvironment, this._gMaterial.gm);
266
- if (material === undefined) {
267
- this.logger.error("Failed to load material from fallback gMaterial");
268
- }
269
- }
270
- }
271
- catch (e) {
272
- this._renderEnvironment.notifyError("Failed to load material. Will show default material.");
273
- this.logger.errorFromCaught(e);
274
- }
275
- if (material === undefined) {
276
- this.logger.warn("No material, not even fallback-material");
277
- }
278
- this._material = material;
279
- this._materialMetaData = meta;
280
- this._materialIsDirty = true;
281
- if (material && material.isTransparent) {
282
- this.startSplitGeo();
283
- }
284
- });
285
- }
286
- get boundingBox() {
287
- const stretchDatas = this._stretchDatas;
288
- const stretchReferenceLengthsByMeasureParamCode = this.cfgProductNodeParent.product.configuration._internal
289
- .stretchReferenceLengthsByMeasureParamCode;
290
- return this.getChildMeshes().reduce((a, m) => {
291
- const bb = m.getBoundingInfo().boundingBox;
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
- });
298
- return a;
299
- }, new CfgBoundingBox());
300
- }
301
- getChildCfgMeshes() {
302
- return this.getChildMeshes().filter((f) => f instanceof CfgMesh);
303
- }
304
- refreshStretch() {
305
- this.getChildCfgMeshes().map((childMesh) => childMesh.refreshStretch());
306
- }
307
- addInspectorProperties() {
308
- super.addInspectorProperties();
309
- this.addInspectableCustomProperty({
310
- label: "Available lod levels",
311
- propertyName: "_inspectorLodLevels",
312
- type: InspectableType.String,
313
- });
314
- this.addInspectableCustomProperty({
315
- label: "Mtrl Source path",
316
- propertyName: "_inspectorSourcePath",
317
- type: InspectableType.String,
318
- });
319
- this.addInspectableCustomProperty({
320
- label: "log mtrlSourceWithMetaData",
321
- propertyName: "_inspectorLogMtrlSourceWithMetaData",
322
- type: InspectableType.Checkbox,
323
- });
324
- this.addInspectableCustomProperty({
325
- label: "log GMaterial",
326
- propertyName: "_inspectorLogGMaterial",
327
- type: InspectableType.Checkbox,
328
- });
329
- this.addInspectableCustomProperty({
330
- label: "log MultiGMaterial",
331
- propertyName: "_inspectorLogMultiGMaterial",
332
- type: InspectableType.Checkbox,
333
- });
334
- }
335
- get _inspectorLodLevels() {
336
- return Array.from(this.lod.detailSet().values()).join(", ");
337
- }
338
- get _inspectorSourcePath() {
339
- if (this._materialMetaData === undefined) {
340
- return "-";
341
- }
342
- return this._materialMetaData.sourcePath.join(" ");
343
- }
344
- get _inspectorLogMtrlSourceWithMetaData() {
345
- return this._mtrlSourceWithMetaData === undefined || this._mtrlSourceWithMetaData === null;
346
- }
347
- set _inspectorLogMtrlSourceWithMetaData(x) {
348
- if (this._mtrlSourceWithMetaData === undefined || this._mtrlSourceWithMetaData === null) {
349
- return;
350
- }
351
- logMtrlSourceWithMetaDataToConsole(this._mtrlSourceWithMetaData);
352
- }
353
- get _inspectorLogGMaterial() {
354
- var _a;
355
- return ((_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.gMaterial) === undefined;
356
- }
357
- set _inspectorLogGMaterial(x) {
358
- var _a;
359
- const m = (_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.gMaterial;
360
- if (m === undefined) {
361
- return;
362
- }
363
- console.log(m);
364
- }
365
- get _inspectorLogMultiGMaterial() {
366
- var _a;
367
- return ((_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.multiGMaterial) === undefined;
368
- }
369
- set _inspectorLogMultiGMaterial(x) {
370
- var _a;
371
- const m = (_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.multiGMaterial;
372
- if (m === undefined) {
373
- return;
374
- }
375
- console.log(m);
376
- }
377
- }
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { Matrix } from "@babylonjs/core/Maths/math.vector.js";
11
+ import { InspectableType } from "@babylonjs/core/Misc/iInspectable.js";
12
+ import { logMtrlSourceWithMetaDataToConsole } from "@configura/web-api";
13
+ import { SymBox } from "@configura/web-core/dist/cm/format/cmsym/components/SymBox.js";
14
+ import { SymGfxMode } from "@configura/web-core/dist/cm/format/cmsym/components/SymComponent.js";
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";
17
+ import { SymReps } from "@configura/web-core/dist/cm/format/cmsym/components/SymReps.js";
18
+ import { SymSphere } from "@configura/web-core/dist/cm/format/cmsym/components/SymSphere.js";
19
+ import { DetailMask } from "@configura/web-core/dist/cm/geometry/DetailMask.js";
20
+ import { LogObservable } from "@configura/web-utilities";
21
+ import { CfgGeometry } from "../geometry/CfgGeometry.js";
22
+ import { CfgMesh } from "../geometry/CfgMesh.js";
23
+ import { splitIndexComplete, splitIndexQuick } from "../geometry/geoSplitter.js";
24
+ import { toStretchedPoint } from "../geometry/stretch/CfgStretchData.js";
25
+ import { gMaterialToCfgMaterial, mtrlSourceToCfgMaterial, } from "../material/material.js";
26
+ import { CfgBoundingBox } from "../utilities/CfgBoundingBox.js";
27
+ import { aTriMeshBox, aTriMeshPlane, aTriMeshSphere } from "../utilities/utilities3D.js";
28
+ import { GeometryCacheEntry } from "../view/RenderEnv.js";
29
+ import { CfgTransformNode } from "./CfgTransformNode.js";
30
+ const QUICK_SPLIT_INDEX_SIZE_LIMIT = 20000;
31
+ const COMPLETE_SPLIT_INDEX_SIZE_LIMIT = 5000;
32
+ const COMPLETE_SPLIT_FINAL_GROUPS_COUNT_LIMIT = 20;
33
+ const COMPLETE_SPLIT_PROGRESS_GROUPS_COUNT_LIMIT = 100;
34
+ var SplitGeoStatus;
35
+ (function (SplitGeoStatus) {
36
+ SplitGeoStatus["Idle"] = "Idle";
37
+ SplitGeoStatus["Splitting"] = "Splitting";
38
+ SplitGeoStatus["Unapplied"] = "Unapplied";
39
+ SplitGeoStatus["Done"] = "Done";
40
+ })(SplitGeoStatus || (SplitGeoStatus = {}));
41
+ function getDetailMask(symNode) {
42
+ const symReps = symNode.symReps();
43
+ if (!(symReps instanceof SymReps)) {
44
+ return;
45
+ }
46
+ if (symReps._details === undefined) {
47
+ return;
48
+ }
49
+ const lod = symReps._details.get(SymGfxMode.x3D);
50
+ if (!(lod instanceof DetailMask)) {
51
+ return;
52
+ }
53
+ return lod;
54
+ }
55
+ function symComponentToGeometry(logger, renderEnvironment, component, stretchDatas, uvMapper) {
56
+ var _a;
57
+ return __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* () {
64
+ let mesh = undefined;
65
+ if (component instanceof SymMesh) {
66
+ mesh = component.mesh(logger, renderEnvironment.symMeshEnv);
67
+ }
68
+ else if (component instanceof SymSphere) {
69
+ mesh = aTriMeshSphere(component.radius, component.center, component.segments);
70
+ }
71
+ else if (component instanceof SymBox) {
72
+ mesh = aTriMeshBox(component.p0, component.p1);
73
+ }
74
+ else if (component instanceof SymPlane) {
75
+ mesh = aTriMeshPlane(component.vector, component.distance, 1);
76
+ }
77
+ if (mesh === undefined) {
78
+ logger.error("SymComponent did not return a mesh", component);
79
+ return undefined;
80
+ }
81
+ return new GeometryCacheEntry(CfgGeometry.fromATriMeshF(logger, "(Geo) " + component.id, mesh, renderEnvironment.scene, stretchDatas, uvMapper), mesh.doubleSided, mesh.lowerLeftTextureOrigin);
82
+ }));
83
+ });
84
+ }
85
+ export class CfgDeferredMeshNode extends CfgTransformNode {
86
+ constructor(renderEnvironment, cfgProductNodeParent, name, lod, _gMaterial, _meshDoubleSided, _lowerLeftTextureOrigin, _geo, _stretchDatas) {
87
+ super(renderEnvironment, name);
88
+ this.cfgProductNodeParent = cfgProductNodeParent;
89
+ this.lod = lod;
90
+ this._gMaterial = _gMaterial;
91
+ this._meshDoubleSided = _meshDoubleSided;
92
+ this._lowerLeftTextureOrigin = _lowerLeftTextureOrigin;
93
+ this._geo = _geo;
94
+ this._stretchDatas = _stretchDatas;
95
+ this._materialIsDirty = false;
96
+ this._mtrlSourceWithMetaData = null;
97
+ this._splitGeoStatus = SplitGeoStatus.Idle;
98
+ this.logger = new LogObservable();
99
+ this.applyMaterial = () => {
100
+ if (this._material === undefined ||
101
+ (!this._materialIsDirty && this._splitGeoStatus !== SplitGeoStatus.Unapplied)) {
102
+ return;
103
+ }
104
+ this._materialIsDirty = false;
105
+ if (this._splitGeoStatus === SplitGeoStatus.Unapplied) {
106
+ this._splitGeoStatus = SplitGeoStatus.Done;
107
+ }
108
+ let geos = [this._geo];
109
+ let labelSuffix = this.name;
110
+ if (this._splitGeos !== undefined) {
111
+ geos = this._splitGeos;
112
+ labelSuffix += " (geo split)";
113
+ }
114
+ let doubleSided = false;
115
+ let backToFront = false;
116
+ let flipTexture = !this._lowerLeftTextureOrigin;
117
+ if (this._meshDoubleSided || this._material.isDoubleSided()) {
118
+ // Double sided can be set both by the mesh and the material, but only the material
119
+ // controls it during rendering. Ensure we are using a material that is double sided.
120
+ doubleSided = true;
121
+ if (this._material.isTransparent) {
122
+ // Mesh will render double sided with possible transparent parts, this is tricky.
123
+ //
124
+ // Since we don't depth sort all triangles in the mesh relative to the camera (which
125
+ // is not doable in the general case) we need to employ a trick to make sure the
126
+ // inside of the object gets rendered before the outside skin.
127
+ //
128
+ // Otherwise, semi-transparent pixels in the outer skin would fully occlude pixels
129
+ // from the inside of the object if they happen to be rendered first. That means
130
+ // that sometimes your would not see the inside of the object through the "holes"
131
+ // in it.
132
+ //
133
+ // A good workaround for correctly made objects (where "correct" is mostly related
134
+ // to the normals) is to render the mesh twice, first the back sides ("inside"),
135
+ // then the front sides ("outside") of the triangles. Babylon.js has such a feature
136
+ // built in called separateCullingPass (or "back then front" below).
137
+ backToFront = true;
138
+ }
139
+ }
140
+ const material = this._material.getPBRMaterial(doubleSided, backToFront, flipTexture);
141
+ this.clear(true);
142
+ for (const geo of geos) {
143
+ const mesh = new CfgMesh(labelSuffix, this._renderEnvironment, this.cfgProductNodeParent, geo, material);
144
+ this.add(mesh);
145
+ }
146
+ };
147
+ this.isAllMeshMaterialsReady = () => this.getChildMeshes().reduce((a, m) => a && (m.material === null || m.material.isReady(m)), true);
148
+ this.startSplitGeo = (force = false) => __awaiter(this, void 0, void 0, function* () {
149
+ if (!force && this._splitGeoStatus !== SplitGeoStatus.Idle) {
150
+ return;
151
+ }
152
+ this._splitGeoStatus = SplitGeoStatus.Splitting;
153
+ const geo = this._geo;
154
+ const indexCount = geo.getTotalIndices();
155
+ if (!force && QUICK_SPLIT_INDEX_SIZE_LIMIT < indexCount) {
156
+ return;
157
+ }
158
+ const splitStart = performance.now();
159
+ const doCompleteSplit = indexCount < COMPLETE_SPLIT_INDEX_SIZE_LIMIT || force;
160
+ let groups;
161
+ if (doCompleteSplit) {
162
+ groups = splitIndexComplete(this.logger, geo, {
163
+ maxFinalGroups: force
164
+ ? Number.POSITIVE_INFINITY
165
+ : COMPLETE_SPLIT_FINAL_GROUPS_COUNT_LIMIT,
166
+ maxProgressGroups: force
167
+ ? Number.POSITIVE_INFINITY
168
+ : COMPLETE_SPLIT_PROGRESS_GROUPS_COUNT_LIMIT,
169
+ acceptCoordinateMatch: true,
170
+ });
171
+ }
172
+ else {
173
+ groups = splitIndexQuick(this.logger, geo);
174
+ }
175
+ if (groups === undefined || groups.length === 1) {
176
+ this._splitGeoStatus = SplitGeoStatus.Done;
177
+ return;
178
+ }
179
+ const splitEnd = performance.now();
180
+ this._splitGeos = groups.map((group) => geo.cloneWithSubset(group));
181
+ const repackEnd = performance.now();
182
+ this._splitGeoStatus = SplitGeoStatus.Unapplied;
183
+ this.logger.info(`${doCompleteSplit ? "Complete" : "Quick"}-split`, `of ${indexCount / 3} triangles into ${groups.length} disjoint groups took ${(splitEnd - splitStart).toFixed(1)} ms, repack took ${(repackEnd - splitEnd).toFixed(1)} ms.`);
184
+ // If material is dirty someone else is responsible for calling applyMaterial
185
+ // at a later point
186
+ if (!this._materialIsDirty) {
187
+ this.applyMaterial();
188
+ }
189
+ });
190
+ this._dummyMaterial = renderEnvironment.dummyMaterial;
191
+ this.resetMaterial();
192
+ }
193
+ static makeCfgDeferredMesh(logger, renderEnvironment, cfgProductNodeParent, detailLevel, symNode, gMaterial, stretchDatas) {
194
+ var _a, _b, _c;
195
+ return __awaiter(this, void 0, void 0, function* () {
196
+ const lod = getDetailMask(symNode);
197
+ if (lod === undefined || !lod.includes(detailLevel)) {
198
+ return;
199
+ }
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();
201
+ if (component === undefined) {
202
+ return;
203
+ }
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) {
210
+ return undefined;
211
+ }
212
+ return new this(renderEnvironment, cfgProductNodeParent, "(Deferred Mesh) " + symNode.id, lod, gMaterial, entry.doubleSided, entry.lowerLeftTextureOrigin, geo, stretchDatas);
213
+ });
214
+ }
215
+ get cfgClassName() {
216
+ return "CfgDeferredMeshNode";
217
+ }
218
+ resetMaterial() {
219
+ this._material = this._dummyMaterial;
220
+ this._materialMetaData = undefined;
221
+ this._materialIsDirty = true;
222
+ this.applyMaterial();
223
+ }
224
+ get originalMatrix() {
225
+ return Matrix.Identity();
226
+ }
227
+ setMaterialAndLoad(mtrlWithMetaData, animatorCoordinator) {
228
+ return __awaiter(this, void 0, void 0, function* () {
229
+ if (this._materialLoadedPromise !== undefined &&
230
+ mtrlWithMetaData !== undefined &&
231
+ this._mtrlSourceWithMetaData !== undefined &&
232
+ this._mtrlSourceWithMetaData !== null &&
233
+ mtrlWithMetaData.mtrl.isSame(this._mtrlSourceWithMetaData.mtrl)) {
234
+ return this._materialLoadedPromise;
235
+ }
236
+ this._mtrlSourceWithMetaData = mtrlWithMetaData;
237
+ this._materialLoadedPromise = this.loadMaterial();
238
+ if (animatorCoordinator !== undefined && mtrlWithMetaData !== undefined) {
239
+ const c = animatorCoordinator.coordinator;
240
+ c.prepareForMaterialChange.bind(c)(this, animatorCoordinator.isNewProduct);
241
+ }
242
+ return this._materialLoadedPromise;
243
+ });
244
+ }
245
+ loadMaterial() {
246
+ return __awaiter(this, void 0, void 0, function* () {
247
+ let material;
248
+ const meta = {
249
+ logger: this.logger,
250
+ sourcePath: ["loadMaterial"],
251
+ };
252
+ if (this._mtrlSourceWithMetaData === null) {
253
+ // null === has not yet been set
254
+ return;
255
+ }
256
+ try {
257
+ if (this._mtrlSourceWithMetaData !== undefined) {
258
+ material = yield mtrlSourceToCfgMaterial(meta, this._mtrlSourceWithMetaData, this._renderEnvironment);
259
+ if (material === undefined) {
260
+ this.logger.error("Failed to load material from mtrlSource");
261
+ }
262
+ }
263
+ else if (this._gMaterial !== undefined && this._gMaterial.gm !== undefined) {
264
+ meta.sourcePath.push("embedded");
265
+ material = yield gMaterialToCfgMaterial(meta, this._renderEnvironment, this._gMaterial.gm);
266
+ if (material === undefined) {
267
+ this.logger.error("Failed to load material from fallback gMaterial");
268
+ }
269
+ }
270
+ }
271
+ catch (e) {
272
+ this._renderEnvironment.notifyError("Failed to load material. Will show default material.");
273
+ this.logger.errorFromCaught(e);
274
+ }
275
+ if (material === undefined) {
276
+ this.logger.warn("No material, not even fallback-material");
277
+ }
278
+ this._material = material;
279
+ this._materialMetaData = meta;
280
+ this._materialIsDirty = true;
281
+ if (material && material.isTransparent) {
282
+ this.startSplitGeo();
283
+ }
284
+ });
285
+ }
286
+ get boundingBox() {
287
+ const stretchDatas = this._stretchDatas;
288
+ const stretchReferenceLengthsByMeasureParamCode = this.cfgProductNodeParent.product.configuration._internal
289
+ .stretchReferenceLengthsByMeasureParamCode;
290
+ return this.getChildMeshes().reduce((a, m) => {
291
+ const bb = m.getBoundingInfo().boundingBox;
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
+ });
298
+ return a;
299
+ }, new CfgBoundingBox());
300
+ }
301
+ getChildCfgMeshes() {
302
+ return this.getChildMeshes().filter((f) => f instanceof CfgMesh);
303
+ }
304
+ refreshStretch() {
305
+ this.getChildCfgMeshes().map((childMesh) => childMesh.refreshStretch());
306
+ }
307
+ addInspectorProperties() {
308
+ super.addInspectorProperties();
309
+ this.addInspectableCustomProperty({
310
+ label: "Available lod levels",
311
+ propertyName: "_inspectorLodLevels",
312
+ type: InspectableType.String,
313
+ });
314
+ this.addInspectableCustomProperty({
315
+ label: "Mtrl Source path",
316
+ propertyName: "_inspectorSourcePath",
317
+ type: InspectableType.String,
318
+ });
319
+ this.addInspectableCustomProperty({
320
+ label: "log mtrlSourceWithMetaData",
321
+ propertyName: "_inspectorLogMtrlSourceWithMetaData",
322
+ type: InspectableType.Checkbox,
323
+ });
324
+ this.addInspectableCustomProperty({
325
+ label: "log GMaterial",
326
+ propertyName: "_inspectorLogGMaterial",
327
+ type: InspectableType.Checkbox,
328
+ });
329
+ this.addInspectableCustomProperty({
330
+ label: "log MultiGMaterial",
331
+ propertyName: "_inspectorLogMultiGMaterial",
332
+ type: InspectableType.Checkbox,
333
+ });
334
+ }
335
+ get _inspectorLodLevels() {
336
+ return Array.from(this.lod.detailSet().values()).join(", ");
337
+ }
338
+ get _inspectorSourcePath() {
339
+ if (this._materialMetaData === undefined) {
340
+ return "-";
341
+ }
342
+ return this._materialMetaData.sourcePath.join(" ");
343
+ }
344
+ get _inspectorLogMtrlSourceWithMetaData() {
345
+ return this._mtrlSourceWithMetaData === undefined || this._mtrlSourceWithMetaData === null;
346
+ }
347
+ set _inspectorLogMtrlSourceWithMetaData(x) {
348
+ if (this._mtrlSourceWithMetaData === undefined || this._mtrlSourceWithMetaData === null) {
349
+ return;
350
+ }
351
+ logMtrlSourceWithMetaDataToConsole(this._mtrlSourceWithMetaData);
352
+ }
353
+ get _inspectorLogGMaterial() {
354
+ var _a;
355
+ return ((_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.gMaterial) === undefined;
356
+ }
357
+ set _inspectorLogGMaterial(x) {
358
+ var _a;
359
+ const m = (_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.gMaterial;
360
+ if (m === undefined) {
361
+ return;
362
+ }
363
+ console.log(m);
364
+ }
365
+ get _inspectorLogMultiGMaterial() {
366
+ var _a;
367
+ return ((_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.multiGMaterial) === undefined;
368
+ }
369
+ set _inspectorLogMultiGMaterial(x) {
370
+ var _a;
371
+ const m = (_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.multiGMaterial;
372
+ if (m === undefined) {
373
+ return;
374
+ }
375
+ console.log(m);
376
+ }
377
+ }