@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,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Texture Debugger - Atlas Panel Module
|
|
3
|
+
*
|
|
4
|
+
* This module handles texture atlas visualization in the UI.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { getState, updateState } from '../../../util/state/scene-state.js';
|
|
8
|
+
|
|
9
|
+
// Track initialization state
|
|
10
|
+
let isInitialized = false;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Initialize the atlas panel and set up event listeners
|
|
14
|
+
*/
|
|
15
|
+
export function initAtlasPanel() {
|
|
16
|
+
// Prevent duplicate logging but allow initialization to continue
|
|
17
|
+
if (isInitialized) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
isInitialized = true;
|
|
22
|
+
|
|
23
|
+
// Initialize the panel once the atlas-heading-container is found and has content
|
|
24
|
+
const initCheck = setInterval(() => {
|
|
25
|
+
const container = document.getElementById('atlas-heading-container');
|
|
26
|
+
if (container && container.children.length > 0) {
|
|
27
|
+
clearInterval(initCheck);
|
|
28
|
+
setupAtlasPanelEvents();
|
|
29
|
+
}
|
|
30
|
+
}, 100);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Set up event listeners for the atlas panel
|
|
35
|
+
*/
|
|
36
|
+
function setupAtlasPanelEvents() {
|
|
37
|
+
const textureTypeButtons = document.querySelectorAll('.texture-type-button');
|
|
38
|
+
|
|
39
|
+
// Check if any button has the active class
|
|
40
|
+
let hasActiveButton = false;
|
|
41
|
+
textureTypeButtons.forEach(button => {
|
|
42
|
+
if (button.classList.contains('active')) {
|
|
43
|
+
hasActiveButton = true;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// If no button is active, set the first one as active
|
|
48
|
+
if (!hasActiveButton && textureTypeButtons.length > 0) {
|
|
49
|
+
textureTypeButtons[0].classList.add('active');
|
|
50
|
+
// Update state with the default texture type
|
|
51
|
+
updateState('currentTextureType', textureTypeButtons[0].dataset.textureType);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Set up texture type button handlers
|
|
55
|
+
textureTypeButtons.forEach(button => {
|
|
56
|
+
button.addEventListener('click', () => {
|
|
57
|
+
// Update active state
|
|
58
|
+
textureTypeButtons.forEach(btn => btn.classList.remove('active'));
|
|
59
|
+
button.classList.add('active');
|
|
60
|
+
|
|
61
|
+
// Update current texture type in state
|
|
62
|
+
updateState('currentTextureType', button.dataset.textureType);
|
|
63
|
+
|
|
64
|
+
// Update visualization
|
|
65
|
+
updateAtlasVisualization();
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Initialize visualization
|
|
70
|
+
updateAtlasVisualization();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Update the atlas visualization based on current texture state
|
|
75
|
+
*/
|
|
76
|
+
export function updateAtlasVisualization() {
|
|
77
|
+
// Get state to retrieve texture objects
|
|
78
|
+
const state = getState();
|
|
79
|
+
|
|
80
|
+
// Check if we have texture objects
|
|
81
|
+
if (!state.textureObjects) {
|
|
82
|
+
console.warn('No texture objects available for atlas visualization');
|
|
83
|
+
// Show no texture state for the canvas
|
|
84
|
+
const atlasCanvas = document.getElementById('atlas-canvas');
|
|
85
|
+
if (atlasCanvas) {
|
|
86
|
+
showNoTextureState(atlasCanvas);
|
|
87
|
+
}
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Get the current atlas textures
|
|
92
|
+
const baseColorTexture = state.textureObjects.baseColor;
|
|
93
|
+
const ormTexture = state.textureObjects.orm;
|
|
94
|
+
const normalTexture = state.textureObjects.normal;
|
|
95
|
+
|
|
96
|
+
// Get the current texture type from state
|
|
97
|
+
const currentTextureType = state.currentTextureType || 'baseColor';
|
|
98
|
+
|
|
99
|
+
// Get the active texture based on current texture type
|
|
100
|
+
let activeTexture = null;
|
|
101
|
+
if (currentTextureType === 'baseColor') {
|
|
102
|
+
activeTexture = baseColorTexture;
|
|
103
|
+
} else if (currentTextureType === 'orm') {
|
|
104
|
+
activeTexture = ormTexture;
|
|
105
|
+
} else if (currentTextureType === 'normal') {
|
|
106
|
+
activeTexture = normalTexture;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Get the atlas canvas
|
|
110
|
+
const atlasCanvas = document.getElementById('atlas-canvas');
|
|
111
|
+
if (!atlasCanvas) {
|
|
112
|
+
console.warn('Atlas canvas not found');
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Get current UV region from state or use default
|
|
117
|
+
const currentRegion = state.currentUvRegion || { min: [0, 0], max: [1, 1] };
|
|
118
|
+
|
|
119
|
+
// Show the active texture or no texture state
|
|
120
|
+
if (activeTexture) {
|
|
121
|
+
updateCanvasWithTexture(activeTexture, currentRegion);
|
|
122
|
+
} else {
|
|
123
|
+
showNoTextureState(atlasCanvas);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Update the canvas with the texture
|
|
129
|
+
* @param {THREE.Texture} texture - The texture to display
|
|
130
|
+
* @param {Object} currentRegion - The UV region to highlight
|
|
131
|
+
*/
|
|
132
|
+
function updateCanvasWithTexture(texture, currentRegion = { min: [0, 0], max: [1, 1] }) {
|
|
133
|
+
const atlasCanvas = document.getElementById('atlas-canvas');
|
|
134
|
+
const coordsText = document.getElementById('coords-text');
|
|
135
|
+
|
|
136
|
+
if (!atlasCanvas || !texture || !texture.image) return;
|
|
137
|
+
|
|
138
|
+
const ctx = atlasCanvas.getContext('2d');
|
|
139
|
+
|
|
140
|
+
// Set canvas dimensions to match texture
|
|
141
|
+
atlasCanvas.width = texture.image.width;
|
|
142
|
+
atlasCanvas.height = texture.image.height;
|
|
143
|
+
|
|
144
|
+
// Clear canvas
|
|
145
|
+
ctx.clearRect(0, 0, atlasCanvas.width, atlasCanvas.height);
|
|
146
|
+
|
|
147
|
+
// Draw the texture with proper scaling
|
|
148
|
+
try {
|
|
149
|
+
ctx.drawImage(texture.image, 0, 0);
|
|
150
|
+
} catch (error) {
|
|
151
|
+
console.error('Error drawing texture to canvas:', error);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Add overlay grid for UV coordinates
|
|
155
|
+
drawUvGrid(ctx, atlasCanvas.width, atlasCanvas.height);
|
|
156
|
+
|
|
157
|
+
// Draw red highlight to show current region used on the model
|
|
158
|
+
drawHighlightRegion(ctx, currentRegion, atlasCanvas.width, atlasCanvas.height);
|
|
159
|
+
|
|
160
|
+
// Set proper CSS for the canvas
|
|
161
|
+
atlasCanvas.style.width = '100%';
|
|
162
|
+
atlasCanvas.style.height = 'auto';
|
|
163
|
+
atlasCanvas.style.maxHeight = '100%';
|
|
164
|
+
atlasCanvas.style.objectFit = 'contain';
|
|
165
|
+
atlasCanvas.style.display = 'block';
|
|
166
|
+
|
|
167
|
+
// Update coordinates text
|
|
168
|
+
if (coordsText) {
|
|
169
|
+
const isFullTexture = (currentRegion.min[0] === 0 && currentRegion.min[1] === 0 &&
|
|
170
|
+
currentRegion.max[0] === 1 && currentRegion.max[1] === 1);
|
|
171
|
+
|
|
172
|
+
if (isFullTexture) {
|
|
173
|
+
coordsText.textContent = `${getState().currentTextureType}: Full texture (0,0) to (1,1)`;
|
|
174
|
+
} else {
|
|
175
|
+
coordsText.textContent = `${getState().currentTextureType}: (${currentRegion.min[0].toFixed(2)},${currentRegion.min[1].toFixed(2)}) to (${currentRegion.max[0].toFixed(2)},${currentRegion.max[1].toFixed(2)})`;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Show "No texture loaded" message in the canvas
|
|
182
|
+
* @param {HTMLCanvasElement} atlasCanvas - The canvas element
|
|
183
|
+
*/
|
|
184
|
+
function showNoTextureState(atlasCanvas) {
|
|
185
|
+
const coordsText = document.getElementById('coords-text');
|
|
186
|
+
if (!atlasCanvas) return;
|
|
187
|
+
|
|
188
|
+
const ctx = atlasCanvas.getContext('2d');
|
|
189
|
+
|
|
190
|
+
// Use a reasonable size for the empty state
|
|
191
|
+
atlasCanvas.width = 260;
|
|
192
|
+
atlasCanvas.height = 260;
|
|
193
|
+
|
|
194
|
+
// Clear canvas with transparent background
|
|
195
|
+
ctx.clearRect(0, 0, atlasCanvas.width, atlasCanvas.height);
|
|
196
|
+
|
|
197
|
+
// Draw a visible border
|
|
198
|
+
ctx.strokeStyle = '#666';
|
|
199
|
+
ctx.lineWidth = 2;
|
|
200
|
+
ctx.strokeRect(2, 2, atlasCanvas.width - 4, atlasCanvas.height - 4);
|
|
201
|
+
|
|
202
|
+
// Add a subtle background to make text more readable
|
|
203
|
+
ctx.fillStyle = 'rgba(40, 40, 40, 0.3)';
|
|
204
|
+
ctx.fillRect(2, 2, atlasCanvas.width - 4, atlasCanvas.height - 4);
|
|
205
|
+
|
|
206
|
+
// Get current texture type from state
|
|
207
|
+
const currentTextureType = getState().currentTextureType || 'texture';
|
|
208
|
+
|
|
209
|
+
// Draw "No Atlas Data" text
|
|
210
|
+
ctx.fillStyle = '#aaa';
|
|
211
|
+
ctx.font = 'bold 16px monospace';
|
|
212
|
+
ctx.textAlign = 'center';
|
|
213
|
+
ctx.textBaseline = 'middle';
|
|
214
|
+
ctx.fillText(`No ${currentTextureType} Data`, atlasCanvas.width / 2, atlasCanvas.height / 2 - 15);
|
|
215
|
+
|
|
216
|
+
// Set proper CSS for the canvas to maintain aspect ratio and fit in container
|
|
217
|
+
atlasCanvas.style.width = '100%';
|
|
218
|
+
atlasCanvas.style.height = 'auto';
|
|
219
|
+
atlasCanvas.style.maxHeight = '100%';
|
|
220
|
+
atlasCanvas.style.objectFit = 'contain';
|
|
221
|
+
atlasCanvas.style.display = 'block';
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Draw a UV coordinate grid on the canvas
|
|
226
|
+
* @param {CanvasRenderingContext2D} ctx - The canvas context
|
|
227
|
+
* @param {number} width - The canvas width
|
|
228
|
+
* @param {number} height - The canvas height
|
|
229
|
+
*/
|
|
230
|
+
function drawUvGrid(ctx, width, height) {
|
|
231
|
+
// Draw grid lines
|
|
232
|
+
ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';
|
|
233
|
+
ctx.lineWidth = 1;
|
|
234
|
+
|
|
235
|
+
// Draw vertical grid lines
|
|
236
|
+
for (let i = 1; i < 10; i++) {
|
|
237
|
+
const x = width * i / 10;
|
|
238
|
+
ctx.beginPath();
|
|
239
|
+
ctx.moveTo(x, 0);
|
|
240
|
+
ctx.lineTo(x, height);
|
|
241
|
+
ctx.stroke();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Draw horizontal grid lines
|
|
245
|
+
for (let i = 1; i < 10; i++) {
|
|
246
|
+
const y = height * i / 10;
|
|
247
|
+
ctx.beginPath();
|
|
248
|
+
ctx.moveTo(0, y);
|
|
249
|
+
ctx.lineTo(width, y);
|
|
250
|
+
ctx.stroke();
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Draw coordinate labels
|
|
254
|
+
ctx.fillStyle = 'white';
|
|
255
|
+
ctx.font = '10px monospace';
|
|
256
|
+
|
|
257
|
+
// 0,0 at bottom left
|
|
258
|
+
ctx.fillText('0,0', 2, height - 2);
|
|
259
|
+
|
|
260
|
+
// 1,0 at bottom right
|
|
261
|
+
ctx.fillText('1,0', width - 20, height - 2);
|
|
262
|
+
|
|
263
|
+
// 0,1 at top left
|
|
264
|
+
ctx.fillText('0,1', 2, 10);
|
|
265
|
+
|
|
266
|
+
// 1,1 at top right
|
|
267
|
+
ctx.fillText('1,1', width - 20, 10);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Draw a highlight region on the canvas
|
|
272
|
+
* @param {CanvasRenderingContext2D} ctx - The canvas context
|
|
273
|
+
* @param {Object} region - The region to highlight {min: [x, y], max: [x, y]}
|
|
274
|
+
* @param {number} width - The canvas width
|
|
275
|
+
* @param {number} height - The canvas height
|
|
276
|
+
*/
|
|
277
|
+
function drawHighlightRegion(ctx, region, width, height) {
|
|
278
|
+
// Draw highlight box
|
|
279
|
+
ctx.strokeStyle = 'red';
|
|
280
|
+
ctx.lineWidth = 2;
|
|
281
|
+
ctx.beginPath();
|
|
282
|
+
|
|
283
|
+
// Calculate rect coordinates (remember Y needs to be flipped)
|
|
284
|
+
const x = width * region.min[0];
|
|
285
|
+
const y = height * (1 - region.max[1]); // Flip Y because canvas coordinates are top-down
|
|
286
|
+
const w = width * (region.max[0] - region.min[0]);
|
|
287
|
+
const h = height * (region.max[1] - region.min[1]);
|
|
288
|
+
|
|
289
|
+
ctx.rect(x, y, w, h);
|
|
290
|
+
ctx.stroke();
|
|
291
|
+
|
|
292
|
+
// Add semi-transparent fill
|
|
293
|
+
ctx.fillStyle = 'rgba(255, 0, 0, 0.1)';
|
|
294
|
+
ctx.fill();
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Update the current UV region in the state
|
|
299
|
+
* @param {Array} min - [x, y] minimum UV coordinates
|
|
300
|
+
* @param {Array} max - [x, y] maximum UV coordinates
|
|
301
|
+
*/
|
|
302
|
+
export function updateUvRegion(min, max) {
|
|
303
|
+
const region = { min, max };
|
|
304
|
+
updateState('currentUvRegion', region);
|
|
305
|
+
updateAtlasVisualization();
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export default {
|
|
309
|
+
initAtlasPanel,
|
|
310
|
+
updateAtlasVisualization,
|
|
311
|
+
updateUvRegion
|
|
312
|
+
};
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/* Mesh Panel Styles */
|
|
2
|
+
|
|
3
|
+
/* Mesh Visibility Panel Styles */
|
|
4
|
+
#mesh-visibility-container {
|
|
5
|
+
margin-bottom: 12px;
|
|
6
|
+
width: 100%;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.subsection-header {
|
|
10
|
+
font-size: 0.95em;
|
|
11
|
+
color: #aaa;
|
|
12
|
+
margin: 0 0 8px 0;
|
|
13
|
+
font-weight: normal;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.mesh-groups-container {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
gap: 6px;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.mesh-group {
|
|
23
|
+
margin-bottom: 8px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.mesh-group-header {
|
|
27
|
+
padding: 2px 0;
|
|
28
|
+
font-size: 0.9em;
|
|
29
|
+
color: #ddd;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.mesh-group-name {
|
|
33
|
+
margin-left: 6px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.mesh-group-count {
|
|
37
|
+
font-size: 0.85em;
|
|
38
|
+
color: #777;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.mesh-group-collapse {
|
|
42
|
+
padding: 0 4px;
|
|
43
|
+
color: #777;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.mesh-items {
|
|
47
|
+
margin-left: 20px;
|
|
48
|
+
margin-top: 4px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.mesh-item {
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
padding: 2px 0;
|
|
55
|
+
font-size: 0.85em;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.mesh-item:hover {
|
|
59
|
+
background-color: rgba(30, 30, 30, 0.8);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.mesh-name {
|
|
63
|
+
margin-left: 6px;
|
|
64
|
+
margin-right: 10px;
|
|
65
|
+
white-space: nowrap;
|
|
66
|
+
overflow: hidden;
|
|
67
|
+
text-overflow: ellipsis;
|
|
68
|
+
max-width: 170px;
|
|
69
|
+
flex-grow: 1;
|
|
70
|
+
color: var(--text-color);
|
|
71
|
+
font-size: 14px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* HTML Editor Icon */
|
|
75
|
+
.mesh-html-editor-icon {
|
|
76
|
+
color: #28a745;
|
|
77
|
+
cursor: pointer;
|
|
78
|
+
margin-left: 8px;
|
|
79
|
+
font-size: 1.1em;
|
|
80
|
+
display: flex;
|
|
81
|
+
align-items: center;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.mesh-html-editor-icon svg {
|
|
85
|
+
width: 14px;
|
|
86
|
+
height: 14px;
|
|
87
|
+
fill: currentColor;
|
|
88
|
+
transition: transform 0.2s ease;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.mesh-html-editor-icon:hover svg {
|
|
92
|
+
transform: rotate(20deg);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Mesh Info Icon */
|
|
96
|
+
.mesh-info-icon {
|
|
97
|
+
color: #6c757d;
|
|
98
|
+
cursor: pointer;
|
|
99
|
+
margin-left: 8px;
|
|
100
|
+
font-size: 1.1em;
|
|
101
|
+
display: flex;
|
|
102
|
+
align-items: center;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.mesh-info-icon svg {
|
|
106
|
+
width: 14px;
|
|
107
|
+
height: 14px;
|
|
108
|
+
fill: currentColor;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* Mesh Item Icons Container */
|
|
112
|
+
.mesh-item-icons {
|
|
113
|
+
display: flex;
|
|
114
|
+
align-items: center;
|
|
115
|
+
gap: 4px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.mesh-toggle {
|
|
119
|
+
margin-right: 8px;
|
|
120
|
+
cursor: pointer;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* No Sample Message */
|
|
124
|
+
.no-sample-message {
|
|
125
|
+
text-align: center;
|
|
126
|
+
color: #777;
|
|
127
|
+
font-size: 0.9em;
|
|
128
|
+
font-style: italic;
|
|
129
|
+
}
|