@zephyr3d/scene 0.9.26 → 0.9.27

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 (95) hide show
  1. package/dist/animation/animationset.js +92 -30
  2. package/dist/animation/animationset.js.map +1 -1
  3. package/dist/animation/joint_dynamics/convex_collider.js +320 -0
  4. package/dist/animation/joint_dynamics/convex_collider.js.map +1 -0
  5. package/dist/animation/skeleton.js +21 -1
  6. package/dist/animation/skeleton.js.map +1 -1
  7. package/dist/asset/model.js +6 -2
  8. package/dist/asset/model.js.map +1 -1
  9. package/dist/camera/camera.js +75 -23
  10. package/dist/camera/camera.js.map +1 -1
  11. package/dist/index.d.ts +4764 -3600
  12. package/dist/index.js +2 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/material/hairstrand.js +235 -235
  15. package/dist/material/hairstrand.js.map +1 -1
  16. package/dist/material/material.js +296 -296
  17. package/dist/material/material.js.map +1 -1
  18. package/dist/material/mixins/lit.js +33 -1
  19. package/dist/material/mixins/lit.js.map +1 -1
  20. package/dist/material/shader/helper.js +404 -3
  21. package/dist/material/shader/helper.js.map +1 -1
  22. package/dist/material/water.js +2057 -72
  23. package/dist/material/water.js.map +1 -1
  24. package/dist/posteffect/motionblur.js +663 -58
  25. package/dist/posteffect/motionblur.js.map +1 -1
  26. package/dist/posteffect/posteffect.js +12 -1
  27. package/dist/posteffect/posteffect.js.map +1 -1
  28. package/dist/posteffect/sao.js +46 -44
  29. package/dist/posteffect/sao.js.map +1 -1
  30. package/dist/posteffect/sss.js +30 -2
  31. package/dist/posteffect/sss.js.map +1 -1
  32. package/dist/render/abuffer_oit.js +37 -37
  33. package/dist/render/abuffer_oit.js.map +1 -1
  34. package/dist/render/clipmap.js +156 -5
  35. package/dist/render/clipmap.js.map +1 -1
  36. package/dist/render/cull_visitor.js +1 -0
  37. package/dist/render/cull_visitor.js.map +1 -1
  38. package/dist/render/dualdepthpeeling_oit.js +49 -49
  39. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  40. package/dist/render/fbm_wavegenerator.js +3 -3
  41. package/dist/render/fbm_wavegenerator.js.map +1 -1
  42. package/dist/render/fft_wavegenerator.js +57 -15
  43. package/dist/render/fft_wavegenerator.js.map +1 -1
  44. package/dist/render/gerstner_wavegenerator.js +127 -20
  45. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  46. package/dist/render/hzb.js +80 -22
  47. package/dist/render/hzb.js.map +1 -1
  48. package/dist/render/lightpass.js +6 -3
  49. package/dist/render/lightpass.js.map +1 -1
  50. package/dist/render/oit.js +11 -11
  51. package/dist/render/oit.js.map +1 -1
  52. package/dist/render/render_queue.js +36 -0
  53. package/dist/render/render_queue.js.map +1 -1
  54. package/dist/render/renderer.js +4 -0
  55. package/dist/render/renderer.js.map +1 -1
  56. package/dist/render/rendergraph/blackboard.js +1 -0
  57. package/dist/render/rendergraph/blackboard.js.map +1 -1
  58. package/dist/render/rendergraph/forward_plus_builder.js +318 -9
  59. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  60. package/dist/render/rendergraph/frame_resource_requirements.js +1 -0
  61. package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -1
  62. package/dist/render/rendergraph/history_resources.js +8 -1
  63. package/dist/render/rendergraph/history_resources.js.map +1 -1
  64. package/dist/render/underwater.js +624 -0
  65. package/dist/render/underwater.js.map +1 -0
  66. package/dist/render/water_caustics.js +1380 -0
  67. package/dist/render/water_caustics.js.map +1 -0
  68. package/dist/render/weightedblended_oit.js +33 -33
  69. package/dist/render/weightedblended_oit.js.map +1 -1
  70. package/dist/scene/water.js +540 -4
  71. package/dist/scene/water.js.map +1 -1
  72. package/dist/shaders/water.js +22 -19
  73. package/dist/shaders/water.js.map +1 -1
  74. package/dist/shaders/water_medium.js +56 -0
  75. package/dist/shaders/water_medium.js.map +1 -0
  76. package/dist/shadow/shadow_region.js +49 -49
  77. package/dist/shadow/shadow_region.js.map +1 -1
  78. package/dist/utility/serialization/manager.js +3 -1
  79. package/dist/utility/serialization/manager.js.map +1 -1
  80. package/dist/utility/serialization/scene/animation.js +31 -2
  81. package/dist/utility/serialization/scene/animation.js.map +1 -1
  82. package/dist/utility/serialization/scene/camera.js +53 -25
  83. package/dist/utility/serialization/scene/camera.js.map +1 -1
  84. package/dist/utility/serialization/scene/light.js.map +1 -1
  85. package/dist/utility/serialization/scene/water.js +1101 -21
  86. package/dist/utility/serialization/scene/water.js.map +1 -1
  87. package/dist/utility/shprojector.js +87 -87
  88. package/dist/utility/shprojector.js.map +1 -1
  89. package/package.json +1 -1
  90. package/dist/render/rendergraph/frame_graph_context.js +0 -41
  91. package/dist/render/rendergraph/frame_graph_context.js.map +0 -1
  92. package/dist/shaders/ssgi.js +0 -63
  93. package/dist/shaders/ssgi.js.map +0 -1
  94. package/dist/shaders/ssgi_reprojection.js +0 -118
  95. package/dist/shaders/ssgi_reprojection.js.map +0 -1
@@ -0,0 +1,320 @@
1
+ import { Matrix4x4, Vector3 } from '@zephyr3d/base';
2
+ import { getVertexFormatComponentCount } from '@zephyr3d/device';
3
+ import '../../scene/scene.js';
4
+ import '../../values.js';
5
+ import '../../render/render_queue.js';
6
+ import '../../render/primitive.js';
7
+ import '../../material/shader/helper.js';
8
+ import '../../material/lambert.js';
9
+ import '../../material/blinn.js';
10
+ import '../../material/unlit.js';
11
+ import '../../material/particle.js';
12
+ import '../../material/subsurfaceprofile.js';
13
+ import '../../material/meshmaterial.js';
14
+ import '../../material/grassmaterial.js';
15
+ import '../../material/terrain-cm.js';
16
+ import '../../material/pbrmr.js';
17
+ import '../../material/pbrsg.js';
18
+ import '../../material/mtoon.js';
19
+ import '../../material/pbrblueprint.js';
20
+ import '../../material/sprite.js';
21
+ import '../../material/sprite_std.js';
22
+ import '../../utility/blueprint/material/texture.js';
23
+ import '../../render/rendergraph/forward_plus_builder.js';
24
+ import '../../render/lightpass.js';
25
+ import '../../render/sky.js';
26
+ import '../../render/clipmap.js';
27
+ import '../../shaders/atmosphere.js';
28
+ import { getSceneMeshAssetBinding } from '../../scene/scene_node.js';
29
+ import '../../shadow/shadowmapper.js';
30
+ import '../../scene/mesh.js';
31
+ import '../../scene/basesprite.js';
32
+ import '../../scene/meshdrawable.js';
33
+ import '../../material/msdf_text.js';
34
+ import '../../scene/water.js';
35
+ import '../../scene/particlesys.js';
36
+ import '../../scene/batchgroup.js';
37
+ import '../../scene/terrain-cm/terrain-cm.js';
38
+ import '../../scene/terrain-cm/grass.js';
39
+ import '../../scene/raycast_visitor.js';
40
+ import { ColliderForce } from './types.js';
41
+
42
+ const EPS = 1e-6;
43
+ /**
44
+ * Generate convex JointDynamics colliders from skinned mesh bone weights.
45
+ *
46
+ * @public
47
+ */ function generateJointDynamicsConvexCollidersFromSkinWeights(meshes, skinBinding, bones, options = {}) {
48
+ const sources = collectSourcePrimitives(meshes);
49
+ const results = [];
50
+ for (const bone of bones){
51
+ const jointIndex = skinBinding.joints.indexOf(bone);
52
+ if (jointIndex < 0) {
53
+ continue;
54
+ }
55
+ const points = collectBonePoints(sources, skinBinding, jointIndex, options);
56
+ if (points.length < (options.minVertexCount ?? 8)) {
57
+ continue;
58
+ }
59
+ const hull = buildConvexHull(points, options.maxHullVertices ?? 48, options.margin ?? 0);
60
+ if (!hull || hull.vertices.length < 4 || hull.planes.length < 4) {
61
+ continue;
62
+ }
63
+ results.push({
64
+ bone,
65
+ vertexCount: points.length,
66
+ hullVertexCount: hull.vertices.length,
67
+ collider: {
68
+ radius: 0,
69
+ radiusTailScale: 1,
70
+ height: 0,
71
+ friction: options.friction ?? 0,
72
+ isInverseCollider: options.inversed ?? false,
73
+ forceType: ColliderForce.Off,
74
+ convex: hull
75
+ }
76
+ });
77
+ }
78
+ return results;
79
+ }
80
+ function collectSourcePrimitives(meshes) {
81
+ const result = [];
82
+ const seen = new Set();
83
+ for (const mesh of meshes){
84
+ const binding = getSceneMeshAssetBinding(mesh);
85
+ const subMesh = binding?.subMesh;
86
+ const primitive = subMesh?.primitive ?? null;
87
+ if (primitive && !seen.has(primitive)) {
88
+ seen.add(primitive);
89
+ result.push({
90
+ primitive,
91
+ subMesh
92
+ });
93
+ }
94
+ }
95
+ return result;
96
+ }
97
+ function collectBonePoints(sources, skinBinding, jointIndex, options) {
98
+ const points = [];
99
+ const weightThreshold = options.weightThreshold ?? 0.45;
100
+ const dominantBoneOnly = options.dominantBoneOnly ?? true;
101
+ const inverseBind = skinBinding.inverseBindMatrices[jointIndex] ?? Matrix4x4.identity();
102
+ for (const source of sources){
103
+ const primitive = source.primitive;
104
+ const positionInfo = primitive.vertices.position;
105
+ const blendIndexInfo = primitive.vertices.blendIndices;
106
+ const blendWeightInfo = primitive.vertices.blendWeights;
107
+ if (!positionInfo || !blendIndexInfo || !blendWeightInfo) {
108
+ continue;
109
+ }
110
+ const positions = positionInfo.data;
111
+ const blendIndices = blendIndexInfo.data;
112
+ const blendWeights = blendWeightInfo.data;
113
+ const posStride = getVertexFormatComponentCount(positionInfo.format);
114
+ const idxStride = getVertexFormatComponentCount(blendIndexInfo.format);
115
+ const weightStride = getVertexFormatComponentCount(blendWeightInfo.format);
116
+ const vertexCount = Math.floor(positions.length / posStride);
117
+ for(let i = 0; i < vertexCount; i++){
118
+ let weight = 0;
119
+ let maxWeight = -1;
120
+ let maxJoint = -1;
121
+ const influenceCount = Math.min(4, idxStride, weightStride);
122
+ for(let k = 0; k < influenceCount; k++){
123
+ const idx = Number(blendIndices[i * idxStride + k]) | 0;
124
+ const w = Number(blendWeights[i * weightStride + k]) || 0;
125
+ if (idx === jointIndex) {
126
+ weight = Math.max(weight, w);
127
+ }
128
+ if (w > maxWeight) {
129
+ maxWeight = w;
130
+ maxJoint = idx;
131
+ }
132
+ }
133
+ if (weight < weightThreshold || dominantBoneOnly && maxJoint !== jointIndex) {
134
+ continue;
135
+ }
136
+ const p = new Vector3(Number(positions[i * posStride]) || 0, Number(positions[i * posStride + 1]) || 0, Number(positions[i * posStride + 2]) || 0);
137
+ points.push(inverseBind.transformPointAffine(p, p));
138
+ }
139
+ }
140
+ return uniquePoints(points);
141
+ }
142
+ function uniquePoints(points) {
143
+ const result = [];
144
+ const keys = new Set();
145
+ for (const point of points){
146
+ const key = `${Math.round(point.x * 100000)}:${Math.round(point.y * 100000)}:${Math.round(point.z * 100000)}`;
147
+ if (!keys.has(key)) {
148
+ keys.add(key);
149
+ result.push(point);
150
+ }
151
+ }
152
+ return result;
153
+ }
154
+ function buildConvexHull(points, maxHullVertices, margin) {
155
+ const sampled = sampleSupportPoints(points, Math.max(8, maxHullVertices));
156
+ if (sampled.length < 4) {
157
+ return null;
158
+ }
159
+ const faces = bruteForceHullFaces(sampled);
160
+ if (faces.length < 4) {
161
+ return null;
162
+ }
163
+ const planes = mergePlanes(faces);
164
+ if (margin > 0) {
165
+ for (const plane of planes){
166
+ plane.distance -= margin;
167
+ }
168
+ }
169
+ return {
170
+ vertices: sampled.map((point)=>point.clone()),
171
+ planes,
172
+ edges: extractHullEdges(sampled, planes)
173
+ };
174
+ }
175
+ function sampleSupportPoints(points, maxCount) {
176
+ if (points.length <= maxCount) {
177
+ return [
178
+ ...points
179
+ ];
180
+ }
181
+ const dirs = buildSampleDirections(maxCount);
182
+ const selected = [];
183
+ const indices = new Set();
184
+ for (const dir of dirs){
185
+ let bestIndex = -1;
186
+ let bestDot = -Infinity;
187
+ for(let i = 0; i < points.length; i++){
188
+ const d = Vector3.dot(points[i], dir);
189
+ if (d > bestDot) {
190
+ bestDot = d;
191
+ bestIndex = i;
192
+ }
193
+ }
194
+ if (bestIndex >= 0 && !indices.has(bestIndex)) {
195
+ indices.add(bestIndex);
196
+ selected.push(points[bestIndex]);
197
+ if (selected.length >= maxCount) {
198
+ break;
199
+ }
200
+ }
201
+ }
202
+ return selected.length >= 4 ? selected : [
203
+ ...points.slice(0, maxCount)
204
+ ];
205
+ }
206
+ function buildSampleDirections(maxCount) {
207
+ const dirs = [
208
+ new Vector3(1, 0, 0),
209
+ new Vector3(-1, 0, 0),
210
+ new Vector3(0, 1, 0),
211
+ new Vector3(0, -1, 0),
212
+ new Vector3(0, 0, 1),
213
+ new Vector3(0, 0, -1)
214
+ ];
215
+ const rings = Math.max(4, Math.ceil(Math.sqrt(maxCount)));
216
+ for(let y = 0; y < rings && dirs.length < maxCount; y++){
217
+ const v = rings === 1 ? 0 : -1 + 2 * y / (rings - 1);
218
+ const r = Math.sqrt(Math.max(0, 1 - v * v));
219
+ for(let x = 0; x < rings * 2 && dirs.length < maxCount; x++){
220
+ const a = x / (rings * 2) * Math.PI * 2;
221
+ dirs.push(new Vector3(Math.cos(a) * r, v, Math.sin(a) * r));
222
+ }
223
+ }
224
+ return dirs;
225
+ }
226
+ function bruteForceHullFaces(points) {
227
+ const center = new Vector3();
228
+ for (const point of points){
229
+ Vector3.add(center, point, center);
230
+ }
231
+ Vector3.scale(center, 1 / points.length, center);
232
+ const faces = [];
233
+ const faceKeys = new Set();
234
+ for(let i = 0; i < points.length - 2; i++){
235
+ for(let j = i + 1; j < points.length - 1; j++){
236
+ for(let k = j + 1; k < points.length; k++){
237
+ const ab = Vector3.sub(points[j], points[i]);
238
+ const ac = Vector3.sub(points[k], points[i]);
239
+ const normal = Vector3.cross(ab, ac);
240
+ const len = normal.magnitude;
241
+ if (len <= EPS) {
242
+ continue;
243
+ }
244
+ Vector3.scale(normal, 1 / len, normal);
245
+ let distance = -Vector3.dot(normal, points[i]);
246
+ if (Vector3.dot(normal, center) + distance > 0) {
247
+ Vector3.scale(normal, -1, normal);
248
+ distance = -Vector3.dot(normal, points[i]);
249
+ }
250
+ let valid = true;
251
+ for(let p = 0; p < points.length; p++){
252
+ if (p === i || p === j || p === k) {
253
+ continue;
254
+ }
255
+ if (Vector3.dot(normal, points[p]) + distance > 1e-5) {
256
+ valid = false;
257
+ break;
258
+ }
259
+ }
260
+ if (!valid) {
261
+ continue;
262
+ }
263
+ const key = planeKey(normal, distance);
264
+ if (faceKeys.has(key)) {
265
+ continue;
266
+ }
267
+ faceKeys.add(key);
268
+ faces.push({
269
+ a: i,
270
+ b: j,
271
+ c: k,
272
+ normal: normal.clone(),
273
+ distance
274
+ });
275
+ }
276
+ }
277
+ }
278
+ return faces;
279
+ }
280
+ function mergePlanes(faces) {
281
+ const planes = [];
282
+ for (const face of faces){
283
+ if (planes.some((plane)=>Math.abs(Vector3.dot(plane.normal, face.normal) - 1) < 1e-4 && Math.abs(plane.distance - face.distance) < 1e-4)) {
284
+ continue;
285
+ }
286
+ planes.push({
287
+ normal: face.normal.clone(),
288
+ distance: face.distance
289
+ });
290
+ }
291
+ return planes;
292
+ }
293
+ function extractHullEdges(vertices, planes) {
294
+ const result = [];
295
+ const keys = new Set();
296
+ for(let i = 0; i < vertices.length - 1; i++){
297
+ for(let j = i + 1; j < vertices.length; j++){
298
+ const sharedPlaneCount = planes.reduce((count, plane)=>{
299
+ const di = Math.abs(Vector3.dot(plane.normal, vertices[i]) + plane.distance);
300
+ const dj = Math.abs(Vector3.dot(plane.normal, vertices[j]) + plane.distance);
301
+ return count + (di < 1e-4 && dj < 1e-4 ? 1 : 0);
302
+ }, 0);
303
+ if (sharedPlaneCount < 2) {
304
+ continue;
305
+ }
306
+ const key = `${i}:${j}`;
307
+ if (!keys.has(key)) {
308
+ keys.add(key);
309
+ result.push(i, j);
310
+ }
311
+ }
312
+ }
313
+ return result;
314
+ }
315
+ function planeKey(normal, distance) {
316
+ return `${Math.round(normal.x * 10000)}:${Math.round(normal.y * 10000)}:${Math.round(normal.z * 10000)}:${Math.round(distance * 10000)}`;
317
+ }
318
+
319
+ export { generateJointDynamicsConvexCollidersFromSkinWeights };
320
+ //# sourceMappingURL=convex_collider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convex_collider.js","sources":["../../../src/animation/joint_dynamics/convex_collider.ts"],"sourcesContent":["import { Matrix4x4, Vector3 } from '@zephyr3d/base';\nimport { getVertexFormatComponentCount } from '@zephyr3d/device';\nimport type { Mesh, SceneNode } from '../../scene';\nimport { getSceneMeshAssetBinding } from '../../scene';\nimport type { AssetPrimitiveInfo, AssetSubMeshData } from '../../asset';\nimport type { SkinBinding } from '../skeleton';\nimport { ColliderForce, type ColliderR, type ConvexColliderPlane } from './types';\n\n/** @public */\nexport type JointDynamicsConvexColliderGenerationOptions = {\n weightThreshold?: number;\n dominantBoneOnly?: boolean;\n maxHullVertices?: number;\n margin?: number;\n minVertexCount?: number;\n friction?: number;\n inversed?: boolean;\n};\n\n/** @public */\nexport type JointDynamicsConvexColliderGenerationResult = {\n bone: SceneNode;\n collider: ColliderR;\n vertexCount: number;\n hullVertexCount: number;\n};\n\ntype SourcePrimitive = {\n primitive: AssetPrimitiveInfo;\n subMesh?: AssetSubMeshData;\n};\n\ntype Face = {\n a: number;\n b: number;\n c: number;\n normal: Vector3;\n distance: number;\n};\n\nconst EPS = 1e-6;\n\n/**\n * Generate convex JointDynamics colliders from skinned mesh bone weights.\n *\n * @public\n */\nexport function generateJointDynamicsConvexCollidersFromSkinWeights(\n meshes: readonly Mesh[],\n skinBinding: SkinBinding,\n bones: readonly SceneNode[],\n options: JointDynamicsConvexColliderGenerationOptions = {}\n): JointDynamicsConvexColliderGenerationResult[] {\n const sources = collectSourcePrimitives(meshes);\n const results: JointDynamicsConvexColliderGenerationResult[] = [];\n for (const bone of bones) {\n const jointIndex = skinBinding.joints.indexOf(bone);\n if (jointIndex < 0) {\n continue;\n }\n const points = collectBonePoints(sources, skinBinding, jointIndex, options);\n if (points.length < (options.minVertexCount ?? 8)) {\n continue;\n }\n const hull = buildConvexHull(points, options.maxHullVertices ?? 48, options.margin ?? 0);\n if (!hull || hull.vertices.length < 4 || hull.planes.length < 4) {\n continue;\n }\n results.push({\n bone,\n vertexCount: points.length,\n hullVertexCount: hull.vertices.length,\n collider: {\n radius: 0,\n radiusTailScale: 1,\n height: 0,\n friction: options.friction ?? 0,\n isInverseCollider: options.inversed ?? false,\n forceType: ColliderForce.Off,\n convex: hull\n }\n });\n }\n return results;\n}\n\nfunction collectSourcePrimitives(meshes: readonly Mesh[]): SourcePrimitive[] {\n const result: SourcePrimitive[] = [];\n const seen = new Set<AssetPrimitiveInfo>();\n for (const mesh of meshes) {\n const binding = getSceneMeshAssetBinding(mesh);\n const subMesh = binding?.subMesh as AssetSubMeshData | undefined;\n const primitive = subMesh?.primitive ?? null;\n if (primitive && !seen.has(primitive)) {\n seen.add(primitive);\n result.push({ primitive, subMesh });\n }\n }\n return result;\n}\n\nfunction collectBonePoints(\n sources: readonly SourcePrimitive[],\n skinBinding: SkinBinding,\n jointIndex: number,\n options: JointDynamicsConvexColliderGenerationOptions\n): Vector3[] {\n const points: Vector3[] = [];\n const weightThreshold = options.weightThreshold ?? 0.45;\n const dominantBoneOnly = options.dominantBoneOnly ?? true;\n const inverseBind = skinBinding.inverseBindMatrices[jointIndex] ?? Matrix4x4.identity();\n for (const source of sources) {\n const primitive = source.primitive;\n const positionInfo = primitive.vertices.position;\n const blendIndexInfo = primitive.vertices.blendIndices;\n const blendWeightInfo = primitive.vertices.blendWeights;\n if (!positionInfo || !blendIndexInfo || !blendWeightInfo) {\n continue;\n }\n const positions = positionInfo.data;\n const blendIndices = blendIndexInfo.data;\n const blendWeights = blendWeightInfo.data;\n const posStride = getVertexFormatComponentCount(positionInfo.format);\n const idxStride = getVertexFormatComponentCount(blendIndexInfo.format);\n const weightStride = getVertexFormatComponentCount(blendWeightInfo.format);\n const vertexCount = Math.floor(positions.length / posStride);\n for (let i = 0; i < vertexCount; i++) {\n let weight = 0;\n let maxWeight = -1;\n let maxJoint = -1;\n const influenceCount = Math.min(4, idxStride, weightStride);\n for (let k = 0; k < influenceCount; k++) {\n const idx = Number(blendIndices[i * idxStride + k]) | 0;\n const w = Number(blendWeights[i * weightStride + k]) || 0;\n if (idx === jointIndex) {\n weight = Math.max(weight, w);\n }\n if (w > maxWeight) {\n maxWeight = w;\n maxJoint = idx;\n }\n }\n if (weight < weightThreshold || (dominantBoneOnly && maxJoint !== jointIndex)) {\n continue;\n }\n const p = new Vector3(\n Number(positions[i * posStride]) || 0,\n Number(positions[i * posStride + 1]) || 0,\n Number(positions[i * posStride + 2]) || 0\n );\n points.push(inverseBind.transformPointAffine(p, p));\n }\n }\n return uniquePoints(points);\n}\n\nfunction uniquePoints(points: readonly Vector3[]): Vector3[] {\n const result: Vector3[] = [];\n const keys = new Set<string>();\n for (const point of points) {\n const key = `${Math.round(point.x * 100000)}:${Math.round(point.y * 100000)}:${Math.round(point.z * 100000)}`;\n if (!keys.has(key)) {\n keys.add(key);\n result.push(point);\n }\n }\n return result;\n}\n\nfunction buildConvexHull(points: readonly Vector3[], maxHullVertices: number, margin: number) {\n const sampled = sampleSupportPoints(points, Math.max(8, maxHullVertices));\n if (sampled.length < 4) {\n return null;\n }\n const faces = bruteForceHullFaces(sampled);\n if (faces.length < 4) {\n return null;\n }\n const planes = mergePlanes(faces);\n if (margin > 0) {\n for (const plane of planes) {\n plane.distance -= margin;\n }\n }\n return {\n vertices: sampled.map((point) => point.clone()),\n planes,\n edges: extractHullEdges(sampled, planes)\n };\n}\n\nfunction sampleSupportPoints(points: readonly Vector3[], maxCount: number): Vector3[] {\n if (points.length <= maxCount) {\n return [...points];\n }\n const dirs = buildSampleDirections(maxCount);\n const selected: Vector3[] = [];\n const indices = new Set<number>();\n for (const dir of dirs) {\n let bestIndex = -1;\n let bestDot = -Infinity;\n for (let i = 0; i < points.length; i++) {\n const d = Vector3.dot(points[i], dir);\n if (d > bestDot) {\n bestDot = d;\n bestIndex = i;\n }\n }\n if (bestIndex >= 0 && !indices.has(bestIndex)) {\n indices.add(bestIndex);\n selected.push(points[bestIndex]);\n if (selected.length >= maxCount) {\n break;\n }\n }\n }\n return selected.length >= 4 ? selected : [...points.slice(0, maxCount)];\n}\n\nfunction buildSampleDirections(maxCount: number): Vector3[] {\n const dirs = [\n new Vector3(1, 0, 0),\n new Vector3(-1, 0, 0),\n new Vector3(0, 1, 0),\n new Vector3(0, -1, 0),\n new Vector3(0, 0, 1),\n new Vector3(0, 0, -1)\n ];\n const rings = Math.max(4, Math.ceil(Math.sqrt(maxCount)));\n for (let y = 0; y < rings && dirs.length < maxCount; y++) {\n const v = rings === 1 ? 0 : -1 + (2 * y) / (rings - 1);\n const r = Math.sqrt(Math.max(0, 1 - v * v));\n for (let x = 0; x < rings * 2 && dirs.length < maxCount; x++) {\n const a = (x / (rings * 2)) * Math.PI * 2;\n dirs.push(new Vector3(Math.cos(a) * r, v, Math.sin(a) * r));\n }\n }\n return dirs;\n}\n\nfunction bruteForceHullFaces(points: readonly Vector3[]): Face[] {\n const center = new Vector3();\n for (const point of points) {\n Vector3.add(center, point, center);\n }\n Vector3.scale(center, 1 / points.length, center);\n const faces: Face[] = [];\n const faceKeys = new Set<string>();\n for (let i = 0; i < points.length - 2; i++) {\n for (let j = i + 1; j < points.length - 1; j++) {\n for (let k = j + 1; k < points.length; k++) {\n const ab = Vector3.sub(points[j], points[i]);\n const ac = Vector3.sub(points[k], points[i]);\n const normal = Vector3.cross(ab, ac);\n const len = normal.magnitude;\n if (len <= EPS) {\n continue;\n }\n Vector3.scale(normal, 1 / len, normal);\n let distance = -Vector3.dot(normal, points[i]);\n if (Vector3.dot(normal, center) + distance > 0) {\n Vector3.scale(normal, -1, normal);\n distance = -Vector3.dot(normal, points[i]);\n }\n let valid = true;\n for (let p = 0; p < points.length; p++) {\n if (p === i || p === j || p === k) {\n continue;\n }\n if (Vector3.dot(normal, points[p]) + distance > 1e-5) {\n valid = false;\n break;\n }\n }\n if (!valid) {\n continue;\n }\n const key = planeKey(normal, distance);\n if (faceKeys.has(key)) {\n continue;\n }\n faceKeys.add(key);\n faces.push({ a: i, b: j, c: k, normal: normal.clone(), distance });\n }\n }\n }\n return faces;\n}\n\nfunction mergePlanes(faces: readonly Face[]): ConvexColliderPlane[] {\n const planes: ConvexColliderPlane[] = [];\n for (const face of faces) {\n if (\n planes.some(\n (plane) =>\n Math.abs(Vector3.dot(plane.normal, face.normal) - 1) < 1e-4 &&\n Math.abs(plane.distance - face.distance) < 1e-4\n )\n ) {\n continue;\n }\n planes.push({ normal: face.normal.clone(), distance: face.distance });\n }\n return planes;\n}\n\nfunction extractHullEdges(\n vertices: readonly Vector3[],\n planes: readonly ConvexColliderPlane[]\n): number[] {\n const result: number[] = [];\n const keys = new Set<string>();\n for (let i = 0; i < vertices.length - 1; i++) {\n for (let j = i + 1; j < vertices.length; j++) {\n const sharedPlaneCount = planes.reduce((count, plane) => {\n const di = Math.abs(Vector3.dot(plane.normal, vertices[i]) + plane.distance);\n const dj = Math.abs(Vector3.dot(plane.normal, vertices[j]) + plane.distance);\n return count + (di < 1e-4 && dj < 1e-4 ? 1 : 0);\n }, 0);\n if (sharedPlaneCount < 2) {\n continue;\n }\n const key = `${i}:${j}`;\n if (!keys.has(key)) {\n keys.add(key);\n result.push(i, j);\n }\n }\n }\n return result;\n}\n\nfunction planeKey(normal: Vector3, distance: number): string {\n return `${Math.round(normal.x * 10000)}:${Math.round(normal.y * 10000)}:${Math.round(normal.z * 10000)}:${Math.round(distance * 10000)}`;\n}\n"],"names":["EPS","generateJointDynamicsConvexCollidersFromSkinWeights","meshes","skinBinding","bones","options","sources","collectSourcePrimitives","results","bone","jointIndex","joints","indexOf","points","collectBonePoints","length","minVertexCount","hull","buildConvexHull","maxHullVertices","margin","vertices","planes","push","vertexCount","hullVertexCount","collider","radius","radiusTailScale","height","friction","isInverseCollider","inversed","forceType","ColliderForce","Off","convex","result","seen","Set","mesh","binding","getSceneMeshAssetBinding","subMesh","primitive","has","add","weightThreshold","dominantBoneOnly","inverseBind","inverseBindMatrices","Matrix4x4","identity","source","positionInfo","position","blendIndexInfo","blendIndices","blendWeightInfo","blendWeights","positions","data","posStride","getVertexFormatComponentCount","format","idxStride","weightStride","Math","floor","i","weight","maxWeight","maxJoint","influenceCount","min","k","idx","Number","w","max","p","Vector3","transformPointAffine","uniquePoints","keys","point","key","round","x","y","z","sampled","sampleSupportPoints","faces","bruteForceHullFaces","mergePlanes","plane","distance","map","clone","edges","extractHullEdges","maxCount","dirs","buildSampleDirections","selected","indices","dir","bestIndex","bestDot","Infinity","d","dot","slice","rings","ceil","sqrt","v","r","a","PI","cos","sin","center","scale","faceKeys","j","ab","sub","ac","normal","cross","len","magnitude","valid","planeKey","b","c","face","some","abs","sharedPlaneCount","reduce","count","di","dj"],"mappings":"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"}
@@ -78,6 +78,8 @@ const humanoidHelperJointTokens = new Set([
78
78
  _joints;
79
79
  _bindPoseByJoint;
80
80
  _bindPose;
81
+ _retargetPoseByJoint;
82
+ _retargetPose;
81
83
  _rootJoint;
82
84
  _rootBindPose;
83
85
  _playing;
@@ -93,6 +95,14 @@ const humanoidHelperJointTokens = new Set([
93
95
  for(let i = 0; i < joints.length; i++){
94
96
  this._bindPoseByJoint.set(joints[i], bindPose[i]);
95
97
  }
98
+ if (options?.retargetPose && options.retargetPose.length !== joints.length) {
99
+ throw new Error('SkeletonRig(): retarget pose must contain one transform per joint');
100
+ }
101
+ this._retargetPose = options?.retargetPose ?? null;
102
+ this._retargetPoseByJoint = this._retargetPose ? new Map(joints.map((joint, index)=>[
103
+ joint,
104
+ this._retargetPose[index]
105
+ ])) : null;
96
106
  const skeletonRoot = this.findRootJoint(this._joints);
97
107
  this._rootJoint = options?.rootJoint ?? skeletonRoot;
98
108
  this._rootBindPose = options?.rootBindPose ?? this.getNodeBindPose(this._rootJoint);
@@ -145,6 +155,12 @@ const humanoidHelperJointTokens = new Set([
145
155
  get bindPose() {
146
156
  return this._bindPose;
147
157
  }
158
+ /** Effective humanoid retarget reference pose. */ get retargetPose() {
159
+ return this._retargetPose ?? this._bindPose;
160
+ }
161
+ /** Whether this rig has a reference pose that is distinct from its bind pose. */ get hasRetargetPose() {
162
+ return !!this._retargetPose;
163
+ }
148
164
  get rootJoint() {
149
165
  return this._rootJoint;
150
166
  }
@@ -158,6 +174,9 @@ const humanoidHelperJointTokens = new Set([
158
174
  getBindPoseForJoint(joint) {
159
175
  return this._bindPoseByJoint.get(joint) ?? null;
160
176
  }
177
+ getRetargetPoseForJoint(joint) {
178
+ return this._retargetPoseByJoint?.get(joint) ?? this.getBindPoseForJoint(joint);
179
+ }
161
180
  get humanoidJointMapping() {
162
181
  return this._humanoidJointMapping;
163
182
  }
@@ -321,7 +340,8 @@ function sideJointPatterns(side, patterns) {
321
340
  this._rig = new SkeletonRig(rig.joints, bindPose, {
322
341
  rootJoint: rig.rootJoint,
323
342
  rootBindPose: rig.rootBindPose,
324
- humanoidJointMapping: rig.humanoidJointMapping
343
+ humanoidJointMapping: rig.humanoidJointMapping,
344
+ retargetPose: rig.hasRetargetPose ? rig.retargetPose : null
325
345
  });
326
346
  }
327
347
  this.updateJointMatrices();