@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.
Files changed (114) hide show
  1. package/bin/cli.js +69 -0
  2. package/package.json +13 -7
  3. package/src/asset_debugger/axis-indicator/axis-indicator.css +6 -0
  4. package/src/asset_debugger/axis-indicator/axis-indicator.html +20 -0
  5. package/src/asset_debugger/axis-indicator/axis-indicator.js +822 -0
  6. package/src/asset_debugger/debugger-scene/debugger-scene.css +142 -0
  7. package/src/asset_debugger/debugger-scene/debugger-scene.html +80 -0
  8. package/src/asset_debugger/debugger-scene/debugger-scene.js +791 -0
  9. package/src/asset_debugger/header/header.css +73 -0
  10. package/src/asset_debugger/header/header.html +24 -0
  11. package/src/asset_debugger/header/header.js +224 -0
  12. package/src/asset_debugger/index.html +76 -0
  13. package/src/asset_debugger/landing-page/landing-page.css +396 -0
  14. package/src/asset_debugger/landing-page/landing-page.html +81 -0
  15. package/src/asset_debugger/landing-page/landing-page.js +611 -0
  16. package/src/asset_debugger/loading-splash/loading-splash.css +195 -0
  17. package/src/asset_debugger/loading-splash/loading-splash.html +22 -0
  18. package/src/asset_debugger/loading-splash/loading-splash.js +59 -0
  19. package/src/asset_debugger/loading-splash/preview-loading-splash.js +66 -0
  20. package/src/asset_debugger/main.css +14 -0
  21. package/src/asset_debugger/modals/examples-modal/examples-modal.css +41 -0
  22. package/src/asset_debugger/modals/examples-modal/examples-modal.html +18 -0
  23. package/src/asset_debugger/modals/examples-modal/examples-modal.js +111 -0
  24. package/src/asset_debugger/modals/examples-modal/examples.js +125 -0
  25. package/src/asset_debugger/modals/html-editor-modal/html-editor-modal.css +452 -0
  26. package/src/asset_debugger/modals/html-editor-modal/html-editor-modal.html +87 -0
  27. package/src/asset_debugger/modals/html-editor-modal/html-editor-modal.js +675 -0
  28. package/src/asset_debugger/modals/mesh-info-modal/mesh-info-modal.css +219 -0
  29. package/src/asset_debugger/modals/mesh-info-modal/mesh-info-modal.html +20 -0
  30. package/src/asset_debugger/modals/mesh-info-modal/mesh-info-modal.js +548 -0
  31. package/src/asset_debugger/modals/settings-modal/settings-modal.css +103 -0
  32. package/src/asset_debugger/modals/settings-modal/settings-modal.html +158 -0
  33. package/src/asset_debugger/modals/settings-modal/settings-modal.js +475 -0
  34. package/src/asset_debugger/panels/asset-panel/asset-panel.css +263 -0
  35. package/src/asset_debugger/panels/asset-panel/asset-panel.html +123 -0
  36. package/src/asset_debugger/panels/asset-panel/asset-panel.js +136 -0
  37. package/src/asset_debugger/panels/asset-panel/atlas-heading/atlas-heading.css +94 -0
  38. package/src/asset_debugger/panels/asset-panel/atlas-heading/atlas-heading.js +312 -0
  39. package/src/asset_debugger/panels/asset-panel/mesh-heading/mesh-heading.css +129 -0
  40. package/src/asset_debugger/panels/asset-panel/mesh-heading/mesh-heading.js +486 -0
  41. package/src/asset_debugger/panels/asset-panel/rig-heading/rig-heading.css +545 -0
  42. package/src/asset_debugger/panels/asset-panel/rig-heading/rig-heading.js +538 -0
  43. package/src/asset_debugger/panels/asset-panel/uv-heading/uv-heading.css +70 -0
  44. package/src/asset_debugger/panels/asset-panel/uv-heading/uv-heading.js +586 -0
  45. package/src/asset_debugger/panels/world-panel/world-panel.css +364 -0
  46. package/src/asset_debugger/panels/world-panel/world-panel.html +173 -0
  47. package/src/asset_debugger/panels/world-panel/world-panel.js +1891 -0
  48. package/src/asset_debugger/router.js +190 -0
  49. package/src/asset_debugger/util/animation/playback/animation-playback-controller.js +150 -0
  50. package/src/asset_debugger/util/animation/playback/animation-preview-controller.js +316 -0
  51. package/src/asset_debugger/util/animation/playback/css3d-bounce-controller.js +400 -0
  52. package/src/asset_debugger/util/animation/playback/css3d-reversal-controller.js +821 -0
  53. package/src/asset_debugger/util/animation/render/css3d-prerender-controller.js +696 -0
  54. package/src/asset_debugger/util/animation/render/debug-texture-factory.js +0 -0
  55. package/src/asset_debugger/util/animation/render/iframe2texture-render-controller.js +199 -0
  56. package/src/asset_debugger/util/animation/render/image2texture-prerender-controller.js +461 -0
  57. package/src/asset_debugger/util/animation/render/pbr-material-factory.js +82 -0
  58. package/src/asset_debugger/util/common.css +280 -0
  59. package/src/asset_debugger/util/data/animation-classifier.js +323 -0
  60. package/src/asset_debugger/util/data/duplicate-handler.js +20 -0
  61. package/src/asset_debugger/util/data/glb-buffer-manager.js +407 -0
  62. package/src/asset_debugger/util/data/glb-classifier.js +290 -0
  63. package/src/asset_debugger/util/data/html-formatter.js +76 -0
  64. package/src/asset_debugger/util/data/html-linter.js +276 -0
  65. package/src/asset_debugger/util/data/localstorage-manager.js +265 -0
  66. package/src/asset_debugger/util/data/mesh-html-manager.js +295 -0
  67. package/src/asset_debugger/util/data/string-serder.js +303 -0
  68. package/src/asset_debugger/util/data/texture-classifier.js +663 -0
  69. package/src/asset_debugger/util/data/upload/background-file-handler.js +292 -0
  70. package/src/asset_debugger/util/data/upload/dropzone-preview-controller.js +396 -0
  71. package/src/asset_debugger/util/data/upload/file-upload-manager.js +495 -0
  72. package/src/asset_debugger/util/data/upload/glb-file-handler.js +36 -0
  73. package/src/asset_debugger/util/data/upload/glb-preview-controller.js +317 -0
  74. package/src/asset_debugger/util/data/upload/lighting-file-handler.js +194 -0
  75. package/src/asset_debugger/util/data/upload/model-file-manager.js +104 -0
  76. package/src/asset_debugger/util/data/upload/texture-file-handler.js +166 -0
  77. package/src/asset_debugger/util/data/upload/zip-handler.js +686 -0
  78. package/src/asset_debugger/util/loaders/html2canvas-loader.js +107 -0
  79. package/src/asset_debugger/util/rig/bone-kinematics.js +403 -0
  80. package/src/asset_debugger/util/rig/rig-constraint-manager.js +618 -0
  81. package/src/asset_debugger/util/rig/rig-controller.js +612 -0
  82. package/src/asset_debugger/util/rig/rig-factory.js +628 -0
  83. package/src/asset_debugger/util/rig/rig-handle-factory.js +46 -0
  84. package/src/asset_debugger/util/rig/rig-label-factory.js +441 -0
  85. package/src/asset_debugger/util/rig/rig-mouse-handler.js +377 -0
  86. package/src/asset_debugger/util/rig/rig-state-manager.js +175 -0
  87. package/src/asset_debugger/util/rig/rig-tooltip-manager.js +267 -0
  88. package/src/asset_debugger/util/rig/rig-ui-factory.js +700 -0
  89. package/src/asset_debugger/util/scene/background-manager.js +284 -0
  90. package/src/asset_debugger/util/scene/camera-controller.js +243 -0
  91. package/src/asset_debugger/util/scene/css3d-debug-controller.js +406 -0
  92. package/src/asset_debugger/util/scene/css3d-frame-factory.js +113 -0
  93. package/src/asset_debugger/util/scene/css3d-scene-manager.js +529 -0
  94. package/src/asset_debugger/util/scene/glb-controller.js +208 -0
  95. package/src/asset_debugger/util/scene/lighting-manager.js +690 -0
  96. package/src/asset_debugger/util/scene/threejs-model-manager.js +437 -0
  97. package/src/asset_debugger/util/scene/threejs-preview-manager.js +207 -0
  98. package/src/asset_debugger/util/scene/threejs-preview-setup.js +478 -0
  99. package/src/asset_debugger/util/scene/threejs-scene-controller.js +286 -0
  100. package/src/asset_debugger/util/scene/ui-manager.js +107 -0
  101. package/src/asset_debugger/util/state/animation-state.js +128 -0
  102. package/src/asset_debugger/util/state/css3d-state.js +83 -0
  103. package/src/asset_debugger/util/state/glb-preview-state.js +31 -0
  104. package/src/asset_debugger/util/state/log-util.js +197 -0
  105. package/src/asset_debugger/util/state/scene-state.js +452 -0
  106. package/src/asset_debugger/util/state/threejs-state.js +54 -0
  107. package/src/asset_debugger/util/workers/lighting-worker.js +61 -0
  108. package/src/asset_debugger/util/workers/model-worker.js +109 -0
  109. package/src/asset_debugger/util/workers/texture-worker.js +54 -0
  110. package/src/asset_debugger/util/workers/worker-manager.js +212 -0
  111. package/src/asset_debugger/widgets/mesh-info-widget.js +280 -0
  112. package/src/index.html +261 -0
  113. package/src/index.js +8 -0
  114. 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
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Blorktools - 3D Asset Development Toolset
3
+ * Main entry point for the package
4
+ */
5
+
6
+ // Export individual tools
7
+ export const tools = {
8
+ };
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
+ });