@benjos/create-boilerplate 1.5.1 → 1.5.6
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/README.md +0 -4
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +18 -0
- package/dist/constants.js.map +1 -0
- package/dist/constants.test.d.ts +2 -0
- package/dist/constants.test.d.ts.map +1 -0
- package/dist/constants.test.js +30 -0
- package/dist/constants.test.js.map +1 -0
- package/dist/createProject.d.ts +2 -0
- package/dist/createProject.d.ts.map +1 -0
- package/dist/createProject.js +52 -0
- package/dist/createProject.js.map +1 -0
- package/dist/createProject.test.d.ts +2 -0
- package/dist/createProject.test.d.ts.map +1 -0
- package/dist/createProject.test.js +85 -0
- package/dist/createProject.test.js.map +1 -0
- package/dist/index.js +16 -69
- package/dist/index.js.map +1 -1
- package/dist/prompts.d.ts +4 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +26 -0
- package/dist/prompts.js.map +1 -0
- package/dist/prompts.test.d.ts +2 -0
- package/dist/prompts.test.d.ts.map +1 -0
- package/dist/prompts.test.js +50 -0
- package/dist/prompts.test.js.map +1 -0
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +10 -8
- package/template-vanilla/package-lock.json +1000 -1476
- package/template-vanilla/package.json +11 -11
- package/template-vanilla/src/experiences/Experience.ts +1 -1
- package/template-vanilla/src/experiences/constants/experiences/ViewId.ts +2 -7
- package/template-vanilla/src/experiences/engines/threes/app/MainThreeApp.ts +8 -5
- package/template-vanilla/src/experiences/managers/LoaderManager.ts +4 -5
- package/template-vanilla/src/experiences/materials/threes/loaders/LoaderMaterial.ts +8 -5
- package/template-vanilla/src/experiences/views/threes/bases/ThreeViewBase.ts +1 -1
- package/template-vanilla/src/experiences/views/threes/{worlds/components/actors/bases → bases/components}/ThreeAnimatedModelBase.ts +3 -3
- package/template-vanilla/src/experiences/views/threes/{worlds/components/actors/bases → bases/components}/ThreeModelBase.ts +3 -3
- package/template-vanilla/src/experiences/views/threes/loaders/components/TemplateLoaderThreeActor.ts +1 -1
- package/template-vanilla/src/experiences/views/threes/worlds/World2ThreeView.ts +5 -5
- package/template-vanilla/src/experiences/views/threes/worlds/WorldThreeView.ts +5 -5
- package/template-vanilla/src/experiences/views/threes/worlds/components/Environment.ts +1 -1
- package/template-vanilla/src/experiences/views/threes/worlds/components/{actors/TemplateFont.ts → TemplateFont.ts} +3 -3
- package/template-vanilla/src/experiences/views/threes/worlds/components/{actors/TemplateMesh.ts → TemplateMesh.ts} +3 -3
- package/template-vanilla/src/experiences/views/threes/worlds/components/{actors/TemplateMesh2.ts → TemplateMesh2.ts} +3 -3
- package/template-vanilla/src/experiences/views/threes/worlds/components/{actors/TemplateModel.ts → TemplateModel.ts} +4 -4
- package/template-vanilla/tsconfig.json +3 -3
- package/template-vue/eslint.config.js +130 -0
- package/template-vue/index.html +17 -0
- package/{template-react → template-vue}/package-lock.json +1260 -2121
- package/template-vue/package.json +43 -0
- package/template-vue/readme.md +34 -0
- package/template-vue/src/experiences/Experience.ts +27 -0
- package/template-vue/src/experiences/cameras/threes/DebugThreeCameraController.ts +55 -0
- package/template-vue/src/experiences/cameras/threes/LoaderThreeCameraController.ts +25 -0
- package/template-vue/src/experiences/cameras/threes/MainThreeCameraController.ts +24 -0
- package/template-vue/src/experiences/cameras/threes/bases/ThreeCameraControllerBase.ts +90 -0
- package/template-vue/src/experiences/commands/InitCommand.ts +50 -0
- package/template-vue/src/experiences/constants/experiences/AnimationId.ts +3 -0
- package/template-vue/src/experiences/constants/experiences/AssetId.ts +8 -0
- package/template-vue/src/experiences/constants/experiences/CameraId.ts +7 -0
- package/template-vue/src/experiences/constants/experiences/DebugGuiTitle.ts +6 -0
- package/template-vue/src/experiences/constants/experiences/Object3dId.ts +3 -0
- package/template-vue/src/experiences/constants/experiences/ViewId.ts +11 -0
- package/template-vue/src/experiences/constants/experiences/ViewType.ts +6 -0
- package/template-vue/src/experiences/engines/threes/MainThree.ts +11 -0
- package/template-vue/src/experiences/engines/threes/app/LoaderThreeApp.ts +49 -0
- package/template-vue/src/experiences/engines/threes/app/MainThreeApp.ts +112 -0
- package/template-vue/src/experiences/engines/threes/app/bases/ThreeAppBase.ts +128 -0
- package/template-vue/src/experiences/engines/vues/MainVue.vue +9 -0
- package/template-vue/src/experiences/managers/DebugManager.ts +87 -0
- package/template-vue/src/experiences/managers/LoaderManager.ts +176 -0
- package/template-vue/src/experiences/managers/threes/ThreeAssetsManager.ts +263 -0
- package/template-vue/src/experiences/managers/threes/ThreeCameraControllerManager.ts +46 -0
- package/template-vue/src/experiences/managers/threes/ThreeRaycasterManager.ts +21 -0
- package/template-vue/src/experiences/materials/threes/loaders/LoaderMaterial.ts +47 -0
- package/template-vue/src/experiences/renderers/threes/LoaderRenderer.ts +18 -0
- package/template-vue/src/experiences/renderers/threes/Renderer.ts +71 -0
- package/template-vue/src/experiences/renderers/threes/bases/WebGLRendererBase.ts +29 -0
- package/template-vue/src/experiences/shaders/threes/loaders/LoaderFragmentShader.glsl +8 -0
- package/template-vue/src/experiences/shaders/threes/loaders/LoaderVertexShader.glsl +3 -0
- package/template-vue/src/experiences/styles/abstracts/_import.scss +5 -0
- package/template-vue/src/experiences/styles/abstracts/functions.scss +3 -0
- package/template-vue/src/experiences/styles/abstracts/variables.scss +7 -0
- package/template-vue/src/experiences/styles/commons/fonts.scss +10 -0
- package/template-vue/src/experiences/styles/commons/main.scss +59 -0
- package/template-vue/src/experiences/styles/commons/texts.scss +1 -0
- package/template-vue/src/experiences/styles/style.scss +7 -0
- package/template-vue/src/experiences/styles/views/loader.scss +70 -0
- package/template-vue/src/experiences/types/assetTypes.ts +8 -0
- package/template-vue/src/experiences/types/cameraTypes.ts +37 -0
- package/template-vue/src/experiences/types/global.d.ts +9 -0
- package/template-vue/src/experiences/types/shaders.d.ts +4 -0
- package/template-vue/src/experiences/views/threes/bases/ThreeViewBase.ts +49 -0
- package/template-vue/src/experiences/views/threes/bases/components/ThreeActorBase.ts +44 -0
- package/template-vue/src/experiences/views/threes/bases/components/ThreeAnimatedModelBase.ts +63 -0
- package/template-vue/src/experiences/views/threes/bases/components/ThreeModelBase.ts +48 -0
- package/template-vue/src/experiences/views/threes/loaders/LoaderThreeView.ts +28 -0
- package/template-vue/src/experiences/views/threes/loaders/components/TemplateLoaderThreeActor.ts +49 -0
- package/template-vue/src/experiences/views/threes/worlds/World2ThreeView.ts +35 -0
- package/template-vue/src/experiences/views/threes/worlds/WorldThreeView.ts +35 -0
- package/template-vue/src/experiences/views/threes/worlds/components/Environment.ts +89 -0
- package/template-vue/src/experiences/views/threes/worlds/components/TemplateFont.ts +58 -0
- package/template-vue/src/experiences/views/threes/worlds/components/TemplateMesh.ts +65 -0
- package/template-vue/src/experiences/views/threes/worlds/components/TemplateMesh2.ts +71 -0
- package/template-vue/src/experiences/views/threes/worlds/components/TemplateModel.ts +33 -0
- package/template-vue/src/experiences/views/vues/LoaderView.vue +55 -0
- package/template-vue/src/main.ts +7 -0
- package/template-vue/tsconfig.app.json +8 -0
- package/template-vue/tsconfig.json +7 -0
- package/template-vue/tsconfig.node.json +16 -0
- package/template-vue/vite.config.ts +16 -0
- package/template-react/eslint.config.js +0 -23
- package/template-react/index.html +0 -17
- package/template-react/package.json +0 -46
- package/template-react/readme.md +0 -31
- package/template-react/src/App.css +0 -42
- package/template-react/src/App.tsx +0 -10
- package/template-react/src/index.css +0 -68
- package/template-react/src/main.tsx +0 -10
- package/template-react/tsconfig.app.json +0 -34
- package/template-react/tsconfig.json +0 -7
- package/template-react/tsconfig.node.json +0 -26
- package/template-react/vite.config.ts +0 -29
- /package/template-vanilla/src/experiences/views/threes/{worlds/components/actors/bases → bases/components}/ThreeActorBase.ts +0 -0
- /package/{template-react → template-vue}/.prettierignore +0 -0
- /package/{template-react → template-vue}/.prettierrc +0 -0
- /package/{template-react → template-vue}/public/assets/fonts/LICENSE +0 -0
- /package/{template-react → template-vue}/public/assets/fonts/template.typeface.json +0 -0
- /package/{template-react → template-vue}/public/assets/hdrs/template.hdr +0 -0
- /package/{template-react → template-vue}/public/assets/icons/benjosLogoBlack.svg +0 -0
- /package/{template-react → template-vue}/public/assets/loaders/draco/README.md +0 -0
- /package/{template-react → template-vue}/public/assets/loaders/draco/draco_decoder.js +0 -0
- /package/{template-react → template-vue}/public/assets/loaders/draco/draco_decoder.wasm +0 -0
- /package/{template-react → template-vue}/public/assets/loaders/draco/draco_encoder.js +0 -0
- /package/{template-react → template-vue}/public/assets/loaders/draco/draco_wasm_wrapper.js +0 -0
- /package/{template-react → template-vue}/public/assets/loaders/draco/gltf/draco_decoder.js +0 -0
- /package/{template-react → template-vue}/public/assets/loaders/draco/gltf/draco_decoder.wasm +0 -0
- /package/{template-react → template-vue}/public/assets/loaders/draco/gltf/draco_encoder.js +0 -0
- /package/{template-react → template-vue}/public/assets/loaders/draco/gltf/draco_wasm_wrapper.js +0 -0
- /package/{template-react → template-vue}/public/assets/models/template.glb +0 -0
- /package/{template-react → template-vue}/public/assets/textures/template.jpg +0 -0
- /package/{template-react/assets_source/.gitkeep → template-vue/src/experiences/styles/abstracts/mixins.scss} +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { DomResizeManager, TickerManager } from '@benjos/cookware';
|
|
2
|
+
import { Scene } from 'three';
|
|
3
|
+
import ThreeCameraControllerBase from '../../../../cameras/threes/bases/ThreeCameraControllerBase';
|
|
4
|
+
import { ViewId } from '../../../../constants/experiences/ViewId';
|
|
5
|
+
import LoaderManager from '../../../../managers/LoaderManager';
|
|
6
|
+
import WebGLRendererBase from '../../../../renderers/threes/bases/WebGLRendererBase';
|
|
7
|
+
import ThreeViewBase from '../../../../views/threes/bases/ThreeViewBase';
|
|
8
|
+
|
|
9
|
+
export default abstract class ThreeAppBase {
|
|
10
|
+
declare protected _domElementContainer: HTMLElement;
|
|
11
|
+
declare protected _scene: Scene;
|
|
12
|
+
declare protected _cameraController: ThreeCameraControllerBase;
|
|
13
|
+
declare protected _renderer: WebGLRendererBase;
|
|
14
|
+
protected readonly _views: ThreeViewBase[];
|
|
15
|
+
protected readonly _viewBuilder: Map<ViewId, new () => ThreeViewBase>;
|
|
16
|
+
declare protected _currentView: ThreeViewBase;
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
this._views = [];
|
|
20
|
+
this._viewBuilder = new Map();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public init(): void {
|
|
24
|
+
TickerManager.add(this._update);
|
|
25
|
+
|
|
26
|
+
this._setDomElementContainer();
|
|
27
|
+
this._generateScenes();
|
|
28
|
+
this._generateCameras();
|
|
29
|
+
this._generateRenderers();
|
|
30
|
+
this._declareViews();
|
|
31
|
+
|
|
32
|
+
this._onResize();
|
|
33
|
+
DomResizeManager.onResize.add(this._onResize);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
protected _setDomElementContainer(): void {
|
|
37
|
+
//
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
protected _generateScenes(): void {
|
|
41
|
+
//
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
protected _generateCameras(): void {
|
|
45
|
+
//
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
protected _generateRenderers(): void {
|
|
49
|
+
//
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
protected _declareViews(): void {
|
|
53
|
+
//
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
protected _generateView(viewId: ViewId): ThreeViewBase {
|
|
57
|
+
const ViewConstructor = this._viewBuilder.get(viewId);
|
|
58
|
+
if (!ViewConstructor) {
|
|
59
|
+
throw new Error(`View constructor for ID '${viewId}' not found.`);
|
|
60
|
+
}
|
|
61
|
+
const view = new ViewConstructor();
|
|
62
|
+
this._views.push(view);
|
|
63
|
+
return view;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public async setCurrentView(viewId: ViewId): Promise<void> {
|
|
67
|
+
if (this._currentView?.viewId === viewId) return;
|
|
68
|
+
|
|
69
|
+
let view = this._getViewById(viewId);
|
|
70
|
+
if (!view) view = this._generateView(viewId);
|
|
71
|
+
|
|
72
|
+
view.declareAssets();
|
|
73
|
+
|
|
74
|
+
await LoaderManager.loadAssetsWithTransition(this._swapView.bind(this, view));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private readonly _swapView = (view: ThreeViewBase): void => {
|
|
78
|
+
if (this._currentView) this._removeOldView(this._currentView);
|
|
79
|
+
this._currentView = view;
|
|
80
|
+
view.init();
|
|
81
|
+
this.scene.add(this._currentView);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private _getViewById(viewId: ViewId): ThreeViewBase | null {
|
|
85
|
+
let view;
|
|
86
|
+
for (const v of this._views) {
|
|
87
|
+
if (v.viewId === viewId) view = v;
|
|
88
|
+
}
|
|
89
|
+
return view || null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private _removeOldView(view: ThreeViewBase): void {
|
|
93
|
+
this.scene.remove(view);
|
|
94
|
+
view.dispose();
|
|
95
|
+
view.reset();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
protected _onResize = (): void => {
|
|
99
|
+
this._renderer.domElement.width = window.innerWidth;
|
|
100
|
+
this._renderer.domElement.height = window.innerHeight;
|
|
101
|
+
|
|
102
|
+
this._cameraController.resize();
|
|
103
|
+
this._renderer.resize();
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
private _update = (dt: number): void => {
|
|
107
|
+
this._cameraController.update(dt);
|
|
108
|
+
this._currentView?.update(dt);
|
|
109
|
+
this._renderer.update(dt);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
//#region Getters
|
|
113
|
+
//
|
|
114
|
+
public get domElementContainer(): HTMLElement {
|
|
115
|
+
return this._domElementContainer;
|
|
116
|
+
}
|
|
117
|
+
public get scene(): Scene {
|
|
118
|
+
return this._scene;
|
|
119
|
+
}
|
|
120
|
+
public get renderer(): WebGLRendererBase {
|
|
121
|
+
return this._renderer;
|
|
122
|
+
}
|
|
123
|
+
public get cameraController(): ThreeCameraControllerBase {
|
|
124
|
+
return this._cameraController;
|
|
125
|
+
}
|
|
126
|
+
//
|
|
127
|
+
//#endregion
|
|
128
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { DomKeyboardManager } from '@benjos/cookware';
|
|
2
|
+
import { KeyboardConstant } from '@benjos/spices';
|
|
3
|
+
import GUI from 'lil-gui';
|
|
4
|
+
import { ThreePerf } from 'three-perf';
|
|
5
|
+
import { DebugGuiTitle } from '../constants/experiences/DebugGuiTitle';
|
|
6
|
+
import MainThreeApp from '../engines/threes/app/MainThreeApp';
|
|
7
|
+
|
|
8
|
+
class DebugManager {
|
|
9
|
+
private static readonly _IS_ACTIVE_STRING: string = '#debug';
|
|
10
|
+
private static readonly _GUI_WIDTH: number = 300;
|
|
11
|
+
private static readonly _GUI_TITLE: string = 'Debug Panel';
|
|
12
|
+
private static readonly _THREE_PERF_ANCHOR_X: 'left' | 'right' = 'left';
|
|
13
|
+
private static readonly _THREE_PERF_ANCHOR_Y: 'top' | 'bottom' = 'bottom';
|
|
14
|
+
private static readonly _TOGGLE_HIDDEN_KEYS: string[] = [
|
|
15
|
+
KeyboardConstant.CODES.SHIFT_LEFT,
|
|
16
|
+
KeyboardConstant.CODES.KEY_H,
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
declare private _gui: GUI;
|
|
20
|
+
declare private _threePerf: ThreePerf;
|
|
21
|
+
|
|
22
|
+
public init(): void {
|
|
23
|
+
if (this.isActive) {
|
|
24
|
+
this._initGui();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private _initGui(): void {
|
|
29
|
+
this._gui = new GUI({
|
|
30
|
+
width: DebugManager._GUI_WIDTH,
|
|
31
|
+
title: DebugManager._GUI_TITLE,
|
|
32
|
+
closeFolders: true,
|
|
33
|
+
});
|
|
34
|
+
this._gui.close();
|
|
35
|
+
DomKeyboardManager.onKeyDown.remove(this._onKeyDown);
|
|
36
|
+
DomKeyboardManager.onKeyDown.add(this._onKeyDown);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private _initThreePerf = (): void => {
|
|
40
|
+
this._threePerf = new ThreePerf({
|
|
41
|
+
anchorX: DebugManager._THREE_PERF_ANCHOR_X,
|
|
42
|
+
anchorY: DebugManager._THREE_PERF_ANCHOR_Y,
|
|
43
|
+
domElement: document.body,
|
|
44
|
+
renderer: MainThreeApp.renderer,
|
|
45
|
+
showGraph: false,
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
private _addGuiFolder(title: DebugGuiTitle): GUI {
|
|
50
|
+
return this._gui.addFolder(title);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public getGuiFolder(title: DebugGuiTitle): GUI {
|
|
54
|
+
let gui = this._gui.folders.find(gui => gui._title === title);
|
|
55
|
+
if (!gui) gui = this._addGuiFolder(title);
|
|
56
|
+
return gui;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public beginThreePerf(): void {
|
|
60
|
+
if (!this._threePerf) this._initThreePerf();
|
|
61
|
+
this._threePerf.begin();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public endThreePerf(): void {
|
|
65
|
+
this._threePerf.end();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private readonly _onKeyDown = (_e: KeyboardEvent): void => {
|
|
69
|
+
if (DomKeyboardManager.areAllKeysDown(DebugManager._TOGGLE_HIDDEN_KEYS)) {
|
|
70
|
+
this._gui.show(this._gui._hidden);
|
|
71
|
+
this._threePerf.visible = !this._threePerf.visible;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
//#region Getters
|
|
76
|
+
//
|
|
77
|
+
public get isActive(): boolean {
|
|
78
|
+
return window.location.hash === DebugManager._IS_ACTIVE_STRING;
|
|
79
|
+
}
|
|
80
|
+
public get gui(): GUI {
|
|
81
|
+
return this._gui;
|
|
82
|
+
}
|
|
83
|
+
//
|
|
84
|
+
//#endregion
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export default new DebugManager();
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { Action, TickerManager } from '@benjos/cookware';
|
|
2
|
+
import ThreeAssetsManager from './threes/ThreeAssetsManager';
|
|
3
|
+
|
|
4
|
+
class LoaderManager {
|
|
5
|
+
private static readonly _MIN_LOAD_DURATION: number = 0.5;
|
|
6
|
+
|
|
7
|
+
private _totalSize = 0;
|
|
8
|
+
private _loadedSize = 0;
|
|
9
|
+
private _progress = 0;
|
|
10
|
+
private _isTransitioning = false;
|
|
11
|
+
private _elapsed = 0;
|
|
12
|
+
private _hasAssetsToLoad = false;
|
|
13
|
+
private _assetsFinished = false;
|
|
14
|
+
private _transitionResolves: (() => void)[] = [];
|
|
15
|
+
private _showTransition: (() => Promise<void>) | null = null;
|
|
16
|
+
private _hideTransition: (() => Promise<void>) | null = null;
|
|
17
|
+
|
|
18
|
+
public readonly onBeginLoad = new Action();
|
|
19
|
+
public readonly onProgress = new Action();
|
|
20
|
+
public readonly onFinishLoad = new Action();
|
|
21
|
+
public readonly onShow = new Action();
|
|
22
|
+
public readonly onHide = new Action();
|
|
23
|
+
|
|
24
|
+
public init(): void {
|
|
25
|
+
this._addCallbacks();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public setShowTransition(callback: () => Promise<void>): void {
|
|
29
|
+
this._showTransition = callback;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public setHideTransition(callback: () => Promise<void>): void {
|
|
33
|
+
this._hideTransition = callback;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private _addCallbacks(): void {
|
|
37
|
+
this._removeCallbacks();
|
|
38
|
+
ThreeAssetsManager.onLoad.add(this._onLoad);
|
|
39
|
+
ThreeAssetsManager.onProgress.add(this._onAssetProgress);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private _removeCallbacks(): void {
|
|
43
|
+
ThreeAssetsManager.onLoad.remove(this._onLoad);
|
|
44
|
+
ThreeAssetsManager.onProgress.remove(this._onAssetProgress);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private _beginLoad = (): void => {
|
|
48
|
+
ThreeAssetsManager.beginLoad();
|
|
49
|
+
this.onBeginLoad.execute();
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
private _finishLoad = (): void => {
|
|
53
|
+
ThreeAssetsManager.finishLoad();
|
|
54
|
+
this.onFinishLoad.execute();
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
private async _showLoader(): Promise<void> {
|
|
58
|
+
this.onShow.execute();
|
|
59
|
+
if (this._showTransition) await this._showTransition();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private async _hideLoader(): Promise<void> {
|
|
63
|
+
this.onHide.execute();
|
|
64
|
+
if (this._hideTransition) await this._hideTransition();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private readonly _onAssetsFinish = (): void => {
|
|
68
|
+
this._assetsFinished = true;
|
|
69
|
+
this.onFinishLoad.remove(this._onAssetsFinish);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
private readonly _onTransitionTick = (dt: number): void => {
|
|
73
|
+
this._elapsed += dt;
|
|
74
|
+
const timerProgress = Math.min(this._elapsed / LoaderManager._MIN_LOAD_DURATION, 1);
|
|
75
|
+
|
|
76
|
+
let assetProgress = 1;
|
|
77
|
+
if (this._hasAssetsToLoad && !this._assetsFinished) {
|
|
78
|
+
assetProgress = this._totalSize > 0 ? Math.min(this._loadedSize / this._totalSize, 1) : 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
this._progress = Math.min(timerProgress, assetProgress);
|
|
82
|
+
this.onProgress.execute();
|
|
83
|
+
|
|
84
|
+
if (timerProgress >= 1 && this._assetsFinished) {
|
|
85
|
+
this._progress = 1;
|
|
86
|
+
this.onProgress.execute();
|
|
87
|
+
TickerManager.remove(this._onTransitionTick);
|
|
88
|
+
this._transitionResolves.forEach((resolve) => resolve());
|
|
89
|
+
this._transitionResolves.length = 0;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
public async loadAssetsWithTransition(onReady?: () => void | Promise<void>): Promise<void> {
|
|
94
|
+
const isNested = this._isTransitioning;
|
|
95
|
+
if (!isNested) {
|
|
96
|
+
this._isTransitioning = true;
|
|
97
|
+
await this._showLoader();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this._hasAssetsToLoad = !this._checkIsFinished();
|
|
101
|
+
|
|
102
|
+
if (this._hasAssetsToLoad || !isNested) {
|
|
103
|
+
this._progress = 0;
|
|
104
|
+
this._elapsed = 0;
|
|
105
|
+
this._assetsFinished = !this._hasAssetsToLoad;
|
|
106
|
+
this.onProgress.execute();
|
|
107
|
+
|
|
108
|
+
if (this._hasAssetsToLoad) {
|
|
109
|
+
this.onFinishLoad.add(this._onAssetsFinish);
|
|
110
|
+
this._beginLoad();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
await new Promise<void>((resolve) => {
|
|
114
|
+
this._transitionResolves.push(resolve);
|
|
115
|
+
TickerManager.add(this._onTransitionTick);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (onReady) await onReady();
|
|
120
|
+
|
|
121
|
+
if (!isNested) {
|
|
122
|
+
this._isTransitioning = false;
|
|
123
|
+
await this._hideLoader();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private _onLoad = (): void => {
|
|
128
|
+
this._refreshSizes();
|
|
129
|
+
if (this._checkIsFinished()) this._finishLoad();
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
private _checkIsFinished = (): boolean => {
|
|
133
|
+
if (!ThreeAssetsManager.isLoaded) return false;
|
|
134
|
+
return true;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
private _onAssetProgress = (): void => {
|
|
138
|
+
this._refreshSizes();
|
|
139
|
+
this._progress = this._totalSize > 0 ? Math.min(this._loadedSize / this._totalSize, 1) : 0;
|
|
140
|
+
this.onProgress.execute();
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
private _refreshSizes = (): void => {
|
|
144
|
+
this._refreshTotalSize();
|
|
145
|
+
this._refreshLoadedSize();
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
private _refreshTotalSize = (): void => {
|
|
149
|
+
this._totalSize = 0;
|
|
150
|
+
this._totalSize += ThreeAssetsManager.totalSize;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
private _refreshLoadedSize = (): void => {
|
|
154
|
+
this._loadedSize = 0;
|
|
155
|
+
this._loadedSize += ThreeAssetsManager.loadedSize;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
//#region Getters
|
|
159
|
+
//
|
|
160
|
+
public get isLoaded(): boolean {
|
|
161
|
+
return this._checkIsFinished();
|
|
162
|
+
}
|
|
163
|
+
public get progress(): number {
|
|
164
|
+
return this._progress;
|
|
165
|
+
}
|
|
166
|
+
public get totalSize(): number {
|
|
167
|
+
return this._totalSize;
|
|
168
|
+
}
|
|
169
|
+
public get loadedSize(): number {
|
|
170
|
+
return this._loadedSize;
|
|
171
|
+
}
|
|
172
|
+
//
|
|
173
|
+
//#endregion
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export default new LoaderManager();
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { Action, AssetUtils } from '@benjos/cookware';
|
|
2
|
+
import {
|
|
3
|
+
DataTexture,
|
|
4
|
+
EquirectangularRefractionMapping,
|
|
5
|
+
LinearSRGBColorSpace,
|
|
6
|
+
RepeatWrapping,
|
|
7
|
+
Texture,
|
|
8
|
+
TextureLoader,
|
|
9
|
+
type ColorSpace,
|
|
10
|
+
type Mapping,
|
|
11
|
+
type Wrapping,
|
|
12
|
+
} from 'three';
|
|
13
|
+
import { DRACOLoader, Font, FontLoader, GLTFLoader, HDRLoader, type GLTF } from 'three/examples/jsm/Addons.js';
|
|
14
|
+
import type { AssetId } from '../../constants/experiences/AssetId';
|
|
15
|
+
import { AssetType } from '../../types/assetTypes';
|
|
16
|
+
|
|
17
|
+
export interface ThreeAssetToLoad {
|
|
18
|
+
id: AssetId;
|
|
19
|
+
type: AssetType;
|
|
20
|
+
path: string;
|
|
21
|
+
option?: ThreeAssetOption;
|
|
22
|
+
loadedSize: number;
|
|
23
|
+
totalSize: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ThreeAssetOption {}
|
|
27
|
+
|
|
28
|
+
export interface ThreeTextureOption extends ThreeAssetOption {
|
|
29
|
+
colorSpace?: ColorSpace;
|
|
30
|
+
wrapping?: Wrapping;
|
|
31
|
+
repeatX?: number;
|
|
32
|
+
repeatY?: number;
|
|
33
|
+
centerX?: number;
|
|
34
|
+
centerY?: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface ThreeHDROption extends ThreeAssetOption {
|
|
38
|
+
mapping?: Mapping;
|
|
39
|
+
colorSpace?: ColorSpace;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ThreeModelOption extends ThreeAssetOption {}
|
|
43
|
+
|
|
44
|
+
export interface ThreeFontOption extends ThreeAssetOption {}
|
|
45
|
+
|
|
46
|
+
class ThreeAssetsManager {
|
|
47
|
+
private static readonly _DRACO_LOADER_PATH: string = 'loaders/draco/';
|
|
48
|
+
private static readonly _DEFAULT_TEXTURE_OPTION_COLOR_SPACE: ColorSpace = LinearSRGBColorSpace;
|
|
49
|
+
private static readonly _DEFAULT_TEXTURE_OPTION_WRAPPING: Wrapping = RepeatWrapping;
|
|
50
|
+
private static readonly _DEFAULT_TEXTURE_OPTION_REPEAT_X: number = 1;
|
|
51
|
+
private static readonly _DEFAULT_TEXTURE_OPTION_REPEAT_Y: number = 1;
|
|
52
|
+
private static readonly _DEFAULT_TEXTURE_OPTION_CENTER_X: number = 0.5;
|
|
53
|
+
private static readonly _DEFAULT_TEXTURE_OPTION_CENTER_Y: number = 0.5;
|
|
54
|
+
private static readonly _DEFAULT_HDR_MAPPING: Mapping = EquirectangularRefractionMapping;
|
|
55
|
+
private static readonly _DEFAULT_HDR_COLOR_SPACE: ColorSpace = LinearSRGBColorSpace;
|
|
56
|
+
private static readonly _DEFAULT_LOADED_SIZE: number = 0;
|
|
57
|
+
private static readonly _DEFAULT_TOTAL_SIZE: number = -1;
|
|
58
|
+
private static readonly _DEFAULT_TEXTURE_TOTAL_SIZE: number = 1;
|
|
59
|
+
|
|
60
|
+
private readonly _assets: Map<string, Texture | DataTexture | GLTF | Font> = new Map<
|
|
61
|
+
string,
|
|
62
|
+
Texture | GLTF | Font
|
|
63
|
+
>();
|
|
64
|
+
private readonly _toLoadList: ThreeAssetToLoad[] = [];
|
|
65
|
+
private _expectedAssetsCount = 0;
|
|
66
|
+
|
|
67
|
+
private readonly _textureLoader = new TextureLoader();
|
|
68
|
+
private readonly _hdrLoader = new HDRLoader();
|
|
69
|
+
private readonly _gltfLoader = new GLTFLoader();
|
|
70
|
+
private readonly _dracoLoader = new DRACOLoader();
|
|
71
|
+
private readonly _fontLoader = new FontLoader();
|
|
72
|
+
|
|
73
|
+
public readonly onLoad = new Action();
|
|
74
|
+
public readonly onProgress = new Action();
|
|
75
|
+
|
|
76
|
+
public init(): void {
|
|
77
|
+
this._dracoLoader.setDecoderPath(AssetUtils.GetPath(ThreeAssetsManager._DRACO_LOADER_PATH));
|
|
78
|
+
this._gltfLoader.setDRACOLoader(this._dracoLoader);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public addTexture(id: AssetId, path: string, textureOption?: ThreeTextureOption): void {
|
|
82
|
+
this._toLoadList.push({
|
|
83
|
+
id,
|
|
84
|
+
type: AssetType.TEXTURE,
|
|
85
|
+
path,
|
|
86
|
+
option: textureOption,
|
|
87
|
+
loadedSize: ThreeAssetsManager._DEFAULT_LOADED_SIZE,
|
|
88
|
+
totalSize: ThreeAssetsManager._DEFAULT_TEXTURE_TOTAL_SIZE,
|
|
89
|
+
});
|
|
90
|
+
this._expectedAssetsCount++;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public addHDR(id: AssetId, path: string, hdrOption?: ThreeHDROption): void {
|
|
94
|
+
this._toLoadList.push({
|
|
95
|
+
id,
|
|
96
|
+
type: AssetType.HDR,
|
|
97
|
+
path,
|
|
98
|
+
option: hdrOption,
|
|
99
|
+
loadedSize: ThreeAssetsManager._DEFAULT_LOADED_SIZE,
|
|
100
|
+
totalSize: ThreeAssetsManager._DEFAULT_TOTAL_SIZE,
|
|
101
|
+
});
|
|
102
|
+
this._expectedAssetsCount++;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
public addModel(id: AssetId, path: string, modelOption?: ThreeModelOption): void {
|
|
106
|
+
this._toLoadList.push({
|
|
107
|
+
id,
|
|
108
|
+
type: AssetType.MODEL,
|
|
109
|
+
path,
|
|
110
|
+
option: modelOption,
|
|
111
|
+
loadedSize: ThreeAssetsManager._DEFAULT_LOADED_SIZE,
|
|
112
|
+
totalSize: ThreeAssetsManager._DEFAULT_TOTAL_SIZE,
|
|
113
|
+
});
|
|
114
|
+
this._expectedAssetsCount++;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
public addFont(id: AssetId, path: string, fontOption?: ThreeFontOption): void {
|
|
118
|
+
this._toLoadList.push({
|
|
119
|
+
id,
|
|
120
|
+
type: AssetType.FONT,
|
|
121
|
+
path,
|
|
122
|
+
option: fontOption,
|
|
123
|
+
loadedSize: ThreeAssetsManager._DEFAULT_LOADED_SIZE,
|
|
124
|
+
totalSize: ThreeAssetsManager._DEFAULT_TOTAL_SIZE,
|
|
125
|
+
});
|
|
126
|
+
this._expectedAssetsCount++;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
public beginLoad(): void {
|
|
130
|
+
if (this._toLoadList.length === 0) {
|
|
131
|
+
this.onLoad.execute();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
for (const asset of this._toLoadList) {
|
|
135
|
+
if (asset.type === AssetType.TEXTURE) this._loadTexture(asset);
|
|
136
|
+
else if (asset.type === AssetType.HDR) this._loadHDR(asset);
|
|
137
|
+
else if (asset.type === AssetType.MODEL) this._loadModel(asset);
|
|
138
|
+
else if (asset.type === AssetType.FONT) this._loadFont(asset);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public finishLoad(): void {
|
|
143
|
+
this._toLoadList.length = 0;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
private _loadTexture(asset: ThreeAssetToLoad): void {
|
|
147
|
+
const option = asset.option as ThreeTextureOption | undefined;
|
|
148
|
+
this._textureLoader.load(
|
|
149
|
+
asset.path,
|
|
150
|
+
(texture) => {
|
|
151
|
+
texture.colorSpace = option?.colorSpace ?? ThreeAssetsManager._DEFAULT_TEXTURE_OPTION_COLOR_SPACE;
|
|
152
|
+
texture.wrapS = texture.wrapT = option?.wrapping ?? ThreeAssetsManager._DEFAULT_TEXTURE_OPTION_WRAPPING;
|
|
153
|
+
texture.repeat.set(
|
|
154
|
+
option?.repeatX ?? ThreeAssetsManager._DEFAULT_TEXTURE_OPTION_REPEAT_X,
|
|
155
|
+
option?.repeatY ?? ThreeAssetsManager._DEFAULT_TEXTURE_OPTION_REPEAT_Y
|
|
156
|
+
);
|
|
157
|
+
texture.center.set(
|
|
158
|
+
option?.centerX ?? ThreeAssetsManager._DEFAULT_TEXTURE_OPTION_CENTER_X,
|
|
159
|
+
option?.centerY ?? ThreeAssetsManager._DEFAULT_TEXTURE_OPTION_CENTER_Y
|
|
160
|
+
);
|
|
161
|
+
asset.loadedSize = asset.totalSize;
|
|
162
|
+
this._onLoad(asset.id, texture);
|
|
163
|
+
},
|
|
164
|
+
(event: ProgressEvent) => this._onProgress(asset, event),
|
|
165
|
+
() => this._onError(AssetType.TEXTURE, asset.id, asset.path)
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private _loadHDR(asset: ThreeAssetToLoad): void {
|
|
170
|
+
const option = asset.option as ThreeHDROption | undefined;
|
|
171
|
+
this._hdrLoader.load(
|
|
172
|
+
asset.path,
|
|
173
|
+
(dataTexture) => {
|
|
174
|
+
dataTexture.mapping = option?.mapping ?? ThreeAssetsManager._DEFAULT_HDR_MAPPING;
|
|
175
|
+
dataTexture.colorSpace = option?.colorSpace ?? ThreeAssetsManager._DEFAULT_HDR_COLOR_SPACE;
|
|
176
|
+
this._onLoad(asset.id, dataTexture);
|
|
177
|
+
},
|
|
178
|
+
(event: ProgressEvent) => this._onProgress(asset, event),
|
|
179
|
+
() => this._onError(AssetType.HDR, asset.id, asset.path)
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
private _loadModel(asset: ThreeAssetToLoad): void {
|
|
184
|
+
this._gltfLoader.load(
|
|
185
|
+
asset.path,
|
|
186
|
+
(model) => this._onLoad(asset.id, model),
|
|
187
|
+
(event: ProgressEvent) => this._onProgress(asset, event),
|
|
188
|
+
() => this._onError(AssetType.MODEL, asset.id, asset.path)
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
private _loadFont(asset: ThreeAssetToLoad): void {
|
|
193
|
+
this._fontLoader.load(
|
|
194
|
+
asset.path,
|
|
195
|
+
(font) => this._onLoad(asset.id, font),
|
|
196
|
+
(event: ProgressEvent) => this._onProgress(asset, event),
|
|
197
|
+
() => this._onError(AssetType.FONT, asset.id, asset.path)
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
private _onLoad(id: AssetId, asset: Texture | GLTF | Font): void {
|
|
202
|
+
this._assets.set(id, asset);
|
|
203
|
+
this.onLoad.execute();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
private _onProgress(asset: ThreeAssetToLoad, event: ProgressEvent): void {
|
|
207
|
+
if (asset.totalSize === ThreeAssetsManager._DEFAULT_TOTAL_SIZE) asset.totalSize = event.total;
|
|
208
|
+
asset.loadedSize = event.loaded;
|
|
209
|
+
this.onProgress.execute();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
private _onError(type: AssetType, id: AssetId, path: string): void {
|
|
213
|
+
throw new Error(`ThreeAssetsManager: Failed to load ${type} with id '${id}' from path '${path}'`);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
public getTexture(id: AssetId): Texture {
|
|
217
|
+
const asset = this._assets.get(id);
|
|
218
|
+
if (!asset) throw new Error(`Texture with id '${id}' not found!`);
|
|
219
|
+
return asset as Texture;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
public getHDR(id: AssetId): DataTexture {
|
|
223
|
+
const asset = this._assets.get(id);
|
|
224
|
+
if (!asset) throw new Error(`HDR with id '${id}' not found!`);
|
|
225
|
+
return asset as DataTexture;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
public getModel(id: AssetId): GLTF {
|
|
229
|
+
const asset = this._assets.get(id);
|
|
230
|
+
if (!asset) throw new Error(`Model with id '${id}' not found!`);
|
|
231
|
+
return asset as GLTF;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
public getFont(id: AssetId): Font {
|
|
235
|
+
const asset = this._assets.get(id);
|
|
236
|
+
if (!asset) throw new Error(`Font with id '${id}' not found!`);
|
|
237
|
+
return asset as Font;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
//#region Getters
|
|
241
|
+
//
|
|
242
|
+
public get isLoaded(): boolean {
|
|
243
|
+
return this._assets.size === this._expectedAssetsCount;
|
|
244
|
+
}
|
|
245
|
+
public get totalSize(): number {
|
|
246
|
+
let totalSize = 0;
|
|
247
|
+
for (const asset of this._toLoadList) {
|
|
248
|
+
totalSize += asset.totalSize;
|
|
249
|
+
}
|
|
250
|
+
return totalSize;
|
|
251
|
+
}
|
|
252
|
+
public get loadedSize(): number {
|
|
253
|
+
let loadedSize = 0;
|
|
254
|
+
for (const asset of this._toLoadList) {
|
|
255
|
+
loadedSize += asset.loadedSize;
|
|
256
|
+
}
|
|
257
|
+
return loadedSize;
|
|
258
|
+
}
|
|
259
|
+
//
|
|
260
|
+
//#endregion
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export default new ThreeAssetsManager();
|