sdl-mcp 0.12.2 → 0.12.3

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 (276) hide show
  1. package/README.md +10 -0
  2. package/config/sdlmcp.config.example.json +53 -8
  3. package/config/sdlmcp.config.schema.json +530 -106
  4. package/dist/.tsbuildinfo +1 -1
  5. package/dist/benchmark/external-manifest.d.ts +162 -0
  6. package/dist/benchmark/external-manifest.d.ts.map +1 -0
  7. package/dist/benchmark/external-manifest.js +336 -0
  8. package/dist/benchmark/external-manifest.js.map +1 -0
  9. package/dist/benchmark/external-runner.d.ts +100 -0
  10. package/dist/benchmark/external-runner.d.ts.map +1 -0
  11. package/dist/benchmark/external-runner.js +1171 -0
  12. package/dist/benchmark/external-runner.js.map +1 -0
  13. package/dist/benchmark/output-file.d.ts +3 -0
  14. package/dist/benchmark/output-file.d.ts.map +1 -0
  15. package/dist/benchmark/output-file.js +8 -0
  16. package/dist/benchmark/output-file.js.map +1 -0
  17. package/dist/cli/argParsing.d.ts.map +1 -1
  18. package/dist/cli/argParsing.js +6 -0
  19. package/dist/cli/argParsing.js.map +1 -1
  20. package/dist/cli/commands/benchmark.d.ts.map +1 -1
  21. package/dist/cli/commands/benchmark.js +3 -2
  22. package/dist/cli/commands/benchmark.js.map +1 -1
  23. package/dist/cli/commands/index.d.ts +1 -0
  24. package/dist/cli/commands/index.d.ts.map +1 -1
  25. package/dist/cli/commands/index.js +13 -7
  26. package/dist/cli/commands/index.js.map +1 -1
  27. package/dist/cli/commands/init.d.ts +5 -1
  28. package/dist/cli/commands/init.d.ts.map +1 -1
  29. package/dist/cli/commands/init.js +73 -3
  30. package/dist/cli/commands/init.js.map +1 -1
  31. package/dist/cli/commands/serve.d.ts.map +1 -1
  32. package/dist/cli/commands/serve.js +2 -0
  33. package/dist/cli/commands/serve.js.map +1 -1
  34. package/dist/cli/index.js +2 -0
  35. package/dist/cli/index.js.map +1 -1
  36. package/dist/cli/transport/http.d.ts +1 -35
  37. package/dist/cli/transport/http.d.ts.map +1 -1
  38. package/dist/cli/transport/http.js +151 -175
  39. package/dist/cli/transport/http.js.map +1 -1
  40. package/dist/cli/types.d.ts +1 -0
  41. package/dist/cli/types.d.ts.map +1 -1
  42. package/dist/config/constants.d.ts +30 -0
  43. package/dist/config/constants.d.ts.map +1 -1
  44. package/dist/config/constants.js +30 -0
  45. package/dist/config/constants.js.map +1 -1
  46. package/dist/config/types.d.ts +53 -1
  47. package/dist/config/types.d.ts.map +1 -1
  48. package/dist/config/types.js +62 -14
  49. package/dist/config/types.js.map +1 -1
  50. package/dist/db/ladybug-batching.d.ts +1 -0
  51. package/dist/db/ladybug-batching.d.ts.map +1 -1
  52. package/dist/db/ladybug-batching.js +1 -0
  53. package/dist/db/ladybug-batching.js.map +1 -1
  54. package/dist/db/ladybug-core.d.ts +3 -0
  55. package/dist/db/ladybug-core.d.ts.map +1 -1
  56. package/dist/db/ladybug-core.js +72 -2
  57. package/dist/db/ladybug-core.js.map +1 -1
  58. package/dist/db/ladybug-embeddings.d.ts +6 -1
  59. package/dist/db/ladybug-embeddings.d.ts.map +1 -1
  60. package/dist/db/ladybug-embeddings.js +6 -1
  61. package/dist/db/ladybug-embeddings.js.map +1 -1
  62. package/dist/db/ladybug-file-summaries.d.ts.map +1 -1
  63. package/dist/db/ladybug-file-summaries.js +23 -0
  64. package/dist/db/ladybug-file-summaries.js.map +1 -1
  65. package/dist/db/ladybug-queries.js +1 -1
  66. package/dist/db/ladybug-queries.js.map +1 -1
  67. package/dist/db/migrations/index.d.ts.map +1 -1
  68. package/dist/db/migrations/index.js +2 -0
  69. package/dist/db/migrations/index.js.map +1 -1
  70. package/dist/db/migrations/m007-copy-embeddings-to-symbol.d.ts +5 -9
  71. package/dist/db/migrations/m007-copy-embeddings-to-symbol.d.ts.map +1 -1
  72. package/dist/db/migrations/m007-copy-embeddings-to-symbol.js +24 -126
  73. package/dist/db/migrations/m007-copy-embeddings-to-symbol.js.map +1 -1
  74. package/dist/db/migrations/m021-remediate-symbol-embeddings.d.ts +5 -0
  75. package/dist/db/migrations/m021-remediate-symbol-embeddings.d.ts.map +1 -0
  76. package/dist/db/migrations/m021-remediate-symbol-embeddings.js +7 -0
  77. package/dist/db/migrations/m021-remediate-symbol-embeddings.js.map +1 -0
  78. package/dist/db/migrations/symbol-embedding-remediation.d.ts +57 -0
  79. package/dist/db/migrations/symbol-embedding-remediation.d.ts.map +1 -0
  80. package/dist/db/migrations/symbol-embedding-remediation.js +335 -0
  81. package/dist/db/migrations/symbol-embedding-remediation.js.map +1 -0
  82. package/dist/graph/layout/force-layout.d.ts +4 -0
  83. package/dist/graph/layout/force-layout.d.ts.map +1 -0
  84. package/dist/graph/layout/force-layout.js +127 -0
  85. package/dist/graph/layout/force-layout.js.map +1 -0
  86. package/dist/graph/layout/layout-service.d.ts +37 -0
  87. package/dist/graph/layout/layout-service.d.ts.map +1 -0
  88. package/dist/graph/layout/layout-service.js +172 -0
  89. package/dist/graph/layout/layout-service.js.map +1 -0
  90. package/dist/graph/layout/native-engine.d.ts +9 -0
  91. package/dist/graph/layout/native-engine.d.ts.map +1 -0
  92. package/dist/graph/layout/native-engine.js +59 -0
  93. package/dist/graph/layout/native-engine.js.map +1 -0
  94. package/dist/graph/layout/prng.d.ts +3 -0
  95. package/dist/graph/layout/prng.d.ts.map +1 -0
  96. package/dist/graph/layout/prng.js +19 -0
  97. package/dist/graph/layout/prng.js.map +1 -0
  98. package/dist/graph/layout/serializer.d.ts +3 -0
  99. package/dist/graph/layout/serializer.d.ts.map +1 -0
  100. package/dist/graph/layout/serializer.js +20 -0
  101. package/dist/graph/layout/serializer.js.map +1 -0
  102. package/dist/graph/layout/types.d.ts +30 -0
  103. package/dist/graph/layout/types.d.ts.map +1 -0
  104. package/dist/graph/layout/types.js +2 -0
  105. package/dist/graph/layout/types.js.map +1 -0
  106. package/dist/indexer/embeddings.d.ts +7 -0
  107. package/dist/indexer/embeddings.d.ts.map +1 -1
  108. package/dist/indexer/embeddings.js +44 -4
  109. package/dist/indexer/embeddings.js.map +1 -1
  110. package/dist/indexer/file-summary-embeddings.d.ts +12 -0
  111. package/dist/indexer/file-summary-embeddings.d.ts.map +1 -1
  112. package/dist/indexer/file-summary-embeddings.js +83 -21
  113. package/dist/indexer/file-summary-embeddings.js.map +1 -1
  114. package/dist/indexer/fileWalker.d.ts.map +1 -1
  115. package/dist/indexer/fileWalker.js +2 -1
  116. package/dist/indexer/fileWalker.js.map +1 -1
  117. package/dist/indexer/metrics-updater.d.ts.map +1 -1
  118. package/dist/indexer/metrics-updater.js +27 -4
  119. package/dist/indexer/metrics-updater.js.map +1 -1
  120. package/dist/indexer/watcher.d.ts.map +1 -1
  121. package/dist/indexer/watcher.js +2 -1
  122. package/dist/indexer/watcher.js.map +1 -1
  123. package/dist/mcp/context-response-projection.d.ts.map +1 -1
  124. package/dist/mcp/context-response-projection.js +49 -13
  125. package/dist/mcp/context-response-projection.js.map +1 -1
  126. package/dist/mcp/tools/search-edit/planner.d.ts.map +1 -1
  127. package/dist/mcp/tools/search-edit/planner.js +10 -3
  128. package/dist/mcp/tools/search-edit/planner.js.map +1 -1
  129. package/dist/observability/event-tap.d.ts +2 -1
  130. package/dist/observability/event-tap.d.ts.map +1 -1
  131. package/dist/observability/event-tap.js.map +1 -1
  132. package/dist/observability/service.d.ts +11 -4
  133. package/dist/observability/service.d.ts.map +1 -1
  134. package/dist/observability/service.js +83 -13
  135. package/dist/observability/service.js.map +1 -1
  136. package/dist/observability/types.d.ts +48 -2
  137. package/dist/observability/types.d.ts.map +1 -1
  138. package/dist/ui/.tsbuildinfo +1 -0
  139. package/dist/ui/vendor/fflate.js +2692 -0
  140. package/dist/ui/vendor/jsm/controls/ArcballControls.js +3543 -0
  141. package/dist/ui/vendor/jsm/controls/DragControls.js +452 -0
  142. package/dist/ui/vendor/jsm/controls/FirstPersonControls.js +488 -0
  143. package/dist/ui/vendor/jsm/controls/FlyControls.js +384 -0
  144. package/dist/ui/vendor/jsm/controls/MapControls.js +116 -0
  145. package/dist/ui/vendor/jsm/controls/OrbitControls.js +1963 -0
  146. package/dist/ui/vendor/jsm/controls/PointerLockControls.js +264 -0
  147. package/dist/ui/vendor/jsm/controls/TrackballControls.js +1001 -0
  148. package/dist/ui/vendor/jsm/controls/TransformControls.js +2003 -0
  149. package/dist/ui/vendor/jsm/loaders/3DMLoader.js +1836 -0
  150. package/dist/ui/vendor/jsm/loaders/3MFLoader.js +1621 -0
  151. package/dist/ui/vendor/jsm/loaders/AMFLoader.js +541 -0
  152. package/dist/ui/vendor/jsm/loaders/BVHLoader.js +484 -0
  153. package/dist/ui/vendor/jsm/loaders/ColladaLoader.js +153 -0
  154. package/dist/ui/vendor/jsm/loaders/DDSLoader.js +385 -0
  155. package/dist/ui/vendor/jsm/loaders/DRACOLoader.js +772 -0
  156. package/dist/ui/vendor/jsm/loaders/EXRLoader.js +3395 -0
  157. package/dist/ui/vendor/jsm/loaders/FBXLoader.js +4580 -0
  158. package/dist/ui/vendor/jsm/loaders/FontLoader.js +260 -0
  159. package/dist/ui/vendor/jsm/loaders/GCodeLoader.js +318 -0
  160. package/dist/ui/vendor/jsm/loaders/GLTFLoader.js +4860 -0
  161. package/dist/ui/vendor/jsm/loaders/HDRCubeTextureLoader.js +164 -0
  162. package/dist/ui/vendor/jsm/loaders/HDRLoader.js +463 -0
  163. package/dist/ui/vendor/jsm/loaders/IESLoader.js +379 -0
  164. package/dist/ui/vendor/jsm/loaders/KMZLoader.js +163 -0
  165. package/dist/ui/vendor/jsm/loaders/KTX2Loader.js +1276 -0
  166. package/dist/ui/vendor/jsm/loaders/KTXLoader.js +197 -0
  167. package/dist/ui/vendor/jsm/loaders/LDrawLoader.js +2510 -0
  168. package/dist/ui/vendor/jsm/loaders/LUT3dlLoader.js +205 -0
  169. package/dist/ui/vendor/jsm/loaders/LUTCubeLoader.js +190 -0
  170. package/dist/ui/vendor/jsm/loaders/LUTImageLoader.js +190 -0
  171. package/dist/ui/vendor/jsm/loaders/LWOLoader.js +1051 -0
  172. package/dist/ui/vendor/jsm/loaders/LottieLoader.js +130 -0
  173. package/dist/ui/vendor/jsm/loaders/MD2Loader.js +435 -0
  174. package/dist/ui/vendor/jsm/loaders/MDDLoader.js +147 -0
  175. package/dist/ui/vendor/jsm/loaders/MTLLoader.js +593 -0
  176. package/dist/ui/vendor/jsm/loaders/MaterialXLoader.js +1126 -0
  177. package/dist/ui/vendor/jsm/loaders/NRRDLoader.js +718 -0
  178. package/dist/ui/vendor/jsm/loaders/OBJLoader.js +955 -0
  179. package/dist/ui/vendor/jsm/loaders/PCDLoader.js +620 -0
  180. package/dist/ui/vendor/jsm/loaders/PDBLoader.js +272 -0
  181. package/dist/ui/vendor/jsm/loaders/PLYLoader.js +968 -0
  182. package/dist/ui/vendor/jsm/loaders/PVRLoader.js +270 -0
  183. package/dist/ui/vendor/jsm/loaders/RGBELoader.js +18 -0
  184. package/dist/ui/vendor/jsm/loaders/STLLoader.js +421 -0
  185. package/dist/ui/vendor/jsm/loaders/SVGLoader.js +3319 -0
  186. package/dist/ui/vendor/jsm/loaders/TDSLoader.js +1142 -0
  187. package/dist/ui/vendor/jsm/loaders/TGALoader.js +538 -0
  188. package/dist/ui/vendor/jsm/loaders/TIFFLoader.js +59 -0
  189. package/dist/ui/vendor/jsm/loaders/TTFLoader.js +261 -0
  190. package/dist/ui/vendor/jsm/loaders/USDLoader.js +303 -0
  191. package/dist/ui/vendor/jsm/loaders/USDZLoader.js +16 -0
  192. package/dist/ui/vendor/jsm/loaders/UltraHDRLoader.js +755 -0
  193. package/dist/ui/vendor/jsm/loaders/VOXLoader.js +919 -0
  194. package/dist/ui/vendor/jsm/loaders/VRMLLoader.js +3646 -0
  195. package/dist/ui/vendor/jsm/loaders/VTKLoader.js +1293 -0
  196. package/dist/ui/vendor/jsm/loaders/XYZLoader.js +143 -0
  197. package/dist/ui/vendor/jsm/loaders/collada/ColladaComposer.js +3044 -0
  198. package/dist/ui/vendor/jsm/loaders/collada/ColladaParser.js +1977 -0
  199. package/dist/ui/vendor/jsm/loaders/lwo/IFFParser.js +1217 -0
  200. package/dist/ui/vendor/jsm/loaders/lwo/LWO2Parser.js +414 -0
  201. package/dist/ui/vendor/jsm/loaders/lwo/LWO3Parser.js +373 -0
  202. package/dist/ui/vendor/jsm/loaders/usd/USDAParser.js +901 -0
  203. package/dist/ui/vendor/jsm/loaders/usd/USDCParser.js +1878 -0
  204. package/dist/ui/vendor/jsm/loaders/usd/USDComposer.js +4627 -0
  205. package/dist/ui/vendor/jsm/utils/BufferGeometryUtils.js +1501 -0
  206. package/dist/ui/vendor/jsm/utils/CameraUtils.js +82 -0
  207. package/dist/ui/vendor/jsm/utils/ColorUtils.js +76 -0
  208. package/dist/ui/vendor/jsm/utils/GeometryCompressionUtils.js +547 -0
  209. package/dist/ui/vendor/jsm/utils/GeometryUtils.js +226 -0
  210. package/dist/ui/vendor/jsm/utils/LDrawUtils.js +211 -0
  211. package/dist/ui/vendor/jsm/utils/SceneOptimizer.js +458 -0
  212. package/dist/ui/vendor/jsm/utils/SceneUtils.js +363 -0
  213. package/dist/ui/vendor/jsm/utils/ShadowMapViewer.js +244 -0
  214. package/dist/ui/vendor/jsm/utils/ShadowMapViewerGPU.js +233 -0
  215. package/dist/ui/vendor/jsm/utils/SkeletonUtils.js +496 -0
  216. package/dist/ui/vendor/jsm/utils/SortUtils.js +175 -0
  217. package/dist/ui/vendor/jsm/utils/UVsDebug.js +173 -0
  218. package/dist/ui/vendor/jsm/utils/WebGLTextureUtils.js +115 -0
  219. package/dist/ui/vendor/jsm/utils/WebGPUTextureUtils.js +81 -0
  220. package/dist/ui/vendor/jsm/utils/WorkerPool.js +167 -0
  221. package/dist/ui/vendor/three.core.min.js +6 -0
  222. package/dist/ui/vendor/three.module.min.js +6 -0
  223. package/dist/ui/viewer/ambient.js +39 -0
  224. package/dist/ui/viewer/api.js +93 -0
  225. package/dist/ui/viewer/chrome.js +36 -0
  226. package/dist/ui/viewer/edges.js +33 -0
  227. package/dist/ui/viewer/index.html +32 -0
  228. package/dist/ui/viewer/inspector.js +23 -0
  229. package/dist/ui/viewer/lenses/activity.js +24 -0
  230. package/dist/ui/viewer/lenses/community.js +5 -0
  231. package/dist/ui/viewer/lenses/edges.js +4 -0
  232. package/dist/ui/viewer/lenses/impact.js +6 -0
  233. package/dist/ui/viewer/lenses/search.js +69 -0
  234. package/dist/ui/viewer/lod.js +100 -0
  235. package/dist/ui/viewer/main.js +92 -0
  236. package/dist/ui/viewer/picking.js +45 -0
  237. package/dist/ui/viewer/scene.js +85 -0
  238. package/dist/ui/viewer/skins/default-skin.js +15 -0
  239. package/dist/ui/viewer/skins/loader.js +44 -0
  240. package/dist/ui/viewer/skins/manifest-schema.js +30 -0
  241. package/dist/ui/viewer/state.js +44 -0
  242. package/dist/ui/viewer/theme.js +23 -0
  243. package/dist/ui/viewer/universe.js +151 -0
  244. package/dist/ui/viewer/viewer.css +85 -0
  245. package/dist/util/safeRegex.d.ts.map +1 -1
  246. package/dist/util/safeRegex.js +221 -68
  247. package/dist/util/safeRegex.js.map +1 -1
  248. package/dist/viewer/legacy-graph.d.ts +40 -0
  249. package/dist/viewer/legacy-graph.d.ts.map +1 -0
  250. package/dist/viewer/legacy-graph.js +152 -0
  251. package/dist/viewer/legacy-graph.js.map +1 -0
  252. package/dist/viewer/routes.d.ts +10 -0
  253. package/dist/viewer/routes.d.ts.map +1 -0
  254. package/dist/viewer/routes.js +221 -0
  255. package/dist/viewer/routes.js.map +1 -0
  256. package/dist/viewer/service.d.ts +44 -0
  257. package/dist/viewer/service.d.ts.map +1 -0
  258. package/dist/viewer/service.js +160 -0
  259. package/dist/viewer/service.js.map +1 -0
  260. package/dist/viewer/types.d.ts +63 -0
  261. package/dist/viewer/types.d.ts.map +1 -0
  262. package/dist/viewer/types.js +2 -0
  263. package/dist/viewer/types.js.map +1 -0
  264. package/dist/viewer/viewer-config.d.ts +12 -0
  265. package/dist/viewer/viewer-config.d.ts.map +1 -0
  266. package/dist/viewer/viewer-config.js +36 -0
  267. package/dist/viewer/viewer-config.js.map +1 -0
  268. package/package.json +18 -9
  269. package/templates/SDL.md +19 -0
  270. package/templates/claude-code.json +8 -43
  271. package/dist/ui/graph.css +0 -108
  272. package/dist/ui/graph.d.ts +0 -2
  273. package/dist/ui/graph.d.ts.map +0 -1
  274. package/dist/ui/graph.html +0 -52
  275. package/dist/ui/graph.js +0 -259
  276. package/dist/ui/graph.js.map +0 -1
@@ -0,0 +1,919 @@
1
+ import {
2
+ BufferGeometry,
3
+ Color,
4
+ Data3DTexture,
5
+ FileLoader,
6
+ Float32BufferAttribute,
7
+ Group,
8
+ Loader,
9
+ LinearFilter,
10
+ Matrix4,
11
+ Mesh,
12
+ MeshStandardMaterial,
13
+ NearestFilter,
14
+ RedFormat,
15
+ SRGBColorSpace
16
+ } from 'three';
17
+
18
+ // Helper function to read a STRING from the data view
19
+ function readString( data, offset ) {
20
+
21
+ const size = data.getUint32( offset, true );
22
+ offset += 4;
23
+
24
+ let str = '';
25
+ for ( let i = 0; i < size; i ++ ) {
26
+
27
+ str += String.fromCharCode( data.getUint8( offset ++ ) );
28
+
29
+ }
30
+
31
+ return { value: str, size: 4 + size };
32
+
33
+ }
34
+
35
+ // Helper function to read a DICT from the data view
36
+ function readDict( data, offset ) {
37
+
38
+ const dict = {};
39
+ const count = data.getUint32( offset, true );
40
+ offset += 4;
41
+
42
+ let totalSize = 4;
43
+
44
+ for ( let i = 0; i < count; i ++ ) {
45
+
46
+ const key = readString( data, offset );
47
+ offset += key.size;
48
+ totalSize += key.size;
49
+
50
+ const value = readString( data, offset );
51
+ offset += value.size;
52
+ totalSize += value.size;
53
+
54
+ dict[ key.value ] = value.value;
55
+
56
+ }
57
+
58
+ return { value: dict, size: totalSize };
59
+
60
+ }
61
+
62
+ // Helper function to decode ROTATION byte into a rotation matrix
63
+ function decodeRotation( byte ) {
64
+
65
+ // The rotation is stored as a row-major 3x3 matrix encoded in a single byte
66
+ // Bits 0-1: index of the non-zero entry in the first row
67
+ // Bits 2-3: index of the non-zero entry in the second row
68
+ // Bit 4: sign of the first row entry (0 = positive, 1 = negative)
69
+ // Bit 5: sign of the second row entry
70
+ // Bit 6: sign of the third row entry
71
+ // The third row index is determined by the remaining column
72
+
73
+ const index1 = byte & 0x3;
74
+ const index2 = ( byte >> 2 ) & 0x3;
75
+ const sign1 = ( byte >> 4 ) & 0x1 ? - 1 : 1;
76
+ const sign2 = ( byte >> 5 ) & 0x1 ? - 1 : 1;
77
+ const sign3 = ( byte >> 6 ) & 0x1 ? - 1 : 1;
78
+
79
+ // Find the third row index (the one not used by row 0 or row 1)
80
+ const index3 = 3 - index1 - index2;
81
+
82
+ // Build the VOX rotation matrix (row-major 3x3)
83
+ // r[row][col] - each row has one non-zero entry
84
+ const r = [
85
+ [ 0, 0, 0 ],
86
+ [ 0, 0, 0 ],
87
+ [ 0, 0, 0 ]
88
+ ];
89
+
90
+ r[ 0 ][ index1 ] = sign1;
91
+ r[ 1 ][ index2 ] = sign2;
92
+ r[ 2 ][ index3 ] = sign3;
93
+
94
+ // Convert from VOX coordinate system (Z-up) to Three.js (Y-up)
95
+ // VOX: X-right, Y-forward, Z-up
96
+ // Three.js: X-right, Y-up, Z-backward
97
+ // Transformation: x' = x, y' = z, z' = -y
98
+ //
99
+ // To convert rotation matrix R_vox to R_three:
100
+ // R_three = C * R_vox * C^-1
101
+ // where C converts VOX coords to Three.js coords
102
+
103
+ // Apply coordinate change: swap Y and Z, negate new Z
104
+ // This is equivalent to: C * R * C^-1
105
+ const m = new Matrix4();
106
+ m.set(
107
+ r[ 0 ][ 0 ], r[ 0 ][ 2 ], - r[ 0 ][ 1 ], 0,
108
+ r[ 2 ][ 0 ], r[ 2 ][ 2 ], - r[ 2 ][ 1 ], 0,
109
+ - r[ 1 ][ 0 ], - r[ 1 ][ 2 ], r[ 1 ][ 1 ], 0,
110
+ 0, 0, 0, 1
111
+ );
112
+
113
+ return m;
114
+
115
+ }
116
+
117
+ // Apply VOX transform to a Three.js object
118
+ function applyTransform( object, node ) {
119
+
120
+ if ( node.attributes._name ) {
121
+
122
+ object.name = node.attributes._name;
123
+
124
+ }
125
+
126
+ if ( node.frames.length > 0 ) {
127
+
128
+ const frame = node.frames[ 0 ];
129
+
130
+ if ( frame.rotation ) {
131
+
132
+ object.applyMatrix4( frame.rotation );
133
+
134
+ }
135
+
136
+ if ( frame.translation ) {
137
+
138
+ // VOX uses Z-up, Three.js uses Y-up
139
+ object.position.set(
140
+ frame.translation.x,
141
+ frame.translation.z,
142
+ - frame.translation.y
143
+ );
144
+
145
+ }
146
+
147
+ }
148
+
149
+ }
150
+
151
+ // Recursively build Three.js object graph from VOX nodes
152
+ function buildObject( nodeId, nodes, chunks ) {
153
+
154
+ const node = nodes[ nodeId ];
155
+
156
+ if ( node.type === 'transform' ) {
157
+
158
+ const childNode = nodes[ node.childNodeId ];
159
+
160
+ // Check if this transform has actual transformation data
161
+ const frame = node.frames[ 0 ];
162
+ const hasTransform = frame && ( frame.rotation || frame.translation );
163
+
164
+ // Flatten: if child is a single-model shape, apply transform directly to mesh
165
+ if ( childNode.type === 'shape' && childNode.models.length === 1 ) {
166
+
167
+ const chunk = chunks[ childNode.models[ 0 ].modelId ];
168
+ const mesh = buildMesh( chunk );
169
+ applyTransform( mesh, node );
170
+ return mesh;
171
+
172
+ }
173
+
174
+ // If no transform, just return the child directly (avoid unnecessary group)
175
+ if ( ! hasTransform ) {
176
+
177
+ const child = buildObject( node.childNodeId, nodes, chunks );
178
+ if ( child && node.attributes._name ) child.name = node.attributes._name;
179
+ return child;
180
+
181
+ }
182
+
183
+ // Otherwise create a group
184
+ const group = new Group();
185
+ applyTransform( group, node );
186
+
187
+ const child = buildObject( node.childNodeId, nodes, chunks );
188
+ if ( child ) group.add( child );
189
+
190
+ return group;
191
+
192
+ } else if ( node.type === 'group' ) {
193
+
194
+ const group = new Group();
195
+
196
+ for ( const childId of node.childIds ) {
197
+
198
+ const child = buildObject( childId, nodes, chunks );
199
+ if ( child ) group.add( child );
200
+
201
+ }
202
+
203
+ return group;
204
+
205
+ } else if ( node.type === 'shape' ) {
206
+
207
+ // Shape reached directly (shouldn't happen in well-formed files, but handle it)
208
+ if ( node.models.length === 1 ) {
209
+
210
+ const chunk = chunks[ node.models[ 0 ].modelId ];
211
+ return buildMesh( chunk );
212
+
213
+ }
214
+
215
+ const group = new Group();
216
+
217
+ for ( const model of node.models ) {
218
+
219
+ const chunk = chunks[ model.modelId ];
220
+ group.add( buildMesh( chunk ) );
221
+
222
+ }
223
+
224
+ return group;
225
+
226
+ }
227
+
228
+ return null;
229
+
230
+ }
231
+
232
+ /**
233
+ * A loader for the VOX format.
234
+ *
235
+ * ```js
236
+ * const loader = new VOXLoader();
237
+ * const result = await loader.loadAsync( 'models/vox/monu10.vox' );
238
+ *
239
+ * scene.add( result.scene.children[ 0 ] );
240
+ * ```
241
+ * @augments Loader
242
+ * @three_import import { VOXLoader } from 'three/addons/loaders/VOXLoader.js';
243
+ */
244
+ class VOXLoader extends Loader {
245
+
246
+ /**
247
+ * Starts loading from the given URL and passes the loaded VOX asset
248
+ * to the `onLoad()` callback.
249
+ *
250
+ * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
251
+ * @param {function(Object)} onLoad - Executed when the loading process has been finished.
252
+ * @param {onProgressCallback} onProgress - Executed while the loading is in progress.
253
+ * @param {onErrorCallback} onError - Executed when errors occur.
254
+ */
255
+ load( url, onLoad, onProgress, onError ) {
256
+
257
+ const scope = this;
258
+
259
+ const loader = new FileLoader( scope.manager );
260
+ loader.setPath( scope.path );
261
+ loader.setResponseType( 'arraybuffer' );
262
+ loader.setRequestHeader( scope.requestHeader );
263
+ loader.load( url, function ( buffer ) {
264
+
265
+ try {
266
+
267
+ onLoad( scope.parse( buffer ) );
268
+
269
+ } catch ( e ) {
270
+
271
+ if ( onError ) {
272
+
273
+ onError( e );
274
+
275
+ } else {
276
+
277
+ console.error( e );
278
+
279
+ }
280
+
281
+ scope.manager.itemError( url );
282
+
283
+ }
284
+
285
+ }, onProgress, onError );
286
+
287
+ }
288
+
289
+ /**
290
+ * Parses the given VOX data and returns the result object.
291
+ *
292
+ * @param {ArrayBuffer} buffer - The raw VOX data as an array buffer.
293
+ * @return {Object} The parsed VOX data with properties: chunks, scene.
294
+ */
295
+ parse( buffer ) {
296
+
297
+ const data = new DataView( buffer );
298
+
299
+ const id = data.getUint32( 0, true );
300
+ const version = data.getUint32( 4, true );
301
+
302
+ if ( id !== 542658390 ) {
303
+
304
+ console.error( 'THREE.VOXLoader: Invalid VOX file.' );
305
+ return;
306
+
307
+ }
308
+
309
+ if ( version !== 150 && version !== 200 ) {
310
+
311
+ console.error( 'THREE.VOXLoader: Invalid VOX file. Unsupported version:', version );
312
+ return;
313
+
314
+ }
315
+
316
+ const DEFAULT_PALETTE = [
317
+ 0x00000000, 0xffffffff, 0xffccffff, 0xff99ffff, 0xff66ffff, 0xff33ffff, 0xff00ffff, 0xffffccff,
318
+ 0xffccccff, 0xff99ccff, 0xff66ccff, 0xff33ccff, 0xff00ccff, 0xffff99ff, 0xffcc99ff, 0xff9999ff,
319
+ 0xff6699ff, 0xff3399ff, 0xff0099ff, 0xffff66ff, 0xffcc66ff, 0xff9966ff, 0xff6666ff, 0xff3366ff,
320
+ 0xff0066ff, 0xffff33ff, 0xffcc33ff, 0xff9933ff, 0xff6633ff, 0xff3333ff, 0xff0033ff, 0xffff00ff,
321
+ 0xffcc00ff, 0xff9900ff, 0xff6600ff, 0xff3300ff, 0xff0000ff, 0xffffffcc, 0xffccffcc, 0xff99ffcc,
322
+ 0xff66ffcc, 0xff33ffcc, 0xff00ffcc, 0xffffcccc, 0xffcccccc, 0xff99cccc, 0xff66cccc, 0xff33cccc,
323
+ 0xff00cccc, 0xffff99cc, 0xffcc99cc, 0xff9999cc, 0xff6699cc, 0xff3399cc, 0xff0099cc, 0xffff66cc,
324
+ 0xffcc66cc, 0xff9966cc, 0xff6666cc, 0xff3366cc, 0xff0066cc, 0xffff33cc, 0xffcc33cc, 0xff9933cc,
325
+ 0xff6633cc, 0xff3333cc, 0xff0033cc, 0xffff00cc, 0xffcc00cc, 0xff9900cc, 0xff6600cc, 0xff3300cc,
326
+ 0xff0000cc, 0xffffff99, 0xffccff99, 0xff99ff99, 0xff66ff99, 0xff33ff99, 0xff00ff99, 0xffffcc99,
327
+ 0xffcccc99, 0xff99cc99, 0xff66cc99, 0xff33cc99, 0xff00cc99, 0xffff9999, 0xffcc9999, 0xff999999,
328
+ 0xff669999, 0xff339999, 0xff009999, 0xffff6699, 0xffcc6699, 0xff996699, 0xff666699, 0xff336699,
329
+ 0xff006699, 0xffff3399, 0xffcc3399, 0xff993399, 0xff663399, 0xff333399, 0xff003399, 0xffff0099,
330
+ 0xffcc0099, 0xff990099, 0xff660099, 0xff330099, 0xff000099, 0xffffff66, 0xffccff66, 0xff99ff66,
331
+ 0xff66ff66, 0xff33ff66, 0xff00ff66, 0xffffcc66, 0xffcccc66, 0xff99cc66, 0xff66cc66, 0xff33cc66,
332
+ 0xff00cc66, 0xffff9966, 0xffcc9966, 0xff999966, 0xff669966, 0xff339966, 0xff009966, 0xffff6666,
333
+ 0xffcc6666, 0xff996666, 0xff666666, 0xff336666, 0xff006666, 0xffff3366, 0xffcc3366, 0xff993366,
334
+ 0xff663366, 0xff333366, 0xff003366, 0xffff0066, 0xffcc0066, 0xff990066, 0xff660066, 0xff330066,
335
+ 0xff000066, 0xffffff33, 0xffccff33, 0xff99ff33, 0xff66ff33, 0xff33ff33, 0xff00ff33, 0xffffcc33,
336
+ 0xffcccc33, 0xff99cc33, 0xff66cc33, 0xff33cc33, 0xff00cc33, 0xffff9933, 0xffcc9933, 0xff999933,
337
+ 0xff669933, 0xff339933, 0xff009933, 0xffff6633, 0xffcc6633, 0xff996633, 0xff666633, 0xff336633,
338
+ 0xff006633, 0xffff3333, 0xffcc3333, 0xff993333, 0xff663333, 0xff333333, 0xff003333, 0xffff0033,
339
+ 0xffcc0033, 0xff990033, 0xff660033, 0xff330033, 0xff000033, 0xffffff00, 0xffccff00, 0xff99ff00,
340
+ 0xff66ff00, 0xff33ff00, 0xff00ff00, 0xffffcc00, 0xffcccc00, 0xff99cc00, 0xff66cc00, 0xff33cc00,
341
+ 0xff00cc00, 0xffff9900, 0xffcc9900, 0xff999900, 0xff669900, 0xff339900, 0xff009900, 0xffff6600,
342
+ 0xffcc6600, 0xff996600, 0xff666600, 0xff336600, 0xff006600, 0xffff3300, 0xffcc3300, 0xff993300,
343
+ 0xff663300, 0xff333300, 0xff003300, 0xffff0000, 0xffcc0000, 0xff990000, 0xff660000, 0xff330000,
344
+ 0xff0000ee, 0xff0000dd, 0xff0000bb, 0xff0000aa, 0xff000088, 0xff000077, 0xff000055, 0xff000044,
345
+ 0xff000022, 0xff000011, 0xff00ee00, 0xff00dd00, 0xff00bb00, 0xff00aa00, 0xff008800, 0xff007700,
346
+ 0xff005500, 0xff004400, 0xff002200, 0xff001100, 0xffee0000, 0xffdd0000, 0xffbb0000, 0xffaa0000,
347
+ 0xff880000, 0xff770000, 0xff550000, 0xff440000, 0xff220000, 0xff110000, 0xffeeeeee, 0xffdddddd,
348
+ 0xffbbbbbb, 0xffaaaaaa, 0xff888888, 0xff777777, 0xff555555, 0xff444444, 0xff222222, 0xff111111
349
+ ];
350
+
351
+ let i = 8;
352
+
353
+ let chunk;
354
+ const chunks = [];
355
+
356
+ // Extension data
357
+ const nodes = {};
358
+ let palette = DEFAULT_PALETTE;
359
+
360
+ while ( i < data.byteLength ) {
361
+
362
+ let id = '';
363
+
364
+ for ( let j = 0; j < 4; j ++ ) {
365
+
366
+ id += String.fromCharCode( data.getUint8( i ++ ) );
367
+
368
+ }
369
+
370
+ const chunkSize = data.getUint32( i, true ); i += 4;
371
+ i += 4; // childChunks
372
+
373
+ if ( id === 'SIZE' ) {
374
+
375
+ const x = data.getUint32( i, true ); i += 4;
376
+ const y = data.getUint32( i, true ); i += 4;
377
+ const z = data.getUint32( i, true ); i += 4;
378
+
379
+ chunk = {
380
+ palette: DEFAULT_PALETTE,
381
+ size: { x: x, y: y, z: z },
382
+ };
383
+
384
+ chunks.push( chunk );
385
+
386
+ i += chunkSize - ( 3 * 4 );
387
+
388
+ } else if ( id === 'XYZI' ) {
389
+
390
+ const numVoxels = data.getUint32( i, true ); i += 4;
391
+ chunk.data = new Uint8Array( buffer, i, numVoxels * 4 );
392
+
393
+ i += numVoxels * 4;
394
+
395
+ } else if ( id === 'RGBA' ) {
396
+
397
+ palette = [ 0 ];
398
+
399
+ for ( let j = 0; j < 256; j ++ ) {
400
+
401
+ palette[ j + 1 ] = data.getUint32( i, true ); i += 4;
402
+
403
+ }
404
+
405
+ chunk.palette = palette;
406
+
407
+ } else if ( id === 'nTRN' ) {
408
+
409
+ // Transform Node
410
+ const nodeId = data.getUint32( i, true ); i += 4;
411
+ const attributes = readDict( data, i );
412
+ i += attributes.size;
413
+
414
+ const childNodeId = data.getUint32( i, true ); i += 4;
415
+ i += 4; // reserved (-1)
416
+ const layerId = data.getInt32( i, true ); i += 4;
417
+ const numFrames = data.getUint32( i, true ); i += 4;
418
+
419
+ const frames = [];
420
+
421
+ for ( let f = 0; f < numFrames; f ++ ) {
422
+
423
+ const frameDict = readDict( data, i );
424
+ i += frameDict.size;
425
+
426
+ const frame = { rotation: null, translation: null };
427
+
428
+ if ( frameDict.value._r !== undefined ) {
429
+
430
+ frame.rotation = decodeRotation( parseInt( frameDict.value._r ) );
431
+
432
+ }
433
+
434
+ if ( frameDict.value._t !== undefined ) {
435
+
436
+ const parts = frameDict.value._t.split( ' ' ).map( Number );
437
+ frame.translation = { x: parts[ 0 ], y: parts[ 1 ], z: parts[ 2 ] };
438
+
439
+ }
440
+
441
+ frames.push( frame );
442
+
443
+ }
444
+
445
+ nodes[ nodeId ] = {
446
+ type: 'transform',
447
+ id: nodeId,
448
+ attributes: attributes.value,
449
+ childNodeId: childNodeId,
450
+ layerId: layerId,
451
+ frames: frames
452
+ };
453
+
454
+ } else if ( id === 'nGRP' ) {
455
+
456
+ // Group Node
457
+ const nodeId = data.getUint32( i, true ); i += 4;
458
+ const attributes = readDict( data, i );
459
+ i += attributes.size;
460
+
461
+ const numChildren = data.getUint32( i, true ); i += 4;
462
+ const childIds = [];
463
+
464
+ for ( let c = 0; c < numChildren; c ++ ) {
465
+
466
+ childIds.push( data.getUint32( i, true ) ); i += 4;
467
+
468
+ }
469
+
470
+ nodes[ nodeId ] = {
471
+ type: 'group',
472
+ id: nodeId,
473
+ attributes: attributes.value,
474
+ childIds: childIds
475
+ };
476
+
477
+ } else if ( id === 'nSHP' ) {
478
+
479
+ // Shape Node
480
+ const nodeId = data.getUint32( i, true ); i += 4;
481
+ const attributes = readDict( data, i );
482
+ i += attributes.size;
483
+
484
+ const numModels = data.getUint32( i, true ); i += 4;
485
+ const models = [];
486
+
487
+ for ( let m = 0; m < numModels; m ++ ) {
488
+
489
+ const modelId = data.getUint32( i, true ); i += 4;
490
+ const modelAttributes = readDict( data, i );
491
+ i += modelAttributes.size;
492
+
493
+ models.push( {
494
+ modelId: modelId,
495
+ attributes: modelAttributes.value
496
+ } );
497
+
498
+ }
499
+
500
+ nodes[ nodeId ] = {
501
+ type: 'shape',
502
+ id: nodeId,
503
+ attributes: attributes.value,
504
+ models: models
505
+ };
506
+
507
+ } else {
508
+
509
+ // Skip unknown chunks
510
+ i += chunkSize;
511
+
512
+ }
513
+
514
+ }
515
+
516
+ // Apply palette to all chunks
517
+ for ( let c = 0; c < chunks.length; c ++ ) {
518
+
519
+ chunks[ c ].palette = palette;
520
+
521
+ }
522
+
523
+ // Build Three.js scene graph from nodes
524
+ let scene = null;
525
+
526
+ if ( Object.keys( nodes ).length > 0 ) {
527
+
528
+ scene = buildObject( 0, nodes, chunks );
529
+
530
+ }
531
+
532
+ // Build result object
533
+ const result = {
534
+ chunks: chunks,
535
+ scene: scene
536
+ };
537
+
538
+ // @deprecated, r182
539
+ // Proxy for backwards compatibility with array-like access
540
+ let warned = false;
541
+
542
+ return new Proxy( result, {
543
+
544
+ get( target, prop ) {
545
+
546
+ // Handle numeric indices
547
+ if ( typeof prop === 'string' && /^\d+$/.test( prop ) ) {
548
+
549
+ if ( ! warned ) {
550
+
551
+ console.warn( 'THREE.VOXLoader: Accessing result as an array is deprecated. Use result.chunks[] instead.' );
552
+ warned = true;
553
+
554
+ }
555
+
556
+ return target.chunks[ parseInt( prop ) ];
557
+
558
+ }
559
+
560
+ // Handle array properties/methods
561
+ if ( prop === 'length' ) {
562
+
563
+ if ( ! warned ) {
564
+
565
+ console.warn( 'THREE.VOXLoader: Accessing result as an array is deprecated. Use result.chunks instead.' );
566
+ warned = true;
567
+
568
+ }
569
+
570
+ return target.chunks.length;
571
+
572
+ }
573
+
574
+ // Handle iteration
575
+ if ( prop === Symbol.iterator ) {
576
+
577
+ if ( ! warned ) {
578
+
579
+ console.warn( 'THREE.VOXLoader: Iterating result as an array is deprecated. Use result.chunks instead.' );
580
+ warned = true;
581
+
582
+ }
583
+
584
+ return target.chunks[ Symbol.iterator ].bind( target.chunks );
585
+
586
+ }
587
+
588
+ return target[ prop ];
589
+
590
+ }
591
+
592
+ } );
593
+
594
+ }
595
+
596
+ }
597
+
598
+ /**
599
+ * Builds a mesh from a VOX chunk.
600
+ *
601
+ * @param {Object} chunk - A VOX chunk loaded via {@link VOXLoader}.
602
+ * @return {Mesh} The generated mesh.
603
+ */
604
+ function buildMesh( chunk ) {
605
+
606
+ const data = chunk.data;
607
+ const size = chunk.size;
608
+ const palette = chunk.palette;
609
+
610
+ const sx = size.x;
611
+ const sy = size.y;
612
+ const sz = size.z;
613
+
614
+ // Build volume with color indices
615
+
616
+ const volume = new Uint8Array( sx * sy * sz );
617
+
618
+ for ( let j = 0; j < data.length; j += 4 ) {
619
+
620
+ const x = data[ j + 0 ];
621
+ const y = data[ j + 1 ];
622
+ const z = data[ j + 2 ];
623
+ const c = data[ j + 3 ];
624
+
625
+ volume[ x + y * sx + z * sx * sy ] = c;
626
+
627
+ }
628
+
629
+ // Greedy meshing
630
+
631
+ const vertices = [];
632
+ const indices = [];
633
+ const colors = [];
634
+
635
+ const _color = new Color();
636
+ let hasColors = false;
637
+
638
+ // Process each of the 6 face directions
639
+ // dims: the 3 axis sizes, d: which axis is normal to the face
640
+ const dims = [ sx, sy, sz ];
641
+
642
+ for ( let d = 0; d < 3; d ++ ) {
643
+
644
+ const u = ( d + 1 ) % 3;
645
+ const v = ( d + 2 ) % 3;
646
+
647
+ const dimsD = dims[ d ];
648
+ const dimsU = dims[ u ];
649
+ const dimsV = dims[ v ];
650
+
651
+ const q = [ 0, 0, 0 ];
652
+ const mask = new Int16Array( dimsU * dimsV );
653
+
654
+ q[ d ] = 1;
655
+
656
+ // Sweep through slices
657
+ for ( let slice = 0; slice <= dimsD; slice ++ ) {
658
+
659
+ // Build mask for this slice
660
+ let n = 0;
661
+
662
+ for ( let vv = 0; vv < dimsV; vv ++ ) {
663
+
664
+ for ( let uu = 0; uu < dimsU; uu ++ ) {
665
+
666
+ const pos = [ 0, 0, 0 ];
667
+ pos[ d ] = slice;
668
+ pos[ u ] = uu;
669
+ pos[ v ] = vv;
670
+
671
+ const x0 = pos[ 0 ], y0 = pos[ 1 ], z0 = pos[ 2 ];
672
+
673
+ // Get voxel behind and in front of this face
674
+ const behind = ( slice > 0 ) ? volume[ ( x0 - q[ 0 ] ) + ( y0 - q[ 1 ] ) * sx + ( z0 - q[ 2 ] ) * sx * sy ] : 0;
675
+ const infront = ( slice < dimsD ) ? volume[ x0 + y0 * sx + z0 * sx * sy ] : 0;
676
+
677
+ // Face exists if exactly one side is solid
678
+ if ( behind > 0 && infront === 0 ) {
679
+
680
+ mask[ n ] = behind; // positive face
681
+
682
+ } else if ( infront > 0 && behind === 0 ) {
683
+
684
+ mask[ n ] = - infront; // negative face
685
+
686
+ } else {
687
+
688
+ mask[ n ] = 0;
689
+
690
+ }
691
+
692
+ n ++;
693
+
694
+ }
695
+
696
+ }
697
+
698
+ // Greedy merge mask into quads
699
+ n = 0;
700
+
701
+ for ( let vv = 0; vv < dimsV; vv ++ ) {
702
+
703
+ for ( let uu = 0; uu < dimsU; ) {
704
+
705
+ const c = mask[ n ];
706
+
707
+ if ( c !== 0 ) {
708
+
709
+ // Find width
710
+ let w = 1;
711
+
712
+ while ( uu + w < dimsU && mask[ n + w ] === c ) {
713
+
714
+ w ++;
715
+
716
+ }
717
+
718
+ // Find height
719
+ let h = 1;
720
+ let done = false;
721
+
722
+ while ( vv + h < dimsV && ! done ) {
723
+
724
+ for ( let k = 0; k < w; k ++ ) {
725
+
726
+ if ( mask[ n + k + h * dimsU ] !== c ) {
727
+
728
+ done = true;
729
+ break;
730
+
731
+ }
732
+
733
+ }
734
+
735
+ if ( ! done ) h ++;
736
+
737
+ }
738
+
739
+ // Add quad
740
+ const pos = [ 0, 0, 0 ];
741
+ pos[ d ] = slice;
742
+ pos[ u ] = uu;
743
+ pos[ v ] = vv;
744
+
745
+ const du = [ 0, 0, 0 ];
746
+ const dv = [ 0, 0, 0 ];
747
+ du[ u ] = w;
748
+ dv[ v ] = h;
749
+
750
+ // Get color
751
+ const colorIndex = Math.abs( c );
752
+ const hex = palette[ colorIndex ];
753
+ const r = ( hex >> 0 & 0xff ) / 0xff;
754
+ const g = ( hex >> 8 & 0xff ) / 0xff;
755
+ const b = ( hex >> 16 & 0xff ) / 0xff;
756
+
757
+ if ( r > 0 || g > 0 || b > 0 ) hasColors = true;
758
+
759
+ _color.setRGB( r, g, b, SRGBColorSpace );
760
+
761
+ // Convert VOX coords to Three.js coords (Y-up)
762
+ // VOX: X right, Y forward, Z up -> Three.js: X right, Y up, Z back
763
+ const toThree = ( p ) => [
764
+ p[ 0 ] - sx / 2,
765
+ p[ 2 ] - sz / 2,
766
+ - p[ 1 ] + sy / 2
767
+ ];
768
+
769
+ const v0 = toThree( pos );
770
+ const v1 = toThree( [ pos[ 0 ] + du[ 0 ], pos[ 1 ] + du[ 1 ], pos[ 2 ] + du[ 2 ] ] );
771
+ const v2 = toThree( [ pos[ 0 ] + du[ 0 ] + dv[ 0 ], pos[ 1 ] + du[ 1 ] + dv[ 1 ], pos[ 2 ] + du[ 2 ] + dv[ 2 ] ] );
772
+ const v3 = toThree( [ pos[ 0 ] + dv[ 0 ], pos[ 1 ] + dv[ 1 ], pos[ 2 ] + dv[ 2 ] ] );
773
+
774
+ const idx = vertices.length / 3;
775
+
776
+ // Winding order depends on face direction
777
+ if ( c > 0 ) {
778
+
779
+ vertices.push( ...v0, ...v1, ...v2, ...v3 );
780
+ indices.push( idx, idx + 1, idx + 2, idx, idx + 2, idx + 3 );
781
+
782
+ } else {
783
+
784
+ vertices.push( ...v0, ...v3, ...v2, ...v1 );
785
+ indices.push( idx, idx + 1, idx + 2, idx, idx + 2, idx + 3 );
786
+
787
+ }
788
+
789
+ colors.push(
790
+ _color.r, _color.g, _color.b,
791
+ _color.r, _color.g, _color.b,
792
+ _color.r, _color.g, _color.b,
793
+ _color.r, _color.g, _color.b
794
+ );
795
+
796
+ // Clear mask
797
+ for ( let hh = 0; hh < h; hh ++ ) {
798
+
799
+ for ( let ww = 0; ww < w; ww ++ ) {
800
+
801
+ mask[ n + ww + hh * dimsU ] = 0;
802
+
803
+ }
804
+
805
+ }
806
+
807
+ uu += w;
808
+ n += w;
809
+
810
+ } else {
811
+
812
+ uu ++;
813
+ n ++;
814
+
815
+ }
816
+
817
+ }
818
+
819
+ }
820
+
821
+ }
822
+
823
+ }
824
+
825
+ const geometry = new BufferGeometry();
826
+ geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
827
+ geometry.setIndex( indices );
828
+ geometry.computeVertexNormals();
829
+
830
+ const material = new MeshStandardMaterial();
831
+
832
+ if ( hasColors ) {
833
+
834
+ geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
835
+ material.vertexColors = true;
836
+
837
+ }
838
+
839
+ return new Mesh( geometry, material );
840
+
841
+ }
842
+
843
+ /**
844
+ * Builds a 3D texture from a VOX chunk.
845
+ *
846
+ * @param {Object} chunk - A VOX chunk loaded via {@link VOXLoader}.
847
+ * @return {Data3DTexture} The generated 3D texture.
848
+ */
849
+ function buildData3DTexture( chunk ) {
850
+
851
+ const data = chunk.data;
852
+ const size = chunk.size;
853
+
854
+ const offsety = size.x;
855
+ const offsetz = size.x * size.y;
856
+
857
+ const array = new Uint8Array( size.x * size.y * size.z );
858
+
859
+ for ( let j = 0; j < data.length; j += 4 ) {
860
+
861
+ const x = data[ j + 0 ];
862
+ const y = data[ j + 1 ];
863
+ const z = data[ j + 2 ];
864
+
865
+ const index = x + ( y * offsety ) + ( z * offsetz );
866
+
867
+ array[ index ] = 255;
868
+
869
+ }
870
+
871
+ const texture = new Data3DTexture( array, size.x, size.y, size.z );
872
+
873
+ texture.format = RedFormat;
874
+ texture.minFilter = NearestFilter;
875
+ texture.magFilter = LinearFilter;
876
+ texture.unpackAlignment = 1;
877
+ texture.needsUpdate = true;
878
+
879
+ return texture;
880
+
881
+ }
882
+
883
+ // @deprecated, r182
884
+
885
+ class VOXMesh extends Mesh {
886
+
887
+ constructor( chunk ) {
888
+
889
+ console.warn( 'VOXMesh has been deprecated. Use buildMesh() instead.' );
890
+
891
+ const mesh = buildMesh( chunk );
892
+
893
+ super( mesh.geometry, mesh.material );
894
+
895
+ }
896
+
897
+ }
898
+
899
+ class VOXData3DTexture extends Data3DTexture {
900
+
901
+ constructor( chunk ) {
902
+
903
+ console.warn( 'VOXData3DTexture has been deprecated. Use buildData3DTexture() instead.' );
904
+
905
+ const texture = buildData3DTexture( chunk );
906
+
907
+ super( texture.image.data, texture.image.width, texture.image.height, texture.image.depth );
908
+
909
+ this.format = texture.format;
910
+ this.minFilter = texture.minFilter;
911
+ this.magFilter = texture.magFilter;
912
+ this.unpackAlignment = texture.unpackAlignment;
913
+ this.needsUpdate = true;
914
+
915
+ }
916
+
917
+ }
918
+
919
+ export { VOXLoader, buildMesh, buildData3DTexture, VOXMesh, VOXData3DTexture };