@carbonenginejs/runtime-resource 0.12.0 → 0.12.1

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 (170) hide show
  1. package/dist/CjsResMan.js +4 -4
  2. package/dist/CjsResMan.js.map +1 -1
  3. package/dist/_virtual/_rollupPluginBabelHelpers.js +1 -4
  4. package/dist/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
  5. package/dist/format/CjsByteReader.js +310 -0
  6. package/dist/format/CjsByteReader.js.map +1 -0
  7. package/dist/format/CjsByteWriter.js +242 -0
  8. package/dist/format/CjsByteWriter.js.map +1 -0
  9. package/dist/format/CjsFormatError.js +41 -0
  10. package/dist/format/CjsFormatError.js.map +1 -0
  11. package/dist/format/CjsStringTable.js +268 -0
  12. package/dist/format/CjsStringTable.js.map +1 -0
  13. package/dist/format/carbonEffect/CjsCarbonEffectReader.js +361 -0
  14. package/dist/format/carbonEffect/CjsCarbonEffectReader.js.map +1 -0
  15. package/dist/format/carbonEffect/CjsCarbonEffectWriter.js +373 -0
  16. package/dist/format/carbonEffect/CjsCarbonEffectWriter.js.map +1 -0
  17. package/dist/format/carbonEffect/carbonDescriptionFromPortable.js +372 -0
  18. package/dist/format/carbonEffect/carbonDescriptionFromPortable.js.map +1 -0
  19. package/dist/format/carbonEffect/carbonEffectBackendBlock.js +427 -0
  20. package/dist/format/carbonEffect/carbonEffectBackendBlock.js.map +1 -0
  21. package/dist/format/carbonEffect/carbonEffectRecords.js +955 -0
  22. package/dist/format/carbonEffect/carbonEffectRecords.js.map +1 -0
  23. package/dist/format/compareUtf8.js +36 -0
  24. package/dist/format/compareUtf8.js.map +1 -0
  25. package/dist/format/index.js +11 -0
  26. package/dist/format/index.js.map +1 -0
  27. package/dist/formats/bnk/CjsBnkFormat.js +10 -4
  28. package/dist/formats/bnk/CjsBnkFormat.js.map +1 -1
  29. package/dist/formats/bnk/core/eventAction.js +305 -0
  30. package/dist/formats/bnk/core/eventAction.js.map +1 -0
  31. package/dist/formats/bnk/core/helpers.js +11 -2
  32. package/dist/formats/bnk/core/helpers.js.map +1 -1
  33. package/dist/formats/bnk/core/nodeBase.js +532 -0
  34. package/dist/formats/bnk/core/nodeBase.js.map +1 -0
  35. package/dist/formats/bnk/core/sfxNodes.js +252 -152
  36. package/dist/formats/bnk/core/sfxNodes.js.map +1 -1
  37. package/dist/formats/hlsl/core/HlslReader.js +7 -257
  38. package/dist/formats/hlsl/core/HlslReader.js.map +1 -1
  39. package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js +781 -0
  40. package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js.map +1 -0
  41. package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js +21 -1
  42. package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js.map +1 -1
  43. package/dist/formats/index.js +1 -1
  44. package/dist/formats/webgl/core/cewg/CewgPackage.js +2 -1
  45. package/dist/formats/webgl/core/cewg/CewgPackage.js.map +1 -1
  46. package/dist/formats/webgl/core/cewg/binary.js +11 -93
  47. package/dist/formats/webgl/core/cewg/binary.js.map +1 -1
  48. package/dist/formats/webgl/core/effectPackage.js +1 -1
  49. package/dist/formats/webgpu/CjsWebgpuFormat.js +4 -23
  50. package/dist/formats/webgpu/CjsWebgpuFormat.js.map +1 -1
  51. package/dist/formats/webgpu/core/buildCarbonEffectContainer.js +197 -0
  52. package/dist/formats/webgpu/core/buildCarbonEffectContainer.js.map +1 -0
  53. package/dist/formats/webgpu/core/cewgpu/CewgpuContainer.js +368 -0
  54. package/dist/formats/webgpu/core/cewgpu/CewgpuContainer.js.map +1 -0
  55. package/dist/formats/webgpu/core/cewgpu/containerViews.js +355 -0
  56. package/dist/formats/webgpu/core/cewgpu/containerViews.js.map +1 -0
  57. package/dist/formats/webgpu/core/cewgpu/validateContainer.js +90 -0
  58. package/dist/formats/webgpu/core/cewgpu/validateContainer.js.map +1 -0
  59. package/dist/formats/webgpu/core/effectBackendBodySet.js +21 -20
  60. package/dist/formats/webgpu/core/effectBackendBodySet.js.map +1 -1
  61. package/dist/formats/webgpu/core/helpers.js +87 -92
  62. package/dist/formats/webgpu/core/helpers.js.map +1 -1
  63. package/dist/formats/webgpu/core/ir/analyzeRegisterValues.js +14 -13
  64. package/dist/formats/webgpu/core/ir/analyzeRegisterValues.js.map +1 -1
  65. package/dist/formats/webgpu/core/ir/inferValueTypes.js +10 -8
  66. package/dist/formats/webgpu/core/ir/inferValueTypes.js.map +1 -1
  67. package/dist/formats/webgpu/core/packageEffect.js +94 -9
  68. package/dist/formats/webgpu/core/packageEffect.js.map +1 -1
  69. package/dist/formats/webgpu/core/packageMetadata.js +10 -1
  70. package/dist/formats/webgpu/core/packageMetadata.js.map +1 -1
  71. package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js +17 -15
  72. package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js.map +1 -1
  73. package/dist/formats/webgpu/core/wgsl/buildWgslBindingPlan.js +13 -12
  74. package/dist/formats/webgpu/core/wgsl/buildWgslBindingPlan.js.map +1 -1
  75. package/dist/formats/webgpu/core/wgsl/buildWgslSet.js +9 -8
  76. package/dist/formats/webgpu/core/wgsl/buildWgslSet.js.map +1 -1
  77. package/dist/formats/webgpu/core/wgsl/lowerComputeProgram.js +23 -22
  78. package/dist/formats/webgpu/core/wgsl/lowerComputeProgram.js.map +1 -1
  79. package/dist/formats/webgpu/core/wgsl/selectionPlans.js +46 -44
  80. package/dist/formats/webgpu/core/wgsl/selectionPlans.js.map +1 -1
  81. package/dist/resource/CjsResource.js +700 -684
  82. package/dist/resource/CjsResource.js.map +1 -1
  83. package/dist/resource/Tr2LightProfileRes.js +18 -27
  84. package/dist/resource/Tr2LightProfileRes.js.map +1 -1
  85. package/dist/resource/audio/CjsAudioBufferRes.js +2 -2
  86. package/dist/resource/audio/CjsAudioBufferRes.js.map +1 -1
  87. package/dist/resource/audio/CjsAudioRes.js +2 -2
  88. package/dist/resource/audio/CjsAudioRes.js.map +1 -1
  89. package/dist/resource/geometry/TriGeometryRes.js +605 -586
  90. package/dist/resource/geometry/TriGeometryRes.js.map +1 -1
  91. package/dist/resource/geometry/granny/Tr2GrannyStateRes.js +21 -30
  92. package/dist/resource/geometry/granny/Tr2GrannyStateRes.js.map +1 -1
  93. package/dist/resource/geometry/granny/TriGrannyRes.js +21 -30
  94. package/dist/resource/geometry/granny/TriGrannyRes.js.map +1 -1
  95. package/dist/resource/shader/Tr2EffectRes.js +9 -7
  96. package/dist/resource/shader/Tr2EffectRes.js.map +1 -1
  97. package/dist/resource/shader/Tr2MaterialArea.js +5 -3
  98. package/dist/resource/shader/Tr2MaterialArea.js.map +1 -1
  99. package/dist/resource/shader/Tr2MaterialMesh.js +4 -2
  100. package/dist/resource/shader/Tr2MaterialMesh.js.map +1 -1
  101. package/dist/resource/shader/Tr2MaterialRes.js +5 -3
  102. package/dist/resource/shader/Tr2MaterialRes.js.map +1 -1
  103. package/dist/resource/shader/Tr2Shader.js +26 -21
  104. package/dist/resource/shader/Tr2Shader.js.map +1 -1
  105. package/dist/resource/shader/Tr2ShaderPermutation.js +8 -6
  106. package/dist/resource/shader/Tr2ShaderPermutation.js.map +1 -1
  107. package/dist/resource/shader/reflection/Tr2EffectDefine.js +5 -3
  108. package/dist/resource/shader/reflection/Tr2EffectDefine.js.map +1 -1
  109. package/dist/resource/shader/reflection/Tr2EffectDescription.js +5 -3
  110. package/dist/resource/shader/reflection/Tr2EffectDescription.js.map +1 -1
  111. package/dist/resource/shader/reflection/Tr2EffectLibrary.js +17 -15
  112. package/dist/resource/shader/reflection/Tr2EffectLibrary.js.map +1 -1
  113. package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js +11 -9
  114. package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js.map +1 -1
  115. package/dist/resource/shader/reflection/Tr2EffectResource.js +8 -6
  116. package/dist/resource/shader/reflection/Tr2EffectResource.js.map +1 -1
  117. package/dist/resource/shader/reflection/Tr2EffectStageInput.js +15 -13
  118. package/dist/resource/shader/reflection/Tr2EffectStageInput.js.map +1 -1
  119. package/dist/resource/shader/reflection/Tr2EffectTechnique.js +7 -5
  120. package/dist/resource/shader/reflection/Tr2EffectTechnique.js.map +1 -1
  121. package/dist/resource/shader/reflection/Tr2Pass.js +11 -9
  122. package/dist/resource/shader/reflection/Tr2Pass.js.map +1 -1
  123. package/dist/resource/shader/sampler/Tr2SamplerSetup.js +8 -6
  124. package/dist/resource/shader/sampler/Tr2SamplerSetup.js.map +1 -1
  125. package/dist/resource/texture/CjsTextureArrayRes.js +400 -411
  126. package/dist/resource/texture/CjsTextureArrayRes.js.map +1 -1
  127. package/dist/resource/texture/Tr2ImageRes.js +99 -95
  128. package/dist/resource/texture/Tr2ImageRes.js.map +1 -1
  129. package/dist/resource/texture/TriTextureRes.js +312 -273
  130. package/dist/resource/texture/TriTextureRes.js.map +1 -1
  131. package/docs/README.md +13 -1
  132. package/docs/architecture.md +3 -3
  133. package/docs/concepts/resource-lifecycle.md +9 -2
  134. package/docs/concepts/shader-resource-model.md +114 -0
  135. package/docs/concepts/writing-an-engine-adapter.md +115 -0
  136. package/docs/formats/README.md +24 -1
  137. package/docs/formats/carbon-effect-container.md +452 -0
  138. package/docs/formats/dxbc/reference/classes/README.md +5 -72
  139. package/docs/formats/hlsl/reference/api.md +5 -4
  140. package/docs/formats/hlsl/reference/classes/README.md +6 -11
  141. package/docs/formats/provenance.md +23 -13
  142. package/docs/formats/webgl/reference/classes/README.md +5 -92
  143. package/docs/formats/webgpu/README.md +19 -16
  144. package/docs/formats/webgpu/architecture.md +15 -12
  145. package/docs/formats/webgpu/formats/cewgpu.md +175 -438
  146. package/docs/formats/webgpu/guides/effect-packaging.md +132 -140
  147. package/docs/formats/webgpu/reference/api.md +131 -131
  148. package/docs/formats/webgpu/reference/classes/README.md +5 -62
  149. package/docs/formats/webgpu/reference/wgsl-compatibility.md +146 -45
  150. package/docs/formats/wwise.md +34 -8
  151. package/docs/reference/classes/core.md +80 -0
  152. package/docs/reference/classes/formats.md +18 -28
  153. package/docs/reference/events.md +25 -0
  154. package/docs/reference/motherlode-cache.md +22 -8
  155. package/docs/reference/workers.md +5 -5
  156. package/docs/roadmap.md +61 -41
  157. package/package.json +2 -1
  158. package/dist/formats/webgpu/core/cewgpu/CewgpuPackage.js +0 -415
  159. package/dist/formats/webgpu/core/cewgpu/CewgpuPackage.js.map +0 -1
  160. package/dist/formats/webgpu/core/cewgpu/CewgpuPackageBuilder.js +0 -100
  161. package/dist/formats/webgpu/core/cewgpu/CewgpuPackageBuilder.js.map +0 -1
  162. package/dist/formats/webgpu/core/cewgpu/binary.js +0 -93
  163. package/dist/formats/webgpu/core/cewgpu/binary.js.map +0 -1
  164. package/dist/formats/webgpu/core/cewgpu/tags.js +0 -17
  165. package/dist/formats/webgpu/core/cewgpu/tags.js.map +0 -1
  166. package/dist/formats/webgpu/core/effectPackageValidation.js +0 -1078
  167. package/dist/formats/webgpu/core/effectPackageValidation.js.map +0 -1
  168. package/docs/formats/hlsl/reference/classes/carbon-compatibility.md +0 -66
  169. package/docs/formats/hlsl/reference/classes/public-api.md +0 -26
  170. package/docs/formats/hlsl/reference/classes/tr2-effect-model.md +0 -150
@@ -1,15 +1,16 @@
1
- import { identity as _identity, applyDecs2311 as _applyDecs2311 } from '../../_virtual/_rollupPluginBabelHelpers.js';
2
- import { io, type, carbon, impl } from '@carbonenginejs/runtime-utils/schema';
1
+ import { CjsSchema, carbon, impl, type, io } from '@carbonenginejs/runtime-utils/schema';
3
2
  import { box3 } from '@carbonenginejs/runtime-utils/box3';
4
3
  import { triangleNormalTo } from '@carbonenginejs/runtime-utils/mesh';
5
4
  import { ray3 } from '@carbonenginejs/runtime-utils/ray3';
6
5
  import { sph3 } from '@carbonenginejs/runtime-utils/sph3';
7
6
  import { vec3 } from '@carbonenginejs/runtime-utils/vec3';
8
7
  import { vec4 } from '@carbonenginejs/runtime-utils/vec4';
9
- import { CjsResource as _CjsResource } from '../CjsResource.js';
8
+ import { CjsResource } from '../CjsResource.js';
10
9
  import { assertResourcePayloadObject, assertResourcePayloadArray, resourcePayloadError, resourceBoundaryError } from '../resourceBoundary.js';
11
10
 
12
- let _initProto, _initClass, _init_forceLod, _init_extra_forceLod, _init_forcedLodIndex, _init_extra_forcedLodIndex, _init_name, _init_extra_name;
11
+ // Source: trinity/trinity/Resources/TriGeometryRes.h
12
+ // Source: trinity/trinity/Resources/TriGeometryRes.cpp
13
+ // Source: trinity/trinity/Resources/TriGeometryRes_Blue.cpp
13
14
 
14
15
  /**
15
16
  * Resource record that owns geometry payload facts (meshes, optional
@@ -19,638 +20,656 @@ let _initProto, _initClass, _init_forceLod, _init_extra_forceLod, _init_forcedLo
19
20
  * Geometry inspection composes the generic math supplied by runtime-utils
20
21
  * with resource-specific payload traversal.
21
22
  */
22
- let _TriGeometryRes;
23
- new class extends _identity {
24
- static [class TriGeometryRes extends _CjsResource {
25
- static {
26
- ({
27
- e: [_init_forceLod, _init_extra_forceLod, _init_forcedLodIndex, _init_extra_forcedLodIndex, _init_name, _init_extra_name, _initProto],
28
- c: [_TriGeometryRes, _initClass]
29
- } = _applyDecs2311(this, [type.define({
30
- className: "TriGeometryRes",
31
- family: "resources"
32
- })], [[[io, io.readwrite, type, type.boolean], 16, "forceLod"], [[io, io.readwrite, type, type.int32], 16, "forcedLodIndex"], [[io, io.readwrite, type, type.string], 16, "name"], [[carbon, carbon.method, impl, impl.adapted], 18, "GetMeshCount"], [[carbon, carbon.method, impl, impl.adapted], 18, "GetAnimationCount"], [[carbon, carbon.method, impl, impl.adapted], 18, "GetSkeletonCount"], [[carbon, carbon.method, impl, impl.adapted], 18, "GetSkeletonData"], [[carbon, carbon.method, impl, impl.adapted], 18, "GetMeshAreaCount"], [[carbon, carbon.method, impl, impl.adapted], 18, "GetMeshName"], [[carbon, carbon.method, impl, impl.adapted], 18, "GetMeshAreaName"], [[carbon, carbon.method, impl, impl.adapted], 18, "GetAreaBoundingBox"], [[carbon, carbon.method, impl, impl.adapted], 18, "GetBoundingBox"], [[carbon, carbon.method, impl, impl.adapted], 18, "GetBoundingSphere"], [[carbon, carbon.method, impl, impl.adapted], 18, "CalculateBoundingBoxFromTransform"], [[carbon, carbon.method, impl, impl.adapted], 18, "RecalculateBoundingSphere"], [[carbon, carbon.method, impl, impl.notSupported], 18, "Reload"], [[carbon, carbon.method, impl, impl.adapted], 18, "GetIntersectionPointNormalBone"], [[carbon, carbon.method, impl, impl.adapted], 18, "GetAreaIntersectionPointNormalBone"], [[carbon, carbon.method, impl, impl.adapted], 18, "GetMeshVertexElements"], [[carbon, carbon.method, impl, impl.notSupported], 18, "SaveMesh"]], 0, void 0, _CjsResource));
33
- }
34
- forceLod = (_initProto(this), _init_forceLod(this, false));
35
- forcedLodIndex = (_init_extra_forceLod(this), _init_forcedLodIndex(this, -1));
36
- name = (_init_extra_forcedLodIndex(this), _init_name(this, ""));
37
-
38
- /** Creates a TriGeometryRes with caller-provided initial state. */
39
- constructor(values = null) {
40
- super(), _init_extra_name(this);
41
- this.SetValues(values || {}, {
42
- markDirty: false,
43
- skipUpdate: true,
44
- skipEvents: true
45
- });
46
- }
23
+ class TriGeometryRes extends CjsResource {
24
+ forceLod = false;
25
+ forcedLodIndex = -1;
26
+ name = "";
27
+
28
+ /** Creates a TriGeometryRes with caller-provided initial state. */
29
+ constructor(values = null) {
30
+ super();
31
+ this.SetValues(values || {}, {
32
+ markDirty: false,
33
+ skipUpdate: true,
34
+ skipEvents: true
35
+ });
36
+ }
47
37
 
48
- /**
49
- * Attach a plain geometry payload.
50
- *
51
- * @param {object|null} payload
52
- * @param {object|null} options
53
- * @returns {TriGeometryRes}
54
- */
55
- SetPayload(payload = null, options = null) {
56
- if (payload === null) {
57
- super.SetPayload(null);
58
- return this;
59
- }
60
- assertResourcePayloadObject("TriGeometryRes", payload);
61
- assertResourcePayloadArray("TriGeometryRes", payload, "meshes");
62
- for (const field of ["skeletons", "animations"]) {
63
- if (payload[field] !== undefined && !Array.isArray(payload[field])) {
64
- throw resourcePayloadError("TriGeometryRes", "Expected an array when provided.", field);
65
- }
66
- }
67
- super.SetPayload(payload);
68
- this.SetValues(options || {});
38
+ /**
39
+ * Attach a plain geometry payload.
40
+ *
41
+ * @param {object|null} payload
42
+ * @param {object|null} options
43
+ * @returns {TriGeometryRes}
44
+ */
45
+ SetPayload(payload = null, options = null) {
46
+ if (payload === null) {
47
+ super.SetPayload(null);
69
48
  return this;
70
49
  }
71
-
72
- /**
73
- * Get mesh count from the CPU geometry payload.
74
- *
75
- * @returns {number}
76
- */
77
- GetMeshCount() {
78
- return this.GetPayload()?.meshes?.length || 0;
50
+ assertResourcePayloadObject("TriGeometryRes", payload);
51
+ assertResourcePayloadArray("TriGeometryRes", payload, "meshes");
52
+ for (const field of ["skeletons", "animations"]) {
53
+ if (payload[field] !== undefined && !Array.isArray(payload[field])) {
54
+ throw resourcePayloadError("TriGeometryRes", "Expected an array when provided.", field);
55
+ }
79
56
  }
57
+ super.SetPayload(payload);
58
+ this.SetValues(options || {});
59
+ return this;
60
+ }
80
61
 
81
- /**
82
- * Get animation count from the CPU geometry payload.
83
- *
84
- * @returns {number}
85
- */
86
- GetAnimationCount() {
87
- return this.GetPayload()?.animations?.length || 0;
88
- }
62
+ /**
63
+ * Get mesh count from the CPU geometry payload.
64
+ *
65
+ * @returns {number}
66
+ */
67
+ GetMeshCount() {
68
+ return this.GetPayload()?.meshes?.length || 0;
69
+ }
89
70
 
90
- /**
91
- * Get skeleton count from the CPU geometry payload.
92
- *
93
- * @returns {number}
94
- */
95
- GetSkeletonCount() {
96
- return this.GetPayload()?.skeletons?.length || 0;
97
- }
71
+ /**
72
+ * Get animation count from the CPU geometry payload.
73
+ *
74
+ * @returns {number}
75
+ */
76
+ GetAnimationCount() {
77
+ return this.GetPayload()?.animations?.length || 0;
78
+ }
98
79
 
99
- /**
100
- * Get one resource-owned skeleton from the CPU geometry payload.
101
- *
102
- * @param {number} skeletonIndex
103
- * @returns {*}
104
- */
105
- GetSkeletonData(skeletonIndex = 0) {
106
- const index = Number(skeletonIndex);
107
- if (!Number.isInteger(index) || index < 0) {
108
- return null;
109
- }
110
- return this.GetPayload()?.skeletons?.[index] || null;
111
- }
80
+ /**
81
+ * Get skeleton count from the CPU geometry payload.
82
+ *
83
+ * @returns {number}
84
+ */
85
+ GetSkeletonCount() {
86
+ return this.GetPayload()?.skeletons?.length || 0;
87
+ }
112
88
 
113
- /**
114
- * Get mesh area count from a CPU geometry payload mesh.
115
- *
116
- * @param {number} meshIndex
117
- * @returns {number}
118
- */
119
- GetMeshAreaCount(meshIndex = 0) {
120
- const mesh = this.GetPayload()?.meshes?.[meshIndex];
121
- return mesh?.areas?.length || 0;
89
+ /**
90
+ * Get one resource-owned skeleton from the CPU geometry payload.
91
+ *
92
+ * @param {number} skeletonIndex
93
+ * @returns {*}
94
+ */
95
+ GetSkeletonData(skeletonIndex = 0) {
96
+ const index = Number(skeletonIndex);
97
+ if (!Number.isInteger(index) || index < 0) {
98
+ return null;
122
99
  }
100
+ return this.GetPayload()?.skeletons?.[index] || null;
101
+ }
123
102
 
124
- /**
125
- * Get mesh name from a CPU geometry payload.
126
- *
127
- * @param {number} meshIndex
128
- * @returns {string}
129
- */
130
- GetMeshName(meshIndex = 0) {
131
- return this.GetPayload()?.meshes?.[meshIndex]?.name || "";
132
- }
103
+ /**
104
+ * Get mesh area count from a CPU geometry payload mesh.
105
+ *
106
+ * @param {number} meshIndex
107
+ * @returns {number}
108
+ */
109
+ GetMeshAreaCount(meshIndex = 0) {
110
+ const mesh = this.GetPayload()?.meshes?.[meshIndex];
111
+ return mesh?.areas?.length || 0;
112
+ }
133
113
 
134
- /**
135
- * Get mesh area name from a CPU geometry payload.
136
- *
137
- * @param {number} meshIndex
138
- * @param {number} areaIndex
139
- * @returns {string}
140
- */
141
- GetMeshAreaName(meshIndex = 0, areaIndex = 0) {
142
- return this.GetPayload()?.meshes?.[meshIndex]?.areas?.[areaIndex]?.name || "";
143
- }
114
+ /**
115
+ * Get mesh name from a CPU geometry payload.
116
+ *
117
+ * @param {number} meshIndex
118
+ * @returns {string}
119
+ */
120
+ GetMeshName(meshIndex = 0) {
121
+ return this.GetPayload()?.meshes?.[meshIndex]?.name || "";
122
+ }
144
123
 
145
- /**
146
- * Get area bounding box from geometry payload data.
147
- *
148
- * @param {number} meshIndex
149
- * @param {number} areaIndex
150
- * @param {ArrayLike<number>|null} outMin
151
- * @param {ArrayLike<number>|null} outMax
152
- * @returns {*|boolean}
153
- */
154
- GetAreaBoundingBox(meshIndex = 0, areaIndex = 0, outMin = null, outMax = null) {
155
- const area = _TriGeometryRes.getMeshAreas(this.GetPayload()?.meshes?.[meshIndex])?.[areaIndex];
156
- const bounds = _TriGeometryRes.getBounds(area);
157
- return _TriGeometryRes.copyBounds(bounds, outMin, outMax);
158
- }
124
+ /**
125
+ * Get mesh area name from a CPU geometry payload.
126
+ *
127
+ * @param {number} meshIndex
128
+ * @param {number} areaIndex
129
+ * @returns {string}
130
+ */
131
+ GetMeshAreaName(meshIndex = 0, areaIndex = 0) {
132
+ return this.GetPayload()?.meshes?.[meshIndex]?.areas?.[areaIndex]?.name || "";
133
+ }
159
134
 
160
- /**
161
- * Get mesh bounding box from geometry payload data.
162
- * @param {number} meshIndex
163
- * @param {ArrayLike<number>|null} outMin
164
- * @param {ArrayLike<number>|null} outMax
165
- * @returns {*|boolean}
166
- */
167
- GetBoundingBox(meshIndex = 0, outMin = null, outMax = null) {
168
- const payload = this.GetPayload();
169
- const bounds = _TriGeometryRes.getBounds(payload?.meshes?.[meshIndex]) || _TriGeometryRes.getBounds(payload);
170
- return _TriGeometryRes.copyBounds(bounds, outMin, outMax);
171
- }
135
+ /**
136
+ * Get area bounding box from geometry payload data.
137
+ *
138
+ * @param {number} meshIndex
139
+ * @param {number} areaIndex
140
+ * @param {ArrayLike<number>|null} outMin
141
+ * @param {ArrayLike<number>|null} outMax
142
+ * @returns {*|boolean}
143
+ */
144
+ GetAreaBoundingBox(meshIndex = 0, areaIndex = 0, outMin = null, outMax = null) {
145
+ const area = TriGeometryRes.getMeshAreas(this.GetPayload()?.meshes?.[meshIndex])?.[areaIndex];
146
+ const bounds = TriGeometryRes.getBounds(area);
147
+ return TriGeometryRes.copyBounds(bounds, outMin, outMax);
148
+ }
172
149
 
173
- /**
174
- * Get mesh bounding sphere from geometry payload data.
175
- * @param {number} meshIndex
176
- * @param {ArrayLike<number>|null} out
177
- * @returns {*|boolean}
178
- */
179
- GetBoundingSphere(meshIndex = 0, out = null) {
180
- const payload = this.GetPayload();
181
- const sphere = _TriGeometryRes.getSphere(payload?.meshes?.[meshIndex]) || _TriGeometryRes.getSphere(payload);
182
- if (!out) return sphere;
183
- if (!sphere) return false;
184
- vec4.copy(out, sphere);
185
- return true;
186
- }
150
+ /**
151
+ * Get mesh bounding box from geometry payload data.
152
+ * @param {number} meshIndex
153
+ * @param {ArrayLike<number>|null} outMin
154
+ * @param {ArrayLike<number>|null} outMax
155
+ * @returns {*|boolean}
156
+ */
157
+ GetBoundingBox(meshIndex = 0, outMin = null, outMax = null) {
158
+ const payload = this.GetPayload();
159
+ const bounds = TriGeometryRes.getBounds(payload?.meshes?.[meshIndex]) || TriGeometryRes.getBounds(payload);
160
+ return TriGeometryRes.copyBounds(bounds, outMin, outMax);
161
+ }
187
162
 
188
- /**
189
- * Calculate a transformed bounding box from canonical CPU vertex data.
190
- *
191
- * Carbon stores the same matrix bytes as gl-matrix; transforming one point
192
- * therefore uses the ordinary column-vector index layout.
193
- *
194
- * @param {number} meshIndex
195
- * @param {ArrayLike<number>} transform
196
- * @returns {{min: number[], max: number[]}|null}
197
- */
198
- CalculateBoundingBoxFromTransform(meshIndex = 0, transform = null) {
199
- if (!transform || transform.length < 16) {
200
- throw new TypeError("TriGeometryRes transform must contain 16 matrix elements.");
201
- }
202
- const mesh = this.GetPayload()?.meshes?.[meshIndex];
203
- if (!mesh) return null;
204
- const positions = _TriGeometryRes.getMeshPositions(mesh);
205
- const sourceBounds = _TriGeometryRes.getBounds(mesh);
206
- if (!positions && !sourceBounds) return null;
207
- const bounds = box3.alloc(),
208
- point = vec3.alloc();
209
- try {
210
- if (!_TriGeometryRes.setBoundsFromPositions(bounds, positions, point)) {
211
- if (!sourceBounds) return null;
212
- box3.fromBounds(bounds, sourceBounds.min, sourceBounds.max);
213
- }
214
- box3.transformMat4(bounds, bounds, transform);
215
- return {
216
- min: [bounds[0], bounds[1], bounds[2]],
217
- max: [bounds[3], bounds[4], bounds[5]]
218
- };
219
- } finally {
220
- vec3.unalloc(point);
221
- box3.unalloc(bounds);
163
+ /**
164
+ * Get mesh bounding sphere from geometry payload data.
165
+ * @param {number} meshIndex
166
+ * @param {ArrayLike<number>|null} out
167
+ * @returns {*|boolean}
168
+ */
169
+ GetBoundingSphere(meshIndex = 0, out = null) {
170
+ const payload = this.GetPayload();
171
+ const sphere = TriGeometryRes.getSphere(payload?.meshes?.[meshIndex]) || TriGeometryRes.getSphere(payload);
172
+ if (!out) return sphere;
173
+ if (!sphere) return false;
174
+ vec4.copy(out, sphere);
175
+ return true;
176
+ }
177
+
178
+ /**
179
+ * Calculate a transformed bounding box from canonical CPU vertex data.
180
+ *
181
+ * Carbon stores the same matrix bytes as gl-matrix; transforming one point
182
+ * therefore uses the ordinary column-vector index layout.
183
+ *
184
+ * @param {number} meshIndex
185
+ * @param {ArrayLike<number>} transform
186
+ * @returns {{min: number[], max: number[]}|null}
187
+ */
188
+ CalculateBoundingBoxFromTransform(meshIndex = 0, transform = null) {
189
+ if (!transform || transform.length < 16) {
190
+ throw new TypeError("TriGeometryRes transform must contain 16 matrix elements.");
191
+ }
192
+ const mesh = this.GetPayload()?.meshes?.[meshIndex];
193
+ if (!mesh) return null;
194
+ const positions = TriGeometryRes.getMeshPositions(mesh);
195
+ const sourceBounds = TriGeometryRes.getBounds(mesh);
196
+ if (!positions && !sourceBounds) return null;
197
+ const bounds = box3.alloc(),
198
+ point = vec3.alloc();
199
+ try {
200
+ if (!TriGeometryRes.setBoundsFromPositions(bounds, positions, point)) {
201
+ if (!sourceBounds) return null;
202
+ box3.fromBounds(bounds, sourceBounds.min, sourceBounds.max);
222
203
  }
204
+ box3.transformMat4(bounds, bounds, transform);
205
+ return {
206
+ min: [bounds[0], bounds[1], bounds[2]],
207
+ max: [bounds[3], bounds[4], bounds[5]]
208
+ };
209
+ } finally {
210
+ vec3.unalloc(point);
211
+ box3.unalloc(bounds);
223
212
  }
213
+ }
224
214
 
225
- /**
226
- * Recalculate bounding sphere data from canonical CPU vertex positions.
227
- *
228
- * @returns {boolean}
229
- */
230
- RecalculateBoundingSphere() {
231
- let updated = false;
232
- const sphere = sph3.alloc(),
233
- point = vec3.alloc();
234
- try {
235
- for (const mesh of this.GetPayload()?.meshes || []) {
236
- if (!_TriGeometryRes.calculateMeshSphere(sphere, mesh, point)) continue;
237
- _TriGeometryRes.setMeshSphere(mesh, sphere);
238
- updated = true;
239
- }
240
- return updated;
241
- } finally {
242
- vec3.unalloc(point);
243
- sph3.unalloc(sphere);
215
+ /**
216
+ * Recalculate bounding sphere data from canonical CPU vertex positions.
217
+ *
218
+ * @returns {boolean}
219
+ */
220
+ RecalculateBoundingSphere() {
221
+ let updated = false;
222
+ const sphere = sph3.alloc(),
223
+ point = vec3.alloc();
224
+ try {
225
+ for (const mesh of this.GetPayload()?.meshes || []) {
226
+ if (!TriGeometryRes.calculateMeshSphere(sphere, mesh, point)) continue;
227
+ TriGeometryRes.setMeshSphere(mesh, sphere);
228
+ updated = true;
244
229
  }
230
+ return updated;
231
+ } finally {
232
+ vec3.unalloc(point);
233
+ sph3.unalloc(sphere);
245
234
  }
235
+ }
246
236
 
247
- /**
248
- * Reloading belongs to the resource manager because it owns source and
249
- * canonical replacement policy.
250
- *
251
- * @throws {Error}
252
- */
253
- Reload() {
254
- throw resourceBoundaryError("TriGeometryRes", "Reload", "Request a reload through CjsResMan so source reads and canonical replacement remain manager-owned.");
255
- }
237
+ /**
238
+ * Reloading belongs to the resource manager because it owns source and
239
+ * canonical replacement policy.
240
+ *
241
+ * @throws {Error}
242
+ */
243
+ Reload() {
244
+ throw resourceBoundaryError("TriGeometryRes", "Reload", "Request a reload through CjsResMan so source reads and canonical replacement remain manager-owned.");
245
+ }
256
246
 
257
- /**
258
- * Intersect a ray with canonical CPU triangle data.
259
- *
260
- * @param {ArrayLike<number>} position
261
- * @param {ArrayLike<number>} direction
262
- * @returns {object}
263
- */
264
- GetIntersectionPointNormalBone(position, direction) {
265
- return _TriGeometryRes.intersectGeometry(this.GetPayload()?.meshes, position, direction, -1);
266
- }
247
+ /**
248
+ * Intersect a ray with canonical CPU triangle data.
249
+ *
250
+ * @param {ArrayLike<number>} position
251
+ * @param {ArrayLike<number>} direction
252
+ * @returns {object}
253
+ */
254
+ GetIntersectionPointNormalBone(position, direction) {
255
+ return TriGeometryRes.intersectGeometry(this.GetPayload()?.meshes, position, direction, -1);
256
+ }
267
257
 
268
- /**
269
- * Intersect a ray with one area index across canonical CPU meshes.
270
- *
271
- * @param {ArrayLike<number>} position
272
- * @param {ArrayLike<number>} direction
273
- * @param {number} areaIndex
274
- * @returns {object}
275
- */
276
- GetAreaIntersectionPointNormalBone(position, direction, areaIndex = -1) {
277
- if (!Number.isInteger(areaIndex) || areaIndex < -1) {
278
- throw new RangeError("TriGeometryRes area index must be -1 or a non-negative integer.");
279
- }
280
- return _TriGeometryRes.intersectGeometry(this.GetPayload()?.meshes, position, direction, areaIndex);
281
- }
258
+ /**
259
+ * Intersect a ray with one area index across canonical CPU meshes.
260
+ *
261
+ * @param {ArrayLike<number>} position
262
+ * @param {ArrayLike<number>} direction
263
+ * @param {number} areaIndex
264
+ * @returns {object}
265
+ */
266
+ GetAreaIntersectionPointNormalBone(position, direction, areaIndex = -1) {
267
+ if (!Number.isInteger(areaIndex) || areaIndex < -1) {
268
+ throw new RangeError("TriGeometryRes area index must be -1 or a non-negative integer.");
269
+ }
270
+ return TriGeometryRes.intersectGeometry(this.GetPayload()?.meshes, position, direction, areaIndex);
271
+ }
282
272
 
283
- /**
284
- * Get vertex element descriptors for a mesh.
285
- *
286
- * @param {number} meshIndex
287
- * @returns {Array<*>}
288
- */
289
- GetMeshVertexElements(meshIndex = 0) {
290
- return this.GetPayload()?.meshes?.[meshIndex]?.vertexElements || [];
291
- }
273
+ /**
274
+ * Get vertex element descriptors for a mesh.
275
+ *
276
+ * @param {number} meshIndex
277
+ * @returns {Array<*>}
278
+ */
279
+ GetMeshVertexElements(meshIndex = 0) {
280
+ return this.GetPayload()?.meshes?.[meshIndex]?.vertexElements || [];
281
+ }
292
282
 
293
- /**
294
- * Saving belongs to the selected geometry format writer and destination.
295
- *
296
- * @throws {Error}
297
- */
298
- SaveMesh() {
299
- throw resourceBoundaryError("TriGeometryRes", "SaveMesh", "Use a geometry format writer with the resource payload and a caller-owned destination.");
300
- }
301
- /**
302
- * Gets the canonical area list from a mesh or its first LOD.
303
- *
304
- * @param {object|null} mesh
305
- * @returns {Array<*>|null}
306
- */
307
- static getMeshAreas(mesh) {
308
- return mesh?.areas || mesh?.lods?.[0]?.areas || null;
309
- }
283
+ /**
284
+ * Saving belongs to the selected geometry format writer and destination.
285
+ *
286
+ * @throws {Error}
287
+ */
288
+ SaveMesh() {
289
+ throw resourceBoundaryError("TriGeometryRes", "SaveMesh", "Use a geometry format writer with the resource payload and a caller-owned destination.");
290
+ }
291
+ static payload = "geometry";
292
+
293
+ /**
294
+ * Gets the canonical area list from a mesh or its first LOD.
295
+ *
296
+ * @param {object|null} mesh
297
+ * @returns {Array<*>|null}
298
+ */
299
+ static getMeshAreas(mesh) {
300
+ return mesh?.areas || mesh?.lods?.[0]?.areas || null;
301
+ }
310
302
 
311
- /**
312
- * Gets canonical bounds from a geometry payload object.
313
- *
314
- * @param {object|null} value
315
- * @returns {{min: ArrayLike<number>, max: ArrayLike<number>}|null}
316
- */
317
- static getBounds(value) {
318
- if (!value || typeof value !== "object") return null;
319
- if (value.bounds?.min && value.bounds?.max) return value.bounds;
320
- if (value.minBounds && value.maxBounds) {
321
- return {
322
- min: value.minBounds,
323
- max: value.maxBounds
324
- };
325
- }
326
- return null;
327
- }
303
+ /**
304
+ * Gets canonical bounds from a geometry payload object.
305
+ *
306
+ * @param {object|null} value
307
+ * @returns {{min: ArrayLike<number>, max: ArrayLike<number>}|null}
308
+ */
309
+ static getBounds(value) {
310
+ if (!value || typeof value !== "object") return null;
311
+ if (value.bounds?.min && value.bounds?.max) return value.bounds;
312
+ if (value.minBounds && value.maxBounds) {
313
+ return {
314
+ min: value.minBounds,
315
+ max: value.maxBounds
316
+ };
317
+ }
318
+ return null;
319
+ }
328
320
 
329
- /**
330
- * Gets the canonical bounding sphere from a geometry payload object.
331
- *
332
- * @param {object|null} value
333
- * @returns {ArrayLike<number>|null}
334
- */
335
- static getSphere(value) {
336
- if (!value || typeof value !== "object") return null;
337
- return value.sphere || value.boundingSphere || null;
338
- }
321
+ /**
322
+ * Gets the canonical bounding sphere from a geometry payload object.
323
+ *
324
+ * @param {object|null} value
325
+ * @returns {ArrayLike<number>|null}
326
+ */
327
+ static getSphere(value) {
328
+ if (!value || typeof value !== "object") return null;
329
+ return value.sphere || value.boundingSphere || null;
330
+ }
339
331
 
340
- /**
341
- * Copies bounds into caller-owned outputs, or returns the source object.
342
- *
343
- * @param {{min: ArrayLike<number>, max: ArrayLike<number>}|null} bounds
344
- * @param {ArrayLike<number>|null} outMin
345
- * @param {ArrayLike<number>|null} outMax
346
- * @returns {*|boolean}
347
- */
348
- static copyBounds(bounds, outMin, outMax) {
349
- if (!outMin && !outMax) return bounds;
350
- if (!bounds || !outMin || !outMax) return false;
351
- vec3.copy(outMin, bounds.min);
352
- vec3.copy(outMax, bounds.max);
353
- return true;
354
- }
332
+ /**
333
+ * Copies bounds into caller-owned outputs, or returns the source object.
334
+ *
335
+ * @param {{min: ArrayLike<number>, max: ArrayLike<number>}|null} bounds
336
+ * @param {ArrayLike<number>|null} outMin
337
+ * @param {ArrayLike<number>|null} outMax
338
+ * @returns {*|boolean}
339
+ */
340
+ static copyBounds(bounds, outMin, outMax) {
341
+ if (!outMin && !outMax) return bounds;
342
+ if (!bounds || !outMin || !outMax) return false;
343
+ vec3.copy(outMin, bounds.min);
344
+ vec3.copy(outMax, bounds.max);
345
+ return true;
346
+ }
355
347
 
356
- /**
357
- * Gets canonical positions from a mesh or its first LOD.
358
- *
359
- * @param {object|null} mesh
360
- * @returns {ArrayLike<number>|Array<ArrayLike<number>>|null}
361
- */
362
- static getMeshPositions(mesh) {
363
- return mesh?.vertex?.position || mesh?.positions || mesh?.lods?.[0]?.vertex?.position || mesh?.lods?.[0]?.positions || null;
364
- }
348
+ /**
349
+ * Gets canonical positions from a mesh or its first LOD.
350
+ *
351
+ * @param {object|null} mesh
352
+ * @returns {ArrayLike<number>|Array<ArrayLike<number>>|null}
353
+ */
354
+ static getMeshPositions(mesh) {
355
+ return mesh?.vertex?.position || mesh?.positions || mesh?.lods?.[0]?.vertex?.position || mesh?.lods?.[0]?.positions || null;
356
+ }
365
357
 
366
- /**
367
- * Gets the number of vertices represented by flat or nested positions.
368
- *
369
- * @param {ArrayLike<number>|Array<ArrayLike<number>>|null} positions
370
- * @returns {number}
371
- */
372
- static getPositionCount(positions) {
373
- if (!positions) return 0;
374
- return typeof positions[0] === "number" ? Math.floor(positions.length / 3) : positions.length;
375
- }
358
+ /**
359
+ * Gets the number of vertices represented by flat or nested positions.
360
+ *
361
+ * @param {ArrayLike<number>|Array<ArrayLike<number>>|null} positions
362
+ * @returns {number}
363
+ */
364
+ static getPositionCount(positions) {
365
+ if (!positions) return 0;
366
+ return typeof positions[0] === "number" ? Math.floor(positions.length / 3) : positions.length;
367
+ }
376
368
 
377
- /**
378
- * Calculates bounds from canonical positions using caller-owned scratch.
379
- *
380
- * @param {ArrayLike<number>} out
381
- * @param {ArrayLike<number>|Array<ArrayLike<number>>|null} positions
382
- * @param {ArrayLike<number>} point
383
- * @returns {boolean}
384
- */
385
- static setBoundsFromPositions(out, positions, point) {
386
- const count = this.getPositionCount(positions);
387
- let found = false;
388
- for (let index = 0; index < count; index++) {
389
- if (!this.copyPosition(point, positions, index)) continue;
390
- if (!found) {
391
- out[0] = out[3] = point[0];
392
- out[1] = out[4] = point[1];
393
- out[2] = out[5] = point[2];
394
- found = true;
395
- continue;
396
- }
397
- out[0] = Math.min(out[0], point[0]);
398
- out[1] = Math.min(out[1], point[1]);
399
- out[2] = Math.min(out[2], point[2]);
400
- out[3] = Math.max(out[3], point[0]);
401
- out[4] = Math.max(out[4], point[1]);
402
- out[5] = Math.max(out[5], point[2]);
369
+ /**
370
+ * Calculates bounds from canonical positions using caller-owned scratch.
371
+ *
372
+ * @param {ArrayLike<number>} out
373
+ * @param {ArrayLike<number>|Array<ArrayLike<number>>|null} positions
374
+ * @param {ArrayLike<number>} point
375
+ * @returns {boolean}
376
+ */
377
+ static setBoundsFromPositions(out, positions, point) {
378
+ const count = this.getPositionCount(positions);
379
+ let found = false;
380
+ for (let index = 0; index < count; index++) {
381
+ if (!this.copyPosition(point, positions, index)) continue;
382
+ if (!found) {
383
+ out[0] = out[3] = point[0];
384
+ out[1] = out[4] = point[1];
385
+ out[2] = out[5] = point[2];
386
+ found = true;
387
+ continue;
403
388
  }
404
- return found;
389
+ out[0] = Math.min(out[0], point[0]);
390
+ out[1] = Math.min(out[1], point[1]);
391
+ out[2] = Math.min(out[2], point[2]);
392
+ out[3] = Math.max(out[3], point[0]);
393
+ out[4] = Math.max(out[4], point[1]);
394
+ out[5] = Math.max(out[5], point[2]);
395
+ }
396
+ return found;
397
+ }
398
+
399
+ /**
400
+ * Calculates a bounding sphere from positions using caller-owned scratch.
401
+ *
402
+ * @param {ArrayLike<number>} out
403
+ * @param {ArrayLike<number>|Array<ArrayLike<number>>|null} positions
404
+ * @param {ArrayLike<number>} point
405
+ * @returns {boolean}
406
+ */
407
+ static setSphereFromPositions(out, positions, point) {
408
+ const count = this.getPositionCount(positions);
409
+ let found = false,
410
+ minX = Infinity,
411
+ minY = Infinity,
412
+ minZ = Infinity,
413
+ maxX = -Infinity,
414
+ maxY = -Infinity,
415
+ maxZ = -Infinity;
416
+ for (let index = 0; index < count; index++) {
417
+ if (!this.copyPosition(point, positions, index)) continue;
418
+ minX = Math.min(minX, point[0]);
419
+ minY = Math.min(minY, point[1]);
420
+ minZ = Math.min(minZ, point[2]);
421
+ maxX = Math.max(maxX, point[0]);
422
+ maxY = Math.max(maxY, point[1]);
423
+ maxZ = Math.max(maxZ, point[2]);
424
+ found = true;
425
+ }
426
+ if (!found) return false;
427
+ out[0] = (minX + maxX) * 0.5;
428
+ out[1] = (minY + maxY) * 0.5;
429
+ out[2] = (minZ + maxZ) * 0.5;
430
+ let maxSquaredRadius = 0;
431
+ for (let index = 0; index < count; index++) {
432
+ if (!this.copyPosition(point, positions, index)) continue;
433
+ const x = out[0] - point[0],
434
+ y = out[1] - point[1],
435
+ z = out[2] - point[2];
436
+ maxSquaredRadius = Math.max(maxSquaredRadius, x * x + y * y + z * z);
437
+ }
438
+ out[3] = Math.sqrt(maxSquaredRadius);
439
+ return true;
440
+ }
441
+
442
+ /**
443
+ * Calculates a mesh sphere from positions or existing bounds.
444
+ *
445
+ * @param {ArrayLike<number>} out
446
+ * @param {object} mesh
447
+ * @param {ArrayLike<number>} point
448
+ * @returns {boolean}
449
+ */
450
+ static calculateMeshSphere(out, mesh, point) {
451
+ if (this.setSphereFromPositions(out, this.getMeshPositions(mesh), point)) return true;
452
+ const bounds = this.getBounds(mesh);
453
+ if (!bounds) return false;
454
+ sph3.fromBounds(out, bounds.min, bounds.max);
455
+ return true;
456
+ }
457
+
458
+ /**
459
+ * Stores a calculated sphere in the mesh's canonical sphere fields.
460
+ *
461
+ * @param {object} mesh
462
+ * @param {ArrayLike<number>} sphere
463
+ * @returns {void}
464
+ */
465
+ static setMeshSphere(mesh, sphere) {
466
+ if (mesh.sphere && typeof mesh.sphere.set === "function") mesh.sphere.set(sphere);else mesh.sphere = [...sphere];
467
+ if (mesh.boundingSphere && typeof mesh.boundingSphere.set === "function") {
468
+ mesh.boundingSphere.set(sphere);
469
+ } else if ("boundingSphere" in mesh) {
470
+ mesh.boundingSphere = [...sphere];
405
471
  }
472
+ }
406
473
 
407
- /**
408
- * Calculates a bounding sphere from positions using caller-owned scratch.
409
- *
410
- * @param {ArrayLike<number>} out
411
- * @param {ArrayLike<number>|Array<ArrayLike<number>>|null} positions
412
- * @param {ArrayLike<number>} point
413
- * @returns {boolean}
414
- */
415
- static setSphereFromPositions(out, positions, point) {
416
- const count = this.getPositionCount(positions);
417
- let found = false,
418
- minX = Infinity,
419
- minY = Infinity,
420
- minZ = Infinity,
421
- maxX = -Infinity,
422
- maxY = -Infinity,
423
- maxZ = -Infinity;
424
- for (let index = 0; index < count; index++) {
425
- if (!this.copyPosition(point, positions, index)) continue;
426
- minX = Math.min(minX, point[0]);
427
- minY = Math.min(minY, point[1]);
428
- minZ = Math.min(minZ, point[2]);
429
- maxX = Math.max(maxX, point[0]);
430
- maxY = Math.max(maxY, point[1]);
431
- maxZ = Math.max(maxZ, point[2]);
432
- found = true;
433
- }
434
- if (!found) return false;
435
- out[0] = (minX + maxX) * 0.5;
436
- out[1] = (minY + maxY) * 0.5;
437
- out[2] = (minZ + maxZ) * 0.5;
438
- let maxSquaredRadius = 0;
439
- for (let index = 0; index < count; index++) {
440
- if (!this.copyPosition(point, positions, index)) continue;
441
- const x = out[0] - point[0],
442
- y = out[1] - point[1],
443
- z = out[2] - point[2];
444
- maxSquaredRadius = Math.max(maxSquaredRadius, x * x + y * y + z * z);
474
+ /**
475
+ * Intersects a ray with canonical CPU geometry.
476
+ *
477
+ * @param {Array<object>|null} meshes
478
+ * @param {ArrayLike<number>} position
479
+ * @param {ArrayLike<number>} direction
480
+ * @param {number} areaIndex
481
+ * @returns {object}
482
+ */
483
+ static intersectGeometry(meshes, position, direction, areaIndex) {
484
+ this.validateRayVector(position, "position");
485
+ this.validateRayVector(direction, "direction");
486
+ const ray = ray3.from(ray3.alloc(), position, direction),
487
+ point = vec3.alloc(),
488
+ vertexA = vec3.alloc(),
489
+ vertexB = vec3.alloc(),
490
+ vertexC = vec3.alloc(),
491
+ normal = vec3.alloc();
492
+ let nearest = null;
493
+ try {
494
+ for (let meshIndex = 0; meshIndex < (meshes?.length || 0); meshIndex++) {
495
+ const mesh = meshes[meshIndex];
496
+ const positions = this.getMeshPositions(mesh);
497
+ if (!positions) continue;
498
+ const groups = mesh?.indices || mesh?.lods?.[0]?.indices || null;
499
+ if (ArrayBuffer.isView(groups) || Array.isArray(groups) && typeof groups[0] === "number") {
500
+ if (areaIndex !== -1 && areaIndex !== 0) continue;
501
+ nearest = this.intersectFaces(nearest, groups, 0, mesh, meshIndex, positions, position, ray, point, vertexA, vertexB, vertexC, normal);
502
+ continue;
503
+ }
504
+ if (Array.isArray(groups)) {
505
+ for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {
506
+ if (areaIndex !== -1 && areaIndex !== groupIndex) continue;
507
+ const faces = groups[groupIndex]?.faces || groups[groupIndex]?.indices || [];
508
+ nearest = this.intersectFaces(nearest, faces, groupIndex, mesh, meshIndex, positions, position, ray, point, vertexA, vertexB, vertexC, normal);
509
+ }
510
+ continue;
511
+ }
512
+ if (areaIndex === -1 || areaIndex === 0) {
513
+ nearest = this.intersectFaces(nearest, null, 0, mesh, meshIndex, positions, position, ray, point, vertexA, vertexB, vertexC, normal);
514
+ }
445
515
  }
446
- out[3] = Math.sqrt(maxSquaredRadius);
447
- return true;
516
+ return nearest || {
517
+ hit: false,
518
+ boneIndex: -1,
519
+ point: [0, 0, 0],
520
+ normal: [0, 0, 0],
521
+ distance: Infinity,
522
+ meshIndex: -1,
523
+ areaIndex
524
+ };
525
+ } finally {
526
+ vec3.unalloc(normal);
527
+ vec3.unalloc(vertexC);
528
+ vec3.unalloc(vertexB);
529
+ vec3.unalloc(vertexA);
530
+ vec3.unalloc(point);
531
+ ray3.unalloc(ray);
448
532
  }
533
+ }
449
534
 
450
- /**
451
- * Calculates a mesh sphere from positions or existing bounds.
452
- *
453
- * @param {ArrayLike<number>} out
454
- * @param {object} mesh
455
- * @param {ArrayLike<number>} point
456
- * @returns {boolean}
457
- */
458
- static calculateMeshSphere(out, mesh, point) {
459
- if (this.setSphereFromPositions(out, this.getMeshPositions(mesh), point)) return true;
460
- const bounds = this.getBounds(mesh);
461
- if (!bounds) return false;
462
- sph3.fromBounds(out, bounds.min, bounds.max);
463
- return true;
535
+ /**
536
+ * Validates a caller-provided ray vector.
537
+ *
538
+ * @param {ArrayLike<number>} value
539
+ * @param {string} name
540
+ * @returns {void}
541
+ */
542
+ static validateRayVector(value, name) {
543
+ if (!value || value.length < 3 || !Number.isFinite(value[0]) || !Number.isFinite(value[1]) || !Number.isFinite(value[2])) {
544
+ throw new TypeError(`TriGeometryRes ray ${name} must contain three finite numbers.`);
464
545
  }
546
+ }
465
547
 
466
- /**
467
- * Stores a calculated sphere in the mesh's canonical sphere fields.
468
- *
469
- * @param {object} mesh
470
- * @param {ArrayLike<number>} sphere
471
- * @returns {void}
472
- */
473
- static setMeshSphere(mesh, sphere) {
474
- if (mesh.sphere && typeof mesh.sphere.set === "function") mesh.sphere.set(sphere);else mesh.sphere = [...sphere];
475
- if (mesh.boundingSphere && typeof mesh.boundingSphere.set === "function") {
476
- mesh.boundingSphere.set(sphere);
477
- } else if ("boundingSphere" in mesh) {
478
- mesh.boundingSphere = [...sphere];
548
+ /**
549
+ * Intersects a ray with one flat face list.
550
+ *
551
+ * @param {object|null} nearest
552
+ * @param {ArrayLike<number>|null} faces
553
+ * @param {number} areaIndex
554
+ * @param {object} mesh
555
+ * @param {number} meshIndex
556
+ * @param {ArrayLike<number>|Array<ArrayLike<number>>} positions
557
+ * @param {ArrayLike<number>} rayOrigin
558
+ * @param {ArrayLike<number>} ray
559
+ * @param {ArrayLike<number>} point
560
+ * @param {ArrayLike<number>} vertexA
561
+ * @param {ArrayLike<number>} vertexB
562
+ * @param {ArrayLike<number>} vertexC
563
+ * @param {ArrayLike<number>} normal
564
+ * @returns {object|null}
565
+ */
566
+ static intersectFaces(nearest, faces, areaIndex, mesh, meshIndex, positions, rayOrigin, ray, point, vertexA, vertexB, vertexC, normal) {
567
+ const count = faces?.length ?? this.getPositionCount(positions);
568
+ for (let index = 0; index + 2 < count; index += 3) {
569
+ const vertexIndexA = faces ? faces[index] : index,
570
+ vertexIndexB = faces ? faces[index + 1] : index + 1,
571
+ vertexIndexC = faces ? faces[index + 2] : index + 2;
572
+ if (!this.copyPosition(vertexA, positions, vertexIndexA) || !this.copyPosition(vertexB, positions, vertexIndexB) || !this.copyPosition(vertexC, positions, vertexIndexC) || !ray3.getIntersectVertices(point, ray, vertexA, vertexB, vertexC, false)) {
573
+ continue;
479
574
  }
480
- }
481
-
482
- /**
483
- * Intersects a ray with canonical CPU geometry.
484
- *
485
- * @param {Array<object>|null} meshes
486
- * @param {ArrayLike<number>} position
487
- * @param {ArrayLike<number>} direction
488
- * @param {number} areaIndex
489
- * @returns {object}
490
- */
491
- static intersectGeometry(meshes, position, direction, areaIndex) {
492
- this.validateRayVector(position, "position");
493
- this.validateRayVector(direction, "direction");
494
- const ray = ray3.from(ray3.alloc(), position, direction),
495
- point = vec3.alloc(),
496
- vertexA = vec3.alloc(),
497
- vertexB = vec3.alloc(),
498
- vertexC = vec3.alloc(),
499
- normal = vec3.alloc();
500
- let nearest = null;
501
- try {
502
- for (let meshIndex = 0; meshIndex < (meshes?.length || 0); meshIndex++) {
503
- const mesh = meshes[meshIndex];
504
- const positions = this.getMeshPositions(mesh);
505
- if (!positions) continue;
506
- const groups = mesh?.indices || mesh?.lods?.[0]?.indices || null;
507
- if (ArrayBuffer.isView(groups) || Array.isArray(groups) && typeof groups[0] === "number") {
508
- if (areaIndex !== -1 && areaIndex !== 0) continue;
509
- nearest = this.intersectFaces(nearest, groups, 0, mesh, meshIndex, positions, position, ray, point, vertexA, vertexB, vertexC, normal);
510
- continue;
511
- }
512
- if (Array.isArray(groups)) {
513
- for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {
514
- if (areaIndex !== -1 && areaIndex !== groupIndex) continue;
515
- const faces = groups[groupIndex]?.faces || groups[groupIndex]?.indices || [];
516
- nearest = this.intersectFaces(nearest, faces, groupIndex, mesh, meshIndex, positions, position, ray, point, vertexA, vertexB, vertexC, normal);
517
- }
518
- continue;
519
- }
520
- if (areaIndex === -1 || areaIndex === 0) {
521
- nearest = this.intersectFaces(nearest, null, 0, mesh, meshIndex, positions, position, ray, point, vertexA, vertexB, vertexC, normal);
522
- }
523
- }
524
- return nearest || {
525
- hit: false,
575
+ const distance = vec3.distance(rayOrigin, point);
576
+ if (nearest && nearest.distance <= distance) continue;
577
+ if (!nearest) {
578
+ nearest = {
579
+ hit: true,
526
580
  boneIndex: -1,
527
581
  point: [0, 0, 0],
528
582
  normal: [0, 0, 0],
529
- distance: Infinity,
530
- meshIndex: -1,
583
+ distance,
584
+ meshIndex,
531
585
  areaIndex
532
586
  };
533
- } finally {
534
- vec3.unalloc(normal);
535
- vec3.unalloc(vertexC);
536
- vec3.unalloc(vertexB);
537
- vec3.unalloc(vertexA);
538
- vec3.unalloc(point);
539
- ray3.unalloc(ray);
540
- }
541
- }
542
-
543
- /**
544
- * Validates a caller-provided ray vector.
545
- *
546
- * @param {ArrayLike<number>} value
547
- * @param {string} name
548
- * @returns {void}
549
- */
550
- static validateRayVector(value, name) {
551
- if (!value || value.length < 3 || !Number.isFinite(value[0]) || !Number.isFinite(value[1]) || !Number.isFinite(value[2])) {
552
- throw new TypeError(`TriGeometryRes ray ${name} must contain three finite numbers.`);
553
587
  }
554
- }
555
-
556
- /**
557
- * Intersects a ray with one flat face list.
558
- *
559
- * @param {object|null} nearest
560
- * @param {ArrayLike<number>|null} faces
561
- * @param {number} areaIndex
562
- * @param {object} mesh
563
- * @param {number} meshIndex
564
- * @param {ArrayLike<number>|Array<ArrayLike<number>>} positions
565
- * @param {ArrayLike<number>} rayOrigin
566
- * @param {ArrayLike<number>} ray
567
- * @param {ArrayLike<number>} point
568
- * @param {ArrayLike<number>} vertexA
569
- * @param {ArrayLike<number>} vertexB
570
- * @param {ArrayLike<number>} vertexC
571
- * @param {ArrayLike<number>} normal
572
- * @returns {object|null}
573
- */
574
- static intersectFaces(nearest, faces, areaIndex, mesh, meshIndex, positions, rayOrigin, ray, point, vertexA, vertexB, vertexC, normal) {
575
- const count = faces?.length ?? this.getPositionCount(positions);
576
- for (let index = 0; index + 2 < count; index += 3) {
577
- const vertexIndexA = faces ? faces[index] : index,
578
- vertexIndexB = faces ? faces[index + 1] : index + 1,
579
- vertexIndexC = faces ? faces[index + 2] : index + 2;
580
- if (!this.copyPosition(vertexA, positions, vertexIndexA) || !this.copyPosition(vertexB, positions, vertexIndexB) || !this.copyPosition(vertexC, positions, vertexIndexC) || !ray3.getIntersectVertices(point, ray, vertexA, vertexB, vertexC, false)) {
581
- continue;
582
- }
583
- const distance = vec3.distance(rayOrigin, point);
584
- if (nearest && nearest.distance <= distance) continue;
585
- if (!nearest) {
586
- nearest = {
587
- hit: true,
588
- boneIndex: -1,
589
- point: [0, 0, 0],
590
- normal: [0, 0, 0],
591
- distance,
592
- meshIndex,
593
- areaIndex
594
- };
595
- }
596
- nearest.boneIndex = this.getMeshBoneIndex(mesh, vertexIndexA);
597
- vec3.copy(nearest.point, point);
598
- triangleNormalTo(normal, vertexA, vertexB, vertexC);
599
- vec3.copy(nearest.normal, normal);
600
- nearest.distance = distance;
601
- nearest.meshIndex = meshIndex;
602
- nearest.areaIndex = areaIndex;
603
- }
604
- return nearest;
605
- }
588
+ nearest.boneIndex = this.getMeshBoneIndex(mesh, vertexIndexA);
589
+ vec3.copy(nearest.point, point);
590
+ triangleNormalTo(normal, vertexA, vertexB, vertexC);
591
+ vec3.copy(nearest.normal, normal);
592
+ nearest.distance = distance;
593
+ nearest.meshIndex = meshIndex;
594
+ nearest.areaIndex = areaIndex;
595
+ }
596
+ return nearest;
597
+ }
606
598
 
607
- /**
608
- * Copies one flat or nested position into caller-owned output.
609
- *
610
- * @param {ArrayLike<number>} out
611
- * @param {ArrayLike<number>|Array<ArrayLike<number>>} positions
612
- * @param {number} index
613
- * @returns {boolean}
614
- */
615
- static copyPosition(out, positions, index) {
616
- if (!Number.isInteger(index) || index < 0) return false;
617
- if (typeof positions[0] === "number") {
618
- const offset = index * 3;
619
- if (offset + 2 >= positions.length) return false;
620
- out[0] = positions[offset];
621
- out[1] = positions[offset + 1];
622
- out[2] = positions[offset + 2];
623
- return true;
624
- }
625
- const point = positions[index];
626
- if (!point || point.length < 3) return false;
627
- out[0] = point[0];
628
- out[1] = point[1];
629
- out[2] = point[2];
599
+ /**
600
+ * Copies one flat or nested position into caller-owned output.
601
+ *
602
+ * @param {ArrayLike<number>} out
603
+ * @param {ArrayLike<number>|Array<ArrayLike<number>>} positions
604
+ * @param {number} index
605
+ * @returns {boolean}
606
+ */
607
+ static copyPosition(out, positions, index) {
608
+ if (!Number.isInteger(index) || index < 0) return false;
609
+ if (typeof positions[0] === "number") {
610
+ const offset = index * 3;
611
+ if (offset + 2 >= positions.length) return false;
612
+ out[0] = positions[offset];
613
+ out[1] = positions[offset + 1];
614
+ out[2] = positions[offset + 2];
630
615
  return true;
631
616
  }
617
+ const point = positions[index];
618
+ if (!point || point.length < 3) return false;
619
+ out[0] = point[0];
620
+ out[1] = point[1];
621
+ out[2] = point[2];
622
+ return true;
623
+ }
632
624
 
633
- /**
634
- * Gets the first blend index for a mesh vertex.
635
- *
636
- * @param {object} mesh
637
- * @param {number} vertexIndex
638
- * @returns {number}
639
- */
640
- static getMeshBoneIndex(mesh, vertexIndex) {
641
- const indices = mesh?.vertex?.blendIndices || mesh?.blendIndices;
642
- if (!indices) return -1;
643
- if (typeof indices[0] === "number") {
644
- return Number(indices[vertexIndex * 4] ?? indices[vertexIndex] ?? -1);
645
- }
646
- return Number(indices[vertexIndex]?.[0] ?? -1);
647
- }
648
- }];
649
- payload = "geometry";
650
- constructor() {
651
- super(_TriGeometryRes), _initClass();
625
+ /**
626
+ * Gets the first blend index for a mesh vertex.
627
+ *
628
+ * @param {object} mesh
629
+ * @param {number} vertexIndex
630
+ * @returns {number}
631
+ */
632
+ static getMeshBoneIndex(mesh, vertexIndex) {
633
+ const indices = mesh?.vertex?.blendIndices || mesh?.blendIndices;
634
+ if (!indices) return -1;
635
+ if (typeof indices[0] === "number") {
636
+ return Number(indices[vertexIndex * 4] ?? indices[vertexIndex] ?? -1);
637
+ }
638
+ return Number(indices[vertexIndex]?.[0] ?? -1);
639
+ }
640
+ }
641
+
642
+ // Declared as data rather than with decorators, so the resource tree loads from
643
+ // source without a transform. Field order is key order, and GetValues() exports
644
+ // in that order.
645
+ CjsSchema.define(TriGeometryRes, {
646
+ className: "TriGeometryRes",
647
+ family: "resources",
648
+ fields: {
649
+ forceLod: [type.boolean, io.readwrite],
650
+ forcedLodIndex: [type.int32, io.readwrite],
651
+ name: [type.string, io.readwrite]
652
+ },
653
+ methods: {
654
+ GetMeshCount: [carbon.method, impl.adapted],
655
+ GetAnimationCount: [carbon.method, impl.adapted],
656
+ GetSkeletonCount: [carbon.method, impl.adapted],
657
+ GetSkeletonData: [carbon.method, impl.adapted],
658
+ GetMeshAreaCount: [carbon.method, impl.adapted],
659
+ GetMeshName: [carbon.method, impl.adapted],
660
+ GetMeshAreaName: [carbon.method, impl.adapted],
661
+ GetAreaBoundingBox: [carbon.method, impl.adapted],
662
+ GetBoundingBox: [carbon.method, impl.adapted],
663
+ GetBoundingSphere: [carbon.method, impl.adapted],
664
+ CalculateBoundingBoxFromTransform: [carbon.method, impl.adapted],
665
+ RecalculateBoundingSphere: [carbon.method, impl.adapted],
666
+ Reload: [carbon.method, impl.notSupported],
667
+ GetIntersectionPointNormalBone: [carbon.method, impl.adapted],
668
+ GetAreaIntersectionPointNormalBone: [carbon.method, impl.adapted],
669
+ GetMeshVertexElements: [carbon.method, impl.adapted],
670
+ SaveMesh: [carbon.method, impl.notSupported]
652
671
  }
653
- }();
672
+ });
654
673
 
655
- export { _TriGeometryRes as TriGeometryRes };
674
+ export { TriGeometryRes };
656
675
  //# sourceMappingURL=TriGeometryRes.js.map