@preference-sl/pref-viewer 2.11.0-beta.12 → 2.11.0-beta.14
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.
- package/package.json +61 -50
- package/src/babylonjs-animation-controller.js +57 -74
- package/src/babylonjs-animation-opening-menu.js +111 -90
- package/src/babylonjs-animation-opening.js +25 -27
- package/src/babylonjs-controller.js +110 -37
- package/src/index.js +15 -911
- package/src/pref-viewer.js +911 -0
- package/src/styles.js +141 -3
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { AdvancedDynamicTexture } from "@babylonjs/gui";
|
|
2
1
|
import OpeningAnimationMenu from "./babylonjs-animation-opening-menu.js";
|
|
3
2
|
|
|
4
3
|
/**
|
|
@@ -19,7 +18,7 @@ import OpeningAnimationMenu from "./babylonjs-animation-opening-menu.js";
|
|
|
19
18
|
* - pause(): Pauses the current animation.
|
|
20
19
|
* - goToOpened(): Moves animation to the fully opened state.
|
|
21
20
|
* - goToClosed(): Moves animation to the fully closed state.
|
|
22
|
-
* - showControls(
|
|
21
|
+
* - showControls(canvas): Displays the animation control menu.
|
|
23
22
|
* - hideControls(): Hides the animation control menu.
|
|
24
23
|
* - isControlsVisible(): Returns true if the control menu is visible for this animation.
|
|
25
24
|
*
|
|
@@ -39,14 +38,6 @@ import OpeningAnimationMenu from "./babylonjs-animation-opening-menu.js";
|
|
|
39
38
|
* - #checkProgress(progress): Applies threshold logic to progress.
|
|
40
39
|
* - #updateControlsSlider(): Updates the slider in the control menu.
|
|
41
40
|
* - #updateControls(): Updates all controls in the menu.
|
|
42
|
-
*
|
|
43
|
-
* Usage Example:
|
|
44
|
-
* const anim = new OpeningAnimation("door", openGroup, closeGroup);
|
|
45
|
-
* anim.playOpen();
|
|
46
|
-
* anim.pause();
|
|
47
|
-
* anim.goToClosed();
|
|
48
|
-
* anim.showControls(adt);
|
|
49
|
-
* anim.hideControls();
|
|
50
41
|
*/
|
|
51
42
|
export default class OpeningAnimation {
|
|
52
43
|
static states = {
|
|
@@ -68,7 +59,6 @@ export default class OpeningAnimation {
|
|
|
68
59
|
#speedRatio = 1.0;
|
|
69
60
|
#loop = false;
|
|
70
61
|
|
|
71
|
-
#advancedDynamicTexture = null;
|
|
72
62
|
#menu = null;
|
|
73
63
|
#progressThreshold = 0.025;
|
|
74
64
|
|
|
@@ -138,13 +128,18 @@ export default class OpeningAnimation {
|
|
|
138
128
|
#goToOpened(useLoop = false) {
|
|
139
129
|
this.#lastPausedFrame = this.#endFrame;
|
|
140
130
|
|
|
141
|
-
if (this.#openAnimation._isStarted && !this.#openAnimation._isPaused)
|
|
131
|
+
if (this.#openAnimation._isStarted && !this.#openAnimation._isPaused){
|
|
142
132
|
this.#openAnimation.pause();
|
|
143
133
|
}
|
|
144
|
-
|
|
134
|
+
this.#openAnimation.goToFrame(this.#endFrame);
|
|
145
135
|
|
|
146
|
-
this.#closeAnimation.
|
|
147
|
-
|
|
136
|
+
if (this.#closeAnimation._isStarted && this.#closeAnimation._isPaused) {
|
|
137
|
+
this.#closeAnimation.goToFrame(this.#startFrame);
|
|
138
|
+
} else {
|
|
139
|
+
this.#closeAnimation.start();
|
|
140
|
+
this.#closeAnimation.pause();
|
|
141
|
+
this.#closeAnimation.goToFrame(this.#startFrame);
|
|
142
|
+
}
|
|
148
143
|
|
|
149
144
|
this.#state = OpeningAnimation.states.opened;
|
|
150
145
|
this.#updateControls();
|
|
@@ -167,8 +162,13 @@ export default class OpeningAnimation {
|
|
|
167
162
|
}
|
|
168
163
|
this.#closeAnimation.goToFrame(this.#endFrame - this.#startFrame);
|
|
169
164
|
|
|
170
|
-
this.#openAnimation.
|
|
171
|
-
|
|
165
|
+
if (this.#openAnimation._isStarted && this.#openAnimation._isPaused) {
|
|
166
|
+
this.#openAnimation.goToFrame(this.#startFrame);
|
|
167
|
+
} else {
|
|
168
|
+
this.#openAnimation.start();
|
|
169
|
+
this.#openAnimation.pause();
|
|
170
|
+
this.#openAnimation.goToFrame(this.#startFrame);
|
|
171
|
+
}
|
|
172
172
|
|
|
173
173
|
this.#state = OpeningAnimation.states.closed;
|
|
174
174
|
this.#updateControls();
|
|
@@ -320,6 +320,7 @@ export default class OpeningAnimation {
|
|
|
320
320
|
if (this.#state === OpeningAnimation.states.opening || this.#state === OpeningAnimation.states.opened) {
|
|
321
321
|
return;
|
|
322
322
|
}
|
|
323
|
+
|
|
323
324
|
if (this.#state === OpeningAnimation.states.closing) {
|
|
324
325
|
this.#lastPausedFrame = this.#endFrame - this.#closeAnimation.getCurrentFrame();
|
|
325
326
|
this.#closeAnimation.pause();
|
|
@@ -344,6 +345,7 @@ export default class OpeningAnimation {
|
|
|
344
345
|
if (this.#state === OpeningAnimation.states.closing || this.#state === OpeningAnimation.states.closed) {
|
|
345
346
|
return;
|
|
346
347
|
}
|
|
348
|
+
|
|
347
349
|
if (this.#state === OpeningAnimation.states.opening) {
|
|
348
350
|
this.#lastPausedFrame = this.#openAnimation.getCurrentFrame();
|
|
349
351
|
this.#openAnimation.pause();
|
|
@@ -397,11 +399,9 @@ export default class OpeningAnimation {
|
|
|
397
399
|
* Displays the animation control menu and sets up callbacks.
|
|
398
400
|
* Synchronizes slider and button states with animation.
|
|
399
401
|
* @public
|
|
400
|
-
* @param {
|
|
402
|
+
* @param {HTMLCanvasElement} canvas - The canvas element for rendering.
|
|
401
403
|
*/
|
|
402
|
-
showControls(
|
|
403
|
-
this.#advancedDynamicTexture = advancedDynamicTexture;
|
|
404
|
-
this.#advancedDynamicTexture.metadata = { animationName: this.name };
|
|
404
|
+
showControls(canvas) {
|
|
405
405
|
const controlCallbacks = {
|
|
406
406
|
onGoToOpened: () => {
|
|
407
407
|
if (this.#state === OpeningAnimation.states.opened) {
|
|
@@ -449,7 +449,7 @@ export default class OpeningAnimation {
|
|
|
449
449
|
this.#menu.animationLoop = this.#loop;
|
|
450
450
|
},
|
|
451
451
|
};
|
|
452
|
-
this.#menu = new OpeningAnimationMenu(this
|
|
452
|
+
this.#menu = new OpeningAnimationMenu(this.name, canvas, this.#state, this.#getProgress(), this.#loop, controlCallbacks);
|
|
453
453
|
|
|
454
454
|
// Attach to Babylon.js scene render loop for real-time updates
|
|
455
455
|
this.#openAnimation._scene.onBeforeRenderObservable.add(this.#updateControlsSlider.bind(this));
|
|
@@ -463,10 +463,9 @@ export default class OpeningAnimation {
|
|
|
463
463
|
if (!this.isControlsVisible()) {
|
|
464
464
|
return;
|
|
465
465
|
}
|
|
466
|
-
// Remove the observer when controls are hidden
|
|
467
466
|
this.#openAnimation._scene.onBeforeRenderObservable.removeCallback(this.#updateControlsSlider.bind(this));
|
|
468
|
-
this.#
|
|
469
|
-
this.#
|
|
467
|
+
this.#menu.dispose();
|
|
468
|
+
this.#menu = null;
|
|
470
469
|
}
|
|
471
470
|
|
|
472
471
|
/**
|
|
@@ -475,7 +474,7 @@ export default class OpeningAnimation {
|
|
|
475
474
|
* @returns {boolean} True if controls are visible for this animation; otherwise, false.
|
|
476
475
|
*/
|
|
477
476
|
isControlsVisible() {
|
|
478
|
-
return !!(this.#
|
|
477
|
+
return !!(this.#menu?.isVisible);
|
|
479
478
|
}
|
|
480
479
|
|
|
481
480
|
/**
|
|
@@ -489,7 +488,6 @@ export default class OpeningAnimation {
|
|
|
489
488
|
* @public
|
|
490
489
|
* @returns {number}
|
|
491
490
|
*/
|
|
492
|
-
|
|
493
491
|
get state() {
|
|
494
492
|
return this.#state;
|
|
495
493
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ArcRotateCamera, AssetContainer, Camera, Color4, DirectionalLight, Engine, HDRCubeTexture, HemisphericLight, IblShadowsRenderPipeline, LoadAssetContainerAsync, MeshBuilder, PointLight, Scene, ShadowGenerator, Tools, Vector3, WebXRDefaultExperience, WebXRFeatureName, WebXRSessionManager } from "@babylonjs/core";
|
|
2
|
-
import { DracoCompression } from "@babylonjs/core/Meshes/Compression/dracoCompression";
|
|
1
|
+
import { ArcRotateCamera, AssetContainer, Camera, Color4, DirectionalLight, Engine, HDRCubeTexture, HemisphericLight, IblShadowsRenderPipeline, LoadAssetContainerAsync, MeshBuilder, PointerEventTypes, PointLight, Scene, ShadowGenerator, Tools, Vector3, WebXRDefaultExperience, WebXRFeatureName, WebXRSessionManager } from "@babylonjs/core";
|
|
2
|
+
import { DracoCompression } from "@babylonjs/core/Meshes/Compression/dracoCompression.js";
|
|
3
3
|
import "@babylonjs/loaders";
|
|
4
|
-
import "@babylonjs/loaders/glTF/2.0/Extensions/KHR_draco_mesh_compression";
|
|
4
|
+
import "@babylonjs/loaders/glTF/2.0/Extensions/KHR_draco_mesh_compression.js";
|
|
5
5
|
import { USDZExportAsync, GLTF2Export } from "@babylonjs/serializers";
|
|
6
6
|
|
|
7
7
|
import GLTFResolver from "./gltf-resolver.js";
|
|
@@ -45,19 +45,37 @@ import BabylonJSAnimationController from "./babylonjs-animation-controller.js";
|
|
|
45
45
|
* - #renderLoop(): Babylon.js render loop callback.
|
|
46
46
|
* - #addStylesToARButton(): Styles AR button.
|
|
47
47
|
* - #createXRExperience(): Initializes WebXR AR experience.
|
|
48
|
-
* - #createCamera()
|
|
49
|
-
* - #
|
|
50
|
-
* - #
|
|
51
|
-
* - #
|
|
52
|
-
* - #
|
|
53
|
-
* - #
|
|
54
|
-
* - #
|
|
55
|
-
* - #
|
|
56
|
-
* - #
|
|
57
|
-
* - #
|
|
58
|
-
* - #
|
|
59
|
-
* - #
|
|
60
|
-
* - #
|
|
48
|
+
* - #createCamera(): Creates and configures the main camera.
|
|
49
|
+
* - #createLights(): Creates and configures scene lights and shadows.
|
|
50
|
+
* - #initializeEnvironmentTexture(): Loads and sets the HDR environment texture.
|
|
51
|
+
* - #initializeIBLShadows(): Sets up IBL shadow pipeline and assigns meshes/materials.
|
|
52
|
+
* - #initializeShadows(): Sets up standard or IBL shadows for meshes.
|
|
53
|
+
* - #setMaxSimultaneousLights(): Updates max simultaneous lights for all materials.
|
|
54
|
+
* - #onPointerObservable(info): Handles pointer events and dispatches to pointer/mouse handlers.
|
|
55
|
+
* - #onPointerUp(event, pickInfo): Handles pointer up events (e.g., right-click for animation menu).
|
|
56
|
+
* - #onPointerMove(event, pickInfo): Handles pointer move events (e.g., mesh highlighting).
|
|
57
|
+
* - #onMouseWheel(event, pickInfo): Handles mouse wheel events for camera zoom.
|
|
58
|
+
* - #onKeyUp(event): Handles keyup events for download dialog and shortcuts.
|
|
59
|
+
* - #enableInteraction(): Adds canvas and scene interaction event listeners.
|
|
60
|
+
* - #disableInteraction(): Removes canvas and scene interaction event listeners.
|
|
61
|
+
* - #disposeEngine(): Disposes engine and releases all resources.
|
|
62
|
+
* - #setOptionsMaterial(optionMaterial): Applies a material option to relevant meshes.
|
|
63
|
+
* - #setOptions_Materials(): Applies all material options from configuration.
|
|
64
|
+
* - #setOptions_Camera(): Applies camera options from configuration.
|
|
65
|
+
* - #findContainerByName(name): Finds a container by its name.
|
|
66
|
+
* - #addContainer(container, updateVisibility): Adds a container to the scene and updates visibility.
|
|
67
|
+
* - #removeContainer(container, updateVisibility): Removes a container from the scene and updates visibility.
|
|
68
|
+
* - #replaceContainer(container, newAssetContainer): Replaces a container in the scene.
|
|
69
|
+
* - #getPrefViewer3DComponent(): Caches and retrieves the parent PREF-VIEWER-3D element.
|
|
70
|
+
* - #getPrefViewerComponent(): Caches and retrieves the parent PREF-VIEWER element.
|
|
71
|
+
* - #updateVisibilityAttributeInComponents(name, isVisible): Updates parent visibility attributes.
|
|
72
|
+
* - #setVisibilityOfWallAndFloorInModel(show): Controls wall/floor mesh visibility.
|
|
73
|
+
* - #stopRender(): Stops the Babylon.js render loop.
|
|
74
|
+
* - #startRender(): Starts the Babylon.js render loop.
|
|
75
|
+
* - #loadAssetContainer(container): Loads an asset container asynchronously.
|
|
76
|
+
* - #loadContainers(): Loads all asset containers and adds them to the scene.
|
|
77
|
+
* - #addDateToName(name): Appends the current date/time to a name string.
|
|
78
|
+
* - #downloadZip(files, name, comment, addDateInName): Generates and downloads a ZIP file.
|
|
61
79
|
* - #openDownloadDialog(): Opens the modal download dialog.
|
|
62
80
|
*
|
|
63
81
|
* Notes:
|
|
@@ -401,13 +419,34 @@ export default class BabylonJSController {
|
|
|
401
419
|
}
|
|
402
420
|
|
|
403
421
|
/**
|
|
404
|
-
*
|
|
422
|
+
* Handles pointer events observed on the Babylon.js scene.
|
|
423
|
+
* @private
|
|
424
|
+
* @param {PointerInfo} info - The pointer event information from Babylon.js.
|
|
425
|
+
* @returns {void}
|
|
426
|
+
*/
|
|
427
|
+
#onPointerObservable(info) {
|
|
428
|
+
const pickInfo = this.#scene.pick(this.#scene.pointerX, this.#scene.pointerY);
|
|
429
|
+
if (info.type === PointerEventTypes.POINTERUP) {
|
|
430
|
+
this.#onPointerUp(info.event, pickInfo);
|
|
431
|
+
} else if (info.type === PointerEventTypes.POINTERMOVE) {
|
|
432
|
+
this.#onPointerMove(info.event, pickInfo);
|
|
433
|
+
} else if (info.type === PointerEventTypes.POINTERWHEEL) {
|
|
434
|
+
this.#onMouseWheel(info.event, pickInfo);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Sets up interaction handlers for the Babylon.js canvas and scene.
|
|
405
440
|
* @private
|
|
406
441
|
* @returns {void}
|
|
407
442
|
*/
|
|
408
443
|
#enableInteraction() {
|
|
409
|
-
this.#canvas
|
|
410
|
-
|
|
444
|
+
if (this.#canvas) {
|
|
445
|
+
this.#canvas.addEventListener("keyup", this.#onKeyUp.bind(this));
|
|
446
|
+
}
|
|
447
|
+
if (this.#scene) {
|
|
448
|
+
this.#scene.onPointerObservable.add(this.#onPointerObservable.bind(this));
|
|
449
|
+
}
|
|
411
450
|
}
|
|
412
451
|
|
|
413
452
|
/**
|
|
@@ -416,8 +455,12 @@ export default class BabylonJSController {
|
|
|
416
455
|
* @returns {void}
|
|
417
456
|
*/
|
|
418
457
|
#disableInteraction() {
|
|
419
|
-
this.#canvas
|
|
420
|
-
|
|
458
|
+
if (this.#canvas) {
|
|
459
|
+
this.#canvas.removeEventListener("keyup", this.#onKeyUp.bind(this));
|
|
460
|
+
}
|
|
461
|
+
if (this.#scene !== null) {
|
|
462
|
+
this.#scene.onPointerObservable.removeCallback(this.#onPointerObservable.bind(this));
|
|
463
|
+
}
|
|
421
464
|
}
|
|
422
465
|
|
|
423
466
|
/**
|
|
@@ -436,18 +479,37 @@ export default class BabylonJSController {
|
|
|
436
479
|
this.#XRExperience = null;
|
|
437
480
|
}
|
|
438
481
|
|
|
482
|
+
/**
|
|
483
|
+
* Handles keyup events on the Babylon.js canvas for triggering model and scene downloads.
|
|
484
|
+
* @private
|
|
485
|
+
* @param {KeyboardEvent} event - The keyup event.
|
|
486
|
+
* @returns {void}
|
|
487
|
+
*/
|
|
488
|
+
#onKeyUp(event) {
|
|
489
|
+
// CTRL + ALT + letter
|
|
490
|
+
if (event.ctrlKey && event.altKey && event.key !== undefined) {
|
|
491
|
+
switch (event.key.toLowerCase()) {
|
|
492
|
+
case "d":
|
|
493
|
+
this.#openDownloadDialog();
|
|
494
|
+
break;
|
|
495
|
+
default:
|
|
496
|
+
break;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
439
501
|
/**
|
|
440
502
|
* Handles mouse wheel events on the Babylon.js canvas for zooming the camera.
|
|
441
503
|
* @private
|
|
442
504
|
* @param {WheelEvent} event - The mouse wheel event.
|
|
443
|
-
* @
|
|
505
|
+
* @param {Object} pickInfo - The result of the scene pick operation (not used in this method).
|
|
506
|
+
* @returns {void|false} Returns false if there is no active camera; otherwise, void.
|
|
444
507
|
*/
|
|
445
|
-
#onMouseWheel(event) {
|
|
446
|
-
if (!this.#scene
|
|
508
|
+
#onMouseWheel(event, pickInfo) {
|
|
509
|
+
if (!this.#scene?.activeCamera) {
|
|
447
510
|
return false;
|
|
448
511
|
}
|
|
449
|
-
//
|
|
450
|
-
//this.#camera.target = pick.hit ? pick.pickedPoint.clone() : this.#camera.target;
|
|
512
|
+
//this.#scene.activeCamera.target = pickInfo.hit ? pickInfo.pickedPoint.clone() : this.#scene.activeCamera.target;
|
|
451
513
|
if (!this.#scene.activeCamera.metadata?.locked) {
|
|
452
514
|
this.#scene.activeCamera.inertialRadiusOffset -= event.deltaY * this.#scene.activeCamera.wheelPrecision * 0.001;
|
|
453
515
|
}
|
|
@@ -455,24 +517,35 @@ export default class BabylonJSController {
|
|
|
455
517
|
}
|
|
456
518
|
|
|
457
519
|
/**
|
|
458
|
-
* Handles
|
|
520
|
+
* Handles pointer up events on the Babylon.js scene.
|
|
459
521
|
* @private
|
|
460
|
-
* @param {
|
|
522
|
+
* @param {PointerEvent} event - The pointer up event.
|
|
523
|
+
* @param {PickInfo} pickInfo - The result of the scene pick operation.
|
|
461
524
|
* @returns {void}
|
|
462
525
|
*/
|
|
463
|
-
#
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
break;
|
|
470
|
-
default:
|
|
471
|
-
break;
|
|
526
|
+
#onPointerUp(event, pickInfo) {
|
|
527
|
+
if (this.#babylonJSAnimationController) {
|
|
528
|
+
this.#babylonJSAnimationController.hideMenu();
|
|
529
|
+
// Right click for showing animation menu
|
|
530
|
+
if (event.button === 2) {
|
|
531
|
+
this.#babylonJSAnimationController.showMenu(pickInfo);
|
|
472
532
|
}
|
|
473
533
|
}
|
|
474
534
|
}
|
|
475
535
|
|
|
536
|
+
/**
|
|
537
|
+
* Handles pointer move events on the Babylon.js scene.
|
|
538
|
+
* @private
|
|
539
|
+
* @param {PointerEvent} event - The pointer move event.
|
|
540
|
+
* @param {PickInfo} pickInfo - The result of the scene pick operation.
|
|
541
|
+
* @returns {void}
|
|
542
|
+
*/
|
|
543
|
+
#onPointerMove(event, pickInfo) {
|
|
544
|
+
if (this.#babylonJSAnimationController) {
|
|
545
|
+
this.#babylonJSAnimationController.hightlightMeshes(pickInfo);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
476
549
|
/**
|
|
477
550
|
* Applies material options from the configuration to the relevant meshes.
|
|
478
551
|
* @private
|