@configura/babylon-view 2.0.0-alpha.8 → 2.0.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 (134) hide show
  1. package/.eslintrc.json +5 -18
  2. package/LICENSE +201 -201
  3. package/README.md +1 -1
  4. package/dist/animation/AnimatableObject.d.ts +8 -8
  5. package/dist/animation/AnimatableObject.js +3 -3
  6. package/dist/animation/animator/Animator.d.ts +33 -33
  7. package/dist/animation/animator/Animator.js +58 -58
  8. package/dist/animation/animator/AnimatorEasing.d.ts +16 -16
  9. package/dist/animation/animator/AnimatorEasing.js +31 -31
  10. package/dist/animation/animator/AnimatorEasingMatrix.d.ts +14 -14
  11. package/dist/animation/animator/AnimatorEasingMatrix.js +16 -16
  12. package/dist/animation/animator/AnimatorHighlight.d.ts +16 -16
  13. package/dist/animation/animator/AnimatorHighlight.js +32 -32
  14. package/dist/animation/animator/AnimatorPointToPoint.d.ts +8 -8
  15. package/dist/animation/animator/AnimatorPointToPoint.js +14 -14
  16. package/dist/animation/animator/AnimatorQueue.d.ts +13 -13
  17. package/dist/animation/animator/AnimatorQueue.js +57 -57
  18. package/dist/animation/animator/AnimatorScale.d.ts +8 -8
  19. package/dist/animation/animator/AnimatorScale.js +13 -13
  20. package/dist/animation/animator/AnimatorSpin.d.ts +10 -10
  21. package/dist/animation/animator/AnimatorSpin.js +13 -13
  22. package/dist/animation/animator/EasingFunctions.d.ts +35 -35
  23. package/dist/animation/animator/EasingFunctions.js +137 -137
  24. package/dist/animation/coordinator/Coordinator.d.ts +28 -28
  25. package/dist/animation/coordinator/Coordinator.js +53 -53
  26. package/dist/animation/coordinator/CoordinatorDropAndSpin.d.ts +22 -22
  27. package/dist/animation/coordinator/CoordinatorDropAndSpin.js +138 -138
  28. package/dist/animation/coordinator/CoordinatorIdentity.d.ts +11 -11
  29. package/dist/animation/coordinator/CoordinatorIdentity.js +14 -14
  30. package/dist/animation/coordinator/CoordinatorNodeQueues.d.ts +18 -18
  31. package/dist/animation/coordinator/CoordinatorNodeQueues.js +50 -50
  32. package/dist/animation/coordinator/CoordinatorPulse.d.ts +21 -21
  33. package/dist/animation/coordinator/CoordinatorPulse.js +47 -47
  34. package/dist/animation/coordinator/CoordinatorPulseBounce.d.ts +14 -14
  35. package/dist/animation/coordinator/CoordinatorPulseBounce.js +35 -35
  36. package/dist/animation/coordinator/CoordinatorPulseHighlight.d.ts +13 -13
  37. package/dist/animation/coordinator/CoordinatorPulseHighlight.js +29 -29
  38. package/dist/animation/coordinator/CoordinatorPulseInflate.d.ts +14 -14
  39. package/dist/animation/coordinator/CoordinatorPulseInflate.js +23 -23
  40. package/dist/camera/CameraCreator.d.ts +5 -5
  41. package/dist/camera/CameraCreator.js +4 -4
  42. package/dist/camera/CfgArcRotateCameraPointersInput.d.ts +26 -26
  43. package/dist/camera/CfgArcRotateCameraPointersInput.js +266 -266
  44. package/dist/camera/CfgOrbitalCamera.d.ts +76 -73
  45. package/dist/camera/CfgOrbitalCamera.js +281 -260
  46. package/dist/camera/CfgOrbitalCameraControlProps.d.ts +14 -11
  47. package/dist/camera/CfgOrbitalCameraControlProps.js +7 -6
  48. package/dist/camera/GradingApplier.d.ts +3 -3
  49. package/dist/camera/GradingApplier.js +48 -48
  50. package/dist/engine/EngineCreator.d.ts +3 -3
  51. package/dist/engine/EngineCreator.js +10 -10
  52. package/dist/geometry/CfgGeometry.d.ts +29 -29
  53. package/dist/geometry/CfgGeometry.js +146 -146
  54. package/dist/geometry/CfgMesh.d.ts +10 -10
  55. package/dist/geometry/CfgMesh.js +38 -38
  56. package/dist/geometry/geoSplitter.d.ts +8 -8
  57. package/dist/geometry/geoSplitter.js +192 -192
  58. package/dist/geometry/stretch/CfgMorphTarget.d.ts +15 -15
  59. package/dist/geometry/stretch/CfgMorphTarget.js +65 -65
  60. package/dist/geometry/stretch/CfgStretchData.d.ts +116 -116
  61. package/dist/geometry/stretch/CfgStretchData.js +350 -350
  62. package/dist/geometry/stretch/CfgStretchMorphGeometry.d.ts +16 -16
  63. package/dist/geometry/stretch/CfgStretchMorphGeometry.js +95 -95
  64. package/dist/index.d.ts +16 -16
  65. package/dist/index.js +16 -16
  66. package/dist/io/CfgHistoryToCameraConfConnector.d.ts +31 -29
  67. package/dist/io/CfgHistoryToCameraConfConnector.js +90 -80
  68. package/dist/io/CfgIOCameraConfConnector.d.ts +35 -35
  69. package/dist/io/CfgIOCameraConfConnector.js +81 -80
  70. package/dist/io/CfgObservableStateToCameraConfConnector.d.ts +10 -10
  71. package/dist/io/CfgObservableStateToCameraConfConnector.js +11 -11
  72. package/dist/io/CfgWindowMessageToCameraConfConnector.d.ts +10 -10
  73. package/dist/io/CfgWindowMessageToCameraConfConnector.js +11 -11
  74. package/dist/light/CfgDirectionalLight.d.ts +8 -8
  75. package/dist/light/CfgDirectionalLight.js +18 -18
  76. package/dist/light/CfgHemisphericLight.d.ts +7 -7
  77. package/dist/light/CfgHemisphericLight.js +17 -17
  78. package/dist/light/CfgPointLight.d.ts +8 -8
  79. package/dist/light/CfgPointLight.js +18 -18
  80. package/dist/light/DefaultLightRig.d.ts +19 -19
  81. package/dist/light/DefaultLightRig.js +77 -77
  82. package/dist/light/LightRigCreator.d.ts +9 -9
  83. package/dist/light/LightRigCreator.js +3 -3
  84. package/dist/material/CfgMaterial.d.ts +68 -68
  85. package/dist/material/CfgMaterial.js +482 -482
  86. package/dist/material/DummyMaterialCreator.d.ts +4 -4
  87. package/dist/material/DummyMaterialCreator.js +15 -15
  88. package/dist/material/material.d.ts +18 -18
  89. package/dist/material/material.js +128 -128
  90. package/dist/material/texture.d.ts +14 -14
  91. package/dist/material/texture.js +306 -306
  92. package/dist/nodes/CfgContentRootNode.d.ts +19 -19
  93. package/dist/nodes/CfgContentRootNode.js +75 -75
  94. package/dist/nodes/CfgDeferredMeshNode.d.ts +55 -55
  95. package/dist/nodes/CfgDeferredMeshNode.js +378 -378
  96. package/dist/nodes/CfgProductNode.d.ts +127 -127
  97. package/dist/nodes/CfgProductNode.js +598 -598
  98. package/dist/nodes/CfgSymNode.d.ts +50 -50
  99. package/dist/nodes/CfgSymNode.js +249 -249
  100. package/dist/nodes/CfgSymRootNode.d.ts +45 -45
  101. package/dist/nodes/CfgSymRootNode.js +229 -229
  102. package/dist/nodes/CfgTransformNode.d.ts +33 -33
  103. package/dist/nodes/CfgTransformNode.js +83 -83
  104. package/dist/scene/SceneCreator.d.ts +6 -6
  105. package/dist/scene/SceneCreator.js +22 -22
  106. package/dist/utilities/CfgBoundingBox.d.ts +21 -21
  107. package/dist/utilities/CfgBoundingBox.js +81 -81
  108. package/dist/utilities/anchor/anchor.d.ts +50 -50
  109. package/dist/utilities/anchor/anchor.js +133 -133
  110. package/dist/utilities/anchor/anchorMap.d.ts +20 -20
  111. package/dist/utilities/anchor/anchorMap.js +111 -111
  112. package/dist/utilities/utilities3D.d.ts +70 -70
  113. package/dist/utilities/utilities3D.js +265 -265
  114. package/dist/utilities/utilitiesColor.d.ts +18 -18
  115. package/dist/utilities/utilitiesColor.js +50 -50
  116. package/dist/utilities/utilitiesImage.d.ts +6 -6
  117. package/dist/utilities/utilitiesImage.js +107 -107
  118. package/dist/utilities/utilitiesSymRootIdentifier.d.ts +7 -7
  119. package/dist/utilities/utilitiesSymRootIdentifier.js +26 -26
  120. package/dist/view/BaseView.d.ts +78 -78
  121. package/dist/view/BaseView.js +303 -303
  122. package/dist/view/BaseViewConfiguration.d.ts +32 -32
  123. package/dist/view/BaseViewConfiguration.js +10 -10
  124. package/dist/view/RenderEnv.d.ts +43 -43
  125. package/dist/view/RenderEnv.js +7 -7
  126. package/dist/view/SingleProductDefaultCameraView.d.ts +38 -37
  127. package/dist/view/SingleProductDefaultCameraView.js +149 -145
  128. package/dist/view/SingleProductDefaultCameraViewConfiguration.d.ts +44 -42
  129. package/dist/view/SingleProductDefaultCameraViewConfiguration.js +11 -11
  130. package/dist/view/SingleProductView.d.ts +44 -44
  131. package/dist/view/SingleProductView.js +212 -212
  132. package/dist/view/SingleProductViewConfiguration.d.ts +32 -32
  133. package/dist/view/SingleProductViewConfiguration.js +19 -19
  134. package/package.json +5 -5
@@ -1,378 +1,378 @@
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, () => {
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 Promise.resolve(undefined);
80
- }
81
- return Promise.resolve(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
- const 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
- const 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
- yield 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
- // Let this not block
283
- void this.startSplitGeo();
284
- }
285
- });
286
- }
287
- get boundingBox() {
288
- const stretchDatas = this._stretchDatas;
289
- const stretchReferenceLengthsByMeasureParamCode = this.cfgProductNodeParent.product.configuration._internal
290
- .stretchReferenceLengthsByMeasureParamCode;
291
- return this.getChildMeshes().reduce((a, m) => {
292
- const bb = m.getBoundingInfo().boundingBox;
293
- const cfgBb = new CfgBoundingBox(bb.minimum, bb.maximum);
294
- cfgBb.corners
295
- .map((c) => toStretchedPoint(c, stretchDatas, stretchReferenceLengthsByMeasureParamCode))
296
- .forEach((c) => {
297
- a.expandWithPoint(c);
298
- });
299
- return a;
300
- }, new CfgBoundingBox());
301
- }
302
- getChildCfgMeshes() {
303
- return this.getChildMeshes().filter((f) => f instanceof CfgMesh);
304
- }
305
- refreshStretch() {
306
- this.getChildCfgMeshes().map((childMesh) => childMesh.refreshStretch());
307
- }
308
- addInspectorProperties() {
309
- super.addInspectorProperties();
310
- this.addInspectableCustomProperty({
311
- label: "Available lod levels",
312
- propertyName: "_inspectorLodLevels",
313
- type: InspectableType.String,
314
- });
315
- this.addInspectableCustomProperty({
316
- label: "Mtrl Source path",
317
- propertyName: "_inspectorSourcePath",
318
- type: InspectableType.String,
319
- });
320
- this.addInspectableCustomProperty({
321
- label: "log mtrlSourceWithMetaData",
322
- propertyName: "_inspectorLogMtrlSourceWithMetaData",
323
- type: InspectableType.Checkbox,
324
- });
325
- this.addInspectableCustomProperty({
326
- label: "log GMaterial",
327
- propertyName: "_inspectorLogGMaterial",
328
- type: InspectableType.Checkbox,
329
- });
330
- this.addInspectableCustomProperty({
331
- label: "log MultiGMaterial",
332
- propertyName: "_inspectorLogMultiGMaterial",
333
- type: InspectableType.Checkbox,
334
- });
335
- }
336
- get _inspectorLodLevels() {
337
- return Array.from(this.lod.detailSet().values()).join(", ");
338
- }
339
- get _inspectorSourcePath() {
340
- if (this._materialMetaData === undefined) {
341
- return "-";
342
- }
343
- return this._materialMetaData.sourcePath.join(" ");
344
- }
345
- get _inspectorLogMtrlSourceWithMetaData() {
346
- return this._mtrlSourceWithMetaData === undefined || this._mtrlSourceWithMetaData === null;
347
- }
348
- set _inspectorLogMtrlSourceWithMetaData(x) {
349
- if (this._mtrlSourceWithMetaData === undefined || this._mtrlSourceWithMetaData === null) {
350
- return;
351
- }
352
- logMtrlSourceWithMetaDataToConsole(this._mtrlSourceWithMetaData);
353
- }
354
- get _inspectorLogGMaterial() {
355
- var _a;
356
- return ((_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.gMaterial) === undefined;
357
- }
358
- set _inspectorLogGMaterial(x) {
359
- var _a;
360
- const m = (_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.gMaterial;
361
- if (m === undefined) {
362
- return;
363
- }
364
- console.log(m);
365
- }
366
- get _inspectorLogMultiGMaterial() {
367
- var _a;
368
- return ((_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.multiGMaterial) === undefined;
369
- }
370
- set _inspectorLogMultiGMaterial(x) {
371
- var _a;
372
- const m = (_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.multiGMaterial;
373
- if (m === undefined) {
374
- return;
375
- }
376
- console.log(m);
377
- }
378
- }
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, () => {
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 Promise.resolve(undefined);
80
+ }
81
+ return Promise.resolve(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
+ const 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
+ const 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
+ yield 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
+ // Let this not block
283
+ void this.startSplitGeo();
284
+ }
285
+ });
286
+ }
287
+ get boundingBox() {
288
+ const stretchDatas = this._stretchDatas;
289
+ const stretchReferenceLengthsByMeasureParamCode = this.cfgProductNodeParent.product.configuration._internal
290
+ .stretchReferenceLengthsByMeasureParamCode;
291
+ return this.getChildMeshes().reduce((a, m) => {
292
+ const bb = m.getBoundingInfo().boundingBox;
293
+ const cfgBb = new CfgBoundingBox(bb.minimum, bb.maximum);
294
+ cfgBb.corners
295
+ .map((c) => toStretchedPoint(c, stretchDatas, stretchReferenceLengthsByMeasureParamCode))
296
+ .forEach((c) => {
297
+ a.expandWithPoint(c);
298
+ });
299
+ return a;
300
+ }, new CfgBoundingBox());
301
+ }
302
+ getChildCfgMeshes() {
303
+ return this.getChildMeshes().filter((f) => f instanceof CfgMesh);
304
+ }
305
+ refreshStretch() {
306
+ this.getChildCfgMeshes().map((childMesh) => childMesh.refreshStretch());
307
+ }
308
+ addInspectorProperties() {
309
+ super.addInspectorProperties();
310
+ this.addInspectableCustomProperty({
311
+ label: "Available lod levels",
312
+ propertyName: "_inspectorLodLevels",
313
+ type: InspectableType.String,
314
+ });
315
+ this.addInspectableCustomProperty({
316
+ label: "Mtrl Source path",
317
+ propertyName: "_inspectorSourcePath",
318
+ type: InspectableType.String,
319
+ });
320
+ this.addInspectableCustomProperty({
321
+ label: "log mtrlSourceWithMetaData",
322
+ propertyName: "_inspectorLogMtrlSourceWithMetaData",
323
+ type: InspectableType.Checkbox,
324
+ });
325
+ this.addInspectableCustomProperty({
326
+ label: "log GMaterial",
327
+ propertyName: "_inspectorLogGMaterial",
328
+ type: InspectableType.Checkbox,
329
+ });
330
+ this.addInspectableCustomProperty({
331
+ label: "log MultiGMaterial",
332
+ propertyName: "_inspectorLogMultiGMaterial",
333
+ type: InspectableType.Checkbox,
334
+ });
335
+ }
336
+ get _inspectorLodLevels() {
337
+ return Array.from(this.lod.detailSet().values()).join(", ");
338
+ }
339
+ get _inspectorSourcePath() {
340
+ if (this._materialMetaData === undefined) {
341
+ return "-";
342
+ }
343
+ return this._materialMetaData.sourcePath.join(" ");
344
+ }
345
+ get _inspectorLogMtrlSourceWithMetaData() {
346
+ return this._mtrlSourceWithMetaData === undefined || this._mtrlSourceWithMetaData === null;
347
+ }
348
+ set _inspectorLogMtrlSourceWithMetaData(x) {
349
+ if (this._mtrlSourceWithMetaData === undefined || this._mtrlSourceWithMetaData === null) {
350
+ return;
351
+ }
352
+ logMtrlSourceWithMetaDataToConsole(this._mtrlSourceWithMetaData);
353
+ }
354
+ get _inspectorLogGMaterial() {
355
+ var _a;
356
+ return ((_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.gMaterial) === undefined;
357
+ }
358
+ set _inspectorLogGMaterial(x) {
359
+ var _a;
360
+ const m = (_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.gMaterial;
361
+ if (m === undefined) {
362
+ return;
363
+ }
364
+ console.log(m);
365
+ }
366
+ get _inspectorLogMultiGMaterial() {
367
+ var _a;
368
+ return ((_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.multiGMaterial) === undefined;
369
+ }
370
+ set _inspectorLogMultiGMaterial(x) {
371
+ var _a;
372
+ const m = (_a = this._materialMetaData) === null || _a === void 0 ? void 0 : _a.multiGMaterial;
373
+ if (m === undefined) {
374
+ return;
375
+ }
376
+ console.log(m);
377
+ }
378
+ }