@littlecarlito/blorktools 0.50.3 → 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,612 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { checkHandleHover, getIsDragging } from './rig-mouse-handler';
|
|
3
|
+
import { getState } from '../state/scene-state';
|
|
4
|
+
import {
|
|
5
|
+
bones,
|
|
6
|
+
boneMaterial,
|
|
7
|
+
lockedBones,
|
|
8
|
+
boneSideMaterial,
|
|
9
|
+
boneVisualsGroup,
|
|
10
|
+
updateAllBoneMatrices,
|
|
11
|
+
restoreLockedBoneRotations,
|
|
12
|
+
clearBoneVisualsGroup
|
|
13
|
+
} from './bone-kinematics';
|
|
14
|
+
import { createBoneLabels, createJointLabels } from './rig-label-factory';
|
|
15
|
+
import { deduplicateItemsByName } from '../data/duplicate-handler';
|
|
16
|
+
import { clearPrimaryRigHandle, primaryRigHandle } from './rig-handle-factory';
|
|
17
|
+
|
|
18
|
+
export let rigDetails = null;
|
|
19
|
+
export const labelGroups = new Map(); // Map to store different types of label groups (joint, bone)
|
|
20
|
+
|
|
21
|
+
// Variables used for rig visualization
|
|
22
|
+
export const rigOptions = {
|
|
23
|
+
displayRig: true,
|
|
24
|
+
forceZ: true,
|
|
25
|
+
wireframe: false,
|
|
26
|
+
primaryColor: 0x4CAF50,
|
|
27
|
+
secondaryColor: 0xFFFF00,
|
|
28
|
+
jointColor: 0x00FFFF,
|
|
29
|
+
showJointLabels: false,
|
|
30
|
+
showBoneLabels: false,
|
|
31
|
+
normalColor: 0xFF0000,
|
|
32
|
+
hoverColor: 0x00FF00,
|
|
33
|
+
activeColor: 0x0000FF,
|
|
34
|
+
worldGravity: 1.0
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Update one or multiple rig options
|
|
39
|
+
* @param {Object} options - Object containing the options to update
|
|
40
|
+
*/
|
|
41
|
+
export function updateRigOptions(options) {
|
|
42
|
+
if (!options) return;
|
|
43
|
+
|
|
44
|
+
// Update each property
|
|
45
|
+
if (options.displayRig !== undefined) rigOptions.displayRig = options.displayRig;
|
|
46
|
+
if (options.forceZ !== undefined) rigOptions.forceZ = options.forceZ;
|
|
47
|
+
if (options.wireframe !== undefined) rigOptions.wireframe = options.wireframe;
|
|
48
|
+
if (options.primaryColor !== undefined) rigOptions.primaryColor = options.primaryColor;
|
|
49
|
+
if (options.secondaryColor !== undefined) rigOptions.secondaryColor = options.secondaryColor;
|
|
50
|
+
if (options.jointColor !== undefined) rigOptions.jointColor = options.jointColor;
|
|
51
|
+
if (options.showJointLabels !== undefined) rigOptions.showJointLabels = options.showJointLabels;
|
|
52
|
+
if (options.showBoneLabels !== undefined) rigOptions.showBoneLabels = options.showBoneLabels;
|
|
53
|
+
if (options.normalColor !== undefined) rigOptions.normalColor = options.normalColor;
|
|
54
|
+
if (options.hoverColor !== undefined) rigOptions.hoverColor = options.hoverColor;
|
|
55
|
+
if (options.activeColor !== undefined) rigOptions.activeColor = options.activeColor;
|
|
56
|
+
if (options.worldGravity !== undefined) rigOptions.worldGravity = options.worldGravity;
|
|
57
|
+
|
|
58
|
+
console.log('Rig options updated:', rigOptions);
|
|
59
|
+
|
|
60
|
+
// Dispatch an event to notify other components of the change
|
|
61
|
+
const event = new CustomEvent('rigOptionsChange', {
|
|
62
|
+
detail: rigOptions
|
|
63
|
+
});
|
|
64
|
+
document.dispatchEvent(event);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Update the rig visualization based on option changes
|
|
69
|
+
*/
|
|
70
|
+
export function updateRigVisualization() {
|
|
71
|
+
if (!boneVisualsGroup) return;
|
|
72
|
+
|
|
73
|
+
console.log('Updating rig visualization with options:', JSON.stringify(rigOptions));
|
|
74
|
+
|
|
75
|
+
// Toggle rig visibility without affecting creation or forceZ
|
|
76
|
+
if (boneVisualsGroup) {
|
|
77
|
+
boneVisualsGroup.visible = rigOptions.displayRig;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (primaryRigHandle) {
|
|
81
|
+
primaryRigHandle.visible = rigOptions.displayRig;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Update joint labels visibility using the dedicated functions
|
|
85
|
+
if (rigOptions.showJointLabels && rigOptions.displayRig) {
|
|
86
|
+
console.log('Showing joint labels');
|
|
87
|
+
showLabels('joint');
|
|
88
|
+
} else {
|
|
89
|
+
console.log('Hiding joint labels');
|
|
90
|
+
hideLabels('joint');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Update bone labels visibility using the dedicated functions
|
|
94
|
+
if (rigOptions.showBoneLabels && rigOptions.displayRig) {
|
|
95
|
+
console.log('Showing bone labels');
|
|
96
|
+
showLabels('bone');
|
|
97
|
+
} else {
|
|
98
|
+
console.log('Hiding bone labels');
|
|
99
|
+
hideLabels('bone');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Create labels if needed but don't exist yet
|
|
103
|
+
const state = getState();
|
|
104
|
+
|
|
105
|
+
// Joint labels
|
|
106
|
+
const jointLabelGroup = state.scene ? state.scene.getObjectByName("JointLabels") : null;
|
|
107
|
+
|
|
108
|
+
if (jointLabelGroup) {
|
|
109
|
+
console.log('Updating joint labels visibility to:', rigOptions.showJointLabels && rigOptions.displayRig);
|
|
110
|
+
|
|
111
|
+
// Update individual label positions
|
|
112
|
+
jointLabelGroup.children.forEach(label => {
|
|
113
|
+
if (label.userData && label.userData.updatePosition) {
|
|
114
|
+
label.userData.updatePosition();
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
} else if (rigOptions.displayRig && state.scene) {
|
|
118
|
+
// If we don't have labels but rig is displayed, create them
|
|
119
|
+
console.log('No joint label group found, creating new joint labels');
|
|
120
|
+
createJointLabels(state.scene);
|
|
121
|
+
|
|
122
|
+
// Set visibility based on showJointLabels option
|
|
123
|
+
if (rigOptions.showJointLabels) {
|
|
124
|
+
showLabels('joint');
|
|
125
|
+
} else {
|
|
126
|
+
hideLabels('joint');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Bone labels
|
|
131
|
+
const boneLabelGroup = state.scene ? state.scene.getObjectByName("BoneLabels") : null;
|
|
132
|
+
|
|
133
|
+
if (boneLabelGroup) {
|
|
134
|
+
console.log('Updating bone labels visibility to:', rigOptions.showBoneLabels && rigOptions.displayRig);
|
|
135
|
+
|
|
136
|
+
// Update individual label positions
|
|
137
|
+
boneLabelGroup.children.forEach(label => {
|
|
138
|
+
if (label.userData && label.userData.updatePosition) {
|
|
139
|
+
label.userData.updatePosition();
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
} else if (rigOptions.displayRig && state.scene) {
|
|
143
|
+
// If we don't have bone labels but rig is displayed, create them
|
|
144
|
+
console.log('No bone label group found, creating new bone labels');
|
|
145
|
+
createBoneLabels(state.scene);
|
|
146
|
+
|
|
147
|
+
// Set visibility based on showBoneLabels option
|
|
148
|
+
if (rigOptions.showBoneLabels) {
|
|
149
|
+
showLabels('bone');
|
|
150
|
+
} else {
|
|
151
|
+
hideLabels('bone');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Refresh the joints data
|
|
156
|
+
refreshJointsData();
|
|
157
|
+
|
|
158
|
+
// Update primary and secondary colors and wireframe state
|
|
159
|
+
if (boneMaterial) {
|
|
160
|
+
boneMaterial.color.setHex(rigOptions.primaryColor);
|
|
161
|
+
boneMaterial.wireframe = rigOptions.wireframe;
|
|
162
|
+
boneMaterial.needsUpdate = true;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (boneSideMaterial) {
|
|
166
|
+
boneSideMaterial.color.setHex(rigOptions.secondaryColor);
|
|
167
|
+
boneSideMaterial.wireframe = rigOptions.wireframe;
|
|
168
|
+
boneSideMaterial.needsUpdate = true;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
boneVisualsGroup.traverse(object => {
|
|
172
|
+
// Update bone sides
|
|
173
|
+
if (object.isMesh && object.userData.bonePart === 'side') {
|
|
174
|
+
// Update color of alternating sides
|
|
175
|
+
if (!object.userData.sideIndex || object.userData.sideIndex % 2 === 0) {
|
|
176
|
+
// Even sides use primary color
|
|
177
|
+
object.material.color.setHex(rigOptions.primaryColor);
|
|
178
|
+
} else {
|
|
179
|
+
// Odd sides use secondary color
|
|
180
|
+
object.material.color.setHex(rigOptions.secondaryColor);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Update wireframe setting
|
|
184
|
+
object.material.wireframe = rigOptions.wireframe;
|
|
185
|
+
object.material.needsUpdate = true;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Update joint materials
|
|
189
|
+
if (object.isMesh && object.userData.bonePart === 'cap') {
|
|
190
|
+
object.material.color.setHex(rigOptions.jointColor);
|
|
191
|
+
object.material.wireframe = rigOptions.wireframe;
|
|
192
|
+
object.material.needsUpdate = true;
|
|
193
|
+
|
|
194
|
+
// Force update visibility of joint labels
|
|
195
|
+
if (object.userData.label) {
|
|
196
|
+
object.userData.label.visible = rigOptions.showJointLabels && rigOptions.displayRig;
|
|
197
|
+
|
|
198
|
+
// Make sure the label appears on top when Force Z is enabled
|
|
199
|
+
if (rigOptions.forceZ) {
|
|
200
|
+
object.userData.label.renderOrder = 1025; // Higher than joint spheres but lower than control handle
|
|
201
|
+
object.userData.label.material.depthTest = false;
|
|
202
|
+
} else {
|
|
203
|
+
object.userData.label.renderOrder = 500;
|
|
204
|
+
object.userData.label.material.depthTest = false; // Always render on top
|
|
205
|
+
}
|
|
206
|
+
object.userData.label.material.needsUpdate = true;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Apply Force Z settings regardless of rig visibility
|
|
212
|
+
if (boneVisualsGroup) {
|
|
213
|
+
if (rigOptions.forceZ) {
|
|
214
|
+
console.log('Applying Force Z index to rig');
|
|
215
|
+
// Move the rig to render on top by setting renderOrder to a high value
|
|
216
|
+
// and disabling depth test for materials
|
|
217
|
+
boneVisualsGroup.renderOrder = 1000; // High value to render after other objects
|
|
218
|
+
|
|
219
|
+
if (boneMaterial) {
|
|
220
|
+
boneMaterial.depthTest = false;
|
|
221
|
+
boneMaterial.needsUpdate = true;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (boneSideMaterial) {
|
|
225
|
+
boneSideMaterial.depthTest = false;
|
|
226
|
+
boneSideMaterial.needsUpdate = true;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Set renderOrder and disable depth test for EVERY mesh in the group
|
|
230
|
+
boneVisualsGroup.traverse(object => {
|
|
231
|
+
if (object.isMesh) {
|
|
232
|
+
if (object.userData.bonePart === 'cap') {
|
|
233
|
+
// Joint spheres get higher renderOrder
|
|
234
|
+
object.renderOrder = 1020;
|
|
235
|
+
} else if (object.userData.bonePart === 'side') {
|
|
236
|
+
// Bone sides get lower renderOrder
|
|
237
|
+
object.renderOrder = 1010;
|
|
238
|
+
} else {
|
|
239
|
+
// Everything else
|
|
240
|
+
object.renderOrder = 1000;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (object.material) {
|
|
244
|
+
object.material.depthTest = false;
|
|
245
|
+
object.material.needsUpdate = true;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
if (primaryRigHandle && primaryRigHandle.material) {
|
|
251
|
+
// Control handle gets highest renderOrder
|
|
252
|
+
primaryRigHandle.renderOrder = 1030;
|
|
253
|
+
primaryRigHandle.material.depthTest = false;
|
|
254
|
+
primaryRigHandle.material.needsUpdate = true;
|
|
255
|
+
}
|
|
256
|
+
} else {
|
|
257
|
+
console.log('Resetting Force Z index for rig');
|
|
258
|
+
// Reset normal depth behavior
|
|
259
|
+
boneVisualsGroup.renderOrder = 0;
|
|
260
|
+
|
|
261
|
+
if (boneMaterial) {
|
|
262
|
+
boneMaterial.depthTest = true;
|
|
263
|
+
boneMaterial.needsUpdate = true;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (boneSideMaterial) {
|
|
267
|
+
boneSideMaterial.depthTest = true;
|
|
268
|
+
boneSideMaterial.needsUpdate = true;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Reset renderOrder and enable depth test for EVERY mesh in the group
|
|
272
|
+
boneVisualsGroup.traverse(object => {
|
|
273
|
+
if (object.isMesh) {
|
|
274
|
+
if (object.userData.bonePart === 'cap') {
|
|
275
|
+
// Even without force-Z, joints should be on top of bones
|
|
276
|
+
object.renderOrder = 10;
|
|
277
|
+
} else {
|
|
278
|
+
object.renderOrder = 0;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (object.material) {
|
|
282
|
+
object.material.depthTest = true;
|
|
283
|
+
object.material.needsUpdate = true;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
if (primaryRigHandle && primaryRigHandle.material) {
|
|
289
|
+
// Control handle should still be above everything else
|
|
290
|
+
primaryRigHandle.renderOrder = 20;
|
|
291
|
+
primaryRigHandle.material.depthTest = true;
|
|
292
|
+
primaryRigHandle.material.needsUpdate = true;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Reset the rig to its initial position
|
|
301
|
+
*/
|
|
302
|
+
export function resetRig() {
|
|
303
|
+
if (!bones.length) return;
|
|
304
|
+
|
|
305
|
+
console.log('Resetting rig to initial position from GLB');
|
|
306
|
+
|
|
307
|
+
// Reset all bone rotations to their initial values from when the model was loaded
|
|
308
|
+
bones.forEach(bone => {
|
|
309
|
+
// Skip locked bones
|
|
310
|
+
if (lockedBones.has(bone.uuid)) return;
|
|
311
|
+
|
|
312
|
+
// If we have stored initial rotation, use it
|
|
313
|
+
if (bone.userData.initialRotation) {
|
|
314
|
+
bone.rotation.set(
|
|
315
|
+
bone.userData.initialRotation.x,
|
|
316
|
+
bone.userData.initialRotation.y,
|
|
317
|
+
bone.userData.initialRotation.z
|
|
318
|
+
);
|
|
319
|
+
bone.rotation.order = bone.userData.initialRotation.order;
|
|
320
|
+
} else {
|
|
321
|
+
// Fallback to identity if no initial rotation stored
|
|
322
|
+
bone.rotation.set(0, 0, 0);
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
// Update all matrices
|
|
327
|
+
updateAllBoneMatrices();
|
|
328
|
+
|
|
329
|
+
// If there's a furthest bone handle, update its position
|
|
330
|
+
if (primaryRigHandle && primaryRigHandle.userData.updatePosition) {
|
|
331
|
+
primaryRigHandle.userData.updatePosition();
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
console.log('Rig reset complete');
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Update a label's position to follow its joint
|
|
339
|
+
* @param {Object} label - The label to update
|
|
340
|
+
* @param {Object} joint - The joint the label is attached to
|
|
341
|
+
*/
|
|
342
|
+
export function updateLabelPosition(label, joint) {
|
|
343
|
+
if (!label || !joint) return;
|
|
344
|
+
|
|
345
|
+
// Get the joint's world position
|
|
346
|
+
const jointPos = new THREE.Vector3();
|
|
347
|
+
joint.getWorldPosition(jointPos);
|
|
348
|
+
|
|
349
|
+
// Position the label slightly above the joint
|
|
350
|
+
label.position.copy(jointPos);
|
|
351
|
+
|
|
352
|
+
// Get default offset in case geometry is missing
|
|
353
|
+
let offset = 0.2;
|
|
354
|
+
|
|
355
|
+
// Add offset based on joint position and geometry if available
|
|
356
|
+
if (joint.geometry && joint.geometry.parameters) {
|
|
357
|
+
// Use the joint's geometry parameters when available
|
|
358
|
+
if (joint.geometry.parameters.radius) {
|
|
359
|
+
offset = joint.geometry.parameters.radius * 2;
|
|
360
|
+
} else if (joint.geometry.parameters.radiusTop) {
|
|
361
|
+
offset = joint.geometry.parameters.radiusTop * 2;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// Apply offset based on joint position (top or bottom)
|
|
366
|
+
if (joint.position && joint.position.y > 0) {
|
|
367
|
+
// Top joint - place above
|
|
368
|
+
label.position.y += offset;
|
|
369
|
+
} else {
|
|
370
|
+
// Bottom joint - place to the side
|
|
371
|
+
label.position.x += offset;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Update animation for rig visuals
|
|
377
|
+
*/
|
|
378
|
+
export function updateRigAnimation() {
|
|
379
|
+
// Set visibility based on displayRig flag
|
|
380
|
+
// But keep force Z settings applied regardless of visibility
|
|
381
|
+
if (!rigOptions.displayRig) {
|
|
382
|
+
// When displayRig is off, hide visuals but maintain ForceZ settings
|
|
383
|
+
if (primaryRigHandle) {
|
|
384
|
+
primaryRigHandle.visible = false;
|
|
385
|
+
}
|
|
386
|
+
if (boneVisualsGroup) {
|
|
387
|
+
boneVisualsGroup.visible = false;
|
|
388
|
+
|
|
389
|
+
// Still update positions even when hidden to ensure ForceZ works properly
|
|
390
|
+
// when the rig becomes visible again
|
|
391
|
+
boneVisualsGroup.children.forEach(boneGroup => {
|
|
392
|
+
if (boneGroup.userData.updatePosition) {
|
|
393
|
+
boneGroup.userData.updatePosition();
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// When displayRig is on, update and show everything
|
|
401
|
+
if (boneVisualsGroup) {
|
|
402
|
+
boneVisualsGroup.visible = true;
|
|
403
|
+
boneVisualsGroup.children.forEach(boneGroup => {
|
|
404
|
+
if (boneGroup.userData.updatePosition) {
|
|
405
|
+
boneGroup.userData.updatePosition();
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Update furthest bone handle
|
|
411
|
+
if (primaryRigHandle) {
|
|
412
|
+
primaryRigHandle.visible = true;
|
|
413
|
+
if (primaryRigHandle.userData.updatePosition && !getIsDragging()) {
|
|
414
|
+
// Only update handle position when not dragging
|
|
415
|
+
primaryRigHandle.userData.updatePosition();
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// Update joint labels
|
|
420
|
+
const state = getState();
|
|
421
|
+
|
|
422
|
+
// Update all label groups
|
|
423
|
+
for (const [type, group] of labelGroups) {
|
|
424
|
+
if (group) {
|
|
425
|
+
group.children.forEach(label => {
|
|
426
|
+
if (label.userData && label.userData.updatePosition) {
|
|
427
|
+
label.userData.updatePosition();
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// Apply locked rotations to bones
|
|
434
|
+
restoreLockedBoneRotations();
|
|
435
|
+
|
|
436
|
+
// Check handle hover on each frame
|
|
437
|
+
checkHandleHover();
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Clear existing rig visualization from the scene
|
|
442
|
+
* @param {Object} scene - The Three.js scene
|
|
443
|
+
*/
|
|
444
|
+
export function clearRigVisualization(scene) {
|
|
445
|
+
if (boneVisualsGroup) {
|
|
446
|
+
scene.remove(boneVisualsGroup);
|
|
447
|
+
clearBoneVisualsGroup();
|
|
448
|
+
}
|
|
449
|
+
if (primaryRigHandle) {
|
|
450
|
+
scene.remove(primaryRigHandle);
|
|
451
|
+
clearPrimaryRigHandle();
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Refresh the joints data based on current bone visualizations
|
|
457
|
+
*/
|
|
458
|
+
function refreshJointsData() {
|
|
459
|
+
// Clear existing joints data
|
|
460
|
+
if (rigDetails && rigDetails.joints) {
|
|
461
|
+
rigDetails.joints = [];
|
|
462
|
+
|
|
463
|
+
// Collect joint data from all bone visualizations
|
|
464
|
+
if (boneVisualsGroup) {
|
|
465
|
+
boneVisualsGroup.traverse(object => {
|
|
466
|
+
if (object.userData && object.userData.isVisualBone) {
|
|
467
|
+
// Get the parent and child bones
|
|
468
|
+
const parentBone = object.userData.parentBone;
|
|
469
|
+
const childBone = object.userData.childBone;
|
|
470
|
+
|
|
471
|
+
if (parentBone && childBone) {
|
|
472
|
+
// Regular joint between parent and child
|
|
473
|
+
const jointName = `Joint_${parentBone.name}_to_${childBone.name}`;
|
|
474
|
+
|
|
475
|
+
// Create joint data (without constraint type)
|
|
476
|
+
const jointData = {
|
|
477
|
+
name: jointName,
|
|
478
|
+
parentBone: parentBone.name,
|
|
479
|
+
childBone: childBone.name,
|
|
480
|
+
position: [object.position.x, object.position.y, object.position.z],
|
|
481
|
+
count: 1
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
rigDetails.joints.push(jointData);
|
|
485
|
+
} else if (object.userData.rootBone) {
|
|
486
|
+
// Root joint
|
|
487
|
+
const rootBone = object.userData.rootBone;
|
|
488
|
+
const jointName = `Root_Joint_${rootBone.name}`;
|
|
489
|
+
|
|
490
|
+
// Create joint data (without constraint type)
|
|
491
|
+
const jointData = {
|
|
492
|
+
name: jointName,
|
|
493
|
+
parentBone: "Scene Root",
|
|
494
|
+
childBone: rootBone.name,
|
|
495
|
+
position: [object.position.x, object.position.y, object.position.z],
|
|
496
|
+
count: 1,
|
|
497
|
+
isRoot: true
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
rigDetails.joints.push(jointData);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// Deduplicate the joints data
|
|
507
|
+
rigDetails.joints = deduplicateItemsByName(rigDetails.joints);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Set a label group
|
|
513
|
+
* @param {string|Object} typeOrName - The type of label group ('joint' or 'bone') or the name for backward compatibility
|
|
514
|
+
* @param {string|Object} nameOrScene - The name of the label group or the scene for backward compatibility
|
|
515
|
+
* @param {Object} [sceneParam] - The Three.js scene (optional for backward compatibility)
|
|
516
|
+
*/
|
|
517
|
+
export function setLabelGroup(typeOrName, nameOrScene, sceneParam) {
|
|
518
|
+
// Handle backward compatibility with old function signature
|
|
519
|
+
let type, name, scene;
|
|
520
|
+
|
|
521
|
+
if (typeof typeOrName === 'string' && (typeOrName === 'joint' || typeOrName === 'bone')) {
|
|
522
|
+
// New signature: (type, name, scene)
|
|
523
|
+
type = typeOrName;
|
|
524
|
+
name = nameOrScene;
|
|
525
|
+
scene = sceneParam;
|
|
526
|
+
} else {
|
|
527
|
+
// Old signature: (name, scene)
|
|
528
|
+
type = 'joint';
|
|
529
|
+
name = typeOrName;
|
|
530
|
+
scene = nameOrScene;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
const group = new THREE.Group();
|
|
534
|
+
group.name = name;
|
|
535
|
+
|
|
536
|
+
// Initialize visibility based on current settings
|
|
537
|
+
const isVisible = type === 'joint'
|
|
538
|
+
? rigOptions.showJointLabels && rigOptions.displayRig
|
|
539
|
+
: rigOptions.showBoneLabels && rigOptions.displayRig;
|
|
540
|
+
|
|
541
|
+
group.visible = isVisible;
|
|
542
|
+
console.log(`Creating ${type} label group with initial visibility:`, group.visible);
|
|
543
|
+
|
|
544
|
+
scene.add(group);
|
|
545
|
+
labelGroups.set(type, group);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Update the rig details object with new values
|
|
552
|
+
* @param {Object} newDetails - The new rig details object
|
|
553
|
+
*/
|
|
554
|
+
export function updateRigDetails(newDetails) {
|
|
555
|
+
rigDetails = newDetails;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Clear all labels of a specific type from the scene
|
|
560
|
+
* @param {string} type - The type of labels to clear ('joint' or 'bone')
|
|
561
|
+
* @param {Object} scene - The Three.js scene
|
|
562
|
+
*/
|
|
563
|
+
export function clearLabels(type, scene) {
|
|
564
|
+
const name = type === 'joint' ? "JointLabels" : "BoneLabels";
|
|
565
|
+
const existingLabels = scene.getObjectByName(name);
|
|
566
|
+
if (existingLabels) {
|
|
567
|
+
scene.remove(existingLabels);
|
|
568
|
+
if (labelGroups.has(type)) {
|
|
569
|
+
labelGroups.delete(type);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Show labels of a specific type
|
|
576
|
+
* @param {string} type - The type of labels to show ('joint' or 'bone')
|
|
577
|
+
*/
|
|
578
|
+
export function showLabels(type) {
|
|
579
|
+
const group = labelGroups.get(type);
|
|
580
|
+
if (group) {
|
|
581
|
+
console.log(`Explicitly showing ${type} labels`);
|
|
582
|
+
group.visible = true; // Force visibility regardless of other settings
|
|
583
|
+
|
|
584
|
+
// Also ensure each individual label is visible
|
|
585
|
+
group.children.forEach(label => {
|
|
586
|
+
if (label) {
|
|
587
|
+
label.visible = true;
|
|
588
|
+
}
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Hide labels of a specific type
|
|
595
|
+
* @param {string} type - The type of labels to hide ('joint' or 'bone')
|
|
596
|
+
*/
|
|
597
|
+
export function hideLabels(type) {
|
|
598
|
+
const group = labelGroups.get(type);
|
|
599
|
+
if (group) {
|
|
600
|
+
console.log(`Explicitly hiding ${type} labels`);
|
|
601
|
+
group.visible = false;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Get a specific label group
|
|
607
|
+
* @param {string} type - The type of label group to retrieve ('joint' or 'bone')
|
|
608
|
+
* @returns {Object} The requested label group or null if not found
|
|
609
|
+
*/
|
|
610
|
+
export function getLabelGroup(type) {
|
|
611
|
+
return labelGroups.get(type);
|
|
612
|
+
}
|