@littlecarlito/blorktools 0.50.4 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +69 -0
- package/package.json +13 -7
- package/src/asset_debugger/axis-indicator/axis-indicator.css +6 -0
- package/src/asset_debugger/axis-indicator/axis-indicator.html +20 -0
- package/src/asset_debugger/axis-indicator/axis-indicator.js +822 -0
- package/src/asset_debugger/debugger-scene/debugger-scene.css +142 -0
- package/src/asset_debugger/debugger-scene/debugger-scene.html +80 -0
- package/src/asset_debugger/debugger-scene/debugger-scene.js +791 -0
- package/src/asset_debugger/header/header.css +73 -0
- package/src/asset_debugger/header/header.html +24 -0
- package/src/asset_debugger/header/header.js +224 -0
- package/src/asset_debugger/index.html +76 -0
- package/src/asset_debugger/landing-page/landing-page.css +396 -0
- package/src/asset_debugger/landing-page/landing-page.html +81 -0
- package/src/asset_debugger/landing-page/landing-page.js +611 -0
- package/src/asset_debugger/loading-splash/loading-splash.css +195 -0
- package/src/asset_debugger/loading-splash/loading-splash.html +22 -0
- package/src/asset_debugger/loading-splash/loading-splash.js +59 -0
- package/src/asset_debugger/loading-splash/preview-loading-splash.js +66 -0
- package/src/asset_debugger/main.css +14 -0
- package/src/asset_debugger/modals/examples-modal/examples-modal.css +41 -0
- package/src/asset_debugger/modals/examples-modal/examples-modal.html +18 -0
- package/src/asset_debugger/modals/examples-modal/examples-modal.js +111 -0
- package/src/asset_debugger/modals/examples-modal/examples.js +125 -0
- package/src/asset_debugger/modals/html-editor-modal/html-editor-modal.css +452 -0
- package/src/asset_debugger/modals/html-editor-modal/html-editor-modal.html +87 -0
- package/src/asset_debugger/modals/html-editor-modal/html-editor-modal.js +675 -0
- package/src/asset_debugger/modals/mesh-info-modal/mesh-info-modal.css +219 -0
- package/src/asset_debugger/modals/mesh-info-modal/mesh-info-modal.html +20 -0
- package/src/asset_debugger/modals/mesh-info-modal/mesh-info-modal.js +548 -0
- package/src/asset_debugger/modals/settings-modal/settings-modal.css +103 -0
- package/src/asset_debugger/modals/settings-modal/settings-modal.html +158 -0
- package/src/asset_debugger/modals/settings-modal/settings-modal.js +475 -0
- package/src/asset_debugger/panels/asset-panel/asset-panel.css +263 -0
- package/src/asset_debugger/panels/asset-panel/asset-panel.html +123 -0
- package/src/asset_debugger/panels/asset-panel/asset-panel.js +136 -0
- package/src/asset_debugger/panels/asset-panel/atlas-heading/atlas-heading.css +94 -0
- package/src/asset_debugger/panels/asset-panel/atlas-heading/atlas-heading.js +312 -0
- package/src/asset_debugger/panels/asset-panel/mesh-heading/mesh-heading.css +129 -0
- package/src/asset_debugger/panels/asset-panel/mesh-heading/mesh-heading.js +486 -0
- package/src/asset_debugger/panels/asset-panel/rig-heading/rig-heading.css +545 -0
- package/src/asset_debugger/panels/asset-panel/rig-heading/rig-heading.js +538 -0
- package/src/asset_debugger/panels/asset-panel/uv-heading/uv-heading.css +70 -0
- package/src/asset_debugger/panels/asset-panel/uv-heading/uv-heading.js +586 -0
- package/src/asset_debugger/panels/world-panel/world-panel.css +364 -0
- package/src/asset_debugger/panels/world-panel/world-panel.html +173 -0
- package/src/asset_debugger/panels/world-panel/world-panel.js +1891 -0
- package/src/asset_debugger/router.js +190 -0
- package/src/asset_debugger/util/animation/playback/animation-playback-controller.js +150 -0
- package/src/asset_debugger/util/animation/playback/animation-preview-controller.js +316 -0
- package/src/asset_debugger/util/animation/playback/css3d-bounce-controller.js +400 -0
- package/src/asset_debugger/util/animation/playback/css3d-reversal-controller.js +821 -0
- package/src/asset_debugger/util/animation/render/css3d-prerender-controller.js +696 -0
- package/src/asset_debugger/util/animation/render/debug-texture-factory.js +0 -0
- package/src/asset_debugger/util/animation/render/iframe2texture-render-controller.js +199 -0
- package/src/asset_debugger/util/animation/render/image2texture-prerender-controller.js +461 -0
- package/src/asset_debugger/util/animation/render/pbr-material-factory.js +82 -0
- package/src/asset_debugger/util/common.css +280 -0
- package/src/asset_debugger/util/data/animation-classifier.js +323 -0
- package/src/asset_debugger/util/data/duplicate-handler.js +20 -0
- package/src/asset_debugger/util/data/glb-buffer-manager.js +407 -0
- package/src/asset_debugger/util/data/glb-classifier.js +290 -0
- package/src/asset_debugger/util/data/html-formatter.js +76 -0
- package/src/asset_debugger/util/data/html-linter.js +276 -0
- package/src/asset_debugger/util/data/localstorage-manager.js +265 -0
- package/src/asset_debugger/util/data/mesh-html-manager.js +295 -0
- package/src/asset_debugger/util/data/string-serder.js +303 -0
- package/src/asset_debugger/util/data/texture-classifier.js +663 -0
- package/src/asset_debugger/util/data/upload/background-file-handler.js +292 -0
- package/src/asset_debugger/util/data/upload/dropzone-preview-controller.js +396 -0
- package/src/asset_debugger/util/data/upload/file-upload-manager.js +495 -0
- package/src/asset_debugger/util/data/upload/glb-file-handler.js +36 -0
- package/src/asset_debugger/util/data/upload/glb-preview-controller.js +317 -0
- package/src/asset_debugger/util/data/upload/lighting-file-handler.js +194 -0
- package/src/asset_debugger/util/data/upload/model-file-manager.js +104 -0
- package/src/asset_debugger/util/data/upload/texture-file-handler.js +166 -0
- package/src/asset_debugger/util/data/upload/zip-handler.js +686 -0
- package/src/asset_debugger/util/loaders/html2canvas-loader.js +107 -0
- package/src/asset_debugger/util/rig/bone-kinematics.js +403 -0
- package/src/asset_debugger/util/rig/rig-constraint-manager.js +618 -0
- package/src/asset_debugger/util/rig/rig-controller.js +612 -0
- package/src/asset_debugger/util/rig/rig-factory.js +628 -0
- package/src/asset_debugger/util/rig/rig-handle-factory.js +46 -0
- package/src/asset_debugger/util/rig/rig-label-factory.js +441 -0
- package/src/asset_debugger/util/rig/rig-mouse-handler.js +377 -0
- package/src/asset_debugger/util/rig/rig-state-manager.js +175 -0
- package/src/asset_debugger/util/rig/rig-tooltip-manager.js +267 -0
- package/src/asset_debugger/util/rig/rig-ui-factory.js +700 -0
- package/src/asset_debugger/util/scene/background-manager.js +284 -0
- package/src/asset_debugger/util/scene/camera-controller.js +243 -0
- package/src/asset_debugger/util/scene/css3d-debug-controller.js +406 -0
- package/src/asset_debugger/util/scene/css3d-frame-factory.js +113 -0
- package/src/asset_debugger/util/scene/css3d-scene-manager.js +529 -0
- package/src/asset_debugger/util/scene/glb-controller.js +208 -0
- package/src/asset_debugger/util/scene/lighting-manager.js +690 -0
- package/src/asset_debugger/util/scene/threejs-model-manager.js +437 -0
- package/src/asset_debugger/util/scene/threejs-preview-manager.js +207 -0
- package/src/asset_debugger/util/scene/threejs-preview-setup.js +478 -0
- package/src/asset_debugger/util/scene/threejs-scene-controller.js +286 -0
- package/src/asset_debugger/util/scene/ui-manager.js +107 -0
- package/src/asset_debugger/util/state/animation-state.js +128 -0
- package/src/asset_debugger/util/state/css3d-state.js +83 -0
- package/src/asset_debugger/util/state/glb-preview-state.js +31 -0
- package/src/asset_debugger/util/state/log-util.js +197 -0
- package/src/asset_debugger/util/state/scene-state.js +452 -0
- package/src/asset_debugger/util/state/threejs-state.js +54 -0
- package/src/asset_debugger/util/workers/lighting-worker.js +61 -0
- package/src/asset_debugger/util/workers/model-worker.js +109 -0
- package/src/asset_debugger/util/workers/texture-worker.js +54 -0
- package/src/asset_debugger/util/workers/worker-manager.js +212 -0
- package/src/asset_debugger/widgets/mesh-info-widget.js +280 -0
- package/src/index.html +261 -0
- package/src/index.js +8 -0
- package/vite.config.js +66 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { getState } from "../util/state/scene-state";
|
|
3
|
+
import { getHtmlSettingsForMesh } from '../util/data/mesh-html-manager';
|
|
4
|
+
|
|
5
|
+
// Info panel state variables
|
|
6
|
+
export let infoPanel = null;
|
|
7
|
+
let infoPanelCollapsed = false;
|
|
8
|
+
let infoPanelPosition = { x: 10, y: 10 }; // Default position in top-left corner
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Create a collapsible info panel for the preview that shows mesh details
|
|
12
|
+
* This panel is similar to the axis indicator and can be collapsed/expanded
|
|
13
|
+
* and dragged around the preview area. It shows detailed information about
|
|
14
|
+
* the mesh being previewed including geometry, materials, and transform data.
|
|
15
|
+
*
|
|
16
|
+
* @param {HTMLElement} container - The container to add the info panel to
|
|
17
|
+
* @param {number} meshId - The ID of the mesh being previewed
|
|
18
|
+
* @returns {HTMLElement} The created info panel element
|
|
19
|
+
*/
|
|
20
|
+
export function createMeshInfoPanel(container, meshId) {
|
|
21
|
+
// Remove any existing info panel
|
|
22
|
+
if (infoPanel) {
|
|
23
|
+
if (infoPanel.parentNode) {
|
|
24
|
+
infoPanel.parentNode.removeChild(infoPanel);
|
|
25
|
+
}
|
|
26
|
+
infoPanel = null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Get mesh data from state
|
|
30
|
+
const state = getState();
|
|
31
|
+
const mesh = state.meshes ? state.meshes[meshId] : null;
|
|
32
|
+
|
|
33
|
+
if (!mesh) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Create the info panel container
|
|
38
|
+
const panel = document.createElement('div');
|
|
39
|
+
panel.id = 'preview-info-panel';
|
|
40
|
+
panel.style.position = 'absolute';
|
|
41
|
+
panel.style.zIndex = '900'; // Lower z-index than the loading overlay (1000)
|
|
42
|
+
panel.style.pointerEvents = 'auto';
|
|
43
|
+
panel.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.3)';
|
|
44
|
+
panel.style.border = '1px solid rgba(50, 50, 50, 0.7)';
|
|
45
|
+
panel.style.borderRadius = '5px';
|
|
46
|
+
panel.style.overflow = 'hidden';
|
|
47
|
+
panel.style.backgroundColor = 'rgba(0, 0, 0, 0)';
|
|
48
|
+
panel.style.width = '250px';
|
|
49
|
+
panel.style.left = `${infoPanelPosition.x}px`;
|
|
50
|
+
panel.style.top = `${infoPanelPosition.y}px`;
|
|
51
|
+
|
|
52
|
+
// Create the header
|
|
53
|
+
const header = document.createElement('div');
|
|
54
|
+
header.id = 'preview-info-header';
|
|
55
|
+
header.style.backgroundColor = 'rgba(30, 30, 30, 0.7)';
|
|
56
|
+
header.style.color = 'white';
|
|
57
|
+
header.style.padding = '5px 10px';
|
|
58
|
+
header.style.cursor = 'grab';
|
|
59
|
+
header.style.userSelect = 'none';
|
|
60
|
+
header.style.display = 'flex';
|
|
61
|
+
header.style.alignItems = 'center';
|
|
62
|
+
header.style.justifyContent = 'space-between';
|
|
63
|
+
header.style.width = '100%';
|
|
64
|
+
header.style.boxSizing = 'border-box';
|
|
65
|
+
|
|
66
|
+
// Add title
|
|
67
|
+
const title = document.createElement('span');
|
|
68
|
+
title.textContent = 'Mesh Info';
|
|
69
|
+
title.style.fontWeight = 'bold';
|
|
70
|
+
title.style.fontSize = '12px';
|
|
71
|
+
|
|
72
|
+
// Add collapse/expand button
|
|
73
|
+
const collapseBtn = document.createElement('span');
|
|
74
|
+
collapseBtn.textContent = infoPanelCollapsed ? '▼' : '▲';
|
|
75
|
+
collapseBtn.style.fontSize = '12px';
|
|
76
|
+
collapseBtn.style.cursor = 'pointer';
|
|
77
|
+
collapseBtn.style.marginLeft = '10px';
|
|
78
|
+
collapseBtn.style.width = '15px';
|
|
79
|
+
collapseBtn.style.textAlign = 'center';
|
|
80
|
+
|
|
81
|
+
// Add elements to header
|
|
82
|
+
header.appendChild(title);
|
|
83
|
+
header.appendChild(collapseBtn);
|
|
84
|
+
|
|
85
|
+
// Create content container
|
|
86
|
+
const content = document.createElement('div');
|
|
87
|
+
content.id = 'preview-info-content';
|
|
88
|
+
content.style.backgroundColor = 'rgba(20, 20, 20, 0.7)';
|
|
89
|
+
content.style.color = 'white';
|
|
90
|
+
content.style.padding = '10px';
|
|
91
|
+
content.style.fontSize = '12px';
|
|
92
|
+
content.style.display = infoPanelCollapsed ? 'none' : 'block';
|
|
93
|
+
content.style.maxHeight = '300px';
|
|
94
|
+
content.style.overflowY = 'auto';
|
|
95
|
+
|
|
96
|
+
// Gather mesh information
|
|
97
|
+
const info = [];
|
|
98
|
+
|
|
99
|
+
// Basic Information
|
|
100
|
+
info.push('<strong>Basic Information</strong>');
|
|
101
|
+
info.push(`Name: ${mesh.name || 'Unnamed'}`);
|
|
102
|
+
info.push(`ID: ${meshId}`);
|
|
103
|
+
info.push(`Visible: ${mesh.visible ? 'Yes' : 'No'}`);
|
|
104
|
+
|
|
105
|
+
// Dimensions
|
|
106
|
+
let dimensions = null;
|
|
107
|
+
if (mesh.geometry) {
|
|
108
|
+
// Compute bounding box if not already computed
|
|
109
|
+
if (!mesh.geometry.boundingBox) {
|
|
110
|
+
mesh.geometry.computeBoundingBox();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (mesh.geometry.boundingBox) {
|
|
114
|
+
const box = mesh.geometry.boundingBox;
|
|
115
|
+
const width = box.max.x - box.min.x;
|
|
116
|
+
const height = box.max.y - box.min.y;
|
|
117
|
+
const depth = box.max.z - box.min.z;
|
|
118
|
+
|
|
119
|
+
dimensions = { width, height, depth };
|
|
120
|
+
|
|
121
|
+
info.push('<strong>Dimensions</strong>');
|
|
122
|
+
info.push(`Width (X): ${width.toFixed(3)}`);
|
|
123
|
+
info.push(`Height (Y): ${height.toFixed(3)}`);
|
|
124
|
+
info.push(`Depth (Z): ${depth.toFixed(3)}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Geometry details
|
|
129
|
+
if (mesh.geometry) {
|
|
130
|
+
info.push('<strong>Geometry</strong>');
|
|
131
|
+
|
|
132
|
+
// Geometry type
|
|
133
|
+
info.push(`Type: ${mesh.geometry.type || 'Unknown'}`);
|
|
134
|
+
|
|
135
|
+
// Vertices count
|
|
136
|
+
const vertexCount = mesh.geometry.attributes && mesh.geometry.attributes.position ?
|
|
137
|
+
mesh.geometry.attributes.position.count : 'Unknown';
|
|
138
|
+
info.push(`Vertices: ${vertexCount}`);
|
|
139
|
+
|
|
140
|
+
// Faces count (triangles)
|
|
141
|
+
let faceCount = 'Unknown';
|
|
142
|
+
if (mesh.geometry.index) {
|
|
143
|
+
faceCount = Math.floor(mesh.geometry.index.count / 3);
|
|
144
|
+
} else if (mesh.geometry.attributes && mesh.geometry.attributes.position) {
|
|
145
|
+
faceCount = Math.floor(mesh.geometry.attributes.position.count / 3);
|
|
146
|
+
}
|
|
147
|
+
info.push(`Faces: ${faceCount}`);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Material details
|
|
151
|
+
if (mesh.material) {
|
|
152
|
+
info.push('<strong>Material</strong>');
|
|
153
|
+
|
|
154
|
+
// Handle multiple materials
|
|
155
|
+
const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
|
|
156
|
+
|
|
157
|
+
info.push(`Count: ${materials.length}`);
|
|
158
|
+
|
|
159
|
+
// Material properties (just show first material if multiple)
|
|
160
|
+
const material = materials[0];
|
|
161
|
+
info.push(`Type: ${material.type || 'Unknown'}`);
|
|
162
|
+
info.push(`Double Sided: ${material.side === THREE.DoubleSide ? 'Yes' : 'No'}`);
|
|
163
|
+
info.push(`Transparent: ${material.transparent ? 'Yes' : 'No'}`);
|
|
164
|
+
|
|
165
|
+
// Color if available
|
|
166
|
+
if (material.color) {
|
|
167
|
+
const colorHex = '#' + material.color.getHexString();
|
|
168
|
+
info.push(`Color: <span style="color:${colorHex}">■</span> ${colorHex}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Transform information
|
|
173
|
+
info.push('<strong>Transform</strong>');
|
|
174
|
+
info.push(`Position: X:${mesh.position.x.toFixed(3)}, Y:${mesh.position.y.toFixed(3)}, Z:${mesh.position.z.toFixed(3)}`);
|
|
175
|
+
info.push(`Rotation: X:${(mesh.rotation.x * 180 / Math.PI).toFixed(1)}°, Y:${(mesh.rotation.y * 180 / Math.PI).toFixed(1)}°, Z:${(mesh.rotation.z * 180 / Math.PI).toFixed(1)}°`);
|
|
176
|
+
info.push(`Scale: X:${mesh.scale.x.toFixed(3)}, Y:${mesh.scale.y.toFixed(3)}, Z:${mesh.scale.z.toFixed(3)}`);
|
|
177
|
+
|
|
178
|
+
// HTML settings
|
|
179
|
+
const htmlSettings = getHtmlSettingsForMesh(meshId);
|
|
180
|
+
if (htmlSettings) {
|
|
181
|
+
info.push('<strong>HTML Settings</strong>');
|
|
182
|
+
info.push(`Render Mode: ${htmlSettings.previewMode || 'threejs'}`);
|
|
183
|
+
info.push(`Playback Speed: ${htmlSettings.playbackSpeed || '1'}`);
|
|
184
|
+
info.push(`Animation: ${htmlSettings.animation?.type || 'play'}`);
|
|
185
|
+
info.push(`Show Borders: ${htmlSettings.showBorders !== false ? 'Yes' : 'No'}`);
|
|
186
|
+
info.push(`Display on Mesh: ${htmlSettings.displayOnMesh === true ? 'Yes' : 'No'}`);
|
|
187
|
+
info.push(`Rig Control Node: ${htmlSettings.rigControlNode === true ? 'Yes' : 'No'}`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Add content to the panel
|
|
191
|
+
content.innerHTML = info.join('<br>');
|
|
192
|
+
|
|
193
|
+
// Add header and content to panel
|
|
194
|
+
panel.appendChild(header);
|
|
195
|
+
panel.appendChild(content);
|
|
196
|
+
|
|
197
|
+
// Add to container
|
|
198
|
+
container.appendChild(panel);
|
|
199
|
+
|
|
200
|
+
// Store reference
|
|
201
|
+
infoPanel = panel;
|
|
202
|
+
|
|
203
|
+
// Add collapse functionality
|
|
204
|
+
collapseBtn.addEventListener('click', (e) => {
|
|
205
|
+
e.stopPropagation(); // Prevent triggering drag
|
|
206
|
+
infoPanelCollapsed = !infoPanelCollapsed;
|
|
207
|
+
collapseBtn.textContent = infoPanelCollapsed ? '▼' : '▲';
|
|
208
|
+
content.style.display = infoPanelCollapsed ? 'none' : 'block';
|
|
209
|
+
updatePanelHeight();
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// Function to update panel height
|
|
213
|
+
function updatePanelHeight() {
|
|
214
|
+
if (infoPanelCollapsed) {
|
|
215
|
+
panel.style.height = `${header.offsetHeight}px`;
|
|
216
|
+
} else {
|
|
217
|
+
panel.style.height = 'auto';
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Call once to set initial height
|
|
222
|
+
updatePanelHeight();
|
|
223
|
+
|
|
224
|
+
// Make the header draggable
|
|
225
|
+
let isHeaderDragging = false;
|
|
226
|
+
let startX, startY;
|
|
227
|
+
let startLeft, startTop;
|
|
228
|
+
|
|
229
|
+
header.addEventListener('mousedown', (e) => {
|
|
230
|
+
isHeaderDragging = true;
|
|
231
|
+
startX = e.clientX;
|
|
232
|
+
startY = e.clientY;
|
|
233
|
+
startLeft = parseInt(panel.style.left);
|
|
234
|
+
startTop = parseInt(panel.style.top);
|
|
235
|
+
header.style.cursor = 'grabbing';
|
|
236
|
+
|
|
237
|
+
e.preventDefault();
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
document.addEventListener('mousemove', (e) => {
|
|
241
|
+
if (!isHeaderDragging) return;
|
|
242
|
+
|
|
243
|
+
const dx = e.clientX - startX;
|
|
244
|
+
const dy = e.clientY - startY;
|
|
245
|
+
|
|
246
|
+
const newLeft = startLeft + dx;
|
|
247
|
+
const newTop = startTop + dy;
|
|
248
|
+
|
|
249
|
+
// Get current container dimensions
|
|
250
|
+
const containerRect = container.getBoundingClientRect();
|
|
251
|
+
const maxLeft = containerRect.width - panel.offsetWidth;
|
|
252
|
+
const maxTop = containerRect.height - panel.offsetHeight;
|
|
253
|
+
|
|
254
|
+
const constrainedLeft = Math.max(0, Math.min(newLeft, maxLeft));
|
|
255
|
+
const constrainedTop = Math.max(0, Math.min(newTop, maxTop));
|
|
256
|
+
|
|
257
|
+
panel.style.left = `${constrainedLeft}px`;
|
|
258
|
+
panel.style.top = `${constrainedTop}px`;
|
|
259
|
+
|
|
260
|
+
// Update stored position
|
|
261
|
+
infoPanelPosition.x = constrainedLeft;
|
|
262
|
+
infoPanelPosition.y = constrainedTop;
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
document.addEventListener('mouseup', () => {
|
|
266
|
+
if (isHeaderDragging) {
|
|
267
|
+
isHeaderDragging = false;
|
|
268
|
+
header.style.cursor = 'grab';
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
return panel;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Reset info panel to null
|
|
277
|
+
*/
|
|
278
|
+
export function resetInfoPanel() {
|
|
279
|
+
infoPanel = null;
|
|
280
|
+
}
|
package/src/index.html
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Development Tools</title>
|
|
7
|
+
<link rel="stylesheet" href="./asset_debugger/util/common.css">
|
|
8
|
+
<style>
|
|
9
|
+
/* Override container styles for this index page */
|
|
10
|
+
body {
|
|
11
|
+
font-family: monospace;
|
|
12
|
+
background-color: var(--bg-color);
|
|
13
|
+
color: var(--text-color);
|
|
14
|
+
margin: 0;
|
|
15
|
+
padding: 20px;
|
|
16
|
+
min-height: 100vh;
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
align-items: center;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.dev-tools-container {
|
|
24
|
+
max-width: 1000px;
|
|
25
|
+
width: 100%;
|
|
26
|
+
background-color: var(--panel-bg);
|
|
27
|
+
border: 1px solid var(--panel-border);
|
|
28
|
+
border-radius: 8px;
|
|
29
|
+
padding: 30px;
|
|
30
|
+
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
|
|
31
|
+
backdrop-filter: blur(10px);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.dev-tools-header {
|
|
35
|
+
text-align: center;
|
|
36
|
+
margin-bottom: 30px;
|
|
37
|
+
border-bottom: 2px solid var(--panel-border);
|
|
38
|
+
padding-bottom: 20px;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.header-section {
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: flex-start;
|
|
44
|
+
gap: 40px;
|
|
45
|
+
margin-bottom: 40px;
|
|
46
|
+
border-bottom: 2px solid var(--panel-border);
|
|
47
|
+
padding-bottom: 30px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.header-left {
|
|
51
|
+
flex: 0 0 auto;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.header-right {
|
|
55
|
+
flex: 1;
|
|
56
|
+
padding-top: 10px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.dev-tools-title {
|
|
60
|
+
font-size: 36px;
|
|
61
|
+
color: var(--primary-color);
|
|
62
|
+
margin: 0;
|
|
63
|
+
text-shadow: 0 0 10px rgba(76, 175, 80, 0.5);
|
|
64
|
+
letter-spacing: 2px;
|
|
65
|
+
white-space: nowrap;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.dev-tools-subtitle {
|
|
69
|
+
font-size: 16px;
|
|
70
|
+
color: var(--text-color);
|
|
71
|
+
margin: 0;
|
|
72
|
+
line-height: 1.5;
|
|
73
|
+
text-align: left;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.tools-section {
|
|
77
|
+
display: flex;
|
|
78
|
+
gap: 30px;
|
|
79
|
+
margin-bottom: 40px;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.notes-section {
|
|
83
|
+
width: 100%;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.tool-card {
|
|
87
|
+
background-color: var(--panel-bg-lighter);
|
|
88
|
+
border: 2px solid var(--panel-border);
|
|
89
|
+
border-radius: 8px;
|
|
90
|
+
padding: 25px;
|
|
91
|
+
transition: all 0.3s ease;
|
|
92
|
+
position: relative;
|
|
93
|
+
overflow: hidden;
|
|
94
|
+
flex: 1;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.tool-card:hover {
|
|
98
|
+
transform: translateY(-8px);
|
|
99
|
+
border-color: var(--tool-color);
|
|
100
|
+
box-shadow: var(--hover-glow);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.tool-card::before {
|
|
104
|
+
content: '';
|
|
105
|
+
position: absolute;
|
|
106
|
+
top: 0;
|
|
107
|
+
left: 0;
|
|
108
|
+
right: 0;
|
|
109
|
+
height: 4px;
|
|
110
|
+
background: linear-gradient(90deg, var(--primary-color), var(--tool-color));
|
|
111
|
+
opacity: 0;
|
|
112
|
+
transition: opacity 0.3s ease;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.tool-card:hover::before {
|
|
116
|
+
opacity: 1;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.tool-card-title {
|
|
120
|
+
font-size: 20px;
|
|
121
|
+
color: var(--primary-color);
|
|
122
|
+
margin: 0 0 15px 0;
|
|
123
|
+
font-weight: bold;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.tool-card-description {
|
|
127
|
+
color: var(--text-color);
|
|
128
|
+
margin: 0 0 20px 0;
|
|
129
|
+
line-height: 1.5;
|
|
130
|
+
font-size: 14px;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.tool-card-link {
|
|
134
|
+
display: inline-block;
|
|
135
|
+
background-color: var(--button-color);
|
|
136
|
+
color: white;
|
|
137
|
+
padding: 12px 20px;
|
|
138
|
+
border-radius: 6px;
|
|
139
|
+
text-decoration: none;
|
|
140
|
+
font-weight: bold;
|
|
141
|
+
font-size: 14px;
|
|
142
|
+
transition: all 0.3s ease;
|
|
143
|
+
border: none;
|
|
144
|
+
cursor: pointer;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.tool-card-link:hover {
|
|
148
|
+
background-color: #0d74c7;
|
|
149
|
+
transform: scale(1.05);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.dev-note {
|
|
153
|
+
background-color: rgba(76, 175, 80, 0.1);
|
|
154
|
+
border: 1px solid var(--primary-color);
|
|
155
|
+
border-left: 4px solid var(--primary-color);
|
|
156
|
+
border-radius: 6px;
|
|
157
|
+
padding: 20px;
|
|
158
|
+
margin-top: 30px;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.dev-note-title {
|
|
162
|
+
font-size: 18px;
|
|
163
|
+
color: var(--primary-color);
|
|
164
|
+
margin: 0 0 15px 0;
|
|
165
|
+
font-weight: bold;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.dev-note-text {
|
|
169
|
+
color: var(--text-color);
|
|
170
|
+
margin: 0;
|
|
171
|
+
line-height: 1.5;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* Responsive adjustments */
|
|
175
|
+
@media (max-width: 768px) {
|
|
176
|
+
body {
|
|
177
|
+
padding: 15px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.dev-tools-container {
|
|
181
|
+
padding: 20px;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.dev-tools-title {
|
|
185
|
+
font-size: 28px;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.tools-grid {
|
|
189
|
+
grid-template-columns: 1fr;
|
|
190
|
+
gap: 20px;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
@media (max-width: 480px) {
|
|
195
|
+
.dev-tools-title {
|
|
196
|
+
font-size: 24px;
|
|
197
|
+
letter-spacing: 1px;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.tool-card {
|
|
201
|
+
padding: 20px;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
</style>
|
|
205
|
+
</head>
|
|
206
|
+
<body>
|
|
207
|
+
<div class="dev-tools-container">
|
|
208
|
+
<div class="header-section">
|
|
209
|
+
<div class="header-left">
|
|
210
|
+
<h1 class="dev-tools-title">Development Tools</h1>
|
|
211
|
+
</div>
|
|
212
|
+
<div class="header-right">
|
|
213
|
+
<p class="dev-tools-subtitle">
|
|
214
|
+
This page provides access to various development tools for the project.<br>
|
|
215
|
+
These tools are only available during development and won't be included in the production build.
|
|
216
|
+
</p>
|
|
217
|
+
</div>
|
|
218
|
+
</div>
|
|
219
|
+
|
|
220
|
+
<div class="tools-section">
|
|
221
|
+
<div class="tool-card">
|
|
222
|
+
<h3 class="tool-card-title">Asset Debugger</h3>
|
|
223
|
+
<p class="tool-card-description">
|
|
224
|
+
Test and debug PBR texture sets with a simple drag-and-drop interface.
|
|
225
|
+
Supports Base Color, ORM, and Normal map atlases with real-time preview.
|
|
226
|
+
</p>
|
|
227
|
+
<a href="./asset_debugger/index.html" class="tool-card-link">Open Asset Debugger</a>
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
|
|
231
|
+
<div class="notes-section">
|
|
232
|
+
<div class="dev-note">
|
|
233
|
+
<h2 class="dev-note-title">Development Notes</h2>
|
|
234
|
+
<p class="dev-note-text">
|
|
235
|
+
These tools are for development purposes only and will not be included in the production build.
|
|
236
|
+
Feel free to add more tools to this directory as needed for your development workflow.
|
|
237
|
+
Each tool maintains its own isolated environment and styling consistent with the project theme.
|
|
238
|
+
</p>
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
|
|
243
|
+
<script>
|
|
244
|
+
// Clean up when navigating to SPAs to prevent DOM bleeding
|
|
245
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
246
|
+
const toolLinks = document.querySelectorAll('.tool-card-link');
|
|
247
|
+
|
|
248
|
+
toolLinks.forEach(link => {
|
|
249
|
+
link.addEventListener('click', function() {
|
|
250
|
+
// Small delay to let the navigation start, then clean up
|
|
251
|
+
setTimeout(() => {
|
|
252
|
+
document.body.innerHTML = '';
|
|
253
|
+
document.body.style.cssText = '';
|
|
254
|
+
document.body.className = '';
|
|
255
|
+
}, 10);
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
</script>
|
|
260
|
+
</body>
|
|
261
|
+
</html>
|
package/src/index.js
ADDED
package/vite.config.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
|
|
7
|
+
function gracefulShutdownPlugin() {
|
|
8
|
+
return {
|
|
9
|
+
name: 'graceful-shutdown',
|
|
10
|
+
configureServer(server) {
|
|
11
|
+
const shutdown = () => {
|
|
12
|
+
server.close();
|
|
13
|
+
process.exit(0);
|
|
14
|
+
};
|
|
15
|
+
process.on('SIGINT', shutdown);
|
|
16
|
+
process.on('SIGTERM', shutdown);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default defineConfig({
|
|
22
|
+
root: path.resolve(__dirname, 'src'),
|
|
23
|
+
build: {
|
|
24
|
+
lib: {
|
|
25
|
+
entry: path.resolve(__dirname, 'src/index.js'),
|
|
26
|
+
name: 'blorktools',
|
|
27
|
+
fileName: 'index'
|
|
28
|
+
},
|
|
29
|
+
outDir: path.resolve(__dirname, 'dist'),
|
|
30
|
+
emptyOutDir: true,
|
|
31
|
+
sourcemap: true,
|
|
32
|
+
rollupOptions: {
|
|
33
|
+
external: ['three', 'jszip'],
|
|
34
|
+
output: {
|
|
35
|
+
globals: {
|
|
36
|
+
three: 'THREE',
|
|
37
|
+
jszip: 'JSZip'
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
server: {
|
|
43
|
+
open: '/index.html',
|
|
44
|
+
port: 3001,
|
|
45
|
+
strictPort: true,
|
|
46
|
+
fs: {
|
|
47
|
+
allow: [__dirname]
|
|
48
|
+
},
|
|
49
|
+
middlewareMode: false
|
|
50
|
+
},
|
|
51
|
+
plugins: [
|
|
52
|
+
gracefulShutdownPlugin()
|
|
53
|
+
],
|
|
54
|
+
optimizeDeps: {
|
|
55
|
+
include: ['js-beautify'],
|
|
56
|
+
exclude: ['jszip'],
|
|
57
|
+
esbuildOptions: {
|
|
58
|
+
define: {
|
|
59
|
+
global: 'globalThis'
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
resolve: {
|
|
64
|
+
alias: {}
|
|
65
|
+
}
|
|
66
|
+
});
|