@littlecarlito/blorktools 0.50.4 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +69 -0
- package/package.json +13 -7
- package/src/asset_debugger/axis-indicator/axis-indicator.css +6 -0
- package/src/asset_debugger/axis-indicator/axis-indicator.html +20 -0
- package/src/asset_debugger/axis-indicator/axis-indicator.js +822 -0
- package/src/asset_debugger/debugger-scene/debugger-scene.css +142 -0
- package/src/asset_debugger/debugger-scene/debugger-scene.html +80 -0
- package/src/asset_debugger/debugger-scene/debugger-scene.js +791 -0
- package/src/asset_debugger/header/header.css +73 -0
- package/src/asset_debugger/header/header.html +24 -0
- package/src/asset_debugger/header/header.js +224 -0
- package/src/asset_debugger/index.html +76 -0
- package/src/asset_debugger/landing-page/landing-page.css +396 -0
- package/src/asset_debugger/landing-page/landing-page.html +81 -0
- package/src/asset_debugger/landing-page/landing-page.js +611 -0
- package/src/asset_debugger/loading-splash/loading-splash.css +195 -0
- package/src/asset_debugger/loading-splash/loading-splash.html +22 -0
- package/src/asset_debugger/loading-splash/loading-splash.js +59 -0
- package/src/asset_debugger/loading-splash/preview-loading-splash.js +66 -0
- package/src/asset_debugger/main.css +14 -0
- package/src/asset_debugger/modals/examples-modal/examples-modal.css +41 -0
- package/src/asset_debugger/modals/examples-modal/examples-modal.html +18 -0
- package/src/asset_debugger/modals/examples-modal/examples-modal.js +111 -0
- package/src/asset_debugger/modals/examples-modal/examples.js +125 -0
- package/src/asset_debugger/modals/html-editor-modal/html-editor-modal.css +452 -0
- package/src/asset_debugger/modals/html-editor-modal/html-editor-modal.html +87 -0
- package/src/asset_debugger/modals/html-editor-modal/html-editor-modal.js +675 -0
- package/src/asset_debugger/modals/mesh-info-modal/mesh-info-modal.css +219 -0
- package/src/asset_debugger/modals/mesh-info-modal/mesh-info-modal.html +20 -0
- package/src/asset_debugger/modals/mesh-info-modal/mesh-info-modal.js +548 -0
- package/src/asset_debugger/modals/settings-modal/settings-modal.css +103 -0
- package/src/asset_debugger/modals/settings-modal/settings-modal.html +158 -0
- package/src/asset_debugger/modals/settings-modal/settings-modal.js +475 -0
- package/src/asset_debugger/panels/asset-panel/asset-panel.css +263 -0
- package/src/asset_debugger/panels/asset-panel/asset-panel.html +123 -0
- package/src/asset_debugger/panels/asset-panel/asset-panel.js +136 -0
- package/src/asset_debugger/panels/asset-panel/atlas-heading/atlas-heading.css +94 -0
- package/src/asset_debugger/panels/asset-panel/atlas-heading/atlas-heading.js +312 -0
- package/src/asset_debugger/panels/asset-panel/mesh-heading/mesh-heading.css +129 -0
- package/src/asset_debugger/panels/asset-panel/mesh-heading/mesh-heading.js +486 -0
- package/src/asset_debugger/panels/asset-panel/rig-heading/rig-heading.css +545 -0
- package/src/asset_debugger/panels/asset-panel/rig-heading/rig-heading.js +538 -0
- package/src/asset_debugger/panels/asset-panel/uv-heading/uv-heading.css +70 -0
- package/src/asset_debugger/panels/asset-panel/uv-heading/uv-heading.js +586 -0
- package/src/asset_debugger/panels/world-panel/world-panel.css +364 -0
- package/src/asset_debugger/panels/world-panel/world-panel.html +173 -0
- package/src/asset_debugger/panels/world-panel/world-panel.js +1891 -0
- package/src/asset_debugger/router.js +190 -0
- package/src/asset_debugger/util/animation/playback/animation-playback-controller.js +150 -0
- package/src/asset_debugger/util/animation/playback/animation-preview-controller.js +316 -0
- package/src/asset_debugger/util/animation/playback/css3d-bounce-controller.js +400 -0
- package/src/asset_debugger/util/animation/playback/css3d-reversal-controller.js +821 -0
- package/src/asset_debugger/util/animation/render/css3d-prerender-controller.js +696 -0
- package/src/asset_debugger/util/animation/render/debug-texture-factory.js +0 -0
- package/src/asset_debugger/util/animation/render/iframe2texture-render-controller.js +199 -0
- package/src/asset_debugger/util/animation/render/image2texture-prerender-controller.js +461 -0
- package/src/asset_debugger/util/animation/render/pbr-material-factory.js +82 -0
- package/src/asset_debugger/util/common.css +280 -0
- package/src/asset_debugger/util/data/animation-classifier.js +323 -0
- package/src/asset_debugger/util/data/duplicate-handler.js +20 -0
- package/src/asset_debugger/util/data/glb-buffer-manager.js +407 -0
- package/src/asset_debugger/util/data/glb-classifier.js +290 -0
- package/src/asset_debugger/util/data/html-formatter.js +76 -0
- package/src/asset_debugger/util/data/html-linter.js +276 -0
- package/src/asset_debugger/util/data/localstorage-manager.js +265 -0
- package/src/asset_debugger/util/data/mesh-html-manager.js +295 -0
- package/src/asset_debugger/util/data/string-serder.js +303 -0
- package/src/asset_debugger/util/data/texture-classifier.js +663 -0
- package/src/asset_debugger/util/data/upload/background-file-handler.js +292 -0
- package/src/asset_debugger/util/data/upload/dropzone-preview-controller.js +396 -0
- package/src/asset_debugger/util/data/upload/file-upload-manager.js +495 -0
- package/src/asset_debugger/util/data/upload/glb-file-handler.js +36 -0
- package/src/asset_debugger/util/data/upload/glb-preview-controller.js +317 -0
- package/src/asset_debugger/util/data/upload/lighting-file-handler.js +194 -0
- package/src/asset_debugger/util/data/upload/model-file-manager.js +104 -0
- package/src/asset_debugger/util/data/upload/texture-file-handler.js +166 -0
- package/src/asset_debugger/util/data/upload/zip-handler.js +686 -0
- package/src/asset_debugger/util/loaders/html2canvas-loader.js +107 -0
- package/src/asset_debugger/util/rig/bone-kinematics.js +403 -0
- package/src/asset_debugger/util/rig/rig-constraint-manager.js +618 -0
- package/src/asset_debugger/util/rig/rig-controller.js +612 -0
- package/src/asset_debugger/util/rig/rig-factory.js +628 -0
- package/src/asset_debugger/util/rig/rig-handle-factory.js +46 -0
- package/src/asset_debugger/util/rig/rig-label-factory.js +441 -0
- package/src/asset_debugger/util/rig/rig-mouse-handler.js +377 -0
- package/src/asset_debugger/util/rig/rig-state-manager.js +175 -0
- package/src/asset_debugger/util/rig/rig-tooltip-manager.js +267 -0
- package/src/asset_debugger/util/rig/rig-ui-factory.js +700 -0
- package/src/asset_debugger/util/scene/background-manager.js +284 -0
- package/src/asset_debugger/util/scene/camera-controller.js +243 -0
- package/src/asset_debugger/util/scene/css3d-debug-controller.js +406 -0
- package/src/asset_debugger/util/scene/css3d-frame-factory.js +113 -0
- package/src/asset_debugger/util/scene/css3d-scene-manager.js +529 -0
- package/src/asset_debugger/util/scene/glb-controller.js +208 -0
- package/src/asset_debugger/util/scene/lighting-manager.js +690 -0
- package/src/asset_debugger/util/scene/threejs-model-manager.js +437 -0
- package/src/asset_debugger/util/scene/threejs-preview-manager.js +207 -0
- package/src/asset_debugger/util/scene/threejs-preview-setup.js +478 -0
- package/src/asset_debugger/util/scene/threejs-scene-controller.js +286 -0
- package/src/asset_debugger/util/scene/ui-manager.js +107 -0
- package/src/asset_debugger/util/state/animation-state.js +128 -0
- package/src/asset_debugger/util/state/css3d-state.js +83 -0
- package/src/asset_debugger/util/state/glb-preview-state.js +31 -0
- package/src/asset_debugger/util/state/log-util.js +197 -0
- package/src/asset_debugger/util/state/scene-state.js +452 -0
- package/src/asset_debugger/util/state/threejs-state.js +54 -0
- package/src/asset_debugger/util/workers/lighting-worker.js +61 -0
- package/src/asset_debugger/util/workers/model-worker.js +109 -0
- package/src/asset_debugger/util/workers/texture-worker.js +54 -0
- package/src/asset_debugger/util/workers/worker-manager.js +212 -0
- package/src/asset_debugger/widgets/mesh-info-widget.js +280 -0
- package/src/index.html +261 -0
- package/src/index.js +8 -0
- package/vite.config.js +66 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Texture Debugger - Scene Management Module
|
|
3
|
+
*
|
|
4
|
+
* This module handles Three.js scene setup, rendering, and animation.
|
|
5
|
+
*/
|
|
6
|
+
import * as THREE from 'three';
|
|
7
|
+
import { getState, updateState } from '../state/scene-state.js';
|
|
8
|
+
import { updateRigAnimation } from '../rig/rig-controller.js';
|
|
9
|
+
import { addLighting, setupEnvironmentLighting } from './lighting-manager.js';
|
|
10
|
+
import { createControls, updateControls, setControlsTarget } from './camera-controller.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Initialize the Three.js scene, camera, renderer and controls
|
|
14
|
+
* @param {HTMLElement} container - The container element for the renderer
|
|
15
|
+
* @param {boolean} showDebugCube - Whether to show the debug cube (default: false)
|
|
16
|
+
* @returns {Object} Scene, camera, renderer, and controls
|
|
17
|
+
*/
|
|
18
|
+
export function initScene(container, showDebugCube = false) {
|
|
19
|
+
console.log('DEBUG: initScene called', {
|
|
20
|
+
containerExists: !!container,
|
|
21
|
+
containerDimensions: container ? `${container.clientWidth}x${container.clientHeight}` : 'N/A',
|
|
22
|
+
parentNode: container?.parentNode?.tagName || 'None',
|
|
23
|
+
viewportID: container?.id || 'Unknown',
|
|
24
|
+
showDebugCube: showDebugCube
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Add a debug cube to confirm scene is rendering
|
|
28
|
+
const addDebugCube = (scene) => {
|
|
29
|
+
const geometry = new THREE.BoxGeometry(1, 1, 1);
|
|
30
|
+
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
|
|
31
|
+
const cube = new THREE.Mesh(geometry, material);
|
|
32
|
+
cube.position.set(0, 0.5, 0);
|
|
33
|
+
scene.add(cube);
|
|
34
|
+
return cube;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const state = getState();
|
|
38
|
+
|
|
39
|
+
// Create scene
|
|
40
|
+
const scene = new THREE.Scene();
|
|
41
|
+
updateState('scene', scene);
|
|
42
|
+
|
|
43
|
+
// Create camera
|
|
44
|
+
const camera = new THREE.PerspectiveCamera(
|
|
45
|
+
75,
|
|
46
|
+
container.clientWidth / container.clientHeight,
|
|
47
|
+
0.1,
|
|
48
|
+
1000
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// Set initial camera position with better perspective angle
|
|
52
|
+
camera.position.set(3, 2, 5); // Position at a diagonal angle instead of just along Z
|
|
53
|
+
updateState('camera', camera);
|
|
54
|
+
|
|
55
|
+
// Create renderer
|
|
56
|
+
const renderer = new THREE.WebGLRenderer({ antialias: true });
|
|
57
|
+
renderer.setSize(container.clientWidth, container.clientHeight);
|
|
58
|
+
renderer.outputColorSpace = THREE.SRGBColorSpace;
|
|
59
|
+
container.appendChild(renderer.domElement);
|
|
60
|
+
updateState('renderer', renderer);
|
|
61
|
+
|
|
62
|
+
// Ensure viewport is visible
|
|
63
|
+
container.style.display = 'block';
|
|
64
|
+
console.log('DEBUG: Set viewport display to block');
|
|
65
|
+
|
|
66
|
+
// Create orbit controls using our controls module
|
|
67
|
+
const controls = createControls(camera, renderer.domElement);
|
|
68
|
+
// No need to update state here as the controls module does it
|
|
69
|
+
|
|
70
|
+
// Add a debug cube to verify the scene is working if showDebugCube is true
|
|
71
|
+
let cube = null;
|
|
72
|
+
if (showDebugCube) {
|
|
73
|
+
cube = addDebugCube(scene);
|
|
74
|
+
console.log('DEBUG: Added green debug cube to scene');
|
|
75
|
+
} else {
|
|
76
|
+
console.log('DEBUG: Debug cube disabled');
|
|
77
|
+
}
|
|
78
|
+
updateState('cube', cube);
|
|
79
|
+
|
|
80
|
+
// Check if we have an HDR/EXR lighting file to use
|
|
81
|
+
const lightingFile = state.lightingFile;
|
|
82
|
+
const hasValidLightingFile = lightingFile &&
|
|
83
|
+
(lightingFile.name.toLowerCase().endsWith('.hdr') ||
|
|
84
|
+
lightingFile.name.toLowerCase().endsWith('.exr'));
|
|
85
|
+
|
|
86
|
+
if (hasValidLightingFile) {
|
|
87
|
+
// Set default black background until the HDR/EXR is loaded
|
|
88
|
+
scene.background = new THREE.Color(0x000000);
|
|
89
|
+
|
|
90
|
+
// We'll set up the environment lighting after the scene is initialized
|
|
91
|
+
// The lighting setup is handled in the startDebugging function
|
|
92
|
+
console.log('HDR/EXR lighting file found, will be applied after scene initialization');
|
|
93
|
+
} else {
|
|
94
|
+
// No HDR/EXR file, add standard lighting
|
|
95
|
+
addLighting(scene);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Set up window resize handler
|
|
99
|
+
setupResizeHandler(container);
|
|
100
|
+
|
|
101
|
+
// Force a resize event
|
|
102
|
+
window.dispatchEvent(new Event('resize'));
|
|
103
|
+
|
|
104
|
+
// Render once immediately
|
|
105
|
+
renderer.render(scene, camera);
|
|
106
|
+
|
|
107
|
+
return { scene, camera, renderer, controls };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Set up window resize handler
|
|
112
|
+
* @param {HTMLElement} container - The container element for the renderer
|
|
113
|
+
*/
|
|
114
|
+
function setupResizeHandler(container) {
|
|
115
|
+
window.addEventListener('resize', () => {
|
|
116
|
+
const state = getState();
|
|
117
|
+
|
|
118
|
+
if (state.camera && state.renderer) {
|
|
119
|
+
// Update camera aspect ratio
|
|
120
|
+
state.camera.aspect = container.clientWidth / container.clientHeight;
|
|
121
|
+
state.camera.updateProjectionMatrix();
|
|
122
|
+
|
|
123
|
+
// Update renderer size
|
|
124
|
+
state.renderer.setSize(container.clientWidth, container.clientHeight);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Start animation loop
|
|
131
|
+
*/
|
|
132
|
+
export function startAnimation() {
|
|
133
|
+
const state = getState();
|
|
134
|
+
|
|
135
|
+
if (!state.animating) {
|
|
136
|
+
state.animating = true;
|
|
137
|
+
animate();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Animation loop
|
|
142
|
+
let lastFrameTime = performance.now();
|
|
143
|
+
|
|
144
|
+
function animate() {
|
|
145
|
+
const state = getState();
|
|
146
|
+
|
|
147
|
+
if (!state.animating) return;
|
|
148
|
+
|
|
149
|
+
requestAnimationFrame(animate);
|
|
150
|
+
|
|
151
|
+
// Time tracking for smooth animation
|
|
152
|
+
const now = performance.now();
|
|
153
|
+
const delta = now - lastFrameTime;
|
|
154
|
+
lastFrameTime = now;
|
|
155
|
+
|
|
156
|
+
// Update rig animation if available
|
|
157
|
+
updateRigAnimation();
|
|
158
|
+
|
|
159
|
+
// Always update orbit controls to ensure smooth inertia/damping
|
|
160
|
+
updateControls();
|
|
161
|
+
|
|
162
|
+
// Render the scene
|
|
163
|
+
if (state.renderer && state.scene && state.camera) {
|
|
164
|
+
state.renderer.render(state.scene, state.camera);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Stop animation loop
|
|
170
|
+
*/
|
|
171
|
+
export function stopAnimation() {
|
|
172
|
+
const state = getState();
|
|
173
|
+
state.animating = false;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Clear the scene of all objects
|
|
178
|
+
*/
|
|
179
|
+
export function clearScene() {
|
|
180
|
+
const state = getState();
|
|
181
|
+
|
|
182
|
+
// Remove existing model from scene if it exists
|
|
183
|
+
if (state.model) {
|
|
184
|
+
state.scene.remove(state.model);
|
|
185
|
+
updateState('model', null);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Remove existing cube if it exists
|
|
189
|
+
if (state.cube) {
|
|
190
|
+
state.scene.remove(state.cube);
|
|
191
|
+
updateState('cube', null);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Clear meshes array
|
|
195
|
+
updateState('meshes', []);
|
|
196
|
+
|
|
197
|
+
// Clear mesh groups
|
|
198
|
+
updateState('meshGroups', {});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Fit camera to object with sophisticated positioning
|
|
203
|
+
* @param {THREE.Object3D} object - The object to fit the camera to
|
|
204
|
+
* @param {number} offset - Optional base offset factor (default: 1.2)
|
|
205
|
+
*/
|
|
206
|
+
export function fitCameraToObject(object, offset = 1.2) {
|
|
207
|
+
const state = getState();
|
|
208
|
+
|
|
209
|
+
if (!object || !state.camera) return;
|
|
210
|
+
|
|
211
|
+
// Create a bounding box for the object
|
|
212
|
+
const boundingBox = new THREE.Box3().setFromObject(object);
|
|
213
|
+
const center = boundingBox.getCenter(new THREE.Vector3());
|
|
214
|
+
const size = boundingBox.getSize(new THREE.Vector3());
|
|
215
|
+
|
|
216
|
+
// Get the camera aspect ratio
|
|
217
|
+
const aspect = state.renderer.domElement.clientWidth / state.renderer.domElement.clientHeight;
|
|
218
|
+
|
|
219
|
+
// Calculate optimal camera position to ensure the model is fully visible
|
|
220
|
+
const fov = state.camera.fov * (Math.PI / 180); // convert to radians
|
|
221
|
+
|
|
222
|
+
// Get model dimensions
|
|
223
|
+
const scaledSizeX = size.x;
|
|
224
|
+
const scaledSizeY = size.y;
|
|
225
|
+
const scaledSizeZ = size.z;
|
|
226
|
+
|
|
227
|
+
// Calculate the center point of the model for camera targeting
|
|
228
|
+
// This is the geometric center, not just (0,0,0)
|
|
229
|
+
const modelCenter = new THREE.Vector3(center.x, center.y, center.z);
|
|
230
|
+
|
|
231
|
+
// Calculate required distance for each dimension
|
|
232
|
+
const distanceForHeight = scaledSizeY / (2 * Math.tan(fov / 2));
|
|
233
|
+
const distanceForWidth = scaledSizeX / (2 * Math.tan(fov / 2) * aspect);
|
|
234
|
+
const distanceForDepth = scaledSizeZ * 1.2; // Add more space for depth
|
|
235
|
+
|
|
236
|
+
// Base distance calculation
|
|
237
|
+
let optimalDistance = Math.max(distanceForWidth, distanceForHeight, distanceForDepth);
|
|
238
|
+
|
|
239
|
+
// Detect extreme model shapes and adjust accordingly
|
|
240
|
+
const aspectRatioXY = scaledSizeX / (scaledSizeY || 0.001); // Avoid division by zero
|
|
241
|
+
const aspectRatioXZ = scaledSizeX / (scaledSizeZ || 0.001);
|
|
242
|
+
const aspectRatioYZ = scaledSizeY / (scaledSizeZ || 0.001);
|
|
243
|
+
|
|
244
|
+
// Add extra buffer for camera distance
|
|
245
|
+
let bufferMultiplier = 1.6; // Base buffer multiplier
|
|
246
|
+
|
|
247
|
+
// Add more buffer for flat/wide models (high aspect ratios)
|
|
248
|
+
if (aspectRatioXY > 4 || aspectRatioXY < 0.25 ||
|
|
249
|
+
aspectRatioXZ > 4 || aspectRatioXZ < 0.25 ||
|
|
250
|
+
aspectRatioYZ > 4 || aspectRatioYZ < 0.25) {
|
|
251
|
+
bufferMultiplier = 2.0; // More space for extreme shapes
|
|
252
|
+
console.log('Extreme model shape detected - using larger buffer');
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Apply buffer to optimal distance
|
|
256
|
+
optimalDistance *= bufferMultiplier;
|
|
257
|
+
|
|
258
|
+
// Set minimum distance
|
|
259
|
+
const finalDistance = Math.max(optimalDistance, 2.5);
|
|
260
|
+
|
|
261
|
+
// Calculate X and Y offsets for perspective view
|
|
262
|
+
const xOffset = finalDistance * 0.4;
|
|
263
|
+
let yOffset = finalDistance * 0.3;
|
|
264
|
+
|
|
265
|
+
// Special handling for very tall models
|
|
266
|
+
if (scaledSizeY > scaledSizeX * 3 && scaledSizeY > scaledSizeZ * 3) {
|
|
267
|
+
// For very tall models, position camera higher to see from middle
|
|
268
|
+
yOffset = Math.min(modelCenter.y + finalDistance * 0.2, finalDistance * 0.7);
|
|
269
|
+
} else if (scaledSizeY < 0.5) {
|
|
270
|
+
// For very flat horizontal models, don't position camera too low
|
|
271
|
+
yOffset = Math.max(modelCenter.y * 2, finalDistance * 0.2);
|
|
272
|
+
} else {
|
|
273
|
+
// For normal models, position camera to see the entire height
|
|
274
|
+
yOffset = Math.max(modelCenter.y, finalDistance * 0.2);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Final camera positioning - position relative to the model's center point
|
|
278
|
+
state.camera.position.set(
|
|
279
|
+
modelCenter.x + xOffset,
|
|
280
|
+
modelCenter.y + yOffset,
|
|
281
|
+
modelCenter.z + finalDistance
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
// Update orbit controls target to the center of the model
|
|
285
|
+
setControlsTarget(modelCenter);
|
|
286
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Texture Debugger - UI Manager Module
|
|
3
|
+
*
|
|
4
|
+
* This module handles the UI interactions and tab switching.
|
|
5
|
+
*/
|
|
6
|
+
import { getState } from '../state/scene-state.js';
|
|
7
|
+
import { updateUvPanel } from '../../panels/asset-panel/uv-heading/uv-heading.js';
|
|
8
|
+
import { updateAtlasVisualization } from '../../panels/asset-panel/atlas-heading/atlas-heading.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Initialize the UI manager and set up event listeners
|
|
12
|
+
*/
|
|
13
|
+
export function initUiManager() {
|
|
14
|
+
// Set up the tab switching
|
|
15
|
+
setupTabs();
|
|
16
|
+
|
|
17
|
+
// Set up keyboard shortcuts
|
|
18
|
+
setupKeyboardShortcuts();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Set up tab switching handlers
|
|
23
|
+
*/
|
|
24
|
+
function setupTabs() {
|
|
25
|
+
const tabs = document.querySelectorAll('.tab-button');
|
|
26
|
+
const tabPanels = document.querySelectorAll('.tab-panel');
|
|
27
|
+
|
|
28
|
+
// Add click event for each tab
|
|
29
|
+
tabs.forEach(tab => {
|
|
30
|
+
tab.addEventListener('click', () => {
|
|
31
|
+
// Remove active class from all tabs and panels
|
|
32
|
+
tabs.forEach(t => t.classList.remove('active'));
|
|
33
|
+
tabPanels.forEach(p => p.classList.remove('active'));
|
|
34
|
+
|
|
35
|
+
// Add active class to current tab
|
|
36
|
+
tab.classList.add('active');
|
|
37
|
+
|
|
38
|
+
// Show the corresponding panel
|
|
39
|
+
const panelId = tab.getAttribute('data-tab');
|
|
40
|
+
const panel = document.getElementById(panelId);
|
|
41
|
+
if (panel) {
|
|
42
|
+
panel.classList.add('active');
|
|
43
|
+
|
|
44
|
+
// If switching to atlas tab, update atlas visualization
|
|
45
|
+
if (panelId === 'atlas-heading') {
|
|
46
|
+
updateAtlasVisualization();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// If switching to UV tab, update UV visualization
|
|
50
|
+
if (panelId === 'uv-heading') {
|
|
51
|
+
updateUvPanel();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Prevent default drag-and-drop behavior for the entire document
|
|
60
|
+
*/
|
|
61
|
+
function preventDefaultDragBehavior() {
|
|
62
|
+
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
|
63
|
+
document.body.addEventListener(eventName, (e) => {
|
|
64
|
+
if (e.target !== document.getElementById('basecolor-dropzone') &&
|
|
65
|
+
e.target !== document.getElementById('orm-dropzone') &&
|
|
66
|
+
e.target !== document.getElementById('normal-dropzone') &&
|
|
67
|
+
e.target !== document.getElementById('model-dropzone') &&
|
|
68
|
+
e.target !== document.getElementById('lighting-dropzone') &&
|
|
69
|
+
e.target !== document.getElementById('background-dropzone') &&
|
|
70
|
+
e.target !== document.getElementById('upload-section') &&
|
|
71
|
+
!e.target.closest('#upload-section')) {
|
|
72
|
+
e.preventDefault();
|
|
73
|
+
e.stopPropagation();
|
|
74
|
+
}
|
|
75
|
+
}, false);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Set up keyboard shortcuts
|
|
81
|
+
*/
|
|
82
|
+
function setupKeyboardShortcuts() {
|
|
83
|
+
document.addEventListener('keydown', (event) => {
|
|
84
|
+
// Tab switching with number keys
|
|
85
|
+
if (event.key === '1') {
|
|
86
|
+
document.getElementById('atlas-tab')?.click();
|
|
87
|
+
} else if (event.key === '2') {
|
|
88
|
+
document.getElementById('uv-tab')?.click();
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Show/hide the loading indicator
|
|
95
|
+
* @param {boolean} show - Whether to show or hide the indicator
|
|
96
|
+
*/
|
|
97
|
+
export function toggleLoadingIndicator(show) {
|
|
98
|
+
const loadingIndicator = document.getElementById('loading-indicator');
|
|
99
|
+
if (loadingIndicator) {
|
|
100
|
+
loadingIndicator.style.display = show ? 'flex' : 'none';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export default {
|
|
105
|
+
initUiManager,
|
|
106
|
+
toggleLoadingIndicator
|
|
107
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
export const ANALYSIS_DURATION_MS = 30000; // 30 seconds - matches preRenderMaxDuration
|
|
2
|
+
|
|
3
|
+
export let finalProgressAnimation = false;
|
|
4
|
+
export let finalProgressStartTime = 0;
|
|
5
|
+
export let finalProgressDuration = 800; // Duration of final progress animation in ms
|
|
6
|
+
|
|
7
|
+
let animationChangeThreshold = 0.008; // Lower threshold for detecting change (was 0.01)
|
|
8
|
+
let animationIdleThreshold = 30; // Number of similar frames before considering animation ended
|
|
9
|
+
let frameChangeRates = []; // Store recent frame change rates
|
|
10
|
+
let animationIdleCount = 0;
|
|
11
|
+
let previousChangeFrequency = 0; // Track previous change frequency
|
|
12
|
+
let preRenderStartTime = 0;
|
|
13
|
+
export let preRenderMaxDuration = 30000; // Increased to 30 seconds for longer animations
|
|
14
|
+
// Image2texture variables
|
|
15
|
+
export let animationDetectionSensitivity = 0.85; // Increased from 0.5 to 0.85 for much stricter detection by default
|
|
16
|
+
let animationEndTime = 0;
|
|
17
|
+
let animationStartTime = 0;
|
|
18
|
+
export let animationStartDetected = false;
|
|
19
|
+
export let animationDetected = false;
|
|
20
|
+
export let preRenderedFrames = [];
|
|
21
|
+
export let animationDuration = 0; // Store detected animation duration
|
|
22
|
+
export let preRenderingInProgress = false;
|
|
23
|
+
export let isAnimationFinite = false;
|
|
24
|
+
|
|
25
|
+
// Update references to use internal functions instead of imports
|
|
26
|
+
// These variables will be exported and should be used by preview-util.js
|
|
27
|
+
export let isPreviewActive = true; // Exported for use in preview-util.js
|
|
28
|
+
export let isPreviewAnimationPaused = false; // Exported for use in preview-util.js
|
|
29
|
+
export let lastTextureUpdateTime = 0; // Exported for use in preview-util.js and threejs-util.js
|
|
30
|
+
|
|
31
|
+
// TIMING STATE - This module owns all animation timing
|
|
32
|
+
export let animationPlaybackStartTime = 0; // When playback actually started
|
|
33
|
+
export let animationCaptureStartTime = 0; // When capture started (for offset calculations)
|
|
34
|
+
// Active playback values
|
|
35
|
+
export let playbackStartTime = 0;
|
|
36
|
+
export let isPlaybackActive = false;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Reset all timing
|
|
40
|
+
*/
|
|
41
|
+
export function resetPlaybackTimingState() {
|
|
42
|
+
playbackStartTime = 0;
|
|
43
|
+
isPlaybackActive = false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function resetPreRenderState() {
|
|
47
|
+
preRenderedFrames = [];
|
|
48
|
+
isAnimationFinite = false;
|
|
49
|
+
preRenderingInProgress = false;
|
|
50
|
+
finalProgressAnimation = false;
|
|
51
|
+
finalProgressStartTime = 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Set the isPreviewAnimationPaused flag
|
|
56
|
+
* @param {boolean} incomingValue - The new value to set
|
|
57
|
+
*/
|
|
58
|
+
export function setIsPreviewAnimationPaused(incomingValue) {
|
|
59
|
+
isPreviewAnimationPaused = incomingValue;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Set the isPreviewActive flag
|
|
64
|
+
* @param {boolean} incomingValue - The new value to set
|
|
65
|
+
*/
|
|
66
|
+
export function setIsPreviewActive(incomingValue) {
|
|
67
|
+
isPreviewActive = incomingValue;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Set the lastTextureUpdateTime
|
|
72
|
+
* @param {number} incomingValue - The new value to set
|
|
73
|
+
*/
|
|
74
|
+
export function setLastTextureUpdateTime(incomingValue) {
|
|
75
|
+
lastTextureUpdateTime = incomingValue;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Set preRenderedFrames array
|
|
80
|
+
* @param {Array} incomingValue - The new value to set
|
|
81
|
+
*/
|
|
82
|
+
export function setPreRenderedFrames(incomingValue) {
|
|
83
|
+
preRenderedFrames = incomingValue;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Set animationDuration value
|
|
88
|
+
* @param {number} incomingValue - The new value to set
|
|
89
|
+
*/
|
|
90
|
+
export function setAnimationDuration(incomingValue) {
|
|
91
|
+
animationDuration = incomingValue;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Set isAnimationFinite state
|
|
96
|
+
* @param {boolean} incomingValue - The new value to set
|
|
97
|
+
*/
|
|
98
|
+
export function setIsAnimationFinite(incomingValue) {
|
|
99
|
+
isAnimationFinite = incomingValue;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function setPreRenderingInProgress(incomingValue) {
|
|
103
|
+
preRenderingInProgress = incomingValue;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function setFinalProgressAnimation(incomingValue) {
|
|
107
|
+
finalProgressAnimation = incomingValue;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function setFinalProgressStartTime(incomingValue) {
|
|
111
|
+
finalProgressStartTime = incomingValue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function setAnimationPlaybackStartTime(incomingValue) {
|
|
115
|
+
animationPlaybackStartTime = incomingValue;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function setAnimationCaptureStartTime(incomingValue) {
|
|
119
|
+
animationCaptureStartTime = incomingValue;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function setPlaybackStartTime(incomingValue) {
|
|
123
|
+
playbackStartTime = incomingValue;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function setIsPlaybackActive(incomingValue) {
|
|
127
|
+
isPlaybackActive = incomingValue;
|
|
128
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Add animation stack tracking variables at the top of the file
|
|
2
|
+
export let animationStack = [];
|
|
3
|
+
export let isReversingAnimations = false;
|
|
4
|
+
// Add flag to disable animation capture during reversal
|
|
5
|
+
export let isCapturingAnimations = true;
|
|
6
|
+
// Store animation properties to properly reverse them
|
|
7
|
+
export let animationProperties = {};
|
|
8
|
+
// Store timestamps for calculating delays
|
|
9
|
+
export let lastAnimationTime = 0;
|
|
10
|
+
// Animation frame tracking
|
|
11
|
+
export let reverseAnimationFrameId = null;
|
|
12
|
+
// Add animation batch tracking for composite effects
|
|
13
|
+
export let currentAnimationBatch = [];
|
|
14
|
+
export let batchTimeWindow = 50; // ms window to consider animations as part of the same batch
|
|
15
|
+
export let lastBatchTime = 0;
|
|
16
|
+
|
|
17
|
+
export function resetAnimationStack() {
|
|
18
|
+
animationStack = [];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function pushAnimationStack(incomingValue) {
|
|
22
|
+
if(!incomingValue) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
animationStack.push(incomingValue);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function setReversingAnimation(incomingValue) {
|
|
29
|
+
isReversingAnimations = incomingValue;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function setCapturingAnimations(incomingValue) {
|
|
33
|
+
isCapturingAnimations = incomingValue;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function resetAnimationProperties() {
|
|
37
|
+
animationProperties = {};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function setLastAnimationTime(incomingValue) {
|
|
41
|
+
if(!incomingValue) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
lastAnimationTime = incomingValue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function resetCurrentAniamtionBatch() {
|
|
48
|
+
currentAnimationBatch = [];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function pushAnimationBatch(incomingValue) {
|
|
52
|
+
if(!incomingValue){
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
currentAnimationBatch.push(incomingValue);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function resetLastBatchTime() {
|
|
59
|
+
lastBatchTime = 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function setLastBatchTime(incomingValue) {
|
|
63
|
+
lastBatchTime = incomingValue;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function resetReverseAnimationFrameId() {
|
|
67
|
+
reverseAnimationFrameId = null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function setReverseAnimationFrameId(incomingValue) {
|
|
71
|
+
reverseAnimationFrameId = incomingValue;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function resetAnimationState() {
|
|
75
|
+
// Clear existing animation stack
|
|
76
|
+
resetAnimationStack();
|
|
77
|
+
setReversingAnimation(false);
|
|
78
|
+
setCapturingAnimations(true);
|
|
79
|
+
resetAnimationProperties();
|
|
80
|
+
setLastAnimationTime(Date.now());
|
|
81
|
+
resetCurrentAniamtionBatch();
|
|
82
|
+
resetLastBatchTime();
|
|
83
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Constants for extension identification
|
|
2
|
+
export const MESH_BINARY_EXTENSION = 'BLORK_mesh_binary_data';
|
|
3
|
+
export const MESH_INDEX_PROPERTY = 'meshIndex';
|
|
4
|
+
export const BINARY_DATA_PROPERTY = 'binaryData';
|
|
5
|
+
|
|
6
|
+
// Keep track of preview resources for cleanup
|
|
7
|
+
export let previewRenderer = null;
|
|
8
|
+
export let previewScene = null;
|
|
9
|
+
export let previewCamera = null;
|
|
10
|
+
export let previewControls = null;
|
|
11
|
+
export let previewAnimationFrame = null;
|
|
12
|
+
|
|
13
|
+
export function setPreviewAnimationFrame(incomingValue) {
|
|
14
|
+
previewAnimationFrame = incomingValue;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function setPreviewScene(incomingValue) {
|
|
18
|
+
previewScene = incomingValue;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function setPreviewCamera(incomingValue) {
|
|
22
|
+
previewCamera = incomingValue;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function setPreviewControls(incomingValue) {
|
|
26
|
+
previewControls = incomingValue;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function setPreviewRenderer(incomingValue) {
|
|
30
|
+
previewRenderer = incomingValue;
|
|
31
|
+
}
|