@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,158 @@
1
+ <!-- Settings Modal Component -->
2
+ <div id="settings-modal" class="modal-overlay">
3
+ <div class="modal-container">
4
+ <div class="modal-header">
5
+ <h3 class="modal-title">Settings</h3>
6
+ <button class="modal-close" id="close-settings-modal">&times;</button>
7
+ </div>
8
+ <div class="modal-body">
9
+ <!-- Settings Tab Navigation -->
10
+ <div class="settings-tabs">
11
+ <button class="settings-tab-button active" data-tab="general-settings">General</button>
12
+ <button class="settings-tab-button" data-tab="rig-settings">Rig Options</button>
13
+ </div>
14
+
15
+ <!-- General Settings Tab -->
16
+ <div id="general-settings" class="settings-tab-content active">
17
+ <div class="settings-row">
18
+ <div class="settings-subheading">Axis Indicator</div>
19
+ </div>
20
+ <div class="settings-row">
21
+ <div class="settings-option">
22
+ <label for="axis-indicator-type">Type:</label>
23
+ <select id="axis-indicator-type" class="settings-select">
24
+ <option value="disabled">Disabled</option>
25
+ <option value="corner">Windowed</option>
26
+ <option value="embedded">Embedded</option>
27
+ </select>
28
+ </div>
29
+ </div>
30
+ <div id="embedded-axis-settings" class="settings-row" style="display: none;">
31
+ <div class="settings-option full-width">
32
+ <label for="axis-intensity">Intensity:</label>
33
+ <div class="slider-container">
34
+ <input type="range" id="axis-intensity" class="settings-slider" min="0.1" max="1" step="0.1" value="0.7">
35
+ <span id="axis-intensity-value">0.7</span>
36
+ </div>
37
+ </div>
38
+ </div>
39
+ </div>
40
+
41
+ <!-- Axis Indicator Settings Tab - loaded dynamically -->
42
+ <div id="axis-settings-container"></div>
43
+
44
+ <!-- Rig Options Settings Tab -->
45
+ <div id="rig-settings" class="settings-tab-content">
46
+ <div class="settings-group">
47
+ <div class="settings-row">
48
+ <div class="settings-subheading">Rig Visualization</div>
49
+ </div>
50
+ <!-- First row - Toggle controls -->
51
+ <div class="settings-row">
52
+ <div class="settings-option">
53
+ <label for="display-rig">Display Rig</label>
54
+ <input type="checkbox" id="display-rig" class="settings-checkbox">
55
+ </div>
56
+ <div class="settings-option">
57
+ <label for="force-z">Force Z-index</label>
58
+ <input type="checkbox" id="force-z" class="settings-checkbox">
59
+ </div>
60
+ </div>
61
+
62
+ <!-- Second row - Toggle controls -->
63
+ <div class="settings-row">
64
+ <div class="settings-option">
65
+ <label for="fill-wireframe">Fill Wireframe</label>
66
+ <input type="checkbox" id="fill-wireframe" class="settings-checkbox">
67
+ </div>
68
+ <div class="settings-option">
69
+ <label for="show-joint-labels">Show Joint Labels</label>
70
+ <input type="checkbox" id="show-joint-labels" class="settings-checkbox">
71
+ </div>
72
+ </div>
73
+
74
+ <!-- Additional options -->
75
+ <div class="settings-row">
76
+ <div class="settings-option">
77
+ <label for="show-bone-labels">Show Bone Labels</label>
78
+ <input type="checkbox" id="show-bone-labels" class="settings-checkbox">
79
+ </div>
80
+ </div>
81
+
82
+ <!-- Rig Colors Section -->
83
+ <div class="settings-row" style="margin-top: 15px;">
84
+ <div class="settings-option full-width collapsible-header">
85
+ <h4 class="settings-subheading">Rig Colors</h4>
86
+ <span class="collapse-indicator">[+]</span>
87
+ </div>
88
+ </div>
89
+
90
+ <div class="collapsible-content" style="display: none;">
91
+ <div class="settings-row">
92
+ <div class="settings-option full-width">
93
+ <label for="primary-color">Primary Color</label>
94
+ <input type="color" id="primary-color" class="settings-color-picker">
95
+ </div>
96
+ </div>
97
+
98
+ <div class="settings-row" id="secondary-color-option" style="display: none;">
99
+ <div class="settings-option full-width">
100
+ <label for="secondary-color">Secondary Color</label>
101
+ <input type="color" id="secondary-color" class="settings-color-picker">
102
+ </div>
103
+ </div>
104
+
105
+ <div class="settings-row">
106
+ <div class="settings-option full-width">
107
+ <label for="joint-color">Joint Color</label>
108
+ <input type="color" id="joint-color" class="settings-color-picker">
109
+ </div>
110
+ </div>
111
+ </div>
112
+
113
+ <!-- Control Handle Colors Section -->
114
+ <div class="settings-row" style="margin-top: 15px;">
115
+ <div class="settings-option full-width collapsible-header">
116
+ <h4 class="settings-subheading">Control Handle Colors</h4>
117
+ <span class="collapse-indicator">[+]</span>
118
+ </div>
119
+ </div>
120
+
121
+ <div class="collapsible-content" style="display: none;">
122
+ <div class="settings-row">
123
+ <div class="settings-option full-width">
124
+ <label for="normal-color">Normal State</label>
125
+ <input type="color" id="normal-color" class="settings-color-picker" value="#FF0000">
126
+ </div>
127
+ </div>
128
+
129
+ <div class="settings-row">
130
+ <div class="settings-option full-width">
131
+ <label for="hover-color">Hover State</label>
132
+ <input type="color" id="hover-color" class="settings-color-picker" value="#00FF00">
133
+ </div>
134
+ </div>
135
+
136
+ <div class="settings-row">
137
+ <div class="settings-option full-width">
138
+ <label for="active-color">Active State</label>
139
+ <input type="color" id="active-color" class="settings-color-picker" value="#0000FF">
140
+ </div>
141
+ </div>
142
+ </div>
143
+
144
+ <!-- Reset Rig button on its own line at the bottom -->
145
+ <div class="settings-row" style="margin-top: 20px;">
146
+ <div class="settings-option full-width text-center">
147
+ <button id="reset-rig" class="reset-button">Reset Rig</button>
148
+ </div>
149
+ </div>
150
+ </div>
151
+ </div>
152
+ </div>
153
+ <div class="modal-footer">
154
+ <button class="modal-btn modal-btn-secondary" id="cancel-settings">Cancel</button>
155
+ <button class="modal-btn modal-btn-primary" id="save-settings">Save Changes</button>
156
+ </div>
157
+ </div>
158
+ </div>
@@ -0,0 +1,475 @@
1
+ /**
2
+ * Settings Modal UI Component for Asset Debugger
3
+ */
4
+ import { saveSettings, loadSettings, getDefaultSettings } from '../../util/data/localstorage-manager.js';
5
+ import { updateRigOptions } from '../../util/rig/rig-controller.js';
6
+
7
+ export class SettingsModal {
8
+ constructor(settings = null) {
9
+ // Add CSS styles for modal
10
+ this.addModalStyles();
11
+
12
+ // Modal elements
13
+ this.modal = document.getElementById('settings-modal');
14
+ this.settingsBtn = document.getElementById('settings-button');
15
+ this.closeBtn = document.getElementById('close-settings-modal');
16
+ this.cancelBtn = document.getElementById('cancel-settings');
17
+ this.saveBtn = document.getElementById('save-settings');
18
+ this.resetRigBtn = document.getElementById('reset-rig');
19
+
20
+ // Form elements
21
+ this.axisIndicatorSelect = document.getElementById('axis-indicator-type');
22
+ this.intensitySlider = document.getElementById('axis-intensity');
23
+ this.intensityValue = document.getElementById('axis-intensity-value');
24
+ this.displayRig = document.getElementById('display-rig');
25
+ this.forceZ = document.getElementById('force-z');
26
+ this.fillWireframe = document.getElementById('fill-wireframe');
27
+ this.primaryColor = document.getElementById('primary-color');
28
+ this.secondaryColor = document.getElementById('secondary-color');
29
+ this.jointColor = document.getElementById('joint-color');
30
+ this.showJointLabels = document.getElementById('show-joint-labels');
31
+ this.normalColor = document.getElementById('normal-color');
32
+ this.hoverColor = document.getElementById('hover-color');
33
+ this.activeColor = document.getElementById('active-color');
34
+ this.showBoneLabels = document.getElementById('show-bone-labels');
35
+
36
+ // Other UI elements
37
+ this.secondaryColorOption = document.getElementById('secondary-color-option');
38
+ this.embeddedSettings = document.getElementById('embedded-axis-settings');
39
+
40
+ // Initialize event listeners
41
+ this.initEventListeners();
42
+
43
+ // Apply settings
44
+ if (settings) {
45
+ // Use provided settings
46
+ this.applySettings(settings);
47
+ } else {
48
+ // No settings provided, use defaults
49
+ const defaults = getDefaultSettings();
50
+ this.applyAxisIndicatorSetting(defaults.axisIndicator.type, defaults.axisIndicator.intensity);
51
+ this.initializeRigOptions();
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Add CSS styles for the modal
57
+ */
58
+ addModalStyles() {
59
+ // Create a style element
60
+ const styleElement = document.createElement('style');
61
+
62
+ // Add the CSS rules
63
+ styleElement.textContent = `
64
+ /* Modal body with fixed height and scrolling */
65
+ .modal-body {
66
+ max-height: 400px;
67
+ overflow-y: auto;
68
+ padding-right: 10px; /* Prevent content shift when scrollbar appears */
69
+ }
70
+
71
+ /* Ensure tab content takes up full width */
72
+ .settings-tab-content {
73
+ width: 100%;
74
+ }
75
+
76
+ /* Fix settings row layout */
77
+ .settings-row {
78
+ display: flex;
79
+ flex-wrap: wrap;
80
+ width: 100%;
81
+ margin-bottom: 10px;
82
+ }
83
+
84
+ /* Settings options (2 per row) */
85
+ .settings-option {
86
+ flex: 0 0 50%;
87
+ box-sizing: border-box;
88
+ }
89
+
90
+ /* For full width options */
91
+ .settings-option.full-width {
92
+ flex: 0 0 100%;
93
+ }
94
+
95
+ /* Headings take full width */
96
+ .settings-subheading {
97
+ flex: 0 0 100%;
98
+ }
99
+
100
+ /* Fix collapsible content layout */
101
+ .collapsible-header {
102
+ display: flex;
103
+ justify-content: space-between;
104
+ width: 100%;
105
+ cursor: pointer;
106
+ }
107
+
108
+ /* Apply same layout to collapsible content */
109
+ .collapsible-content {
110
+ width: 100%;
111
+ display: flex;
112
+ flex-wrap: wrap;
113
+ }
114
+
115
+ /* Inside collapsible content */
116
+ .collapsible-content .settings-option {
117
+ flex: 0 0 50%;
118
+ box-sizing: border-box;
119
+ padding: 5px;
120
+ }
121
+ `;
122
+
123
+ // Add the style element to the document head
124
+ document.head.appendChild(styleElement);
125
+ }
126
+
127
+ /**
128
+ * Initialize all event listeners for the settings modal
129
+ */
130
+ initEventListeners() {
131
+ // Open modal
132
+ if (this.settingsBtn) {
133
+ this.settingsBtn.addEventListener('click', () => this.openModal());
134
+ }
135
+
136
+ // Close modal buttons
137
+ if (this.closeBtn) {
138
+ this.closeBtn.addEventListener('click', () => this.closeModal());
139
+ }
140
+
141
+ if (this.cancelBtn) {
142
+ this.cancelBtn.addEventListener('click', () => this.closeModal());
143
+ }
144
+
145
+ // Save settings
146
+ if (this.saveBtn) {
147
+ this.saveBtn.addEventListener('click', () => this.saveSettings());
148
+ }
149
+
150
+ // Reset rig
151
+ if (this.resetRigBtn) {
152
+ this.resetRigBtn.addEventListener('click', () => {
153
+ const event = new CustomEvent('resetRig');
154
+ document.dispatchEvent(event);
155
+ });
156
+ }
157
+
158
+ // Intensity slider changes
159
+ if (this.intensitySlider && this.intensityValue) {
160
+ this.intensitySlider.addEventListener('input', () => {
161
+ this.intensityValue.textContent = this.intensitySlider.value;
162
+ });
163
+ }
164
+
165
+ // Axis indicator type changes
166
+ if (this.axisIndicatorSelect) {
167
+ this.axisIndicatorSelect.addEventListener('change', () => {
168
+ this.toggleEmbeddedSettings(this.axisIndicatorSelect.value);
169
+ });
170
+ }
171
+
172
+ // Fill wireframe changes
173
+ if (this.fillWireframe) {
174
+ this.fillWireframe.addEventListener('change', () => {
175
+ this.toggleSecondaryColorVisibility(this.fillWireframe.checked);
176
+ });
177
+ }
178
+
179
+ // Setup tabs in settings modal
180
+ const settingsTabs = document.querySelectorAll('.settings-tab-button');
181
+ settingsTabs.forEach(tab => {
182
+ tab.addEventListener('click', () => {
183
+ // Remove active class from all tabs
184
+ settingsTabs.forEach(t => t.classList.remove('active'));
185
+
186
+ // Add active class to clicked tab
187
+ tab.classList.add('active');
188
+
189
+ // Hide all tab content
190
+ document.querySelectorAll('.settings-tab-content').forEach(content => {
191
+ content.classList.remove('active');
192
+ });
193
+
194
+ // Show the selected tab content
195
+ const tabId = tab.getAttribute('data-tab');
196
+ document.getElementById(tabId).classList.add('active');
197
+ });
198
+ });
199
+
200
+ // Setup collapsible sections
201
+ const collapsibleHeaders = document.querySelectorAll('.collapsible-header');
202
+ collapsibleHeaders.forEach(header => {
203
+ header.addEventListener('click', () => {
204
+ // Toggle expanded class
205
+ header.classList.toggle('expanded');
206
+
207
+ // Update the collapse indicator with proper symbol
208
+ const indicator = header.querySelector('.collapse-indicator');
209
+ if (indicator) {
210
+ if (header.classList.contains('expanded')) {
211
+ indicator.textContent = '[-]'; // Minus sign when expanded (with brackets)
212
+ } else {
213
+ indicator.textContent = '[+]'; // Plus sign when collapsed (with brackets)
214
+ }
215
+ }
216
+
217
+ // Toggle the visibility of the next sibling (collapsible content)
218
+ // Find parent settings row if it exists
219
+ const parentRow = header.closest('.settings-row');
220
+
221
+ // If we have a parent row, get its next sibling, otherwise look for the next sibling of the header itself
222
+ let content;
223
+ if (parentRow) {
224
+ content = parentRow.nextElementSibling;
225
+ if (content && content.classList.contains('collapsible-content')) {
226
+ content.style.display = header.classList.contains('expanded') ? 'block' : 'none';
227
+ }
228
+ } else {
229
+ // If no parent row found, try to find sibling content directly
230
+ content = header.nextElementSibling;
231
+ if (content && (content.classList.contains('collapsible-content') || content.classList.contains('metadata-content'))) {
232
+ content.style.display = header.classList.contains('expanded') ? 'block' : 'none';
233
+ }
234
+ }
235
+ });
236
+ });
237
+ }
238
+
239
+ /**
240
+ * Open the settings modal
241
+ */
242
+ openModal() {
243
+ if (this.modal) {
244
+ this.modal.style.display = 'flex';
245
+ }
246
+ }
247
+
248
+ /**
249
+ * Close the settings modal
250
+ */
251
+ closeModal() {
252
+ if (this.modal) {
253
+ this.modal.style.display = 'none';
254
+ }
255
+ }
256
+
257
+ /**
258
+ * Save settings from form values
259
+ */
260
+ saveSettings() {
261
+ // Get values from axis indicator settings
262
+ const axisIndicatorType = this.axisIndicatorSelect ? this.axisIndicatorSelect.value : 'disabled';
263
+ const axisIntensity = this.intensitySlider ? parseFloat(this.intensitySlider.value) : 0.7;
264
+
265
+ // Get values from rig options settings
266
+ const displayRig = this.displayRig ? this.displayRig.checked : false;
267
+ const forceZ = this.forceZ ? this.forceZ.checked : false;
268
+ const fillWireframe = this.fillWireframe ? this.fillWireframe.checked : false;
269
+ const primaryColor = this.primaryColor ? this.primaryColor.value : '#FF00FF';
270
+ const secondaryColor = this.secondaryColor ? this.secondaryColor.value : '#FFFF00';
271
+ const jointColor = this.jointColor ? this.jointColor.value : '#00FFFF';
272
+ const showJointLabels = this.showJointLabels ? this.showJointLabels.checked : false;
273
+ const showBoneLabels = this.showBoneLabels ? this.showBoneLabels.checked : false;
274
+
275
+ // Get control handle colors
276
+ const normalColor = this.normalColor ? this.normalColor.value : '#FF0000';
277
+ const hoverColor = this.hoverColor ? this.hoverColor.value : '#00FF00';
278
+ const activeColor = this.activeColor ? this.activeColor.value : '#0000FF';
279
+
280
+ // Store settings
281
+ const settings = {
282
+ axisIndicator: {
283
+ type: axisIndicatorType,
284
+ intensity: axisIntensity
285
+ },
286
+ rigOptions: {
287
+ displayRig: displayRig,
288
+ forceZ: forceZ,
289
+ wireframe: !fillWireframe, // Invert logic - wireframe is opposite of fill
290
+ primaryColor: parseInt(primaryColor.replace('#', '0x'), 16),
291
+ secondaryColor: parseInt(secondaryColor.replace('#', '0x'), 16),
292
+ jointColor: parseInt(jointColor.replace('#', '0x'), 16),
293
+ showJointLabels: showJointLabels,
294
+ showBoneLabels: showBoneLabels,
295
+ normalColor: parseInt(normalColor.replace('#', '0x'), 16),
296
+ hoverColor: parseInt(hoverColor.replace('#', '0x'), 16),
297
+ activeColor: parseInt(activeColor.replace('#', '0x'), 16)
298
+ }
299
+ };
300
+
301
+ // Store settings using the utility function
302
+ saveSettings(settings);
303
+
304
+ // Update rig options directly
305
+ updateRigOptions(settings.rigOptions);
306
+
307
+ // Apply settings immediately
308
+ this.applyAxisIndicatorSetting(axisIndicatorType, axisIntensity);
309
+ this.applyRigOptionsSetting(settings.rigOptions);
310
+
311
+ // Close the modal
312
+ this.closeModal();
313
+
314
+ // Notify that settings were saved
315
+ console.log('Settings saved:', settings);
316
+ }
317
+
318
+ /**
319
+ * Apply axis indicator settings
320
+ * @param {string} type - The axis indicator type
321
+ * @param {number} intensity - The intensity value (0-1)
322
+ */
323
+ applyAxisIndicatorSetting(type, intensity = 0.7) {
324
+ // Trigger event to notify application of setting change
325
+ const event = new CustomEvent('axisIndicatorModeChange', {
326
+ detail: {
327
+ mode: type,
328
+ intensity: intensity
329
+ }
330
+ });
331
+ document.dispatchEvent(event);
332
+ }
333
+
334
+ /**
335
+ * Apply rig options settings
336
+ * @param {Object} options - The rig options to apply
337
+ */
338
+ applyRigOptionsSetting(options) {
339
+ // Trigger event to notify application of setting change
340
+ const event = new CustomEvent('rigOptionsChange', {
341
+ detail: options
342
+ });
343
+ document.dispatchEvent(event);
344
+ }
345
+
346
+ /**
347
+ * Toggle secondary color visibility based on fill wireframe option
348
+ * @param {boolean} show - Whether to show the secondary color option
349
+ */
350
+ toggleSecondaryColorVisibility(show) {
351
+ if (this.secondaryColorOption) {
352
+ this.secondaryColorOption.style.display = show ? 'flex' : 'none';
353
+ }
354
+ }
355
+
356
+ /**
357
+ * Toggle embedded settings visibility
358
+ * @param {string} type - The axis indicator type
359
+ */
360
+ toggleEmbeddedSettings(type) {
361
+ if (this.embeddedSettings) {
362
+ this.embeddedSettings.style.display = type === 'embedded' ? 'block' : 'none';
363
+ }
364
+ }
365
+
366
+ /**
367
+ * Initialize rig options with default values
368
+ */
369
+ initializeRigOptions() {
370
+ const defaults = getDefaultSettings().rigOptions;
371
+
372
+ // Set default values
373
+ if (this.displayRig) this.displayRig.checked = defaults.displayRig;
374
+ if (this.forceZ) this.forceZ.checked = defaults.forceZ;
375
+ if (this.fillWireframe) this.fillWireframe.checked = !defaults.wireframe;
376
+ if (this.primaryColor) this.primaryColor.value = '#' + defaults.primaryColor.toString(16).padStart(6, '0');
377
+ if (this.secondaryColor) this.secondaryColor.value = '#' + defaults.secondaryColor.toString(16).padStart(6, '0');
378
+ if (this.jointColor) this.jointColor.value = '#' + defaults.jointColor.toString(16).padStart(6, '0');
379
+ if (this.showJointLabels) this.showJointLabels.checked = defaults.showJointLabels;
380
+ if (this.normalColor) this.normalColor.value = '#' + defaults.normalColor.toString(16).padStart(6, '0');
381
+ if (this.hoverColor) this.hoverColor.value = '#' + defaults.hoverColor.toString(16).padStart(6, '0');
382
+ if (this.activeColor) this.activeColor.value = '#' + defaults.activeColor.toString(16).padStart(6, '0');
383
+
384
+ // Hide secondary color option initially
385
+ this.toggleSecondaryColorVisibility(!defaults.wireframe);
386
+ }
387
+
388
+ /**
389
+ * Apply provided settings to the UI
390
+ * @param {Object} settings - Settings object to apply
391
+ */
392
+ applySettings(settings) {
393
+ // Apply axis indicator settings if available
394
+ if (settings.axisIndicator && settings.axisIndicator.type) {
395
+ // Update the dropdown to match saved setting
396
+ if (this.axisIndicatorSelect) {
397
+ this.axisIndicatorSelect.value = settings.axisIndicator.type;
398
+ }
399
+
400
+ // Update intensity slider if available
401
+ if (settings.axisIndicator.intensity !== undefined && this.intensitySlider && this.intensityValue) {
402
+ this.intensitySlider.value = settings.axisIndicator.intensity;
403
+ this.intensityValue.textContent = settings.axisIndicator.intensity;
404
+ }
405
+
406
+ // Apply the setting
407
+ this.applyAxisIndicatorSetting(
408
+ settings.axisIndicator.type,
409
+ settings.axisIndicator.intensity || 0.7
410
+ );
411
+
412
+ // Show/hide embedded settings based on selection
413
+ this.toggleEmbeddedSettings(settings.axisIndicator.type);
414
+ }
415
+
416
+ // Apply rig options settings if available
417
+ if (settings.rigOptions) {
418
+ // Update rig options using the dedicated function
419
+ updateRigOptions(settings.rigOptions);
420
+
421
+ // Update the form values
422
+ if (this.displayRig && settings.rigOptions.displayRig !== undefined) {
423
+ this.displayRig.checked = settings.rigOptions.displayRig;
424
+ }
425
+
426
+ if (this.forceZ && settings.rigOptions.forceZ !== undefined) {
427
+ this.forceZ.checked = settings.rigOptions.forceZ;
428
+ }
429
+
430
+ if (this.fillWireframe && settings.rigOptions.wireframe !== undefined) {
431
+ this.fillWireframe.checked = !settings.rigOptions.wireframe; // Invert logic
432
+ this.toggleSecondaryColorVisibility(!settings.rigOptions.wireframe);
433
+ }
434
+
435
+ if (this.primaryColor && settings.rigOptions.primaryColor !== undefined) {
436
+ this.primaryColor.value = '#' + settings.rigOptions.primaryColor.toString(16).padStart(6, '0');
437
+ }
438
+
439
+ if (this.secondaryColor && settings.rigOptions.secondaryColor !== undefined) {
440
+ this.secondaryColor.value = '#' + settings.rigOptions.secondaryColor.toString(16).padStart(6, '0');
441
+ }
442
+
443
+ if (this.jointColor && settings.rigOptions.jointColor !== undefined) {
444
+ this.jointColor.value = '#' + settings.rigOptions.jointColor.toString(16).padStart(6, '0');
445
+ }
446
+
447
+ if (this.showJointLabels && settings.rigOptions.showJointLabels !== undefined) {
448
+ this.showJointLabels.checked = settings.rigOptions.showJointLabels;
449
+ }
450
+
451
+ if (this.showBoneLabels && settings.rigOptions.showBoneLabels !== undefined) {
452
+ this.showBoneLabels.checked = settings.rigOptions.showBoneLabels;
453
+ }
454
+
455
+ // Set control handle colors if available
456
+ if (this.normalColor && settings.rigOptions.normalColor !== undefined) {
457
+ this.normalColor.value = '#' + settings.rigOptions.normalColor.toString(16).padStart(6, '0');
458
+ }
459
+
460
+ if (this.hoverColor && settings.rigOptions.hoverColor !== undefined) {
461
+ this.hoverColor.value = '#' + settings.rigOptions.hoverColor.toString(16).padStart(6, '0');
462
+ }
463
+
464
+ if (this.activeColor && settings.rigOptions.activeColor !== undefined) {
465
+ this.activeColor.value = '#' + settings.rigOptions.activeColor.toString(16).padStart(6, '0');
466
+ }
467
+
468
+ // Still trigger the event for other components that listen for changes
469
+ this.applyRigOptionsSetting(settings.rigOptions);
470
+ } else {
471
+ // Set default values for rig options
472
+ this.initializeRigOptions();
473
+ }
474
+ }
475
+ }