@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.
- package/dist/CjsResMan.js +4 -4
- package/dist/CjsResMan.js.map +1 -1
- package/dist/_virtual/_rollupPluginBabelHelpers.js +1 -4
- package/dist/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
- package/dist/format/CjsByteReader.js +310 -0
- package/dist/format/CjsByteReader.js.map +1 -0
- package/dist/format/CjsByteWriter.js +242 -0
- package/dist/format/CjsByteWriter.js.map +1 -0
- package/dist/format/CjsFormatError.js +41 -0
- package/dist/format/CjsFormatError.js.map +1 -0
- package/dist/format/CjsStringTable.js +268 -0
- package/dist/format/CjsStringTable.js.map +1 -0
- package/dist/format/carbonEffect/CjsCarbonEffectReader.js +361 -0
- package/dist/format/carbonEffect/CjsCarbonEffectReader.js.map +1 -0
- package/dist/format/carbonEffect/CjsCarbonEffectWriter.js +373 -0
- package/dist/format/carbonEffect/CjsCarbonEffectWriter.js.map +1 -0
- package/dist/format/carbonEffect/carbonDescriptionFromPortable.js +372 -0
- package/dist/format/carbonEffect/carbonDescriptionFromPortable.js.map +1 -0
- package/dist/format/carbonEffect/carbonEffectBackendBlock.js +427 -0
- package/dist/format/carbonEffect/carbonEffectBackendBlock.js.map +1 -0
- package/dist/format/carbonEffect/carbonEffectRecords.js +955 -0
- package/dist/format/carbonEffect/carbonEffectRecords.js.map +1 -0
- package/dist/format/compareUtf8.js +36 -0
- package/dist/format/compareUtf8.js.map +1 -0
- package/dist/format/index.js +11 -0
- package/dist/format/index.js.map +1 -0
- package/dist/formats/bnk/CjsBnkFormat.js +10 -4
- package/dist/formats/bnk/CjsBnkFormat.js.map +1 -1
- package/dist/formats/bnk/core/eventAction.js +305 -0
- package/dist/formats/bnk/core/eventAction.js.map +1 -0
- package/dist/formats/bnk/core/helpers.js +11 -2
- package/dist/formats/bnk/core/helpers.js.map +1 -1
- package/dist/formats/bnk/core/nodeBase.js +532 -0
- package/dist/formats/bnk/core/nodeBase.js.map +1 -0
- package/dist/formats/bnk/core/sfxNodes.js +252 -152
- package/dist/formats/bnk/core/sfxNodes.js.map +1 -1
- package/dist/formats/hlsl/core/HlslReader.js +7 -257
- package/dist/formats/hlsl/core/HlslReader.js.map +1 -1
- package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js +781 -0
- package/dist/formats/hlsl/core/carbonDescriptionToRuntime.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js +21 -1
- package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js.map +1 -1
- package/dist/formats/index.js +1 -1
- package/dist/formats/webgl/core/cewg/CewgPackage.js +2 -1
- package/dist/formats/webgl/core/cewg/CewgPackage.js.map +1 -1
- package/dist/formats/webgl/core/cewg/binary.js +11 -93
- package/dist/formats/webgl/core/cewg/binary.js.map +1 -1
- package/dist/formats/webgl/core/effectPackage.js +1 -1
- package/dist/formats/webgpu/CjsWebgpuFormat.js +4 -23
- package/dist/formats/webgpu/CjsWebgpuFormat.js.map +1 -1
- package/dist/formats/webgpu/core/buildCarbonEffectContainer.js +197 -0
- package/dist/formats/webgpu/core/buildCarbonEffectContainer.js.map +1 -0
- package/dist/formats/webgpu/core/cewgpu/CewgpuContainer.js +368 -0
- package/dist/formats/webgpu/core/cewgpu/CewgpuContainer.js.map +1 -0
- package/dist/formats/webgpu/core/cewgpu/containerViews.js +355 -0
- package/dist/formats/webgpu/core/cewgpu/containerViews.js.map +1 -0
- package/dist/formats/webgpu/core/cewgpu/validateContainer.js +90 -0
- package/dist/formats/webgpu/core/cewgpu/validateContainer.js.map +1 -0
- package/dist/formats/webgpu/core/effectBackendBodySet.js +21 -20
- package/dist/formats/webgpu/core/effectBackendBodySet.js.map +1 -1
- package/dist/formats/webgpu/core/helpers.js +87 -92
- package/dist/formats/webgpu/core/helpers.js.map +1 -1
- package/dist/formats/webgpu/core/ir/analyzeRegisterValues.js +14 -13
- package/dist/formats/webgpu/core/ir/analyzeRegisterValues.js.map +1 -1
- package/dist/formats/webgpu/core/ir/inferValueTypes.js +10 -8
- package/dist/formats/webgpu/core/ir/inferValueTypes.js.map +1 -1
- package/dist/formats/webgpu/core/packageEffect.js +94 -9
- package/dist/formats/webgpu/core/packageEffect.js.map +1 -1
- package/dist/formats/webgpu/core/packageMetadata.js +10 -1
- package/dist/formats/webgpu/core/packageMetadata.js.map +1 -1
- package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js +17 -15
- package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js.map +1 -1
- package/dist/formats/webgpu/core/wgsl/buildWgslBindingPlan.js +13 -12
- package/dist/formats/webgpu/core/wgsl/buildWgslBindingPlan.js.map +1 -1
- package/dist/formats/webgpu/core/wgsl/buildWgslSet.js +9 -8
- package/dist/formats/webgpu/core/wgsl/buildWgslSet.js.map +1 -1
- package/dist/formats/webgpu/core/wgsl/lowerComputeProgram.js +23 -22
- package/dist/formats/webgpu/core/wgsl/lowerComputeProgram.js.map +1 -1
- package/dist/formats/webgpu/core/wgsl/selectionPlans.js +46 -44
- package/dist/formats/webgpu/core/wgsl/selectionPlans.js.map +1 -1
- package/dist/resource/CjsResource.js +700 -684
- package/dist/resource/CjsResource.js.map +1 -1
- package/dist/resource/Tr2LightProfileRes.js +18 -27
- package/dist/resource/Tr2LightProfileRes.js.map +1 -1
- package/dist/resource/audio/CjsAudioBufferRes.js +2 -2
- package/dist/resource/audio/CjsAudioBufferRes.js.map +1 -1
- package/dist/resource/audio/CjsAudioRes.js +2 -2
- package/dist/resource/audio/CjsAudioRes.js.map +1 -1
- package/dist/resource/geometry/TriGeometryRes.js +605 -586
- package/dist/resource/geometry/TriGeometryRes.js.map +1 -1
- package/dist/resource/geometry/granny/Tr2GrannyStateRes.js +21 -30
- package/dist/resource/geometry/granny/Tr2GrannyStateRes.js.map +1 -1
- package/dist/resource/geometry/granny/TriGrannyRes.js +21 -30
- package/dist/resource/geometry/granny/TriGrannyRes.js.map +1 -1
- package/dist/resource/shader/Tr2EffectRes.js +9 -7
- package/dist/resource/shader/Tr2EffectRes.js.map +1 -1
- package/dist/resource/shader/Tr2MaterialArea.js +5 -3
- package/dist/resource/shader/Tr2MaterialArea.js.map +1 -1
- package/dist/resource/shader/Tr2MaterialMesh.js +4 -2
- package/dist/resource/shader/Tr2MaterialMesh.js.map +1 -1
- package/dist/resource/shader/Tr2MaterialRes.js +5 -3
- package/dist/resource/shader/Tr2MaterialRes.js.map +1 -1
- package/dist/resource/shader/Tr2Shader.js +26 -21
- package/dist/resource/shader/Tr2Shader.js.map +1 -1
- package/dist/resource/shader/Tr2ShaderPermutation.js +8 -6
- package/dist/resource/shader/Tr2ShaderPermutation.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectDefine.js +5 -3
- package/dist/resource/shader/reflection/Tr2EffectDefine.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectDescription.js +5 -3
- package/dist/resource/shader/reflection/Tr2EffectDescription.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectLibrary.js +17 -15
- package/dist/resource/shader/reflection/Tr2EffectLibrary.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js +11 -9
- package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectResource.js +8 -6
- package/dist/resource/shader/reflection/Tr2EffectResource.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js +15 -13
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2EffectTechnique.js +7 -5
- package/dist/resource/shader/reflection/Tr2EffectTechnique.js.map +1 -1
- package/dist/resource/shader/reflection/Tr2Pass.js +11 -9
- package/dist/resource/shader/reflection/Tr2Pass.js.map +1 -1
- package/dist/resource/shader/sampler/Tr2SamplerSetup.js +8 -6
- package/dist/resource/shader/sampler/Tr2SamplerSetup.js.map +1 -1
- package/dist/resource/texture/CjsTextureArrayRes.js +400 -411
- package/dist/resource/texture/CjsTextureArrayRes.js.map +1 -1
- package/dist/resource/texture/Tr2ImageRes.js +99 -95
- package/dist/resource/texture/Tr2ImageRes.js.map +1 -1
- package/dist/resource/texture/TriTextureRes.js +312 -273
- package/dist/resource/texture/TriTextureRes.js.map +1 -1
- package/docs/README.md +13 -1
- package/docs/architecture.md +3 -3
- package/docs/concepts/resource-lifecycle.md +9 -2
- package/docs/concepts/shader-resource-model.md +114 -0
- package/docs/concepts/writing-an-engine-adapter.md +115 -0
- package/docs/formats/README.md +24 -1
- package/docs/formats/carbon-effect-container.md +452 -0
- package/docs/formats/dxbc/reference/classes/README.md +5 -72
- package/docs/formats/hlsl/reference/api.md +5 -4
- package/docs/formats/hlsl/reference/classes/README.md +6 -11
- package/docs/formats/provenance.md +23 -13
- package/docs/formats/webgl/reference/classes/README.md +5 -92
- package/docs/formats/webgpu/README.md +19 -16
- package/docs/formats/webgpu/architecture.md +15 -12
- package/docs/formats/webgpu/formats/cewgpu.md +175 -438
- package/docs/formats/webgpu/guides/effect-packaging.md +132 -140
- package/docs/formats/webgpu/reference/api.md +131 -131
- package/docs/formats/webgpu/reference/classes/README.md +5 -62
- package/docs/formats/webgpu/reference/wgsl-compatibility.md +146 -45
- package/docs/formats/wwise.md +34 -8
- package/docs/reference/classes/core.md +80 -0
- package/docs/reference/classes/formats.md +18 -28
- package/docs/reference/events.md +25 -0
- package/docs/reference/motherlode-cache.md +22 -8
- package/docs/reference/workers.md +5 -5
- package/docs/roadmap.md +61 -41
- package/package.json +2 -1
- package/dist/formats/webgpu/core/cewgpu/CewgpuPackage.js +0 -415
- package/dist/formats/webgpu/core/cewgpu/CewgpuPackage.js.map +0 -1
- package/dist/formats/webgpu/core/cewgpu/CewgpuPackageBuilder.js +0 -100
- package/dist/formats/webgpu/core/cewgpu/CewgpuPackageBuilder.js.map +0 -1
- package/dist/formats/webgpu/core/cewgpu/binary.js +0 -93
- package/dist/formats/webgpu/core/cewgpu/binary.js.map +0 -1
- package/dist/formats/webgpu/core/cewgpu/tags.js +0 -17
- package/dist/formats/webgpu/core/cewgpu/tags.js.map +0 -1
- package/dist/formats/webgpu/core/effectPackageValidation.js +0 -1078
- package/dist/formats/webgpu/core/effectPackageValidation.js.map +0 -1
- package/docs/formats/hlsl/reference/classes/carbon-compatibility.md +0 -66
- package/docs/formats/hlsl/reference/classes/public-api.md +0 -26
- package/docs/formats/hlsl/reference/classes/tr2-effect-model.md +0 -150
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
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
|
|
8
|
+
import { CjsResource } from '../CjsResource.js';
|
|
10
9
|
import { assertResourcePayloadObject, assertResourcePayloadArray, resourcePayloadError, resourceBoundaryError } from '../resourceBoundary.js';
|
|
11
10
|
|
|
12
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
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
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
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
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
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
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
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
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
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
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
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
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
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
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
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
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
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
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
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
|
-
|
|
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
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
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
|
-
|
|
447
|
-
|
|
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
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
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
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
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
|
-
|
|
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
|
|
530
|
-
meshIndex
|
|
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
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
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
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
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
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
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 {
|
|
674
|
+
export { TriGeometryRes };
|
|
656
675
|
//# sourceMappingURL=TriGeometryRes.js.map
|