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,363 @@
1
+ import {
2
+ BufferAttribute,
3
+ BufferGeometry,
4
+ Color,
5
+ Group,
6
+ Matrix4,
7
+ Mesh,
8
+ Vector3
9
+ } from 'three';
10
+
11
+ import { mergeGroups, deepCloneAttribute } from './BufferGeometryUtils.js';
12
+
13
+ /**
14
+ * @module SceneUtils
15
+ * @three_import import * as SceneUtils from 'three/addons/utils/SceneUtils.js';
16
+ */
17
+
18
+ const _color = /*@__PURE__*/new Color();
19
+ const _matrix = /*@__PURE__*/new Matrix4();
20
+
21
+ /**
22
+ * This function creates a mesh for each instance of the given instanced mesh and
23
+ * adds it to a group. Each mesh will honor the current 3D transformation of its
24
+ * corresponding instance.
25
+ *
26
+ * @param {InstancedMesh} instancedMesh - The instanced mesh.
27
+ * @return {Group} A group of meshes.
28
+ */
29
+ function createMeshesFromInstancedMesh( instancedMesh ) {
30
+
31
+ const group = new Group();
32
+
33
+ const count = instancedMesh.count;
34
+ const geometry = instancedMesh.geometry;
35
+ const material = instancedMesh.material;
36
+
37
+ for ( let i = 0; i < count; i ++ ) {
38
+
39
+ const mesh = new Mesh( geometry, material );
40
+
41
+ instancedMesh.getMatrixAt( i, mesh.matrix );
42
+ mesh.matrix.decompose( mesh.position, mesh.quaternion, mesh.scale );
43
+
44
+ group.add( mesh );
45
+
46
+ }
47
+
48
+ group.copy( instancedMesh );
49
+ group.updateMatrixWorld(); // ensure correct world matrices of meshes
50
+
51
+ return group;
52
+
53
+ }
54
+
55
+ /**
56
+ * This function creates a mesh for each geometry-group of the given multi-material mesh and
57
+ * adds it to a group.
58
+ *
59
+ * @param {Mesh} mesh - The multi-material mesh.
60
+ * @return {Group} A group of meshes.
61
+ */
62
+ function createMeshesFromMultiMaterialMesh( mesh ) {
63
+
64
+ if ( Array.isArray( mesh.material ) === false ) {
65
+
66
+ console.warn( 'THREE.SceneUtils.createMeshesFromMultiMaterialMesh(): The given mesh has no multiple materials.' );
67
+ return mesh;
68
+
69
+ }
70
+
71
+ const object = new Group();
72
+ object.copy( mesh );
73
+
74
+ // merge groups (which automatically sorts them)
75
+
76
+ const geometry = mergeGroups( mesh.geometry );
77
+
78
+ const index = geometry.index;
79
+ const groups = geometry.groups;
80
+ const attributeNames = Object.keys( geometry.attributes );
81
+
82
+ // create a mesh for each group by extracting the buffer data into a new geometry
83
+
84
+ for ( let i = 0; i < groups.length; i ++ ) {
85
+
86
+ const group = groups[ i ];
87
+
88
+ const start = group.start;
89
+ const end = start + group.count;
90
+
91
+ const newGeometry = new BufferGeometry();
92
+ const newMaterial = mesh.material[ group.materialIndex ];
93
+
94
+ // process all buffer attributes
95
+
96
+ for ( let j = 0; j < attributeNames.length; j ++ ) {
97
+
98
+ const name = attributeNames[ j ];
99
+ const attribute = geometry.attributes[ name ];
100
+ const itemSize = attribute.itemSize;
101
+
102
+ const newLength = group.count * itemSize;
103
+ const type = attribute.array.constructor;
104
+
105
+ const newArray = new type( newLength );
106
+ const newAttribute = new BufferAttribute( newArray, itemSize );
107
+
108
+ for ( let k = start, n = 0; k < end; k ++, n ++ ) {
109
+
110
+ const ind = index.getX( k );
111
+
112
+ if ( itemSize >= 1 ) newAttribute.setX( n, attribute.getX( ind ) );
113
+ if ( itemSize >= 2 ) newAttribute.setY( n, attribute.getY( ind ) );
114
+ if ( itemSize >= 3 ) newAttribute.setZ( n, attribute.getZ( ind ) );
115
+ if ( itemSize >= 4 ) newAttribute.setW( n, attribute.getW( ind ) );
116
+
117
+ }
118
+
119
+
120
+ newGeometry.setAttribute( name, newAttribute );
121
+
122
+ }
123
+
124
+ const newMesh = new Mesh( newGeometry, newMaterial );
125
+ object.add( newMesh );
126
+
127
+ }
128
+
129
+ return object;
130
+
131
+ }
132
+
133
+ /**
134
+ * This function represents an alternative way to create 3D objects with multiple materials.
135
+ * Normally, {@link BufferGeometry#groups} are used which might introduce issues e.g. when
136
+ * exporting the object to a 3D format. This function accepts a geometry and an array of
137
+ * materials and creates for each material a mesh that is added to a group.
138
+ *
139
+ * @param {BufferGeometry} geometry - The geometry.
140
+ * @param {Array<Material>} materials - An array of materials.
141
+ * @return {Group} A group representing a multi-material object.
142
+ */
143
+ function createMultiMaterialObject( geometry, materials ) {
144
+
145
+ const group = new Group();
146
+
147
+ for ( let i = 0, l = materials.length; i < l; i ++ ) {
148
+
149
+ group.add( new Mesh( geometry, materials[ i ] ) );
150
+
151
+ }
152
+
153
+ return group;
154
+
155
+ }
156
+
157
+
158
+ /**
159
+ * Executes a reducer function for each vertex of the given 3D object.
160
+ * `reduceVertices()` returns a single value: the function's accumulated result.
161
+ *
162
+ * @param {Object3D} object - The 3D object that should be processed. It must have a
163
+ * geometry with a `position` attribute.
164
+ * @param {function(number,Vector3):number} func - The reducer function. First argument
165
+ * is the current value, second argument the current vertex.
166
+ * @param {any} initialValue - The initial value.
167
+ * @return {any} The result.
168
+ */
169
+ function reduceVertices( object, func, initialValue ) {
170
+
171
+ let value = initialValue;
172
+ const vertex = new Vector3();
173
+
174
+ object.updateWorldMatrix( true, true );
175
+
176
+ object.traverseVisible( ( child ) => {
177
+
178
+ const { geometry } = child;
179
+
180
+ if ( geometry !== undefined ) {
181
+
182
+ const { position } = geometry.attributes;
183
+
184
+ if ( position !== undefined ) {
185
+
186
+ for ( let i = 0, l = position.count; i < l; i ++ ) {
187
+
188
+ if ( child.isMesh ) {
189
+
190
+ child.getVertexPosition( i, vertex );
191
+
192
+ } else {
193
+
194
+ vertex.fromBufferAttribute( position, i );
195
+
196
+ }
197
+
198
+ if ( ! child.isSkinnedMesh ) {
199
+
200
+ vertex.applyMatrix4( child.matrixWorld );
201
+
202
+ }
203
+
204
+ value = func( value, vertex );
205
+
206
+ }
207
+
208
+ }
209
+
210
+ }
211
+
212
+ } );
213
+
214
+ return value;
215
+
216
+ }
217
+
218
+ /**
219
+ * Sorts the instances of the given instanced mesh.
220
+ *
221
+ * @param {InstancedMesh} mesh - The instanced mesh to sort.
222
+ * @param {function(number, number):number} compareFn - A custom compare function for the sort.
223
+ */
224
+ function sortInstancedMesh( mesh, compareFn ) {
225
+
226
+ // store copy of instanced attributes for lookups
227
+
228
+ const instanceMatrixRef = deepCloneAttribute( mesh.instanceMatrix );
229
+ const instanceColorRef = mesh.instanceColor ? deepCloneAttribute( mesh.instanceColor ) : null;
230
+
231
+ const attributeRefs = new Map();
232
+
233
+ for ( const name in mesh.geometry.attributes ) {
234
+
235
+ const attribute = mesh.geometry.attributes[ name ];
236
+
237
+ if ( attribute.isInstancedBufferAttribute ) {
238
+
239
+ attributeRefs.set( attribute, deepCloneAttribute( attribute ) );
240
+
241
+ }
242
+
243
+ }
244
+
245
+
246
+ // compute sort order
247
+
248
+ const tokens = [];
249
+
250
+ for ( let i = 0; i < mesh.count; i ++ ) tokens.push( i );
251
+
252
+ tokens.sort( compareFn );
253
+
254
+
255
+ // apply sort order
256
+
257
+ for ( let i = 0; i < tokens.length; i ++ ) {
258
+
259
+ const refIndex = tokens[ i ];
260
+
261
+ _matrix.fromArray( instanceMatrixRef.array, refIndex * mesh.instanceMatrix.itemSize );
262
+ _matrix.toArray( mesh.instanceMatrix.array, i * mesh.instanceMatrix.itemSize );
263
+
264
+ if ( mesh.instanceColor ) {
265
+
266
+ _color.fromArray( instanceColorRef.array, refIndex * mesh.instanceColor.itemSize );
267
+ _color.toArray( mesh.instanceColor.array, i * mesh.instanceColor.itemSize );
268
+
269
+ }
270
+
271
+ for ( const name in mesh.geometry.attributes ) {
272
+
273
+ const attribute = mesh.geometry.attributes[ name ];
274
+
275
+ if ( attribute.isInstancedBufferAttribute ) {
276
+
277
+ const attributeRef = attributeRefs.get( attribute );
278
+
279
+ attribute.setX( i, attributeRef.getX( refIndex ) );
280
+ if ( attribute.itemSize > 1 ) attribute.setY( i, attributeRef.getY( refIndex ) );
281
+ if ( attribute.itemSize > 2 ) attribute.setZ( i, attributeRef.getZ( refIndex ) );
282
+ if ( attribute.itemSize > 3 ) attribute.setW( i, attributeRef.getW( refIndex ) );
283
+
284
+ }
285
+
286
+ }
287
+
288
+ }
289
+
290
+ }
291
+
292
+ /**
293
+ * Generator based alternative to {@link Object3D#traverse}.
294
+ *
295
+ * @param {Object3D} object - Object to traverse.
296
+ * @yields {Object3D} Objects that passed the filter condition.
297
+ */
298
+ function* traverseGenerator( object ) {
299
+
300
+ yield object;
301
+
302
+ const children = object.children;
303
+
304
+ for ( let i = 0, l = children.length; i < l; i ++ ) {
305
+
306
+ yield* traverseGenerator( children[ i ] );
307
+
308
+ }
309
+
310
+ }
311
+
312
+ /**
313
+ * Generator based alternative to {@link Object3D#traverseVisible}.
314
+ *
315
+ * @param {Object3D} object Object to traverse.
316
+ * @yields {Object3D} Objects that passed the filter condition.
317
+ */
318
+ function* traverseVisibleGenerator( object ) {
319
+
320
+ if ( object.visible === false ) return;
321
+
322
+ yield object;
323
+
324
+ const children = object.children;
325
+
326
+ for ( let i = 0, l = children.length; i < l; i ++ ) {
327
+
328
+ yield* traverseVisibleGenerator( children[ i ] );
329
+
330
+ }
331
+
332
+ }
333
+
334
+ /**
335
+ * Generator based alternative to {@link Object3D#traverseAncestors}.
336
+ *
337
+ * @param {Object3D} object Object to traverse.
338
+ * @yields {Object3D} Objects that passed the filter condition.
339
+ */
340
+ function* traverseAncestorsGenerator( object ) {
341
+
342
+ const parent = object.parent;
343
+
344
+ if ( parent !== null ) {
345
+
346
+ yield parent;
347
+
348
+ yield* traverseAncestorsGenerator( parent );
349
+
350
+ }
351
+
352
+ }
353
+
354
+ export {
355
+ createMeshesFromInstancedMesh,
356
+ createMeshesFromMultiMaterialMesh,
357
+ createMultiMaterialObject,
358
+ reduceVertices,
359
+ sortInstancedMesh,
360
+ traverseGenerator,
361
+ traverseVisibleGenerator,
362
+ traverseAncestorsGenerator
363
+ };
@@ -0,0 +1,244 @@
1
+ import {
2
+ DoubleSide,
3
+ CanvasTexture,
4
+ Mesh,
5
+ MeshBasicMaterial,
6
+ OrthographicCamera,
7
+ PlaneGeometry,
8
+ Scene,
9
+ ShaderMaterial
10
+ } from 'three';
11
+
12
+ /**
13
+ * This is a helper for visualising a given light's shadow map.
14
+ * It works for shadow casting lights: DirectionalLight and SpotLight.
15
+ * It renders out the shadow map and displays it on a HUD.
16
+ *
17
+ * This module can only be used with {@link WebGLRenderer}. When using {@link WebGPURenderer},
18
+ * import the class from `ShadowMapViewerGPU.js`.
19
+ *
20
+ * ```js
21
+ * const lightShadowMapViewer = new ShadowMapViewer( light );
22
+ * lightShadowMapViewer.position.x = 10;
23
+ * lightShadowMapViewer.position.y = SCREEN_HEIGHT - ( SHADOW_MAP_HEIGHT / 4 ) - 10;
24
+ * lightShadowMapViewer.size.width = SHADOW_MAP_WIDTH / 4;
25
+ * lightShadowMapViewer.size.height = SHADOW_MAP_HEIGHT / 4;
26
+ * lightShadowMapViewer.update();
27
+ * ```
28
+ *
29
+ * @three_import import { ShadowMapViewer } from 'three/addons/utils/ShadowMapViewer.js';
30
+ */
31
+ class ShadowMapViewer {
32
+
33
+ /**
34
+ * Constructs a new shadow map viewer.
35
+ *
36
+ * @param {Light} light - The shadow casting light.
37
+ */
38
+ constructor( light ) {
39
+
40
+ //- Internals
41
+ const scope = this;
42
+ const doRenderLabel = ( light.name !== undefined && light.name !== '' );
43
+ let userAutoClearSetting;
44
+
45
+ //Holds the initial position and dimension of the HUD
46
+ const frame = {
47
+ x: 10,
48
+ y: 10,
49
+ width: 256,
50
+ height: 256
51
+ };
52
+
53
+ const camera = new OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, 1, 10 );
54
+ camera.position.set( 0, 0, 2 );
55
+ const scene = new Scene();
56
+
57
+ //HUD for shadow map
58
+ const material = new ShaderMaterial( {
59
+ uniforms: {
60
+ tDiffuse: { value: null },
61
+ opacity: { value: 1.0 }
62
+ },
63
+ vertexShader: /* glsl */`
64
+ varying vec2 vUv;
65
+ void main() {
66
+ vUv = uv;
67
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
68
+ }`,
69
+ fragmentShader: /* glsl */`
70
+ uniform float opacity;
71
+ uniform sampler2D tDiffuse;
72
+ varying vec2 vUv;
73
+ void main() {
74
+ float depth = texture2D( tDiffuse, vUv ).r;
75
+ #ifdef USE_REVERSED_DEPTH_BUFFER
76
+ gl_FragColor = vec4( vec3( depth ), opacity );
77
+ #else
78
+ gl_FragColor = vec4( vec3( 1.0 - depth ), opacity );
79
+ #endif
80
+ }`
81
+ } );
82
+ const plane = new PlaneGeometry( frame.width, frame.height );
83
+ const mesh = new Mesh( plane, material );
84
+
85
+ scene.add( mesh );
86
+
87
+
88
+ //Label for light's name
89
+ let labelCanvas, labelMesh;
90
+
91
+ if ( doRenderLabel ) {
92
+
93
+ labelCanvas = document.createElement( 'canvas' );
94
+
95
+ const context = labelCanvas.getContext( '2d' );
96
+ context.font = 'Bold 20px Arial';
97
+
98
+ const labelWidth = context.measureText( light.name ).width;
99
+ labelCanvas.width = labelWidth;
100
+ labelCanvas.height = 25; //25 to account for g, p, etc.
101
+
102
+ context.font = 'Bold 20px Arial';
103
+ context.fillStyle = 'rgba( 255, 0, 0, 1 )';
104
+ context.fillText( light.name, 0, 20 );
105
+
106
+ const labelTexture = new CanvasTexture( labelCanvas );
107
+
108
+ const labelMaterial = new MeshBasicMaterial( { map: labelTexture, side: DoubleSide, transparent: true } );
109
+
110
+ const labelPlane = new PlaneGeometry( labelCanvas.width, labelCanvas.height );
111
+ labelMesh = new Mesh( labelPlane, labelMaterial );
112
+
113
+ scene.add( labelMesh );
114
+
115
+ }
116
+
117
+
118
+ function resetPosition() {
119
+
120
+ scope.position.set( scope.position.x, scope.position.y );
121
+
122
+ }
123
+
124
+ /**
125
+ * Whether to display the shadow map viewer or not.
126
+ *
127
+ * @type {boolean}
128
+ * @default true
129
+ */
130
+ this.enabled = true;
131
+
132
+ /**
133
+ * The size of the viewer. When changing this property, make sure
134
+ * to call {@link ShadowMapViewer#update}.
135
+ *
136
+ * @type {{width:number,height:number}}
137
+ * @default true
138
+ */
139
+ this.size = {
140
+ width: frame.width,
141
+ height: frame.height,
142
+ set: function ( width, height ) {
143
+
144
+ this.width = width;
145
+ this.height = height;
146
+
147
+ mesh.scale.set( this.width / frame.width, this.height / frame.height, 1 );
148
+
149
+ //Reset the position as it is off when we scale stuff
150
+ resetPosition();
151
+
152
+ }
153
+ };
154
+
155
+ /**
156
+ * The position of the viewer. When changing this property, make sure
157
+ * to call {@link ShadowMapViewer#update}.
158
+ *
159
+ * @type {{x:number,y:number, set:function(number,number)}}
160
+ * @default true
161
+ */
162
+ this.position = {
163
+ x: frame.x,
164
+ y: frame.y,
165
+ set: function ( x, y ) {
166
+
167
+ this.x = x;
168
+ this.y = y;
169
+
170
+ const width = scope.size.width;
171
+ const height = scope.size.height;
172
+
173
+ mesh.position.set( - window.innerWidth / 2 + width / 2 + this.x, window.innerHeight / 2 - height / 2 - this.y, 0 );
174
+
175
+ if ( doRenderLabel ) labelMesh.position.set( mesh.position.x, mesh.position.y - scope.size.height / 2 + labelCanvas.height / 2, 0 );
176
+
177
+ }
178
+ };
179
+
180
+ /**
181
+ * Renders the viewer. This method must be called in the app's animation loop.
182
+ *
183
+ * @param {WebGLRenderer} renderer - The renderer.
184
+ */
185
+ this.render = function ( renderer ) {
186
+
187
+ if ( this.enabled ) {
188
+
189
+ //Because a light's .shadowMap is only initialised after the first render pass
190
+ //we have to make sure the correct map is sent into the shader, otherwise we
191
+ //always end up with the scene's first added shadow casting light's shadowMap
192
+ //in the shader
193
+ //See: https://github.com/mrdoob/three.js/issues/5932
194
+ material.uniforms.tDiffuse.value = light.shadow.map.texture;
195
+
196
+ userAutoClearSetting = renderer.autoClear;
197
+ renderer.autoClear = false; // To allow render overlay
198
+ renderer.clearDepth();
199
+ renderer.render( scene, camera );
200
+ renderer.autoClear = userAutoClearSetting; //Restore user's setting
201
+
202
+ }
203
+
204
+ };
205
+
206
+ /**
207
+ * Resizes the viewer. This method should be called whenever the app's
208
+ * window is resized.
209
+ */
210
+ this.updateForWindowResize = function () {
211
+
212
+ if ( this.enabled ) {
213
+
214
+ camera.left = window.innerWidth / - 2;
215
+ camera.right = window.innerWidth / 2;
216
+ camera.top = window.innerHeight / 2;
217
+ camera.bottom = window.innerHeight / - 2;
218
+ camera.updateProjectionMatrix();
219
+
220
+ this.update();
221
+
222
+ }
223
+
224
+ };
225
+
226
+ /**
227
+ * Updates the viewer.
228
+ */
229
+ this.update = function () {
230
+
231
+ this.position.set( this.position.x, this.position.y );
232
+ this.size.set( this.size.width, this.size.height );
233
+
234
+ };
235
+
236
+ //Force an update to set position/size
237
+ this.update();
238
+
239
+ }
240
+
241
+ }
242
+
243
+
244
+ export { ShadowMapViewer };