@babylonjs/viewer 5.0.0 → 5.0.3

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 (127) hide show
  1. package/configuration/configuration.d.ts +107 -107
  2. package/configuration/configuration.js +15 -15
  3. package/configuration/configurationCompatibility.d.ts +8 -8
  4. package/configuration/configurationCompatibility.js +65 -65
  5. package/configuration/configurationContainer.d.ts +10 -10
  6. package/configuration/configurationContainer.js +9 -9
  7. package/configuration/globals.d.ts +6 -6
  8. package/configuration/globals.js +17 -17
  9. package/configuration/index.d.ts +2 -2
  10. package/configuration/index.js +3 -3
  11. package/configuration/interfaces/cameraConfiguration.d.ts +31 -31
  12. package/configuration/interfaces/cameraConfiguration.js +1 -1
  13. package/configuration/interfaces/colorGradingConfiguration.d.ts +81 -81
  14. package/configuration/interfaces/colorGradingConfiguration.js +1 -1
  15. package/configuration/interfaces/defaultRenderingPipelineConfiguration.d.ts +20 -20
  16. package/configuration/interfaces/defaultRenderingPipelineConfiguration.js +1 -1
  17. package/configuration/interfaces/environmentMapConfiguration.d.ts +22 -22
  18. package/configuration/interfaces/environmentMapConfiguration.js +1 -1
  19. package/configuration/interfaces/groundConfiguration.d.ts +24 -24
  20. package/configuration/interfaces/groundConfiguration.js +1 -1
  21. package/configuration/interfaces/imageProcessingConfiguration.d.ts +43 -43
  22. package/configuration/interfaces/imageProcessingConfiguration.js +1 -1
  23. package/configuration/interfaces/index.d.ts +15 -15
  24. package/configuration/interfaces/index.js +15 -15
  25. package/configuration/interfaces/lightConfiguration.d.ts +60 -60
  26. package/configuration/interfaces/lightConfiguration.js +1 -1
  27. package/configuration/interfaces/modelAnimationConfiguration.d.ts +26 -26
  28. package/configuration/interfaces/modelAnimationConfiguration.js +1 -1
  29. package/configuration/interfaces/modelConfiguration.d.ts +65 -65
  30. package/configuration/interfaces/modelConfiguration.js +1 -1
  31. package/configuration/interfaces/observersConfiguration.d.ts +5 -5
  32. package/configuration/interfaces/observersConfiguration.js +1 -1
  33. package/configuration/interfaces/sceneConfiguration.d.ts +48 -48
  34. package/configuration/interfaces/sceneConfiguration.js +1 -1
  35. package/configuration/interfaces/sceneOptimizerConfiguration.d.ts +23 -23
  36. package/configuration/interfaces/sceneOptimizerConfiguration.js +1 -1
  37. package/configuration/interfaces/skyboxConfiguration.d.ts +21 -21
  38. package/configuration/interfaces/skyboxConfiguration.js +1 -1
  39. package/configuration/interfaces/templateConfiguration.d.ts +67 -67
  40. package/configuration/interfaces/templateConfiguration.js +1 -1
  41. package/configuration/interfaces/vrConfiguration.d.ts +16 -16
  42. package/configuration/interfaces/vrConfiguration.js +1 -1
  43. package/configuration/loader.d.ts +4 -4
  44. package/configuration/loader.js +16 -16
  45. package/configuration/mappers.d.ts +42 -42
  46. package/configuration/mappers.js +190 -190
  47. package/configuration/renderOnlyLoader.d.ts +33 -33
  48. package/configuration/renderOnlyLoader.js +161 -161
  49. package/configuration/types/default.d.ts +6 -6
  50. package/configuration/types/default.js +120 -120
  51. package/configuration/types/environmentMap.d.ts +5 -5
  52. package/configuration/types/environmentMap.js +13 -13
  53. package/configuration/types/extended.d.ts +6 -6
  54. package/configuration/types/extended.js +316 -316
  55. package/configuration/types/index.d.ts +13 -13
  56. package/configuration/types/index.js +49 -49
  57. package/configuration/types/minimal.d.ts +6 -6
  58. package/configuration/types/minimal.js +42 -42
  59. package/configuration/types/renderOnlyDefault.d.ts +30 -30
  60. package/configuration/types/renderOnlyDefault.js +30 -30
  61. package/configuration/types/shadowLight.d.ts +9 -9
  62. package/configuration/types/shadowLight.js +63 -63
  63. package/helper/index.d.ts +26 -26
  64. package/helper/index.js +62 -62
  65. package/index.d.ts +30 -30
  66. package/index.js +45 -45
  67. package/initializer.d.ts +11 -11
  68. package/initializer.js +34 -34
  69. package/interfaces.d.ts +5 -5
  70. package/interfaces.js +1 -1
  71. package/labs/environmentSerializer.d.ts +126 -126
  72. package/labs/environmentSerializer.js +190 -190
  73. package/labs/texture.d.ts +183 -183
  74. package/labs/texture.js +300 -300
  75. package/labs/viewerLabs.d.ts +51 -51
  76. package/labs/viewerLabs.js +133 -133
  77. package/loader/modelLoader.d.ts +47 -47
  78. package/loader/modelLoader.js +189 -189
  79. package/loader/plugins/applyMaterialConfig.d.ts +12 -12
  80. package/loader/plugins/applyMaterialConfig.js +15 -15
  81. package/loader/plugins/extendedMaterialLoaderPlugin.d.ts +9 -9
  82. package/loader/plugins/extendedMaterialLoaderPlugin.js +15 -15
  83. package/loader/plugins/index.d.ts +18 -18
  84. package/loader/plugins/index.js +42 -42
  85. package/loader/plugins/loaderPlugin.d.ts +24 -24
  86. package/loader/plugins/loaderPlugin.js +1 -1
  87. package/loader/plugins/msftLodLoaderPlugin.d.ts +12 -12
  88. package/loader/plugins/msftLodLoaderPlugin.js +20 -20
  89. package/loader/plugins/telemetryLoaderPlugin.d.ts +12 -12
  90. package/loader/plugins/telemetryLoaderPlugin.js +35 -35
  91. package/managers/observablesManager.d.ts +66 -66
  92. package/managers/observablesManager.js +34 -34
  93. package/managers/sceneManager.d.ts +243 -243
  94. package/managers/sceneManager.js +1388 -1388
  95. package/managers/telemetryManager.d.ts +57 -57
  96. package/managers/telemetryManager.js +113 -113
  97. package/model/modelAnimation.d.ts +215 -215
  98. package/model/modelAnimation.js +232 -232
  99. package/model/viewerModel.d.ts +228 -228
  100. package/model/viewerModel.js +669 -669
  101. package/optimizer/custom/extended.d.ts +11 -11
  102. package/optimizer/custom/extended.js +98 -98
  103. package/optimizer/custom/index.d.ts +8 -8
  104. package/optimizer/custom/index.js +24 -24
  105. package/package.json +5 -5
  106. package/renderOnlyIndex.d.ts +11 -11
  107. package/renderOnlyIndex.js +17 -17
  108. package/templating/eventManager.d.ts +35 -35
  109. package/templating/eventManager.js +65 -65
  110. package/templating/plugins/hdButtonPlugin.d.ts +9 -9
  111. package/templating/plugins/hdButtonPlugin.js +21 -21
  112. package/templating/plugins/printButton.d.ts +9 -9
  113. package/templating/plugins/printButton.js +40 -40
  114. package/templating/templateManager.d.ts +190 -190
  115. package/templating/templateManager.js +553 -553
  116. package/templating/viewerTemplatePlugin.d.ts +21 -21
  117. package/templating/viewerTemplatePlugin.js +68 -68
  118. package/viewer/defaultViewer.d.ts +122 -122
  119. package/viewer/defaultViewer.js +665 -665
  120. package/viewer/renderOnlyViewer.d.ts +8 -8
  121. package/viewer/renderOnlyViewer.js +43 -43
  122. package/viewer/viewer.d.ts +254 -254
  123. package/viewer/viewer.js +777 -777
  124. package/viewer/viewerManager.d.ts +55 -55
  125. package/viewer/viewerManager.js +87 -87
  126. package/viewer/viewerWithTemplate.d.ts +9 -9
  127. package/viewer/viewerWithTemplate.js +19 -19
@@ -1,670 +1,670 @@
1
- import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh.js";
2
- import { Observable } from "@babylonjs/core/Misc/observable.js";
3
- import { AnimationGroup } from "@babylonjs/core/Animations/animationGroup.js";
4
- import { Animation, CircleEase, BackEase, BounceEase, CubicEase, ElasticEase, ExponentialEase, PowerEase, QuadraticEase, QuarticEase, QuinticEase, SineEase, } from "@babylonjs/core/Animations/index.js";
5
- import { Quaternion, Vector3 } from "@babylonjs/core/Maths/math.vector.js";
6
- import { Tags } from "@babylonjs/core/Misc/tags.js";
7
- import { PBRMaterial } from "@babylonjs/core/Materials/PBR/pbrMaterial.js";
8
- import { MultiMaterial } from "@babylonjs/core/Materials/multiMaterial.js";
9
- import { Tools } from "@babylonjs/core/Misc/tools.js";
10
- import { GroupModelAnimation, AnimationPlayMode, EasingFunction, AnimationState } from "./modelAnimation.js";
11
- import { deepmerge, extendClassWithConfig } from "../helper/index.js";
12
- /**
13
- * The current state of the model
14
- */
15
- export var ModelState;
16
- (function (ModelState) {
17
- ModelState[ModelState["INIT"] = 0] = "INIT";
18
- ModelState[ModelState["LOADING"] = 1] = "LOADING";
19
- ModelState[ModelState["LOADED"] = 2] = "LOADED";
20
- ModelState[ModelState["ENTRY"] = 3] = "ENTRY";
21
- ModelState[ModelState["ENTRYDONE"] = 4] = "ENTRYDONE";
22
- ModelState[ModelState["COMPLETE"] = 5] = "COMPLETE";
23
- ModelState[ModelState["CANCELED"] = 6] = "CANCELED";
24
- ModelState[ModelState["ERROR"] = 7] = "ERROR";
25
- })(ModelState || (ModelState = {}));
26
- /**
27
- * The viewer model is a container for all assets representing a sngle loaded model.
28
- */
29
- var ViewerModel = /** @class */ (function () {
30
- function ViewerModel(_observablesManager, modelConfiguration, _configurationContainer) {
31
- var _this = this;
32
- this._observablesManager = _observablesManager;
33
- this._configurationContainer = _configurationContainer;
34
- /**
35
- * the list of meshes that are a part of this model
36
- */
37
- this._meshes = [];
38
- /**
39
- * ParticleSystems connected to this model
40
- */
41
- this.particleSystems = [];
42
- /**
43
- * Skeletons defined in this model
44
- */
45
- this.skeletons = [];
46
- this._loaderDone = false;
47
- this._animatables = [];
48
- this._frameRate = 60;
49
- this._shadowsRenderedAfterLoad = false;
50
- this.onLoadedObservable = new Observable();
51
- this.onLoadErrorObservable = new Observable();
52
- this.onLoadProgressObservable = new Observable();
53
- this.onCompleteObservable = new Observable();
54
- this.onAfterConfigure = new Observable();
55
- this.state = ModelState.INIT;
56
- var scene = this._configurationContainer && this._configurationContainer.scene;
57
- this.rootMesh = new AbstractMesh("modelRootMesh", scene);
58
- this._pivotMesh = new AbstractMesh("pivotMesh", scene);
59
- this._pivotMesh.parent = this.rootMesh;
60
- // rotate 180, gltf fun
61
- this._pivotMesh.rotation.y += Math.PI;
62
- this._scaleTransition = new Animation("scaleAnimation", "scaling", this._frameRate, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CONSTANT);
63
- this._animations = [];
64
- //create a copy of the configuration to make sure it doesn't change even after it is changed in the viewer
65
- this._modelConfiguration = deepmerge((this._configurationContainer && this._configurationContainer.configuration.model) || {}, modelConfiguration);
66
- if (this._observablesManager) {
67
- this._observablesManager.onModelAddedObservable.notifyObservers(this);
68
- }
69
- if (this._modelConfiguration.entryAnimation) {
70
- this.rootMesh.setEnabled(false);
71
- }
72
- this.onLoadedObservable.add(function () {
73
- _this.updateConfiguration(_this._modelConfiguration);
74
- if (_this._observablesManager) {
75
- _this._observablesManager.onModelLoadedObservable.notifyObservers(_this);
76
- }
77
- _this._initAnimations();
78
- });
79
- this.onCompleteObservable.add(function () {
80
- _this.state = ModelState.COMPLETE;
81
- });
82
- }
83
- Object.defineProperty(ViewerModel.prototype, "shadowsRenderedAfterLoad", {
84
- get: function () {
85
- return this._shadowsRenderedAfterLoad;
86
- },
87
- set: function (rendered) {
88
- if (!rendered) {
89
- throw new Error("can only be enabled");
90
- }
91
- else {
92
- this._shadowsRenderedAfterLoad = rendered;
93
- }
94
- },
95
- enumerable: false,
96
- configurable: true
97
- });
98
- ViewerModel.prototype.getViewerId = function () {
99
- return this._configurationContainer && this._configurationContainer.viewerId;
100
- };
101
- Object.defineProperty(ViewerModel.prototype, "enabled", {
102
- /**
103
- * Is this model enabled?
104
- */
105
- get: function () {
106
- return this.rootMesh.isEnabled();
107
- },
108
- /**
109
- * Set whether this model is enabled or not.
110
- */
111
- set: function (enable) {
112
- this.rootMesh.setEnabled(enable);
113
- },
114
- enumerable: false,
115
- configurable: true
116
- });
117
- Object.defineProperty(ViewerModel.prototype, "loaderDone", {
118
- set: function (done) {
119
- this._loaderDone = done;
120
- this._checkCompleteState();
121
- },
122
- enumerable: false,
123
- configurable: true
124
- });
125
- ViewerModel.prototype._checkCompleteState = function () {
126
- if (this._loaderDone && this.state === ModelState.ENTRYDONE) {
127
- this._modelComplete();
128
- }
129
- };
130
- /**
131
- * Add a mesh to this model.
132
- * Any mesh that has no parent will be provided with the root mesh as its new parent.
133
- *
134
- * @param mesh the new mesh to add
135
- * @param triggerLoaded should this mesh trigger the onLoaded observable. Used when adding meshes manually.
136
- */
137
- ViewerModel.prototype.addMesh = function (mesh, triggerLoaded) {
138
- if (!mesh.parent) {
139
- mesh.parent = this._pivotMesh;
140
- }
141
- if (mesh.getClassName() !== "InstancedMesh") {
142
- mesh.receiveShadows = !!this.configuration.receiveShadows;
143
- }
144
- this._meshes.push(mesh);
145
- if (triggerLoaded) {
146
- return this.onLoadedObservable.notifyObserversWithPromise(this);
147
- }
148
- return Promise.resolve(this);
149
- };
150
- Object.defineProperty(ViewerModel.prototype, "meshes", {
151
- /**
152
- * get the list of meshes (excluding the root mesh)
153
- */
154
- get: function () {
155
- return this._meshes;
156
- },
157
- enumerable: false,
158
- configurable: true
159
- });
160
- Object.defineProperty(ViewerModel.prototype, "configuration", {
161
- /**
162
- * Get the model's configuration
163
- */
164
- get: function () {
165
- return this._modelConfiguration;
166
- },
167
- /**
168
- * (Re-)set the model's entire configuration
169
- * @param newConfiguration the new configuration to replace the new one
170
- */
171
- set: function (newConfiguration) {
172
- this._modelConfiguration = newConfiguration;
173
- this._configureModel();
174
- },
175
- enumerable: false,
176
- configurable: true
177
- });
178
- /**
179
- * Update the current configuration with new values.
180
- * Configuration will not be overwritten, but merged with the new configuration.
181
- * Priority is to the new configuration
182
- * @param newConfiguration the configuration to be merged into the current configuration;
183
- */
184
- ViewerModel.prototype.updateConfiguration = function (newConfiguration) {
185
- this._modelConfiguration = deepmerge(this._modelConfiguration, newConfiguration);
186
- this._configureModel();
187
- };
188
- ViewerModel.prototype._initAnimations = function () {
189
- var _this = this;
190
- // check if this is not a gltf loader and init the animations
191
- if (this.skeletons.length) {
192
- this.skeletons.forEach(function (skeleton, idx) {
193
- var ag = new AnimationGroup("animation-" + idx, _this._configurationContainer && _this._configurationContainer.scene);
194
- var add = false;
195
- skeleton.getAnimatables().forEach(function (a) {
196
- if (a.animations && a.animations[0]) {
197
- ag.addTargetedAnimation(a.animations[0], a);
198
- add = true;
199
- }
200
- });
201
- if (add) {
202
- _this.addAnimationGroup(ag);
203
- }
204
- });
205
- }
206
- var completeCallback = function () { };
207
- if (this._modelConfiguration.animation) {
208
- if (this._modelConfiguration.animation.playOnce) {
209
- this._animations.forEach(function (a) {
210
- a.playMode = AnimationPlayMode.ONCE;
211
- });
212
- }
213
- if (this._modelConfiguration.animation.autoStart && this._animations.length) {
214
- var animationName_1 = this._modelConfiguration.animation.autoStart === true ? this._animations[0].name : this._modelConfiguration.animation.autoStart;
215
- completeCallback = function () {
216
- _this.playAnimation(animationName_1);
217
- };
218
- }
219
- }
220
- this._enterScene(completeCallback);
221
- };
222
- /**
223
- * Animates the model from the current position to the default position
224
- * @param completeCallback A function to call when the animation has completed
225
- */
226
- ViewerModel.prototype._enterScene = function (completeCallback) {
227
- var _this = this;
228
- var scene = this.rootMesh.getScene();
229
- var previousValue = scene.animationPropertiesOverride.enableBlending;
230
- var callback = function () {
231
- _this.state = ModelState.ENTRYDONE;
232
- scene.animationPropertiesOverride.enableBlending = previousValue;
233
- _this._checkCompleteState();
234
- if (completeCallback) {
235
- completeCallback();
236
- }
237
- };
238
- if (!this._entryAnimation) {
239
- callback();
240
- return;
241
- }
242
- this.rootMesh.setEnabled(true);
243
- // disable blending for the sake of the entry animation;
244
- scene.animationPropertiesOverride.enableBlending = false;
245
- this._applyAnimation(this._entryAnimation, true, callback);
246
- };
247
- // /**
248
- // * Animates the model from the current position to the exit-screen position
249
- // * @param completeCallback A function to call when the animation has completed
250
- // */
251
- // private _exitScene(completeCallback: () => void): void {
252
- // if (!this._exitAnimation) {
253
- // completeCallback();
254
- // return;
255
- // }
256
- // this._applyAnimation(this._exitAnimation, false, completeCallback);
257
- // }
258
- ViewerModel.prototype._modelComplete = function () {
259
- var _this = this;
260
- //reapply material defines to be sure:
261
- var meshes = this._pivotMesh.getChildMeshes(false);
262
- meshes
263
- .filter(function (m) { return m.material; })
264
- .forEach(function (mesh) {
265
- _this._applyModelMaterialConfiguration(mesh.material);
266
- });
267
- this.state = ModelState.COMPLETE;
268
- this.onCompleteObservable.notifyObservers(this);
269
- };
270
- /**
271
- * Add a new animation group to this model.
272
- * @param animationGroup the new animation group to be added
273
- */
274
- ViewerModel.prototype.addAnimationGroup = function (animationGroup) {
275
- this._animations.push(new GroupModelAnimation(animationGroup));
276
- };
277
- /**
278
- * Get the ModelAnimation array
279
- */
280
- ViewerModel.prototype.getAnimations = function () {
281
- return this._animations;
282
- };
283
- /**
284
- * Get the animations' names. Using the names you can play a specific animation.
285
- */
286
- ViewerModel.prototype.getAnimationNames = function () {
287
- return this._animations.map(function (a) { return a.name; });
288
- };
289
- /**
290
- * Get an animation by the provided name. Used mainly when playing n animation.
291
- * @param name the name of the animation to find
292
- */
293
- ViewerModel.prototype._getAnimationByName = function (name) {
294
- // can't use .find, noe available on IE
295
- var filtered = this._animations.filter(function (a) { return a.name === name.trim(); });
296
- // what the next line means - if two animations have the same name, they will not be returned!
297
- if (filtered.length === 1) {
298
- return filtered[0];
299
- }
300
- else {
301
- return null;
302
- }
303
- };
304
- /**
305
- * Choose an initialized animation using its name and start playing it
306
- * @param name the name of the animation to play
307
- * @returns The model aniamtion to be played.
308
- */
309
- ViewerModel.prototype.playAnimation = function (name) {
310
- var animation = this.setCurrentAnimationByName(name);
311
- if (animation) {
312
- animation.start();
313
- }
314
- return animation;
315
- };
316
- ViewerModel.prototype.setCurrentAnimationByName = function (name) {
317
- var animation = this._getAnimationByName(name.trim());
318
- if (animation) {
319
- if (this.currentAnimation && this.currentAnimation.state !== AnimationState.STOPPED) {
320
- this.currentAnimation.stop();
321
- }
322
- this.currentAnimation = animation;
323
- return animation;
324
- }
325
- else {
326
- throw new Error("animation not found - " + name);
327
- }
328
- };
329
- ViewerModel.prototype._configureModel = function () {
330
- var _this = this;
331
- // this can be changed to the meshes that have rootMesh a parent without breaking anything.
332
- var meshesWithNoParent = [this.rootMesh]; //this._meshes.filter(m => m.parent === this.rootMesh);
333
- var updateMeshesWithNoParent = function (variable, value, param) {
334
- meshesWithNoParent.forEach(function (mesh) {
335
- if (param) {
336
- mesh[variable][param] = value;
337
- }
338
- else {
339
- mesh[variable] = value;
340
- }
341
- });
342
- };
343
- var updateXYZ = function (variable, configValues) {
344
- if (configValues.x !== undefined) {
345
- updateMeshesWithNoParent(variable, configValues.x, "x");
346
- }
347
- if (configValues.y !== undefined) {
348
- updateMeshesWithNoParent(variable, configValues.y, "y");
349
- }
350
- if (configValues.z !== undefined) {
351
- updateMeshesWithNoParent(variable, configValues.z, "z");
352
- }
353
- if (configValues.w !== undefined) {
354
- updateMeshesWithNoParent(variable, configValues.w, "w");
355
- }
356
- };
357
- if (this._modelConfiguration.normalize) {
358
- var center = false;
359
- var unitSize = false;
360
- var parentIndex = void 0;
361
- if (this._modelConfiguration.normalize === true) {
362
- center = true;
363
- unitSize = true;
364
- }
365
- else {
366
- center = !!this._modelConfiguration.normalize.center;
367
- unitSize = !!this._modelConfiguration.normalize.unitSize;
368
- parentIndex = this._modelConfiguration.normalize.parentIndex;
369
- }
370
- var meshesToNormalize = [];
371
- if (parentIndex !== undefined) {
372
- meshesToNormalize.push(this._meshes[parentIndex]);
373
- }
374
- else {
375
- meshesToNormalize = this._pivotMesh.getChildMeshes(true).length === 1 ? [this._pivotMesh] : meshesWithNoParent;
376
- }
377
- if (unitSize) {
378
- meshesToNormalize.forEach(function (mesh) {
379
- mesh.normalizeToUnitCube(true);
380
- mesh.computeWorldMatrix(true);
381
- });
382
- }
383
- if (center) {
384
- meshesToNormalize.forEach(function (mesh) {
385
- var boundingInfo = mesh.getHierarchyBoundingVectors(true);
386
- var sizeVec = boundingInfo.max.subtract(boundingInfo.min);
387
- var halfSizeVec = sizeVec.scale(0.5);
388
- var center = boundingInfo.min.add(halfSizeVec);
389
- mesh.position = center.scale(-1);
390
- mesh.position.y += halfSizeVec.y;
391
- // Recompute Info.
392
- mesh.computeWorldMatrix(true);
393
- });
394
- }
395
- }
396
- else {
397
- // if centered, should be done here
398
- }
399
- // position?
400
- if (this._modelConfiguration.position) {
401
- updateXYZ("position", this._modelConfiguration.position);
402
- }
403
- if (this._modelConfiguration.rotation) {
404
- //quaternion?
405
- if (this._modelConfiguration.rotation.w) {
406
- meshesWithNoParent.forEach(function (mesh) {
407
- if (!mesh.rotationQuaternion) {
408
- mesh.rotationQuaternion = new Quaternion();
409
- }
410
- });
411
- updateXYZ("rotationQuaternion", this._modelConfiguration.rotation);
412
- }
413
- else {
414
- updateXYZ("rotation", this._modelConfiguration.rotation);
415
- }
416
- }
417
- if (this._modelConfiguration.rotationOffsetAxis) {
418
- var rotationAxis_1 = new Vector3(this._modelConfiguration.rotationOffsetAxis.x, this._modelConfiguration.rotationOffsetAxis.y, this._modelConfiguration.rotationOffsetAxis.z);
419
- meshesWithNoParent.forEach(function (m) {
420
- if (_this._modelConfiguration.rotationOffsetAngle) {
421
- m.rotate(rotationAxis_1, _this._modelConfiguration.rotationOffsetAngle);
422
- }
423
- });
424
- }
425
- if (this._modelConfiguration.scaling) {
426
- updateXYZ("scaling", this._modelConfiguration.scaling);
427
- }
428
- if (this._modelConfiguration.castShadow) {
429
- this._meshes.forEach(function (mesh) {
430
- Tags.AddTagsTo(mesh, "castShadow");
431
- });
432
- }
433
- var meshes = this._pivotMesh.getChildMeshes(false);
434
- meshes
435
- .filter(function (m) { return m.material; })
436
- .forEach(function (mesh) {
437
- _this._applyModelMaterialConfiguration(mesh.material);
438
- });
439
- if (this._modelConfiguration.entryAnimation) {
440
- this._entryAnimation = this._modelAnimationConfigurationToObject(this._modelConfiguration.entryAnimation);
441
- }
442
- // if (this._modelConfiguration.exitAnimation) {
443
- // this._exitAnimation = this._modelAnimationConfigurationToObject(this._modelConfiguration.exitAnimation);
444
- // }
445
- this.onAfterConfigure.notifyObservers(this);
446
- };
447
- ViewerModel.prototype._modelAnimationConfigurationToObject = function (animConfig) {
448
- var anim = {
449
- time: 0.5,
450
- };
451
- if (animConfig.scaling) {
452
- anim.scaling = Vector3.Zero();
453
- }
454
- if (animConfig.easingFunction !== undefined) {
455
- anim.easingFunction = animConfig.easingFunction;
456
- }
457
- if (animConfig.easingMode !== undefined) {
458
- anim.easingMode = animConfig.easingMode;
459
- }
460
- extendClassWithConfig(anim, animConfig);
461
- return anim;
462
- };
463
- /**
464
- * Apply a material configuration to a material
465
- * @param material Material to apply configuration to
466
- * @hidden
467
- */
468
- ViewerModel.prototype._applyModelMaterialConfiguration = function (material) {
469
- if (!this._modelConfiguration.material) {
470
- return;
471
- }
472
- extendClassWithConfig(material, this._modelConfiguration.material);
473
- if (material instanceof PBRMaterial) {
474
- if (this._modelConfiguration.material.directIntensity !== undefined) {
475
- material.directIntensity = this._modelConfiguration.material.directIntensity;
476
- }
477
- if (this._modelConfiguration.material.emissiveIntensity !== undefined) {
478
- material.emissiveIntensity = this._modelConfiguration.material.emissiveIntensity;
479
- }
480
- if (this._modelConfiguration.material.environmentIntensity !== undefined) {
481
- material.environmentIntensity = this._modelConfiguration.material.environmentIntensity;
482
- }
483
- if (this._modelConfiguration.material.directEnabled !== undefined) {
484
- material.disableLighting = !this._modelConfiguration.material.directEnabled;
485
- }
486
- if (this._configurationContainer && this._configurationContainer.reflectionColor) {
487
- material.reflectionColor = this._configurationContainer.reflectionColor.clone();
488
- }
489
- }
490
- else if (material instanceof MultiMaterial) {
491
- for (var i = 0; i < material.subMaterials.length; i++) {
492
- var subMaterial = material.subMaterials[i];
493
- if (subMaterial) {
494
- this._applyModelMaterialConfiguration(subMaterial);
495
- }
496
- }
497
- }
498
- };
499
- /**
500
- * Start entry/exit animation given an animation configuration
501
- * @param animationConfiguration Entry/Exit animation configuration
502
- * @param isEntry Pass true if the animation is an entry animation
503
- * @param completeCallback Callback to execute when the animation completes
504
- */
505
- ViewerModel.prototype._applyAnimation = function (animationConfiguration, isEntry, completeCallback) {
506
- var animations = [];
507
- //scale
508
- if (animationConfiguration.scaling) {
509
- var scaleStart = isEntry ? animationConfiguration.scaling : new Vector3(1, 1, 1);
510
- var scaleEnd = isEntry ? new Vector3(1, 1, 1) : animationConfiguration.scaling;
511
- if (!scaleStart.equals(scaleEnd)) {
512
- this.rootMesh.scaling = scaleStart;
513
- this._setLinearKeys(this._scaleTransition, this.rootMesh.scaling, scaleEnd, animationConfiguration.time);
514
- animations.push(this._scaleTransition);
515
- }
516
- }
517
- //Start the animation(s)
518
- this.transitionTo(animations, animationConfiguration.time, this._createEasingFunction(animationConfiguration.easingFunction), animationConfiguration.easingMode, function () {
519
- if (completeCallback) {
520
- completeCallback();
521
- }
522
- });
523
- };
524
- /**
525
- * Begin @animations with the specified @easingFunction
526
- * @param animations The BABYLON Animations to begin
527
- * @param duration of transition, in seconds
528
- * @param easingFunction An easing function to apply
529
- * @param easingMode A easing mode to apply to the easingFunction
530
- * @param onAnimationEnd Call back trigger at the end of the animation.
531
- */
532
- ViewerModel.prototype.transitionTo = function (animations, duration, easingFunction, easingMode, // BABYLON.EasingFunction.EASINGMODE_EASEINOUT,
533
- onAnimationEnd) {
534
- if (easingMode === void 0) { easingMode = 2; }
535
- if (easingFunction) {
536
- for (var _i = 0, animations_1 = animations; _i < animations_1.length; _i++) {
537
- var animation = animations_1[_i];
538
- easingFunction.setEasingMode(easingMode);
539
- animation.setEasingFunction(easingFunction);
540
- }
541
- }
542
- //Stop any current animations before starting the new one - merging not yet supported.
543
- this.stopAllAnimations();
544
- this.rootMesh.animations = animations;
545
- if (this.rootMesh.getScene().beginAnimation !== undefined) {
546
- var animatable = this.rootMesh.getScene().beginAnimation(this.rootMesh, 0, this._frameRate * duration, false, 1, function () {
547
- if (onAnimationEnd) {
548
- onAnimationEnd();
549
- }
550
- });
551
- this._animatables.push(animatable);
552
- }
553
- };
554
- /**
555
- * Sets key values on an Animation from first to last frame.
556
- * @param animation The Babylon animation object to set keys on
557
- * @param startValue The value of the first key
558
- * @param endValue The value of the last key
559
- * @param duration The duration of the animation, used to determine the end frame
560
- */
561
- ViewerModel.prototype._setLinearKeys = function (animation, startValue, endValue, duration) {
562
- animation.setKeys([
563
- {
564
- frame: 0,
565
- value: startValue,
566
- },
567
- {
568
- frame: this._frameRate * duration,
569
- value: endValue,
570
- },
571
- ]);
572
- };
573
- /**
574
- * Creates and returns a Babylon easing funtion object based on a string representing the Easing function
575
- * @param easingFunctionID The enum of the easing funtion to create
576
- * @return The newly created Babylon easing function object
577
- */
578
- ViewerModel.prototype._createEasingFunction = function (easingFunctionID) {
579
- var easingFunction;
580
- switch (easingFunctionID) {
581
- case EasingFunction.CircleEase:
582
- easingFunction = new CircleEase();
583
- break;
584
- case EasingFunction.BackEase:
585
- easingFunction = new BackEase(0.3);
586
- break;
587
- case EasingFunction.BounceEase:
588
- easingFunction = new BounceEase();
589
- break;
590
- case EasingFunction.CubicEase:
591
- easingFunction = new CubicEase();
592
- break;
593
- case EasingFunction.ElasticEase:
594
- easingFunction = new ElasticEase();
595
- break;
596
- case EasingFunction.ExponentialEase:
597
- easingFunction = new ExponentialEase();
598
- break;
599
- case EasingFunction.PowerEase:
600
- easingFunction = new PowerEase();
601
- break;
602
- case EasingFunction.QuadraticEase:
603
- easingFunction = new QuadraticEase();
604
- break;
605
- case EasingFunction.QuarticEase:
606
- easingFunction = new QuarticEase();
607
- break;
608
- case EasingFunction.QuinticEase:
609
- easingFunction = new QuinticEase();
610
- break;
611
- case EasingFunction.SineEase:
612
- easingFunction = new SineEase();
613
- break;
614
- default:
615
- Tools.Log("No ease function found");
616
- break;
617
- }
618
- return easingFunction;
619
- };
620
- /**
621
- * Stops and removes all animations that have been applied to the model
622
- */
623
- ViewerModel.prototype.stopAllAnimations = function () {
624
- if (this.rootMesh) {
625
- this.rootMesh.animations = [];
626
- }
627
- if (this.currentAnimation) {
628
- this.currentAnimation.stop();
629
- }
630
- while (this._animatables.length) {
631
- this._animatables[0].onAnimationEnd = null;
632
- this._animatables[0].stop();
633
- this._animatables.shift();
634
- }
635
- };
636
- /**
637
- * Will remove this model from the viewer (but NOT dispose it).
638
- */
639
- ViewerModel.prototype.remove = function () {
640
- this.stopAllAnimations();
641
- // hide it
642
- this.rootMesh.isVisible = false;
643
- if (this._observablesManager) {
644
- this._observablesManager.onModelRemovedObservable.notifyObservers(this);
645
- }
646
- };
647
- /**
648
- * Dispose this model, including all of its associated assets.
649
- */
650
- ViewerModel.prototype.dispose = function () {
651
- this.remove();
652
- this.onAfterConfigure.clear();
653
- this.onLoadedObservable.clear();
654
- this.onLoadErrorObservable.clear();
655
- this.onLoadProgressObservable.clear();
656
- if (this.loader && this.loader.name === "gltf") {
657
- this.loader.dispose();
658
- }
659
- this.particleSystems.forEach(function (ps) { return ps.dispose(); });
660
- this.particleSystems.length = 0;
661
- this.skeletons.forEach(function (s) { return s.dispose(); });
662
- this.skeletons.length = 0;
663
- this._animations.forEach(function (ag) { return ag.dispose(); });
664
- this._animations.length = 0;
665
- this.rootMesh.dispose(false, true);
666
- };
667
- return ViewerModel;
668
- }());
669
- export { ViewerModel };
1
+ import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh.js";
2
+ import { Observable } from "@babylonjs/core/Misc/observable.js";
3
+ import { AnimationGroup } from "@babylonjs/core/Animations/animationGroup.js";
4
+ import { Animation, CircleEase, BackEase, BounceEase, CubicEase, ElasticEase, ExponentialEase, PowerEase, QuadraticEase, QuarticEase, QuinticEase, SineEase, } from "@babylonjs/core/Animations/index.js";
5
+ import { Quaternion, Vector3 } from "@babylonjs/core/Maths/math.vector.js";
6
+ import { Tags } from "@babylonjs/core/Misc/tags.js";
7
+ import { PBRMaterial } from "@babylonjs/core/Materials/PBR/pbrMaterial.js";
8
+ import { MultiMaterial } from "@babylonjs/core/Materials/multiMaterial.js";
9
+ import { Tools } from "@babylonjs/core/Misc/tools.js";
10
+ import { GroupModelAnimation, AnimationPlayMode, EasingFunction, AnimationState } from "./modelAnimation.js";
11
+ import { deepmerge, extendClassWithConfig } from "../helper/index.js";
12
+ /**
13
+ * The current state of the model
14
+ */
15
+ export var ModelState;
16
+ (function (ModelState) {
17
+ ModelState[ModelState["INIT"] = 0] = "INIT";
18
+ ModelState[ModelState["LOADING"] = 1] = "LOADING";
19
+ ModelState[ModelState["LOADED"] = 2] = "LOADED";
20
+ ModelState[ModelState["ENTRY"] = 3] = "ENTRY";
21
+ ModelState[ModelState["ENTRYDONE"] = 4] = "ENTRYDONE";
22
+ ModelState[ModelState["COMPLETE"] = 5] = "COMPLETE";
23
+ ModelState[ModelState["CANCELED"] = 6] = "CANCELED";
24
+ ModelState[ModelState["ERROR"] = 7] = "ERROR";
25
+ })(ModelState || (ModelState = {}));
26
+ /**
27
+ * The viewer model is a container for all assets representing a sngle loaded model.
28
+ */
29
+ var ViewerModel = /** @class */ (function () {
30
+ function ViewerModel(_observablesManager, modelConfiguration, _configurationContainer) {
31
+ var _this = this;
32
+ this._observablesManager = _observablesManager;
33
+ this._configurationContainer = _configurationContainer;
34
+ /**
35
+ * the list of meshes that are a part of this model
36
+ */
37
+ this._meshes = [];
38
+ /**
39
+ * ParticleSystems connected to this model
40
+ */
41
+ this.particleSystems = [];
42
+ /**
43
+ * Skeletons defined in this model
44
+ */
45
+ this.skeletons = [];
46
+ this._loaderDone = false;
47
+ this._animatables = [];
48
+ this._frameRate = 60;
49
+ this._shadowsRenderedAfterLoad = false;
50
+ this.onLoadedObservable = new Observable();
51
+ this.onLoadErrorObservable = new Observable();
52
+ this.onLoadProgressObservable = new Observable();
53
+ this.onCompleteObservable = new Observable();
54
+ this.onAfterConfigure = new Observable();
55
+ this.state = ModelState.INIT;
56
+ var scene = this._configurationContainer && this._configurationContainer.scene;
57
+ this.rootMesh = new AbstractMesh("modelRootMesh", scene);
58
+ this._pivotMesh = new AbstractMesh("pivotMesh", scene);
59
+ this._pivotMesh.parent = this.rootMesh;
60
+ // rotate 180, gltf fun
61
+ this._pivotMesh.rotation.y += Math.PI;
62
+ this._scaleTransition = new Animation("scaleAnimation", "scaling", this._frameRate, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CONSTANT);
63
+ this._animations = [];
64
+ //create a copy of the configuration to make sure it doesn't change even after it is changed in the viewer
65
+ this._modelConfiguration = deepmerge((this._configurationContainer && this._configurationContainer.configuration.model) || {}, modelConfiguration);
66
+ if (this._observablesManager) {
67
+ this._observablesManager.onModelAddedObservable.notifyObservers(this);
68
+ }
69
+ if (this._modelConfiguration.entryAnimation) {
70
+ this.rootMesh.setEnabled(false);
71
+ }
72
+ this.onLoadedObservable.add(function () {
73
+ _this.updateConfiguration(_this._modelConfiguration);
74
+ if (_this._observablesManager) {
75
+ _this._observablesManager.onModelLoadedObservable.notifyObservers(_this);
76
+ }
77
+ _this._initAnimations();
78
+ });
79
+ this.onCompleteObservable.add(function () {
80
+ _this.state = ModelState.COMPLETE;
81
+ });
82
+ }
83
+ Object.defineProperty(ViewerModel.prototype, "shadowsRenderedAfterLoad", {
84
+ get: function () {
85
+ return this._shadowsRenderedAfterLoad;
86
+ },
87
+ set: function (rendered) {
88
+ if (!rendered) {
89
+ throw new Error("can only be enabled");
90
+ }
91
+ else {
92
+ this._shadowsRenderedAfterLoad = rendered;
93
+ }
94
+ },
95
+ enumerable: false,
96
+ configurable: true
97
+ });
98
+ ViewerModel.prototype.getViewerId = function () {
99
+ return this._configurationContainer && this._configurationContainer.viewerId;
100
+ };
101
+ Object.defineProperty(ViewerModel.prototype, "enabled", {
102
+ /**
103
+ * Is this model enabled?
104
+ */
105
+ get: function () {
106
+ return this.rootMesh.isEnabled();
107
+ },
108
+ /**
109
+ * Set whether this model is enabled or not.
110
+ */
111
+ set: function (enable) {
112
+ this.rootMesh.setEnabled(enable);
113
+ },
114
+ enumerable: false,
115
+ configurable: true
116
+ });
117
+ Object.defineProperty(ViewerModel.prototype, "loaderDone", {
118
+ set: function (done) {
119
+ this._loaderDone = done;
120
+ this._checkCompleteState();
121
+ },
122
+ enumerable: false,
123
+ configurable: true
124
+ });
125
+ ViewerModel.prototype._checkCompleteState = function () {
126
+ if (this._loaderDone && this.state === ModelState.ENTRYDONE) {
127
+ this._modelComplete();
128
+ }
129
+ };
130
+ /**
131
+ * Add a mesh to this model.
132
+ * Any mesh that has no parent will be provided with the root mesh as its new parent.
133
+ *
134
+ * @param mesh the new mesh to add
135
+ * @param triggerLoaded should this mesh trigger the onLoaded observable. Used when adding meshes manually.
136
+ */
137
+ ViewerModel.prototype.addMesh = function (mesh, triggerLoaded) {
138
+ if (!mesh.parent) {
139
+ mesh.parent = this._pivotMesh;
140
+ }
141
+ if (mesh.getClassName() !== "InstancedMesh") {
142
+ mesh.receiveShadows = !!this.configuration.receiveShadows;
143
+ }
144
+ this._meshes.push(mesh);
145
+ if (triggerLoaded) {
146
+ return this.onLoadedObservable.notifyObserversWithPromise(this);
147
+ }
148
+ return Promise.resolve(this);
149
+ };
150
+ Object.defineProperty(ViewerModel.prototype, "meshes", {
151
+ /**
152
+ * get the list of meshes (excluding the root mesh)
153
+ */
154
+ get: function () {
155
+ return this._meshes;
156
+ },
157
+ enumerable: false,
158
+ configurable: true
159
+ });
160
+ Object.defineProperty(ViewerModel.prototype, "configuration", {
161
+ /**
162
+ * Get the model's configuration
163
+ */
164
+ get: function () {
165
+ return this._modelConfiguration;
166
+ },
167
+ /**
168
+ * (Re-)set the model's entire configuration
169
+ * @param newConfiguration the new configuration to replace the new one
170
+ */
171
+ set: function (newConfiguration) {
172
+ this._modelConfiguration = newConfiguration;
173
+ this._configureModel();
174
+ },
175
+ enumerable: false,
176
+ configurable: true
177
+ });
178
+ /**
179
+ * Update the current configuration with new values.
180
+ * Configuration will not be overwritten, but merged with the new configuration.
181
+ * Priority is to the new configuration
182
+ * @param newConfiguration the configuration to be merged into the current configuration;
183
+ */
184
+ ViewerModel.prototype.updateConfiguration = function (newConfiguration) {
185
+ this._modelConfiguration = deepmerge(this._modelConfiguration, newConfiguration);
186
+ this._configureModel();
187
+ };
188
+ ViewerModel.prototype._initAnimations = function () {
189
+ var _this = this;
190
+ // check if this is not a gltf loader and init the animations
191
+ if (this.skeletons.length) {
192
+ this.skeletons.forEach(function (skeleton, idx) {
193
+ var ag = new AnimationGroup("animation-" + idx, _this._configurationContainer && _this._configurationContainer.scene);
194
+ var add = false;
195
+ skeleton.getAnimatables().forEach(function (a) {
196
+ if (a.animations && a.animations[0]) {
197
+ ag.addTargetedAnimation(a.animations[0], a);
198
+ add = true;
199
+ }
200
+ });
201
+ if (add) {
202
+ _this.addAnimationGroup(ag);
203
+ }
204
+ });
205
+ }
206
+ var completeCallback = function () { };
207
+ if (this._modelConfiguration.animation) {
208
+ if (this._modelConfiguration.animation.playOnce) {
209
+ this._animations.forEach(function (a) {
210
+ a.playMode = AnimationPlayMode.ONCE;
211
+ });
212
+ }
213
+ if (this._modelConfiguration.animation.autoStart && this._animations.length) {
214
+ var animationName_1 = this._modelConfiguration.animation.autoStart === true ? this._animations[0].name : this._modelConfiguration.animation.autoStart;
215
+ completeCallback = function () {
216
+ _this.playAnimation(animationName_1);
217
+ };
218
+ }
219
+ }
220
+ this._enterScene(completeCallback);
221
+ };
222
+ /**
223
+ * Animates the model from the current position to the default position
224
+ * @param completeCallback A function to call when the animation has completed
225
+ */
226
+ ViewerModel.prototype._enterScene = function (completeCallback) {
227
+ var _this = this;
228
+ var scene = this.rootMesh.getScene();
229
+ var previousValue = scene.animationPropertiesOverride.enableBlending;
230
+ var callback = function () {
231
+ _this.state = ModelState.ENTRYDONE;
232
+ scene.animationPropertiesOverride.enableBlending = previousValue;
233
+ _this._checkCompleteState();
234
+ if (completeCallback) {
235
+ completeCallback();
236
+ }
237
+ };
238
+ if (!this._entryAnimation) {
239
+ callback();
240
+ return;
241
+ }
242
+ this.rootMesh.setEnabled(true);
243
+ // disable blending for the sake of the entry animation;
244
+ scene.animationPropertiesOverride.enableBlending = false;
245
+ this._applyAnimation(this._entryAnimation, true, callback);
246
+ };
247
+ // /**
248
+ // * Animates the model from the current position to the exit-screen position
249
+ // * @param completeCallback A function to call when the animation has completed
250
+ // */
251
+ // private _exitScene(completeCallback: () => void): void {
252
+ // if (!this._exitAnimation) {
253
+ // completeCallback();
254
+ // return;
255
+ // }
256
+ // this._applyAnimation(this._exitAnimation, false, completeCallback);
257
+ // }
258
+ ViewerModel.prototype._modelComplete = function () {
259
+ var _this = this;
260
+ //reapply material defines to be sure:
261
+ var meshes = this._pivotMesh.getChildMeshes(false);
262
+ meshes
263
+ .filter(function (m) { return m.material; })
264
+ .forEach(function (mesh) {
265
+ _this._applyModelMaterialConfiguration(mesh.material);
266
+ });
267
+ this.state = ModelState.COMPLETE;
268
+ this.onCompleteObservable.notifyObservers(this);
269
+ };
270
+ /**
271
+ * Add a new animation group to this model.
272
+ * @param animationGroup the new animation group to be added
273
+ */
274
+ ViewerModel.prototype.addAnimationGroup = function (animationGroup) {
275
+ this._animations.push(new GroupModelAnimation(animationGroup));
276
+ };
277
+ /**
278
+ * Get the ModelAnimation array
279
+ */
280
+ ViewerModel.prototype.getAnimations = function () {
281
+ return this._animations;
282
+ };
283
+ /**
284
+ * Get the animations' names. Using the names you can play a specific animation.
285
+ */
286
+ ViewerModel.prototype.getAnimationNames = function () {
287
+ return this._animations.map(function (a) { return a.name; });
288
+ };
289
+ /**
290
+ * Get an animation by the provided name. Used mainly when playing n animation.
291
+ * @param name the name of the animation to find
292
+ */
293
+ ViewerModel.prototype._getAnimationByName = function (name) {
294
+ // can't use .find, noe available on IE
295
+ var filtered = this._animations.filter(function (a) { return a.name === name.trim(); });
296
+ // what the next line means - if two animations have the same name, they will not be returned!
297
+ if (filtered.length === 1) {
298
+ return filtered[0];
299
+ }
300
+ else {
301
+ return null;
302
+ }
303
+ };
304
+ /**
305
+ * Choose an initialized animation using its name and start playing it
306
+ * @param name the name of the animation to play
307
+ * @returns The model aniamtion to be played.
308
+ */
309
+ ViewerModel.prototype.playAnimation = function (name) {
310
+ var animation = this.setCurrentAnimationByName(name);
311
+ if (animation) {
312
+ animation.start();
313
+ }
314
+ return animation;
315
+ };
316
+ ViewerModel.prototype.setCurrentAnimationByName = function (name) {
317
+ var animation = this._getAnimationByName(name.trim());
318
+ if (animation) {
319
+ if (this.currentAnimation && this.currentAnimation.state !== AnimationState.STOPPED) {
320
+ this.currentAnimation.stop();
321
+ }
322
+ this.currentAnimation = animation;
323
+ return animation;
324
+ }
325
+ else {
326
+ throw new Error("animation not found - " + name);
327
+ }
328
+ };
329
+ ViewerModel.prototype._configureModel = function () {
330
+ var _this = this;
331
+ // this can be changed to the meshes that have rootMesh a parent without breaking anything.
332
+ var meshesWithNoParent = [this.rootMesh]; //this._meshes.filter(m => m.parent === this.rootMesh);
333
+ var updateMeshesWithNoParent = function (variable, value, param) {
334
+ meshesWithNoParent.forEach(function (mesh) {
335
+ if (param) {
336
+ mesh[variable][param] = value;
337
+ }
338
+ else {
339
+ mesh[variable] = value;
340
+ }
341
+ });
342
+ };
343
+ var updateXYZ = function (variable, configValues) {
344
+ if (configValues.x !== undefined) {
345
+ updateMeshesWithNoParent(variable, configValues.x, "x");
346
+ }
347
+ if (configValues.y !== undefined) {
348
+ updateMeshesWithNoParent(variable, configValues.y, "y");
349
+ }
350
+ if (configValues.z !== undefined) {
351
+ updateMeshesWithNoParent(variable, configValues.z, "z");
352
+ }
353
+ if (configValues.w !== undefined) {
354
+ updateMeshesWithNoParent(variable, configValues.w, "w");
355
+ }
356
+ };
357
+ if (this._modelConfiguration.normalize) {
358
+ var center = false;
359
+ var unitSize = false;
360
+ var parentIndex = void 0;
361
+ if (this._modelConfiguration.normalize === true) {
362
+ center = true;
363
+ unitSize = true;
364
+ }
365
+ else {
366
+ center = !!this._modelConfiguration.normalize.center;
367
+ unitSize = !!this._modelConfiguration.normalize.unitSize;
368
+ parentIndex = this._modelConfiguration.normalize.parentIndex;
369
+ }
370
+ var meshesToNormalize = [];
371
+ if (parentIndex !== undefined) {
372
+ meshesToNormalize.push(this._meshes[parentIndex]);
373
+ }
374
+ else {
375
+ meshesToNormalize = this._pivotMesh.getChildMeshes(true).length === 1 ? [this._pivotMesh] : meshesWithNoParent;
376
+ }
377
+ if (unitSize) {
378
+ meshesToNormalize.forEach(function (mesh) {
379
+ mesh.normalizeToUnitCube(true);
380
+ mesh.computeWorldMatrix(true);
381
+ });
382
+ }
383
+ if (center) {
384
+ meshesToNormalize.forEach(function (mesh) {
385
+ var boundingInfo = mesh.getHierarchyBoundingVectors(true);
386
+ var sizeVec = boundingInfo.max.subtract(boundingInfo.min);
387
+ var halfSizeVec = sizeVec.scale(0.5);
388
+ var center = boundingInfo.min.add(halfSizeVec);
389
+ mesh.position = center.scale(-1);
390
+ mesh.position.y += halfSizeVec.y;
391
+ // Recompute Info.
392
+ mesh.computeWorldMatrix(true);
393
+ });
394
+ }
395
+ }
396
+ else {
397
+ // if centered, should be done here
398
+ }
399
+ // position?
400
+ if (this._modelConfiguration.position) {
401
+ updateXYZ("position", this._modelConfiguration.position);
402
+ }
403
+ if (this._modelConfiguration.rotation) {
404
+ //quaternion?
405
+ if (this._modelConfiguration.rotation.w) {
406
+ meshesWithNoParent.forEach(function (mesh) {
407
+ if (!mesh.rotationQuaternion) {
408
+ mesh.rotationQuaternion = new Quaternion();
409
+ }
410
+ });
411
+ updateXYZ("rotationQuaternion", this._modelConfiguration.rotation);
412
+ }
413
+ else {
414
+ updateXYZ("rotation", this._modelConfiguration.rotation);
415
+ }
416
+ }
417
+ if (this._modelConfiguration.rotationOffsetAxis) {
418
+ var rotationAxis_1 = new Vector3(this._modelConfiguration.rotationOffsetAxis.x, this._modelConfiguration.rotationOffsetAxis.y, this._modelConfiguration.rotationOffsetAxis.z);
419
+ meshesWithNoParent.forEach(function (m) {
420
+ if (_this._modelConfiguration.rotationOffsetAngle) {
421
+ m.rotate(rotationAxis_1, _this._modelConfiguration.rotationOffsetAngle);
422
+ }
423
+ });
424
+ }
425
+ if (this._modelConfiguration.scaling) {
426
+ updateXYZ("scaling", this._modelConfiguration.scaling);
427
+ }
428
+ if (this._modelConfiguration.castShadow) {
429
+ this._meshes.forEach(function (mesh) {
430
+ Tags.AddTagsTo(mesh, "castShadow");
431
+ });
432
+ }
433
+ var meshes = this._pivotMesh.getChildMeshes(false);
434
+ meshes
435
+ .filter(function (m) { return m.material; })
436
+ .forEach(function (mesh) {
437
+ _this._applyModelMaterialConfiguration(mesh.material);
438
+ });
439
+ if (this._modelConfiguration.entryAnimation) {
440
+ this._entryAnimation = this._modelAnimationConfigurationToObject(this._modelConfiguration.entryAnimation);
441
+ }
442
+ // if (this._modelConfiguration.exitAnimation) {
443
+ // this._exitAnimation = this._modelAnimationConfigurationToObject(this._modelConfiguration.exitAnimation);
444
+ // }
445
+ this.onAfterConfigure.notifyObservers(this);
446
+ };
447
+ ViewerModel.prototype._modelAnimationConfigurationToObject = function (animConfig) {
448
+ var anim = {
449
+ time: 0.5,
450
+ };
451
+ if (animConfig.scaling) {
452
+ anim.scaling = Vector3.Zero();
453
+ }
454
+ if (animConfig.easingFunction !== undefined) {
455
+ anim.easingFunction = animConfig.easingFunction;
456
+ }
457
+ if (animConfig.easingMode !== undefined) {
458
+ anim.easingMode = animConfig.easingMode;
459
+ }
460
+ extendClassWithConfig(anim, animConfig);
461
+ return anim;
462
+ };
463
+ /**
464
+ * Apply a material configuration to a material
465
+ * @param material Material to apply configuration to
466
+ * @hidden
467
+ */
468
+ ViewerModel.prototype._applyModelMaterialConfiguration = function (material) {
469
+ if (!this._modelConfiguration.material) {
470
+ return;
471
+ }
472
+ extendClassWithConfig(material, this._modelConfiguration.material);
473
+ if (material instanceof PBRMaterial) {
474
+ if (this._modelConfiguration.material.directIntensity !== undefined) {
475
+ material.directIntensity = this._modelConfiguration.material.directIntensity;
476
+ }
477
+ if (this._modelConfiguration.material.emissiveIntensity !== undefined) {
478
+ material.emissiveIntensity = this._modelConfiguration.material.emissiveIntensity;
479
+ }
480
+ if (this._modelConfiguration.material.environmentIntensity !== undefined) {
481
+ material.environmentIntensity = this._modelConfiguration.material.environmentIntensity;
482
+ }
483
+ if (this._modelConfiguration.material.directEnabled !== undefined) {
484
+ material.disableLighting = !this._modelConfiguration.material.directEnabled;
485
+ }
486
+ if (this._configurationContainer && this._configurationContainer.reflectionColor) {
487
+ material.reflectionColor = this._configurationContainer.reflectionColor.clone();
488
+ }
489
+ }
490
+ else if (material instanceof MultiMaterial) {
491
+ for (var i = 0; i < material.subMaterials.length; i++) {
492
+ var subMaterial = material.subMaterials[i];
493
+ if (subMaterial) {
494
+ this._applyModelMaterialConfiguration(subMaterial);
495
+ }
496
+ }
497
+ }
498
+ };
499
+ /**
500
+ * Start entry/exit animation given an animation configuration
501
+ * @param animationConfiguration Entry/Exit animation configuration
502
+ * @param isEntry Pass true if the animation is an entry animation
503
+ * @param completeCallback Callback to execute when the animation completes
504
+ */
505
+ ViewerModel.prototype._applyAnimation = function (animationConfiguration, isEntry, completeCallback) {
506
+ var animations = [];
507
+ //scale
508
+ if (animationConfiguration.scaling) {
509
+ var scaleStart = isEntry ? animationConfiguration.scaling : new Vector3(1, 1, 1);
510
+ var scaleEnd = isEntry ? new Vector3(1, 1, 1) : animationConfiguration.scaling;
511
+ if (!scaleStart.equals(scaleEnd)) {
512
+ this.rootMesh.scaling = scaleStart;
513
+ this._setLinearKeys(this._scaleTransition, this.rootMesh.scaling, scaleEnd, animationConfiguration.time);
514
+ animations.push(this._scaleTransition);
515
+ }
516
+ }
517
+ //Start the animation(s)
518
+ this.transitionTo(animations, animationConfiguration.time, this._createEasingFunction(animationConfiguration.easingFunction), animationConfiguration.easingMode, function () {
519
+ if (completeCallback) {
520
+ completeCallback();
521
+ }
522
+ });
523
+ };
524
+ /**
525
+ * Begin @animations with the specified @easingFunction
526
+ * @param animations The BABYLON Animations to begin
527
+ * @param duration of transition, in seconds
528
+ * @param easingFunction An easing function to apply
529
+ * @param easingMode A easing mode to apply to the easingFunction
530
+ * @param onAnimationEnd Call back trigger at the end of the animation.
531
+ */
532
+ ViewerModel.prototype.transitionTo = function (animations, duration, easingFunction, easingMode, // BABYLON.EasingFunction.EASINGMODE_EASEINOUT,
533
+ onAnimationEnd) {
534
+ if (easingMode === void 0) { easingMode = 2; }
535
+ if (easingFunction) {
536
+ for (var _i = 0, animations_1 = animations; _i < animations_1.length; _i++) {
537
+ var animation = animations_1[_i];
538
+ easingFunction.setEasingMode(easingMode);
539
+ animation.setEasingFunction(easingFunction);
540
+ }
541
+ }
542
+ //Stop any current animations before starting the new one - merging not yet supported.
543
+ this.stopAllAnimations();
544
+ this.rootMesh.animations = animations;
545
+ if (this.rootMesh.getScene().beginAnimation !== undefined) {
546
+ var animatable = this.rootMesh.getScene().beginAnimation(this.rootMesh, 0, this._frameRate * duration, false, 1, function () {
547
+ if (onAnimationEnd) {
548
+ onAnimationEnd();
549
+ }
550
+ });
551
+ this._animatables.push(animatable);
552
+ }
553
+ };
554
+ /**
555
+ * Sets key values on an Animation from first to last frame.
556
+ * @param animation The Babylon animation object to set keys on
557
+ * @param startValue The value of the first key
558
+ * @param endValue The value of the last key
559
+ * @param duration The duration of the animation, used to determine the end frame
560
+ */
561
+ ViewerModel.prototype._setLinearKeys = function (animation, startValue, endValue, duration) {
562
+ animation.setKeys([
563
+ {
564
+ frame: 0,
565
+ value: startValue,
566
+ },
567
+ {
568
+ frame: this._frameRate * duration,
569
+ value: endValue,
570
+ },
571
+ ]);
572
+ };
573
+ /**
574
+ * Creates and returns a Babylon easing funtion object based on a string representing the Easing function
575
+ * @param easingFunctionID The enum of the easing funtion to create
576
+ * @return The newly created Babylon easing function object
577
+ */
578
+ ViewerModel.prototype._createEasingFunction = function (easingFunctionID) {
579
+ var easingFunction;
580
+ switch (easingFunctionID) {
581
+ case EasingFunction.CircleEase:
582
+ easingFunction = new CircleEase();
583
+ break;
584
+ case EasingFunction.BackEase:
585
+ easingFunction = new BackEase(0.3);
586
+ break;
587
+ case EasingFunction.BounceEase:
588
+ easingFunction = new BounceEase();
589
+ break;
590
+ case EasingFunction.CubicEase:
591
+ easingFunction = new CubicEase();
592
+ break;
593
+ case EasingFunction.ElasticEase:
594
+ easingFunction = new ElasticEase();
595
+ break;
596
+ case EasingFunction.ExponentialEase:
597
+ easingFunction = new ExponentialEase();
598
+ break;
599
+ case EasingFunction.PowerEase:
600
+ easingFunction = new PowerEase();
601
+ break;
602
+ case EasingFunction.QuadraticEase:
603
+ easingFunction = new QuadraticEase();
604
+ break;
605
+ case EasingFunction.QuarticEase:
606
+ easingFunction = new QuarticEase();
607
+ break;
608
+ case EasingFunction.QuinticEase:
609
+ easingFunction = new QuinticEase();
610
+ break;
611
+ case EasingFunction.SineEase:
612
+ easingFunction = new SineEase();
613
+ break;
614
+ default:
615
+ Tools.Log("No ease function found");
616
+ break;
617
+ }
618
+ return easingFunction;
619
+ };
620
+ /**
621
+ * Stops and removes all animations that have been applied to the model
622
+ */
623
+ ViewerModel.prototype.stopAllAnimations = function () {
624
+ if (this.rootMesh) {
625
+ this.rootMesh.animations = [];
626
+ }
627
+ if (this.currentAnimation) {
628
+ this.currentAnimation.stop();
629
+ }
630
+ while (this._animatables.length) {
631
+ this._animatables[0].onAnimationEnd = null;
632
+ this._animatables[0].stop();
633
+ this._animatables.shift();
634
+ }
635
+ };
636
+ /**
637
+ * Will remove this model from the viewer (but NOT dispose it).
638
+ */
639
+ ViewerModel.prototype.remove = function () {
640
+ this.stopAllAnimations();
641
+ // hide it
642
+ this.rootMesh.isVisible = false;
643
+ if (this._observablesManager) {
644
+ this._observablesManager.onModelRemovedObservable.notifyObservers(this);
645
+ }
646
+ };
647
+ /**
648
+ * Dispose this model, including all of its associated assets.
649
+ */
650
+ ViewerModel.prototype.dispose = function () {
651
+ this.remove();
652
+ this.onAfterConfigure.clear();
653
+ this.onLoadedObservable.clear();
654
+ this.onLoadErrorObservable.clear();
655
+ this.onLoadProgressObservable.clear();
656
+ if (this.loader && this.loader.name === "gltf") {
657
+ this.loader.dispose();
658
+ }
659
+ this.particleSystems.forEach(function (ps) { return ps.dispose(); });
660
+ this.particleSystems.length = 0;
661
+ this.skeletons.forEach(function (s) { return s.dispose(); });
662
+ this.skeletons.length = 0;
663
+ this._animations.forEach(function (ag) { return ag.dispose(); });
664
+ this._animations.length = 0;
665
+ this.rootMesh.dispose(false, true);
666
+ };
667
+ return ViewerModel;
668
+ }());
669
+ export { ViewerModel };
670
670
  //# sourceMappingURL=viewerModel.js.map