@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,822 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { getState } from '../util/state/scene-state';
|
|
3
|
+
|
|
4
|
+
// Add variables to track axis indicator state
|
|
5
|
+
let axisIndicatorCollapsed = false;
|
|
6
|
+
let axisIndicatorPosition = { x: null, y: null }; // null means use default position
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Create a coordinate axis indicator that blends into the scene
|
|
10
|
+
* @param {Object} scene - The Three.js scene
|
|
11
|
+
* @param {Object} camera - The Three.js camera
|
|
12
|
+
* @param {Object} renderer - The Three.js renderer
|
|
13
|
+
*/
|
|
14
|
+
export function createAxisIndicator(scene, camera, renderer) {
|
|
15
|
+
console.log('Creating modern axis indicator');
|
|
16
|
+
|
|
17
|
+
// Create a new scene for the axis indicator
|
|
18
|
+
const axisScene = new THREE.Scene();
|
|
19
|
+
// Make background transparent to blend with main scene
|
|
20
|
+
axisScene.background = null;
|
|
21
|
+
|
|
22
|
+
// Create a camera for the axis indicator with wider field of view
|
|
23
|
+
const axisCamera = new THREE.PerspectiveCamera(60, 1, 0.1, 20);
|
|
24
|
+
axisCamera.position.set(0, 0, 5); // Position even further back to ensure all axes visible
|
|
25
|
+
axisCamera.lookAt(0, 0, 0);
|
|
26
|
+
|
|
27
|
+
// Create modern axes
|
|
28
|
+
const createAxis = (dir, color) => {
|
|
29
|
+
const group = new THREE.Group();
|
|
30
|
+
|
|
31
|
+
// Create line for positive axis direction
|
|
32
|
+
const lineGeometry = new THREE.BufferGeometry();
|
|
33
|
+
// Make line slightly shorter to leave space for arrow
|
|
34
|
+
const endPoint = new THREE.Vector3(dir.x, dir.y, dir.z).multiplyScalar(0.85);
|
|
35
|
+
lineGeometry.setAttribute('position',
|
|
36
|
+
new THREE.Float32BufferAttribute([0, 0, 0, endPoint.x, endPoint.y, endPoint.z], 3));
|
|
37
|
+
|
|
38
|
+
const lineMaterial = new THREE.LineBasicMaterial({
|
|
39
|
+
color: color,
|
|
40
|
+
linewidth: 8, // Increased from 5 to 8
|
|
41
|
+
depthTest: false,
|
|
42
|
+
transparent: true,
|
|
43
|
+
opacity: 1.0
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const line = new THREE.Line(lineGeometry, lineMaterial);
|
|
47
|
+
group.add(line);
|
|
48
|
+
|
|
49
|
+
// Create negative axis direction (thicker, more visible dotted line)
|
|
50
|
+
const negLineGeometry = new THREE.BufferGeometry();
|
|
51
|
+
const negDir = new THREE.Vector3(-dir.x, -dir.y, -dir.z).multiplyScalar(0.85); // Increased from 0.7
|
|
52
|
+
negLineGeometry.setAttribute('position',
|
|
53
|
+
new THREE.Float32BufferAttribute([0, 0, 0, negDir.x, negDir.y, negDir.z], 3));
|
|
54
|
+
|
|
55
|
+
const dashedLineMaterial = new THREE.LineDashedMaterial({
|
|
56
|
+
color: color,
|
|
57
|
+
linewidth: 10, // Increased from 8
|
|
58
|
+
scale: 1,
|
|
59
|
+
dashSize: 0.18, // Increased from 0.15
|
|
60
|
+
gapSize: 0.07,
|
|
61
|
+
depthTest: false,
|
|
62
|
+
transparent: true,
|
|
63
|
+
opacity: 0.9 // Increased from 0.8
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const dashedLine = new THREE.Line(negLineGeometry, dashedLineMaterial);
|
|
67
|
+
dashedLine.computeLineDistances(); // Required for dashed lines
|
|
68
|
+
group.add(dashedLine);
|
|
69
|
+
|
|
70
|
+
// Create modern arrow head (smaller)
|
|
71
|
+
const arrowGeometry = new THREE.CylinderGeometry(0, 0.1, 0.25, 8, 1); // Reduced from 0.15, 0.35
|
|
72
|
+
const arrowMaterial = new THREE.MeshBasicMaterial({
|
|
73
|
+
color: color,
|
|
74
|
+
transparent: true,
|
|
75
|
+
opacity: 1.0,
|
|
76
|
+
depthTest: false
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const arrow = new THREE.Mesh(arrowGeometry, arrowMaterial);
|
|
80
|
+
|
|
81
|
+
// Position at the end of the line
|
|
82
|
+
arrow.position.copy(dir);
|
|
83
|
+
|
|
84
|
+
// Rotate arrow to point in the right direction
|
|
85
|
+
if (dir.x === 1) {
|
|
86
|
+
arrow.rotation.z = -Math.PI / 2;
|
|
87
|
+
} else if (dir.y === 1) {
|
|
88
|
+
// Default orientation works for Y
|
|
89
|
+
} else if (dir.z === 1) {
|
|
90
|
+
arrow.rotation.x = Math.PI / 2;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
group.add(arrow);
|
|
94
|
+
|
|
95
|
+
// Create text label
|
|
96
|
+
const text = dir.x === 1 ? 'X' : dir.y === 1 ? 'Y' : 'Z';
|
|
97
|
+
const canvas = document.createElement('canvas');
|
|
98
|
+
canvas.width = 192; // Increased from 128 to 192
|
|
99
|
+
canvas.height = 192; // Increased from 128 to 192
|
|
100
|
+
const ctx = canvas.getContext('2d');
|
|
101
|
+
|
|
102
|
+
// Clear canvas
|
|
103
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
104
|
+
|
|
105
|
+
// Draw text with a subtle glow effect
|
|
106
|
+
ctx.font = 'bold 90px Arial'; // Increased from 68px to 90px
|
|
107
|
+
ctx.textAlign = 'center';
|
|
108
|
+
ctx.textBaseline = 'middle';
|
|
109
|
+
|
|
110
|
+
// Add a subtle glow effect
|
|
111
|
+
ctx.shadowColor = color;
|
|
112
|
+
ctx.shadowBlur = 10; // Increased from 8 to 10
|
|
113
|
+
ctx.fillStyle = color;
|
|
114
|
+
ctx.fillText(text, canvas.width/2, canvas.height/2);
|
|
115
|
+
|
|
116
|
+
const texture = new THREE.CanvasTexture(canvas);
|
|
117
|
+
const spriteMaterial = new THREE.SpriteMaterial({
|
|
118
|
+
map: texture,
|
|
119
|
+
transparent: true,
|
|
120
|
+
depthTest: false
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const sprite = new THREE.Sprite(spriteMaterial);
|
|
124
|
+
// Position text beyond the arrow
|
|
125
|
+
sprite.position.copy(dir).multiplyScalar(1.5); // Increased from 1.4 to 1.5
|
|
126
|
+
sprite.scale.set(0.6, 0.6, 0.6); // Increased from 0.45 to 0.6
|
|
127
|
+
|
|
128
|
+
group.add(sprite);
|
|
129
|
+
|
|
130
|
+
return group;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// Create the three axes with modern colors
|
|
134
|
+
const xAxis = createAxis(new THREE.Vector3(1, 0, 0), '#ff4136'); // Vibrant red
|
|
135
|
+
const yAxis = createAxis(new THREE.Vector3(0, 1, 0), '#2ecc40'); // Vibrant green
|
|
136
|
+
const zAxis = createAxis(new THREE.Vector3(0, 0, 1), '#0074d9'); // Vibrant blue
|
|
137
|
+
|
|
138
|
+
axisScene.add(xAxis);
|
|
139
|
+
axisScene.add(yAxis);
|
|
140
|
+
axisScene.add(zAxis);
|
|
141
|
+
|
|
142
|
+
// Add a subtle center dot
|
|
143
|
+
const centerGeometry = new THREE.SphereGeometry(0.06, 16, 16); // Increased from 0.04, 12, 12
|
|
144
|
+
const centerMaterial = new THREE.MeshBasicMaterial({
|
|
145
|
+
color: 0xffffff,
|
|
146
|
+
transparent: true,
|
|
147
|
+
opacity: 0.9, // Increased from 0.8
|
|
148
|
+
depthTest: false
|
|
149
|
+
});
|
|
150
|
+
const centerSphere = new THREE.Mesh(centerGeometry, centerMaterial);
|
|
151
|
+
axisScene.add(centerSphere);
|
|
152
|
+
|
|
153
|
+
// Store references for cleanup later if needed
|
|
154
|
+
const state = getState();
|
|
155
|
+
state.axisScene = axisScene;
|
|
156
|
+
state.axisCamera = axisCamera;
|
|
157
|
+
|
|
158
|
+
// Find the correct viewport container (using the viewport ID)
|
|
159
|
+
let viewportContainer = document.getElementById('viewport');
|
|
160
|
+
|
|
161
|
+
// Fallback to direct parent if viewport not found
|
|
162
|
+
if (!viewportContainer) {
|
|
163
|
+
console.log('Viewport element not found, using renderer parent');
|
|
164
|
+
viewportContainer = renderer.domElement.closest('#viewport') ||
|
|
165
|
+
renderer.domElement.closest('#view-container') ||
|
|
166
|
+
renderer.domElement.closest('.view-panel') ||
|
|
167
|
+
renderer.domElement.parentElement;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
console.log('Found viewport container:', viewportContainer);
|
|
171
|
+
|
|
172
|
+
// Size for the axis indicator (proportional to viewport size)
|
|
173
|
+
const size = Math.min(180, viewportContainer.offsetWidth / 4);
|
|
174
|
+
|
|
175
|
+
// Create container for the entire axis indicator (header + display)
|
|
176
|
+
const axisContainer = document.createElement('div');
|
|
177
|
+
axisContainer.id = 'axis-indicator-container';
|
|
178
|
+
axisContainer.style.position = 'absolute';
|
|
179
|
+
axisContainer.style.width = `${size}px`;
|
|
180
|
+
axisContainer.style.zIndex = '1000';
|
|
181
|
+
axisContainer.style.pointerEvents = 'auto';
|
|
182
|
+
axisContainer.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.3)';
|
|
183
|
+
axisContainer.style.border = '1px solid rgba(50, 50, 50, 0.7)';
|
|
184
|
+
axisContainer.style.borderRadius = '5px';
|
|
185
|
+
axisContainer.style.overflow = 'hidden';
|
|
186
|
+
|
|
187
|
+
// Initial position (top-right corner of the viewport)
|
|
188
|
+
const margin = 10;
|
|
189
|
+
if (axisIndicatorPosition.x === null || axisIndicatorPosition.y === null) {
|
|
190
|
+
axisIndicatorPosition.x = viewportContainer.offsetWidth - size - margin;
|
|
191
|
+
axisIndicatorPosition.y = margin;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
axisContainer.style.left = `${axisIndicatorPosition.x}px`;
|
|
195
|
+
axisContainer.style.top = `${axisIndicatorPosition.y}px`;
|
|
196
|
+
|
|
197
|
+
// Create the header
|
|
198
|
+
const header = document.createElement('div');
|
|
199
|
+
header.id = 'axis-indicator-header';
|
|
200
|
+
header.style.backgroundColor = 'rgba(30, 30, 30, 0.7)';
|
|
201
|
+
header.style.color = 'white';
|
|
202
|
+
header.style.padding = '5px 10px';
|
|
203
|
+
header.style.cursor = 'grab';
|
|
204
|
+
header.style.userSelect = 'none';
|
|
205
|
+
header.style.display = 'flex';
|
|
206
|
+
header.style.alignItems = 'center';
|
|
207
|
+
header.style.justifyContent = 'space-between';
|
|
208
|
+
header.style.width = '100%'; // Full width
|
|
209
|
+
header.style.boxSizing = 'border-box'; // Include padding in width calculation
|
|
210
|
+
|
|
211
|
+
// Add title
|
|
212
|
+
const title = document.createElement('span');
|
|
213
|
+
title.textContent = 'Axis Indicator';
|
|
214
|
+
title.style.fontWeight = 'bold';
|
|
215
|
+
title.style.fontSize = '12px';
|
|
216
|
+
|
|
217
|
+
// Add collapse/expand button
|
|
218
|
+
const collapseBtn = document.createElement('span');
|
|
219
|
+
collapseBtn.textContent = axisIndicatorCollapsed ? '▼' : '▲';
|
|
220
|
+
collapseBtn.style.fontSize = '12px';
|
|
221
|
+
collapseBtn.style.cursor = 'pointer';
|
|
222
|
+
collapseBtn.style.marginLeft = '10px';
|
|
223
|
+
collapseBtn.style.width = '15px';
|
|
224
|
+
collapseBtn.style.textAlign = 'center';
|
|
225
|
+
|
|
226
|
+
// Add collapse functionality
|
|
227
|
+
collapseBtn.addEventListener('click', (e) => {
|
|
228
|
+
e.stopPropagation(); // Prevent triggering drag
|
|
229
|
+
axisIndicatorCollapsed = !axisIndicatorCollapsed;
|
|
230
|
+
collapseBtn.textContent = axisIndicatorCollapsed ? '▼' : '▲';
|
|
231
|
+
|
|
232
|
+
// Toggle display area visibility directly
|
|
233
|
+
const canvasContainer = document.getElementById('axis-indicator-canvas-container');
|
|
234
|
+
if (canvasContainer) {
|
|
235
|
+
canvasContainer.style.display = axisIndicatorCollapsed ? 'none' : 'block';
|
|
236
|
+
// Update container height when collapsed/expanded
|
|
237
|
+
updateContainerHeight();
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// Add elements to header
|
|
242
|
+
header.appendChild(title);
|
|
243
|
+
header.appendChild(collapseBtn);
|
|
244
|
+
|
|
245
|
+
// Create canvas container for the indicator display
|
|
246
|
+
const canvasContainer = document.createElement('div');
|
|
247
|
+
canvasContainer.id = 'axis-indicator-canvas-container';
|
|
248
|
+
canvasContainer.style.width = `${size}px`;
|
|
249
|
+
canvasContainer.style.height = `${size}px`;
|
|
250
|
+
canvasContainer.style.backgroundColor = 'rgba(0, 0, 0, 0)';
|
|
251
|
+
canvasContainer.style.display = axisIndicatorCollapsed ? 'none' : 'block';
|
|
252
|
+
|
|
253
|
+
// Add both elements to the container
|
|
254
|
+
axisContainer.appendChild(header);
|
|
255
|
+
axisContainer.appendChild(canvasContainer);
|
|
256
|
+
|
|
257
|
+
// Add the container to the viewport
|
|
258
|
+
viewportContainer.appendChild(axisContainer);
|
|
259
|
+
|
|
260
|
+
// Function to update container height based on collapsed state
|
|
261
|
+
function updateContainerHeight() {
|
|
262
|
+
if (axisIndicatorCollapsed) {
|
|
263
|
+
axisContainer.style.height = `${header.offsetHeight}px`;
|
|
264
|
+
} else {
|
|
265
|
+
axisContainer.style.height = 'auto';
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Call once to set initial height
|
|
270
|
+
updateContainerHeight();
|
|
271
|
+
|
|
272
|
+
// Store scale factor for axis objects
|
|
273
|
+
let axisScale = 1.0;
|
|
274
|
+
const scaleMin = 0.5;
|
|
275
|
+
const scaleMax = 3.0;
|
|
276
|
+
|
|
277
|
+
// Add zoom functionality when hovering over the indicator
|
|
278
|
+
canvasContainer.addEventListener('wheel', (e) => {
|
|
279
|
+
e.preventDefault();
|
|
280
|
+
|
|
281
|
+
// Determine zoom direction
|
|
282
|
+
const delta = Math.sign(-e.deltaY);
|
|
283
|
+
|
|
284
|
+
// Adjust scale factor
|
|
285
|
+
axisScale += delta * 0.15;
|
|
286
|
+
axisScale = Math.max(scaleMin, Math.min(scaleMax, axisScale));
|
|
287
|
+
|
|
288
|
+
// Apply scale to all axis objects
|
|
289
|
+
xAxis.scale.set(axisScale, axisScale, axisScale);
|
|
290
|
+
yAxis.scale.set(axisScale, axisScale, axisScale);
|
|
291
|
+
zAxis.scale.set(axisScale, axisScale, axisScale);
|
|
292
|
+
centerSphere.scale.set(axisScale, axisScale, axisScale);
|
|
293
|
+
|
|
294
|
+
console.log(`Axis scale: ${axisScale.toFixed(2)}`);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// Make the header draggable (moves the entire container)
|
|
298
|
+
let isHeaderDragging = false;
|
|
299
|
+
let startX, startY;
|
|
300
|
+
let startLeft, startTop;
|
|
301
|
+
|
|
302
|
+
header.addEventListener('mousedown', (e) => {
|
|
303
|
+
isHeaderDragging = true;
|
|
304
|
+
startX = e.clientX;
|
|
305
|
+
startY = e.clientY;
|
|
306
|
+
startLeft = parseInt(axisContainer.style.left);
|
|
307
|
+
startTop = parseInt(axisContainer.style.top);
|
|
308
|
+
header.style.cursor = 'grabbing';
|
|
309
|
+
|
|
310
|
+
e.preventDefault();
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
document.addEventListener('mousemove', (e) => {
|
|
314
|
+
if (!isHeaderDragging) return;
|
|
315
|
+
|
|
316
|
+
const dx = e.clientX - startX;
|
|
317
|
+
const dy = e.clientY - startY;
|
|
318
|
+
|
|
319
|
+
const newLeft = startLeft + dx;
|
|
320
|
+
const newTop = startTop + dy;
|
|
321
|
+
|
|
322
|
+
// Get current viewport container dimensions
|
|
323
|
+
const containerRect = viewportContainer.getBoundingClientRect();
|
|
324
|
+
const maxLeft = containerRect.width - axisContainer.offsetWidth;
|
|
325
|
+
const maxTop = containerRect.height - axisContainer.offsetHeight;
|
|
326
|
+
|
|
327
|
+
const constrainedLeft = Math.max(0, Math.min(newLeft, maxLeft));
|
|
328
|
+
const constrainedTop = Math.max(0, Math.min(newTop, maxTop));
|
|
329
|
+
|
|
330
|
+
axisContainer.style.left = `${constrainedLeft}px`;
|
|
331
|
+
axisContainer.style.top = `${constrainedTop}px`;
|
|
332
|
+
|
|
333
|
+
// Update stored position
|
|
334
|
+
axisIndicatorPosition.x = constrainedLeft;
|
|
335
|
+
axisIndicatorPosition.y = constrainedTop;
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
document.addEventListener('mouseup', () => {
|
|
339
|
+
if (isHeaderDragging) {
|
|
340
|
+
isHeaderDragging = false;
|
|
341
|
+
header.style.cursor = 'grab';
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
// Create a separate renderer for the axis scene
|
|
346
|
+
const axisRenderer = new THREE.WebGLRenderer({
|
|
347
|
+
alpha: true,
|
|
348
|
+
antialias: true
|
|
349
|
+
});
|
|
350
|
+
axisRenderer.setSize(size, size);
|
|
351
|
+
axisRenderer.setClearColor(0x000000, 0);
|
|
352
|
+
|
|
353
|
+
// Add the renderer to the container
|
|
354
|
+
canvasContainer.appendChild(axisRenderer.domElement);
|
|
355
|
+
|
|
356
|
+
// Store renderer reference
|
|
357
|
+
axisScene.renderer = axisRenderer;
|
|
358
|
+
|
|
359
|
+
// Add a render callback to draw the axis indicator
|
|
360
|
+
const originalRender = renderer.render;
|
|
361
|
+
renderer.render = function(scene, camera) {
|
|
362
|
+
// Call original render with main scene and camera
|
|
363
|
+
originalRender.call(this, scene, camera);
|
|
364
|
+
|
|
365
|
+
// Skip rendering if collapsed or container was removed
|
|
366
|
+
const canvasContainer = document.getElementById('axis-indicator-canvas-container');
|
|
367
|
+
if (axisIndicatorCollapsed || !canvasContainer) {
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// Update rotation to match main camera
|
|
372
|
+
if (state.camera) {
|
|
373
|
+
const cameraDir = new THREE.Vector3(0, 0, -1).applyQuaternion(state.camera.quaternion);
|
|
374
|
+
const distance = axisCamera.position.length();
|
|
375
|
+
axisCamera.position.copy(cameraDir).negate().multiplyScalar(distance);
|
|
376
|
+
axisCamera.lookAt(0, 0, 0);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Apply semi-transparency when overlaying content
|
|
380
|
+
const applyTransparency = (obj, factor) => {
|
|
381
|
+
if (obj.material) {
|
|
382
|
+
obj.material.opacity = obj.material.opacity * factor;
|
|
383
|
+
}
|
|
384
|
+
if (obj.children) {
|
|
385
|
+
obj.children.forEach(child => applyTransparency(child, factor));
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
// Apply transparency to all objects in axis scene
|
|
390
|
+
axisScene.children.forEach(obj => applyTransparency(obj, 0.7));
|
|
391
|
+
|
|
392
|
+
// Render axis scene with its own renderer
|
|
393
|
+
axisRenderer.render(axisScene, axisCamera);
|
|
394
|
+
|
|
395
|
+
// Reset transparency after rendering
|
|
396
|
+
axisScene.children.forEach(obj => {
|
|
397
|
+
const resetOpacity = (o) => {
|
|
398
|
+
if (o.material && o.material.opacity) {
|
|
399
|
+
o.material.opacity = o.material.opacity / 0.7;
|
|
400
|
+
}
|
|
401
|
+
if (o.children) {
|
|
402
|
+
o.children.forEach(child => resetOpacity(child));
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
resetOpacity(obj);
|
|
406
|
+
});
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
console.log('Modern axis indicator created with draggable header');
|
|
410
|
+
|
|
411
|
+
// Reset transparency after rendering
|
|
412
|
+
axisScene.children.forEach(obj => {
|
|
413
|
+
const resetOpacity = (o) => {
|
|
414
|
+
if (o.material && o.material.opacity) {
|
|
415
|
+
o.material.opacity = o.material.opacity / 0.7;
|
|
416
|
+
}
|
|
417
|
+
if (o.children) {
|
|
418
|
+
o.children.forEach(child => resetOpacity(child));
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
resetOpacity(obj);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
// Create axis indicator mode event listener
|
|
425
|
+
document.addEventListener('axisIndicatorModeChange', function(e) {
|
|
426
|
+
const mode = e.detail.mode;
|
|
427
|
+
const intensity = e.detail.intensity || 0.7;
|
|
428
|
+
console.log('Axis indicator mode changed to:', mode);
|
|
429
|
+
|
|
430
|
+
// Update the state's embedded intensity if applicable
|
|
431
|
+
const state = getState();
|
|
432
|
+
if (state.embeddedAxisIndicator) {
|
|
433
|
+
state.embeddedAxisIndicator.intensity = intensity;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Toggle between windowed, embedded, and disabled modes
|
|
437
|
+
if (mode === 'embedded') {
|
|
438
|
+
// Hide windowed version if it exists
|
|
439
|
+
const axisContainer = document.getElementById('axis-indicator-container');
|
|
440
|
+
if (axisContainer) {
|
|
441
|
+
axisContainer.style.display = 'none';
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// Create embedded version
|
|
445
|
+
createEmbeddedAxisIndicator(scene, camera, renderer);
|
|
446
|
+
} else if (mode === 'disabled') {
|
|
447
|
+
// Hide windowed version if it exists
|
|
448
|
+
const axisContainer = document.getElementById('axis-indicator-container');
|
|
449
|
+
if (axisContainer) {
|
|
450
|
+
axisContainer.style.display = 'none';
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// Remove embedded version if it exists
|
|
454
|
+
removeEmbeddedAxisIndicator();
|
|
455
|
+
} else {
|
|
456
|
+
// Show windowed version if it exists
|
|
457
|
+
const axisContainer = document.getElementById('axis-indicator-container');
|
|
458
|
+
if (axisContainer) {
|
|
459
|
+
axisContainer.style.display = 'block';
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Remove embedded version if it exists
|
|
463
|
+
removeEmbeddedAxisIndicator();
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
// Function to create embedded axis indicator
|
|
468
|
+
function createEmbeddedAxisIndicator(scene, camera, renderer) {
|
|
469
|
+
// Check if we already have an embedded axis indicator
|
|
470
|
+
const state = getState();
|
|
471
|
+
if (state.embeddedAxisIndicator) {
|
|
472
|
+
// If it exists, just set active to true
|
|
473
|
+
state.embeddedAxisIndicator.active = true;
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
console.log('Creating embedded axis indicator');
|
|
478
|
+
|
|
479
|
+
// Create a new scene for the embedded axis indicator
|
|
480
|
+
const embeddedAxisScene = new THREE.Scene();
|
|
481
|
+
embeddedAxisScene.background = null; // Transparent background
|
|
482
|
+
|
|
483
|
+
// Create a camera for the embedded axis indicator with wide FOV
|
|
484
|
+
const embeddedAxisCamera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000);
|
|
485
|
+
embeddedAxisCamera.position.set(0, 0, 15); // Scaled back for better visibility
|
|
486
|
+
embeddedAxisCamera.lookAt(0, 0, 0);
|
|
487
|
+
|
|
488
|
+
// Create appropriately sized axes for background
|
|
489
|
+
const axisScale = 6.0; // Reduced scale by 25% (from 8.0 to 6.0)
|
|
490
|
+
|
|
491
|
+
// Create a modified axis creation function with thicker lines and smaller cones
|
|
492
|
+
const createEmbeddedAxis = (dir, color) => {
|
|
493
|
+
const group = new THREE.Group();
|
|
494
|
+
|
|
495
|
+
// Create line for positive axis direction - MUCH THICKER
|
|
496
|
+
const lineGeometry = new THREE.BufferGeometry();
|
|
497
|
+
const endPoint = new THREE.Vector3(dir.x, dir.y, dir.z).multiplyScalar(0.92); // Longer line
|
|
498
|
+
lineGeometry.setAttribute('position',
|
|
499
|
+
new THREE.Float32BufferAttribute([0, 0, 0, endPoint.x, endPoint.y, endPoint.z], 3));
|
|
500
|
+
|
|
501
|
+
const lineMaterial = new THREE.LineBasicMaterial({
|
|
502
|
+
color: color,
|
|
503
|
+
linewidth: 45,
|
|
504
|
+
depthTest: false,
|
|
505
|
+
transparent: true,
|
|
506
|
+
opacity: 1.0
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
const line = new THREE.Line(lineGeometry, lineMaterial);
|
|
510
|
+
group.add(line);
|
|
511
|
+
|
|
512
|
+
// Create negative axis direction with thicker dashed line
|
|
513
|
+
const negLineGeometry = new THREE.BufferGeometry();
|
|
514
|
+
const negDir = new THREE.Vector3(-dir.x, -dir.y, -dir.z).multiplyScalar(0.92); // Longer line
|
|
515
|
+
negLineGeometry.setAttribute('position',
|
|
516
|
+
new THREE.Float32BufferAttribute([0, 0, 0, negDir.x, negDir.y, negDir.z], 3));
|
|
517
|
+
|
|
518
|
+
const dashedLineMaterial = new THREE.LineDashedMaterial({
|
|
519
|
+
color: color,
|
|
520
|
+
linewidth: 45,
|
|
521
|
+
scale: 1,
|
|
522
|
+
dashSize: 0.2, // Larger dashes
|
|
523
|
+
gapSize: 0.05, // Smaller gaps
|
|
524
|
+
depthTest: false,
|
|
525
|
+
transparent: true,
|
|
526
|
+
opacity: 0.9
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
const dashedLine = new THREE.Line(negLineGeometry, dashedLineMaterial);
|
|
530
|
+
dashedLine.computeLineDistances(); // Required for dashed lines
|
|
531
|
+
group.add(dashedLine);
|
|
532
|
+
|
|
533
|
+
// Create very small arrow head (cone)
|
|
534
|
+
const arrowGeometry = new THREE.CylinderGeometry(0, 0.05, 0.15, 6, 1); // Tiny cone
|
|
535
|
+
const arrowMaterial = new THREE.MeshBasicMaterial({
|
|
536
|
+
color: color,
|
|
537
|
+
transparent: true,
|
|
538
|
+
opacity: 1.0,
|
|
539
|
+
depthTest: false
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
const arrow = new THREE.Mesh(arrowGeometry, arrowMaterial);
|
|
543
|
+
|
|
544
|
+
// Position at the end of the line
|
|
545
|
+
arrow.position.copy(dir);
|
|
546
|
+
|
|
547
|
+
// Rotate arrow to point in the right direction
|
|
548
|
+
if (dir.x === 1) {
|
|
549
|
+
arrow.rotation.z = -Math.PI / 2;
|
|
550
|
+
} else if (dir.y === 1) {
|
|
551
|
+
// Default orientation works for Y
|
|
552
|
+
} else if (dir.z === 1) {
|
|
553
|
+
arrow.rotation.x = Math.PI / 2;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
group.add(arrow);
|
|
557
|
+
|
|
558
|
+
// Create larger and more visible text label
|
|
559
|
+
const text = dir.x === 1 ? 'X' : dir.y === 1 ? 'Y' : 'Z';
|
|
560
|
+
const canvas = document.createElement('canvas');
|
|
561
|
+
canvas.width = 256; // Larger canvas for clearer text
|
|
562
|
+
canvas.height = 256;
|
|
563
|
+
const ctx = canvas.getContext('2d');
|
|
564
|
+
|
|
565
|
+
// Clear canvas
|
|
566
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
567
|
+
|
|
568
|
+
// Draw text with a stronger glow effect
|
|
569
|
+
ctx.font = 'bold 96px Arial'; // Larger font
|
|
570
|
+
ctx.textAlign = 'center';
|
|
571
|
+
ctx.textBaseline = 'middle';
|
|
572
|
+
|
|
573
|
+
// Add a stronger glow effect
|
|
574
|
+
ctx.shadowColor = color;
|
|
575
|
+
ctx.shadowBlur = 15;
|
|
576
|
+
ctx.fillStyle = color;
|
|
577
|
+
ctx.fillText(text, canvas.width/2, canvas.height/2);
|
|
578
|
+
|
|
579
|
+
const texture = new THREE.CanvasTexture(canvas);
|
|
580
|
+
const spriteMaterial = new THREE.SpriteMaterial({
|
|
581
|
+
map: texture,
|
|
582
|
+
transparent: true,
|
|
583
|
+
depthTest: false
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
const sprite = new THREE.Sprite(spriteMaterial);
|
|
587
|
+
// Position text closer to the arrow tip
|
|
588
|
+
sprite.position.copy(dir).multiplyScalar(1.2); // Reduced from 1.6 to bring labels closer
|
|
589
|
+
sprite.scale.set(0.6, 0.6, 0.6); // Reduced label size by 25% (from 0.8 to 0.6)
|
|
590
|
+
|
|
591
|
+
group.add(sprite);
|
|
592
|
+
|
|
593
|
+
return group;
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
// Create the three axes using our embedded axis creation function
|
|
597
|
+
const embeddedXAxis = createEmbeddedAxis(new THREE.Vector3(1, 0, 0), '#ff4136'); // Red
|
|
598
|
+
const embeddedYAxis = createEmbeddedAxis(new THREE.Vector3(0, 1, 0), '#2ecc40'); // Green
|
|
599
|
+
const embeddedZAxis = createEmbeddedAxis(new THREE.Vector3(0, 0, 1), '#0074d9'); // Blue
|
|
600
|
+
|
|
601
|
+
// Scale up the axes for visibility while keeping proportions reasonable
|
|
602
|
+
embeddedXAxis.scale.set(axisScale, axisScale, axisScale);
|
|
603
|
+
embeddedYAxis.scale.set(axisScale, axisScale, axisScale);
|
|
604
|
+
embeddedZAxis.scale.set(axisScale, axisScale, axisScale);
|
|
605
|
+
|
|
606
|
+
// Add axes to the embedded scene
|
|
607
|
+
embeddedAxisScene.add(embeddedXAxis);
|
|
608
|
+
embeddedAxisScene.add(embeddedYAxis);
|
|
609
|
+
embeddedAxisScene.add(embeddedZAxis);
|
|
610
|
+
|
|
611
|
+
// Create a smaller center reference point (MAKE INVISIBLE)
|
|
612
|
+
const embeddedCenterGeometry = new THREE.SphereGeometry(0.05 * axisScale, 16, 16);
|
|
613
|
+
const embeddedCenterMaterial = new THREE.MeshBasicMaterial({
|
|
614
|
+
color: 0xffffff,
|
|
615
|
+
transparent: true,
|
|
616
|
+
opacity: 0, // Set opacity to 0 to make it invisible
|
|
617
|
+
depthTest: false
|
|
618
|
+
});
|
|
619
|
+
const embeddedCenterSphere = new THREE.Mesh(embeddedCenterGeometry, embeddedCenterMaterial);
|
|
620
|
+
embeddedAxisScene.add(embeddedCenterSphere);
|
|
621
|
+
|
|
622
|
+
// Get intensity value from settings if available
|
|
623
|
+
let intensity = 0.7; // Default intensity
|
|
624
|
+
const savedSettings = localStorage.getItem('assetDebuggerSettings');
|
|
625
|
+
if (savedSettings) {
|
|
626
|
+
try {
|
|
627
|
+
const settings = JSON.parse(savedSettings);
|
|
628
|
+
if (settings.axisIndicator && settings.axisIndicator.intensity !== undefined) {
|
|
629
|
+
intensity = settings.axisIndicator.intensity;
|
|
630
|
+
}
|
|
631
|
+
} catch (e) {
|
|
632
|
+
console.error('Error reading intensity from settings:', e);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
// Store references
|
|
637
|
+
state.embeddedAxisIndicator = {
|
|
638
|
+
scene: embeddedAxisScene,
|
|
639
|
+
camera: embeddedAxisCamera,
|
|
640
|
+
xAxis: embeddedXAxis,
|
|
641
|
+
yAxis: embeddedYAxis,
|
|
642
|
+
zAxis: embeddedZAxis,
|
|
643
|
+
centerSphere: embeddedCenterSphere,
|
|
644
|
+
scale: axisScale,
|
|
645
|
+
active: true, // Mark as active
|
|
646
|
+
intensity: intensity // Use intensity from settings
|
|
647
|
+
};
|
|
648
|
+
|
|
649
|
+
// Create a renderer for the embedded axis indicator
|
|
650
|
+
const originalRender = renderer.render;
|
|
651
|
+
|
|
652
|
+
// Replace the renderer.render method
|
|
653
|
+
renderer.render = function(mainScene, mainCamera) {
|
|
654
|
+
// Check if embedded axis indicator is active
|
|
655
|
+
if (state.embeddedAxisIndicator && state.embeddedAxisIndicator.active) {
|
|
656
|
+
// First clear the renderer with black background
|
|
657
|
+
const oldClearColor = renderer.getClearColor(new THREE.Color());
|
|
658
|
+
const oldClearAlpha = renderer.getClearAlpha();
|
|
659
|
+
|
|
660
|
+
// Save auto clear settings
|
|
661
|
+
const oldAutoClear = renderer.autoClear;
|
|
662
|
+
const oldAutoClearColor = renderer.autoClearColor;
|
|
663
|
+
const oldAutoClearDepth = renderer.autoClearDepth;
|
|
664
|
+
const oldAutoClearStencil = renderer.autoClearStencil;
|
|
665
|
+
|
|
666
|
+
// Clear with black background
|
|
667
|
+
renderer.setClearColor(0x000000, 1);
|
|
668
|
+
renderer.clear(); // Clear everything
|
|
669
|
+
|
|
670
|
+
// Update embedded camera to match main camera rotation
|
|
671
|
+
if (mainCamera) {
|
|
672
|
+
const cameraDir = new THREE.Vector3(0, 0, -1).applyQuaternion(mainCamera.quaternion);
|
|
673
|
+
const distance = embeddedAxisCamera.position.length();
|
|
674
|
+
embeddedAxisCamera.position.copy(cameraDir).negate().multiplyScalar(distance);
|
|
675
|
+
embeddedAxisCamera.lookAt(0, 0, 0);
|
|
676
|
+
|
|
677
|
+
// Match aspect ratio
|
|
678
|
+
embeddedAxisCamera.aspect = mainCamera.aspect;
|
|
679
|
+
embeddedAxisCamera.updateProjectionMatrix();
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// Adjust opacity for background effect
|
|
683
|
+
const applyBackgroundOpacity = (obj) => {
|
|
684
|
+
if (obj.material) {
|
|
685
|
+
// Use the stored intensity value
|
|
686
|
+
const intensity = state.embeddedAxisIndicator.intensity || 0.7;
|
|
687
|
+
obj.material.opacity = obj.material.originalOpacity * intensity;
|
|
688
|
+
}
|
|
689
|
+
if (obj.children) {
|
|
690
|
+
obj.children.forEach(child => applyBackgroundOpacity(child));
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
// Save original opacity values first time
|
|
695
|
+
if (!state.embeddedAxisIndicator.opacitySaved) {
|
|
696
|
+
state.embeddedAxisIndicator.scene.traverse(obj => {
|
|
697
|
+
if (obj.material && obj.material.opacity !== undefined) {
|
|
698
|
+
obj.material.originalOpacity = obj.material.opacity;
|
|
699
|
+
}
|
|
700
|
+
});
|
|
701
|
+
state.embeddedAxisIndicator.opacitySaved = true;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
// Apply transparency to all objects in embedded axis scene
|
|
705
|
+
state.embeddedAxisIndicator.scene.traverse(applyBackgroundOpacity);
|
|
706
|
+
|
|
707
|
+
// Special settings for background rendering
|
|
708
|
+
renderer.autoClear = false;
|
|
709
|
+
renderer.autoClearDepth = true;
|
|
710
|
+
renderer.autoClearColor = false;
|
|
711
|
+
renderer.autoClearStencil = false;
|
|
712
|
+
|
|
713
|
+
// Render the axis scene first (as background)
|
|
714
|
+
originalRender.call(this, embeddedAxisScene, embeddedAxisCamera);
|
|
715
|
+
|
|
716
|
+
// Restore original material opacity
|
|
717
|
+
const restoreOpacity = (obj) => {
|
|
718
|
+
if (obj.material && obj.material.originalOpacity !== undefined) {
|
|
719
|
+
obj.material.opacity = obj.material.originalOpacity;
|
|
720
|
+
}
|
|
721
|
+
if (obj.children) {
|
|
722
|
+
obj.children.forEach(child => restoreOpacity(child));
|
|
723
|
+
}
|
|
724
|
+
};
|
|
725
|
+
|
|
726
|
+
state.embeddedAxisIndicator.scene.traverse(restoreOpacity);
|
|
727
|
+
|
|
728
|
+
// Reset settings for main scene render
|
|
729
|
+
renderer.autoClear = false; // Don't clear again
|
|
730
|
+
renderer.setClearColor(oldClearColor, oldClearAlpha);
|
|
731
|
+
|
|
732
|
+
// Now render the main scene on top
|
|
733
|
+
originalRender.call(this, mainScene, mainCamera);
|
|
734
|
+
|
|
735
|
+
// Restore original settings
|
|
736
|
+
renderer.autoClear = oldAutoClear;
|
|
737
|
+
renderer.autoClearColor = oldAutoClearColor;
|
|
738
|
+
renderer.autoClearDepth = oldAutoClearDepth;
|
|
739
|
+
renderer.autoClearStencil = oldAutoClearStencil;
|
|
740
|
+
} else {
|
|
741
|
+
// If embedded mode not active, just render normally
|
|
742
|
+
originalRender.call(this, mainScene, mainCamera);
|
|
743
|
+
}
|
|
744
|
+
};
|
|
745
|
+
|
|
746
|
+
console.log('Full-screen embedded axis indicator created successfully with intensity:', intensity);
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
// Function to remove embedded axis indicator
|
|
750
|
+
function removeEmbeddedAxisIndicator() {
|
|
751
|
+
const state = getState();
|
|
752
|
+
|
|
753
|
+
if (state.embeddedAxisIndicator) {
|
|
754
|
+
console.log('Removing embedded axis indicator');
|
|
755
|
+
|
|
756
|
+
// Mark as inactive first
|
|
757
|
+
state.embeddedAxisIndicator.active = false;
|
|
758
|
+
|
|
759
|
+
// If we have a scene, remove all objects to prevent memory leaks
|
|
760
|
+
if (state.embeddedAxisIndicator.scene) {
|
|
761
|
+
// Dispose of geometries and materials
|
|
762
|
+
state.embeddedAxisIndicator.scene.traverse((object) => {
|
|
763
|
+
if (object.geometry) {
|
|
764
|
+
object.geometry.dispose();
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
if (object.material) {
|
|
768
|
+
if (Array.isArray(object.material)) {
|
|
769
|
+
object.material.forEach(material => material.dispose());
|
|
770
|
+
} else {
|
|
771
|
+
object.material.dispose();
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
// Clear the scene
|
|
777
|
+
while (state.embeddedAxisIndicator.scene.children.length > 0) {
|
|
778
|
+
state.embeddedAxisIndicator.scene.remove(state.embeddedAxisIndicator.scene.children[0]);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
// Free references to Three.js objects
|
|
783
|
+
state.embeddedAxisIndicator.xAxis = null;
|
|
784
|
+
state.embeddedAxisIndicator.yAxis = null;
|
|
785
|
+
state.embeddedAxisIndicator.zAxis = null;
|
|
786
|
+
state.embeddedAxisIndicator.centerSphere = null;
|
|
787
|
+
state.embeddedAxisIndicator.scene = null;
|
|
788
|
+
state.embeddedAxisIndicator.camera = null;
|
|
789
|
+
|
|
790
|
+
// Keep the embeddedAxisIndicator object but mark it as inactive
|
|
791
|
+
// This allows us to maintain settings like intensity
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
// Check for saved settings to initialize correct mode
|
|
796
|
+
const savedSettings = localStorage.getItem('assetDebuggerSettings');
|
|
797
|
+
if (savedSettings) {
|
|
798
|
+
try {
|
|
799
|
+
const settings = JSON.parse(savedSettings);
|
|
800
|
+
if (settings.axisIndicator && settings.axisIndicator.type) {
|
|
801
|
+
const mode = settings.axisIndicator.type;
|
|
802
|
+
const intensity = settings.axisIndicator.intensity || 0.7;
|
|
803
|
+
|
|
804
|
+
// Always forcefully trigger the mode change to ensure correct state
|
|
805
|
+
setTimeout(() => {
|
|
806
|
+
document.dispatchEvent(new CustomEvent('axisIndicatorModeChange', {
|
|
807
|
+
detail: {
|
|
808
|
+
mode: mode,
|
|
809
|
+
intensity: intensity
|
|
810
|
+
}
|
|
811
|
+
}));
|
|
812
|
+
console.log('Forced axis indicator mode:', mode);
|
|
813
|
+
}, 200);
|
|
814
|
+
}
|
|
815
|
+
} catch (e) {
|
|
816
|
+
console.error('Error loading saved axis indicator settings:', e);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
// Draw a debug log to confirm axis indicator creation complete
|
|
821
|
+
console.log('Modern axis indicator setup complete');
|
|
822
|
+
}
|