@babylonjs/loaders 9.26.0 → 9.26.2
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/FBX/fbxConstraintBehavior.d.ts +188 -0
- package/FBX/fbxConstraintBehavior.js +532 -0
- package/FBX/fbxConstraintBehavior.js.map +1 -0
- package/FBX/fbxFileLoader.pure.d.ts +175 -6
- package/FBX/fbxFileLoader.pure.js +1521 -286
- package/FBX/fbxFileLoader.pure.js.map +1 -1
- package/FBX/index.d.ts +4 -1
- package/FBX/index.js +1 -0
- package/FBX/index.js.map +1 -1
- package/FBX/interpreter/animation.d.ts +73 -33
- package/FBX/interpreter/animation.js +620 -223
- package/FBX/interpreter/animation.js.map +1 -1
- package/FBX/interpreter/animationCurve.d.ts +91 -0
- package/FBX/interpreter/animationCurve.js +623 -0
- package/FBX/interpreter/animationCurve.js.map +1 -0
- package/FBX/interpreter/blendShapes.js +9 -18
- package/FBX/interpreter/blendShapes.js.map +1 -1
- package/FBX/interpreter/connections.d.ts +1 -1
- package/FBX/interpreter/connections.js +173 -34
- package/FBX/interpreter/connections.js.map +1 -1
- package/FBX/interpreter/constraints.d.ts +68 -0
- package/FBX/interpreter/constraints.js +143 -0
- package/FBX/interpreter/constraints.js.map +1 -0
- package/FBX/interpreter/fbxInterpreter.d.ts +89 -4
- package/FBX/interpreter/fbxInterpreter.js +474 -122
- package/FBX/interpreter/fbxInterpreter.js.map +1 -1
- package/FBX/interpreter/geometry.d.ts +1 -1
- package/FBX/interpreter/geometry.js +150 -92
- package/FBX/interpreter/geometry.js.map +1 -1
- package/FBX/interpreter/legacyDocument.d.ts +11 -0
- package/FBX/interpreter/legacyDocument.js +425 -0
- package/FBX/interpreter/legacyDocument.js.map +1 -0
- package/FBX/interpreter/materialModel.d.ts +71 -0
- package/FBX/interpreter/materialModel.js +622 -0
- package/FBX/interpreter/materialModel.js.map +1 -0
- package/FBX/interpreter/materials.d.ts +13 -1
- package/FBX/interpreter/materials.js +88 -5
- package/FBX/interpreter/materials.js.map +1 -1
- package/FBX/interpreter/nodeTransform.d.ts +32 -0
- package/FBX/interpreter/nodeTransform.js +54 -0
- package/FBX/interpreter/nodeTransform.js.map +1 -0
- package/FBX/interpreter/nurbs.d.ts +99 -0
- package/FBX/interpreter/nurbs.js +627 -0
- package/FBX/interpreter/nurbs.js.map +1 -0
- package/FBX/interpreter/propertyTemplates.d.ts +23 -0
- package/FBX/interpreter/propertyTemplates.js +109 -2
- package/FBX/interpreter/propertyTemplates.js.map +1 -1
- package/FBX/interpreter/rig.js +16 -0
- package/FBX/interpreter/rig.js.map +1 -1
- package/FBX/interpreter/sceneDiagnostics.js +28 -3
- package/FBX/interpreter/sceneDiagnostics.js.map +1 -1
- package/FBX/interpreter/skeleton.d.ts +4 -18
- package/FBX/interpreter/skeleton.js +16 -94
- package/FBX/interpreter/skeleton.js.map +1 -1
- package/FBX/parsers/fbxAsciiParser.js +119 -9
- package/FBX/parsers/fbxAsciiParser.js.map +1 -1
- package/FBX/parsers/fbxBinaryParser.js +74 -22
- package/FBX/parsers/fbxBinaryParser.js.map +1 -1
- package/FBX/pure.d.ts +1 -0
- package/FBX/pure.js +1 -0
- package/FBX/pure.js.map +1 -1
- package/FBX/types/fbxTypes.d.ts +18 -2
- package/FBX/types/fbxTypes.js +40 -12
- package/FBX/types/fbxTypes.js.map +1 -1
- package/SPLAT/gaussianSplattingStream.d.ts +79 -25
- package/SPLAT/gaussianSplattingStream.js +320 -95
- package/SPLAT/gaussianSplattingStream.js.map +1 -1
- package/USD/usdCommandProtocol.d.ts +20 -4
- package/USD/usdCommandProtocol.js +25 -3
- package/USD/usdCommandProtocol.js.map +1 -1
- package/USD/usdFileLoader.pure.js +2 -0
- package/USD/usdFileLoader.pure.js.map +1 -1
- package/USD/usdSceneMaterializer.js +430 -92
- package/USD/usdSceneMaterializer.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/declarationMapper.d.ts +110 -3
- package/glTF/2.0/Extensions/KHR_interactivity/declarationMapper.js +468 -74
- package/glTF/2.0/Extensions/KHR_interactivity/declarationMapper.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphEventReferenceBlock.d.ts +47 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphEventReferenceBlock.js +68 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphEventReferenceBlock.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphGLTFDataProvider.d.ts +2 -2
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphGLTFDataProvider.js +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphGLTFDataProvider.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphObjectReferenceBlock.d.ts +24 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphObjectReferenceBlock.js +38 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphObjectReferenceBlock.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphUnsupportedInteractivityBlock.d.ts +41 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphUnsupportedInteractivityBlock.js +63 -0
- package/glTF/2.0/Extensions/KHR_interactivity/flowGraphUnsupportedInteractivityBlock.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity/index.d.ts +5 -0
- package/glTF/2.0/Extensions/KHR_interactivity/index.js +5 -0
- package/glTF/2.0/Extensions/KHR_interactivity/index.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphModel.d.ts +112 -0
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphModel.js +773 -0
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphModel.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphParser.d.ts +18 -10
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphParser.js +299 -54
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphParser.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityHostResolver.d.ts +2 -1
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityHostResolver.js +7 -2
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityHostResolver.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityNodeState.d.ts +24 -0
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityNodeState.js +89 -0
- package/glTF/2.0/Extensions/KHR_interactivity/interactivityNodeState.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity/pure.d.ts +5 -0
- package/glTF/2.0/Extensions/KHR_interactivity/pure.js +5 -0
- package/glTF/2.0/Extensions/KHR_interactivity/pure.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity.pure.d.ts +55 -1
- package/glTF/2.0/Extensions/KHR_interactivity.pure.js +124 -76
- package/glTF/2.0/Extensions/KHR_interactivity.pure.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity.types.d.ts +18 -1
- package/glTF/2.0/Extensions/KHR_interactivity.types.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_node_hoverability.pure.d.ts +2 -0
- package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js +114 -56
- package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_node_selectability.pure.d.ts +2 -0
- package/glTF/2.0/Extensions/KHR_node_selectability.pure.js +80 -35
- package/glTF/2.0/Extensions/KHR_node_selectability.pure.js.map +1 -1
- package/glTF/2.0/Extensions/interactivityRefPathToObjectConverter.js +3 -2
- package/glTF/2.0/Extensions/interactivityRefPathToObjectConverter.js.map +1 -1
- package/glTF/2.0/Extensions/objectModelMapping.d.ts +4 -2
- package/glTF/2.0/Extensions/objectModelMapping.js +33 -4
- package/glTF/2.0/Extensions/objectModelMapping.js.map +1 -1
- package/glTF/2.0/glTFLoader.pure.d.ts +1 -1
- package/glTF/2.0/glTFLoader.pure.js +9 -4
- package/glTF/2.0/glTFLoader.pure.js.map +1 -1
- package/glTF/2.0/glTFLoaderExtension.d.ts +2 -1
- package/glTF/2.0/glTFLoaderExtension.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/naming-convention, jsdoc/require-param, jsdoc/require-returns */
|
|
2
|
-
import { findChildByName, findChildrenByName, getPropertyValue, cleanFBXName } from "../types/fbxTypes.js";
|
|
2
|
+
import { findChildByName, findChildrenByName, getPropertyValue, cleanFBXName, getNodeArray } from "../types/fbxTypes.js";
|
|
3
3
|
/**
|
|
4
4
|
* Extract geometry data from an FBX Geometry node.
|
|
5
5
|
* Handles polygon triangulation and layer element expansion.
|
|
@@ -7,17 +7,13 @@ import { findChildByName, findChildrenByName, getPropertyValue, cleanFBXName } f
|
|
|
7
7
|
export function extractGeometry(geometryNode, nodeId) {
|
|
8
8
|
const name = cleanFBXName(getPropertyValue(geometryNode, 1) ?? "Geometry");
|
|
9
9
|
// Extract raw vertices
|
|
10
|
+
// Edge-only meshes (e.g. Blender edge circles) and empty placeholders have no vertices or polygons; they
|
|
11
|
+
// become geometry with zero triangles rather than errors.
|
|
10
12
|
const verticesNode = findChildByName(geometryNode, "Vertices");
|
|
11
|
-
|
|
12
|
-
throw new Error(`Geometry '${name}' has no Vertices node`);
|
|
13
|
-
}
|
|
14
|
-
const rawPositions = toFloat64Array(getNodeArrayValue(verticesNode));
|
|
13
|
+
const rawPositions = verticesNode ? toFloat64Array(getNodeArrayValue(verticesNode)) : new Float64Array(0);
|
|
15
14
|
// Extract polygon vertex indices
|
|
16
15
|
const pviNode = findChildByName(geometryNode, "PolygonVertexIndex");
|
|
17
|
-
|
|
18
|
-
throw new Error(`Geometry '${name}' has no PolygonVertexIndex node`);
|
|
19
|
-
}
|
|
20
|
-
const rawIndices = toInt32Array(getNodeArrayValue(pviNode));
|
|
16
|
+
const rawIndices = pviNode ? toInt32Array(getNodeArrayValue(pviNode)) : new Int32Array(0);
|
|
21
17
|
const diagnostics = [];
|
|
22
18
|
// Parse polygons from the FBX negative-index convention
|
|
23
19
|
const polygons = parsePolygons(rawIndices);
|
|
@@ -161,43 +157,89 @@ function triangulatePolygon(poly, polyIndex, rawPositions, diagnostics) {
|
|
|
161
157
|
return fanTriangulate(poly, polyIndex);
|
|
162
158
|
}
|
|
163
159
|
const isCCW = polygonArea > 0;
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
160
|
+
const clipped = earClip(projected, isCCW, polygonArea);
|
|
161
|
+
if (!clipped) {
|
|
162
|
+
diagnostics.push({
|
|
163
|
+
type: "triangulation-fallback",
|
|
164
|
+
message: `Polygon ${polyIndex} could not be fully ear-clipped; using fan triangulation.`,
|
|
165
|
+
polygonIndex: polyIndex,
|
|
166
|
+
});
|
|
167
|
+
return fanTriangulate(poly, polyIndex);
|
|
168
|
+
}
|
|
169
|
+
return clipped.map(([a, b, c]) => ({ vertices: [poly.startIndex + a, poly.startIndex + b, poly.startIndex + c], polyIndex }));
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Ear clipping on a doubly linked vertex ring. Only reflex vertices can lie inside a candidate ear, so the
|
|
173
|
+
* containment test walks the reflex vertices alone, and the scan resumes after the last clipped ear instead of
|
|
174
|
+
* restarting, which keeps large n-gons (thousands of vertices) at roughly quadratic cost in the reflex count.
|
|
175
|
+
* @returns triangles as local vertex indices, or null when no ear can be found (self-intersecting input)
|
|
176
|
+
*/
|
|
177
|
+
function earClip(points, isCCW, polygonArea) {
|
|
178
|
+
const n = points.length;
|
|
179
|
+
const prev = new Int32Array(n);
|
|
180
|
+
const next = new Int32Array(n);
|
|
181
|
+
for (let i = 0; i < n; i++) {
|
|
182
|
+
prev[i] = (i + n - 1) % n;
|
|
183
|
+
next[i] = (i + 1) % n;
|
|
184
|
+
}
|
|
185
|
+
// Tolerances scale with the polygon so huge and tiny coordinates behave the same.
|
|
186
|
+
const eps = Math.abs(polygonArea) * 1e-12 + 1e-300;
|
|
187
|
+
const sign = isCCW ? 1 : -1;
|
|
188
|
+
const turn = (i) => sign * cross2D(points[prev[i]], points[i], points[next[i]]);
|
|
189
|
+
const reflex = new Uint8Array(n);
|
|
190
|
+
for (let i = 0; i < n; i++) {
|
|
191
|
+
reflex[i] = turn(i) < -eps ? 1 : 0;
|
|
192
|
+
}
|
|
193
|
+
const inside = (p, a, b, c) => {
|
|
194
|
+
// Inside or on the boundary of the (consistently oriented) triangle
|
|
195
|
+
return sign * cross2D(a, b, p) >= -eps && sign * cross2D(b, c, p) >= -eps && sign * cross2D(c, a, p) >= -eps;
|
|
196
|
+
};
|
|
197
|
+
const triangles = [];
|
|
198
|
+
let remaining = n;
|
|
199
|
+
let i = 0;
|
|
200
|
+
let visitedSinceClip = 0;
|
|
201
|
+
while (remaining > 3) {
|
|
202
|
+
const a = prev[i];
|
|
203
|
+
const c = next[i];
|
|
204
|
+
let clip = false;
|
|
205
|
+
if (!reflex[i]) {
|
|
206
|
+
const t = turn(i);
|
|
207
|
+
if (t <= eps) {
|
|
208
|
+
// Collinear vertex: its ear is a zero-area sliver, kept so every n-gon still yields n - 2 triangles.
|
|
209
|
+
clip = true;
|
|
210
|
+
triangles.push([a, i, c]);
|
|
175
211
|
}
|
|
176
|
-
|
|
177
|
-
|
|
212
|
+
else {
|
|
213
|
+
clip = true;
|
|
214
|
+
for (let j = next[c]; j !== a; j = next[j]) {
|
|
215
|
+
if (reflex[j] && inside(points[j], points[a], points[i], points[c])) {
|
|
216
|
+
clip = false;
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (clip) {
|
|
221
|
+
triangles.push([a, i, c]);
|
|
222
|
+
}
|
|
178
223
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
remaining
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
return fanTriangulate(poly, polyIndex);
|
|
224
|
+
}
|
|
225
|
+
if (clip) {
|
|
226
|
+
next[a] = c;
|
|
227
|
+
prev[c] = a;
|
|
228
|
+
remaining--;
|
|
229
|
+
reflex[a] = turn(a) < -eps ? 1 : 0;
|
|
230
|
+
reflex[c] = turn(c) < -eps ? 1 : 0;
|
|
231
|
+
i = c;
|
|
232
|
+
visitedSinceClip = 0;
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
i = c;
|
|
236
|
+
if (++visitedSinceClip > remaining) {
|
|
237
|
+
return null;
|
|
194
238
|
}
|
|
195
239
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
});
|
|
200
|
-
return clipped;
|
|
240
|
+
const last = i;
|
|
241
|
+
triangles.push([prev[last], last, next[last]]);
|
|
242
|
+
return triangles;
|
|
201
243
|
}
|
|
202
244
|
function fanTriangulate(poly, polyIndex) {
|
|
203
245
|
const triangles = [];
|
|
@@ -259,28 +301,6 @@ function signedArea2D(points) {
|
|
|
259
301
|
}
|
|
260
302
|
return area / 2;
|
|
261
303
|
}
|
|
262
|
-
function isConvex(a, b, c, isCCW) {
|
|
263
|
-
const cross = (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
|
|
264
|
-
return isCCW ? cross > 1e-12 : cross < -1e-12;
|
|
265
|
-
}
|
|
266
|
-
function containsAnyPoint(points, remaining, prev, curr, next) {
|
|
267
|
-
for (const index of remaining) {
|
|
268
|
-
if (index === prev || index === curr || index === next) {
|
|
269
|
-
continue;
|
|
270
|
-
}
|
|
271
|
-
if (pointInTriangle(points[index], points[prev], points[curr], points[next])) {
|
|
272
|
-
return true;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
return false;
|
|
276
|
-
}
|
|
277
|
-
function pointInTriangle(p, a, b, c) {
|
|
278
|
-
const area = Math.abs(cross2D(a, b, c));
|
|
279
|
-
const area1 = Math.abs(cross2D(p, a, b));
|
|
280
|
-
const area2 = Math.abs(cross2D(p, b, c));
|
|
281
|
-
const area3 = Math.abs(cross2D(p, c, a));
|
|
282
|
-
return Math.abs(area - (area1 + area2 + area3)) < 1e-10;
|
|
283
|
-
}
|
|
284
304
|
function cross2D(a, b, c) {
|
|
285
305
|
return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
|
|
286
306
|
}
|
|
@@ -481,39 +501,80 @@ function computeTangentHandedness(vertexIndex, tangents, normals, binormals) {
|
|
|
481
501
|
* we need to create unique vertices for each polygon-vertex combination.
|
|
482
502
|
*/
|
|
483
503
|
function buildTriangleMesh(rawPositions, triangles, polyVertexList, expandedNormals, expandedUVs, expandedUVSets, expandedColors, expandedTangents, expandedBinormals) {
|
|
484
|
-
//
|
|
485
|
-
|
|
504
|
+
// FBX stores every attribute per polygon-vertex. Polygon-vertices that share the control point and all attribute
|
|
505
|
+
// values are welded into one output vertex (this is what every DCC does on import); polygon-vertices that differ
|
|
506
|
+
// in any attribute (hard edges, UV seams) stay separate. Skinning and blend shapes index by control point, so
|
|
507
|
+
// welding is transparent to them.
|
|
508
|
+
const polyVertexCount = polyVertexList.length;
|
|
509
|
+
const remap = new Uint32Array(polyVertexCount);
|
|
510
|
+
const unique = [];
|
|
511
|
+
const keyToIndex = new Map();
|
|
512
|
+
const uvSetCount = expandedUVSets.length;
|
|
513
|
+
for (let i = 0; i < polyVertexCount; i++) {
|
|
514
|
+
let key = String(polyVertexList[i].controlPointIndex);
|
|
515
|
+
if (expandedNormals) {
|
|
516
|
+
key += `|${expandedNormals[i * 3]},${expandedNormals[i * 3 + 1]},${expandedNormals[i * 3 + 2]}`;
|
|
517
|
+
}
|
|
518
|
+
for (let u = 0; u < uvSetCount; u++) {
|
|
519
|
+
const d = expandedUVSets[u].data;
|
|
520
|
+
key += `|${d[i * 2]},${d[i * 2 + 1]}`;
|
|
521
|
+
}
|
|
522
|
+
if (expandedColors) {
|
|
523
|
+
key += `|${expandedColors[i * 4]},${expandedColors[i * 4 + 1]},${expandedColors[i * 4 + 2]},${expandedColors[i * 4 + 3]}`;
|
|
524
|
+
}
|
|
525
|
+
if (expandedTangents) {
|
|
526
|
+
key += `|${expandedTangents[i * 4]},${expandedTangents[i * 4 + 1]},${expandedTangents[i * 4 + 2]},${expandedTangents[i * 4 + 3]}`;
|
|
527
|
+
}
|
|
528
|
+
let index = keyToIndex.get(key);
|
|
529
|
+
if (index === undefined) {
|
|
530
|
+
index = unique.length;
|
|
531
|
+
keyToIndex.set(key, index);
|
|
532
|
+
unique.push(i);
|
|
533
|
+
}
|
|
534
|
+
remap[i] = index;
|
|
535
|
+
}
|
|
536
|
+
const vertexCount = unique.length;
|
|
486
537
|
const positions = new Float64Array(vertexCount * 3);
|
|
487
538
|
const controlPointIndices = new Uint32Array(vertexCount);
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
539
|
+
const gather = (src, stride, ctor) => {
|
|
540
|
+
if (!src) {
|
|
541
|
+
return null;
|
|
542
|
+
}
|
|
543
|
+
const out = new ctor(vertexCount * stride);
|
|
544
|
+
for (let v = 0; v < vertexCount; v++) {
|
|
545
|
+
const srcIndex = unique[v] * stride;
|
|
546
|
+
for (let k = 0; k < stride; k++) {
|
|
547
|
+
out[v * stride + k] = src[srcIndex + k];
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
return out;
|
|
551
|
+
};
|
|
552
|
+
// Positions come from control points — keep in original RH space (root node handles RH→LH conversion)
|
|
553
|
+
for (let v = 0; v < vertexCount; v++) {
|
|
554
|
+
const cp = polyVertexList[unique[v]].controlPointIndex;
|
|
555
|
+
positions[v * 3] = rawPositions[cp * 3];
|
|
556
|
+
positions[v * 3 + 1] = rawPositions[cp * 3 + 1];
|
|
557
|
+
positions[v * 3 + 2] = rawPositions[cp * 3 + 2];
|
|
558
|
+
controlPointIndices[v] = cp;
|
|
499
559
|
}
|
|
500
560
|
// Keep original winding order — Z negation handles handedness
|
|
501
561
|
const indexCount = triangles.length * 3;
|
|
502
562
|
const indices = new Uint32Array(indexCount);
|
|
503
563
|
for (let i = 0; i < triangles.length; i++) {
|
|
504
|
-
indices[i * 3] = triangles[i].vertices[0];
|
|
505
|
-
indices[i * 3 + 1] = triangles[i].vertices[1];
|
|
506
|
-
indices[i * 3 + 2] = triangles[i].vertices[2];
|
|
564
|
+
indices[i * 3] = remap[triangles[i].vertices[0]];
|
|
565
|
+
indices[i * 3 + 1] = remap[triangles[i].vertices[1]];
|
|
566
|
+
indices[i * 3 + 2] = remap[triangles[i].vertices[2]];
|
|
507
567
|
}
|
|
568
|
+
const uvSets = expandedUVSets.map((set) => ({ name: set.name, data: gather(set.data, 2, Float64Array) }));
|
|
508
569
|
return {
|
|
509
570
|
positions,
|
|
510
571
|
indices,
|
|
511
|
-
normals: expandedNormals,
|
|
512
|
-
uvs: expandedUVs,
|
|
513
|
-
uvSets
|
|
514
|
-
colors: expandedColors,
|
|
515
|
-
tangents: expandedTangents,
|
|
516
|
-
binormals: expandedBinormals,
|
|
572
|
+
normals: gather(expandedNormals, 3, Float64Array),
|
|
573
|
+
uvs: uvSets.length > 0 ? uvSets[0].data : gather(expandedUVs, 2, Float64Array),
|
|
574
|
+
uvSets,
|
|
575
|
+
colors: gather(expandedColors, 4, Float32Array),
|
|
576
|
+
tangents: gather(expandedTangents, 4, Float64Array),
|
|
577
|
+
binormals: gather(expandedBinormals, 3, Float64Array),
|
|
517
578
|
controlPointIndices,
|
|
518
579
|
};
|
|
519
580
|
}
|
|
@@ -525,7 +586,7 @@ function toFloat64Array(value) {
|
|
|
525
586
|
if (value instanceof Float32Array) {
|
|
526
587
|
return new Float64Array(value);
|
|
527
588
|
}
|
|
528
|
-
if (value instanceof Int32Array) {
|
|
589
|
+
if (value instanceof Int32Array || value instanceof Uint8Array) {
|
|
529
590
|
return new Float64Array(value);
|
|
530
591
|
}
|
|
531
592
|
if (Array.isArray(value)) {
|
|
@@ -548,7 +609,7 @@ function toInt32Array(value) {
|
|
|
548
609
|
}
|
|
549
610
|
return result;
|
|
550
611
|
}
|
|
551
|
-
if (value instanceof Float32Array) {
|
|
612
|
+
if (value instanceof Float32Array || value instanceof Uint8Array) {
|
|
552
613
|
const result = new Int32Array(value.length);
|
|
553
614
|
for (let i = 0; i < value.length; i++) {
|
|
554
615
|
result[i] = Math.round(value[i]);
|
|
@@ -565,9 +626,6 @@ function toInt32Array(value) {
|
|
|
565
626
|
throw new Error(`Cannot convert ${typeof value} to Int32Array`);
|
|
566
627
|
}
|
|
567
628
|
function getNodeArrayValue(node) {
|
|
568
|
-
|
|
569
|
-
return node.properties[0].value;
|
|
570
|
-
}
|
|
571
|
-
return node.properties.map((property) => property.value);
|
|
629
|
+
return getNodeArray(node) ?? new Float64Array(0);
|
|
572
630
|
}
|
|
573
631
|
//# sourceMappingURL=geometry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometry.js","sourceRoot":"","sources":["../../../../../dev/loaders/src/FBX/interpreter/geometry.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention, jsdoc/require-param, jsdoc/require-returns */\r\nimport { type FBXNode, findChildByName, findChildrenByName, getPropertyValue, cleanFBXName } from \"../types/fbxTypes\";\r\n\r\n/** A named UV set */\r\nexport interface FBXUVSet {\r\n /** UV set name (e.g. \"UVMap\", \"lightmap\") */\r\n name: string;\r\n /** Per-vertex UV data [u,v, ...] (expanded to match triangle vertices) */\r\n data: Float64Array;\r\n}\r\n\r\n/** Recoverable geometry import issue. */\r\nexport interface FBXGeometryDiagnostic {\r\n /** Diagnostic category. */\r\n type: \"degenerate-polygon\" | \"triangulation-fallback\" | \"layer-index-out-of-bounds\" | \"layer-data-too-short\";\r\n /** Human-readable diagnostic message. */\r\n message: string;\r\n /** Polygon index associated with the diagnostic, if applicable. */\r\n polygonIndex?: number;\r\n /** Layer element name associated with the diagnostic, if applicable. */\r\n layerName?: string;\r\n /** Source data index associated with the diagnostic, if applicable. */\r\n index?: number;\r\n}\r\n\r\n/** Parsed geometry data ready for Babylon consumption */\r\nexport interface FBXGeometryData {\r\n /** Node ID from the FBX document */\r\n id: number;\r\n /** Geometry name */\r\n name: string;\r\n /** Flat array of vertex positions [x,y,z, x,y,z, ...] */\r\n positions: Float64Array;\r\n /** Triangle indices (already triangulated from n-gons) */\r\n indices: Uint32Array;\r\n /** Per-vertex normals [x,y,z, ...] (expanded to match triangle vertices) */\r\n normals: Float64Array | null;\r\n /** Per-vertex UVs [u,v, ...] (expanded to match triangle vertices) — first UV set for convenience */\r\n uvs: Float64Array | null;\r\n /** All UV sets (including the first) */\r\n uvSets: FBXUVSet[];\r\n /** Per-vertex colors [r,g,b,a, ...] (expanded to match triangle vertices) */\r\n colors: Float32Array | null;\r\n /** Per-vertex tangents [x,y,z,w, ...] expanded to match triangle vertices */\r\n tangents: Float64Array | null;\r\n /** Per-vertex binormals [x,y,z, ...] expanded to match triangle vertices */\r\n binormals: Float64Array | null;\r\n /** Control point index for each polygon-vertex (for skinning lookup) */\r\n controlPointIndices: Uint32Array | null;\r\n /** Per-triangle material index (which material each triangle belongs to) */\r\n materialIndices: Int32Array | null;\r\n /** Recoverable geometry import issues */\r\n diagnostics: FBXGeometryDiagnostic[];\r\n}\r\n\r\n/**\r\n * Extract geometry data from an FBX Geometry node.\r\n * Handles polygon triangulation and layer element expansion.\r\n */\r\nexport function extractGeometry(geometryNode: FBXNode, nodeId: number): FBXGeometryData {\r\n const name = cleanFBXName(getPropertyValue<string>(geometryNode, 1) ?? \"Geometry\");\r\n\r\n // Extract raw vertices\r\n const verticesNode = findChildByName(geometryNode, \"Vertices\");\r\n if (!verticesNode) {\r\n throw new Error(`Geometry '${name}' has no Vertices node`);\r\n }\r\n const rawPositions = toFloat64Array(getNodeArrayValue(verticesNode));\r\n\r\n // Extract polygon vertex indices\r\n const pviNode = findChildByName(geometryNode, \"PolygonVertexIndex\");\r\n if (!pviNode) {\r\n throw new Error(`Geometry '${name}' has no PolygonVertexIndex node`);\r\n }\r\n const rawIndices = toInt32Array(getNodeArrayValue(pviNode));\r\n const diagnostics: FBXGeometryDiagnostic[] = [];\r\n\r\n // Parse polygons from the FBX negative-index convention\r\n const polygons = parsePolygons(rawIndices);\r\n\r\n // Triangulate polygons while preserving polygon-vertex indices for layer data.\r\n const triangles = triangulatePolygons(polygons, rawPositions, diagnostics);\r\n\r\n // Build the list of polygon-vertex pairs for layer element expansion\r\n const polyVertexList = buildPolygonVertexList(polygons);\r\n\r\n // Extract normals\r\n const normalNode = findChildByName(geometryNode, \"LayerElementNormal\");\r\n let normals: Float64Array | null = null;\r\n if (normalNode) {\r\n normals = expandLayerElement(normalNode, \"Normals\", \"NormalsIndex\", polyVertexList, rawPositions.length / 3, 3, diagnostics);\r\n }\r\n\r\n // Extract all UV sets\r\n const uvNodes = findChildrenByName(geometryNode, \"LayerElementUV\");\r\n const uvSets: FBXUVSet[] = [];\r\n for (const uvNode of uvNodes) {\r\n const nameNode = findChildByName(uvNode, \"Name\");\r\n const setName = nameNode ? (getPropertyValue<string>(nameNode, 0) ?? `UVSet${uvSets.length}`) : `UVSet${uvSets.length}`;\r\n const data = expandLayerElement(uvNode, \"UV\", \"UVIndex\", polyVertexList, rawPositions.length / 3, 2, diagnostics);\r\n if (data) {\r\n uvSets.push({ name: setName, data });\r\n }\r\n }\r\n const uvs = uvSets.length > 0 ? uvSets[0].data : null;\r\n\r\n // Extract vertex colors\r\n const colorNode = findChildByName(geometryNode, \"LayerElementColor\");\r\n let colors: Float32Array | null = null;\r\n if (colorNode) {\r\n const colorData = expandLayerElement(colorNode, \"Colors\", \"ColorIndex\", polyVertexList, rawPositions.length / 3, 4, diagnostics);\r\n if (colorData) {\r\n colors = new Float32Array(colorData.length);\r\n for (let i = 0; i < colorData.length; i++) {\r\n colors[i] = colorData[i];\r\n }\r\n }\r\n }\r\n\r\n const tangentNode = findChildByName(geometryNode, \"LayerElementTangent\");\r\n const binormalNode = findChildByName(geometryNode, \"LayerElementBinormal\");\r\n const binormals = binormalNode ? expandLayerElement(binormalNode, \"Binormals\", \"BinormalsIndex\", polyVertexList, rawPositions.length / 3, 3, diagnostics) : null;\r\n const tangents = tangentNode ? expandTangentLayer(tangentNode, polyVertexList, rawPositions.length / 3, normals, binormals, diagnostics) : null;\r\n\r\n // Extract per-polygon material indices\r\n const matNode = findChildByName(geometryNode, \"LayerElementMaterial\");\r\n let polyMaterialIndices: Int32Array | null = null;\r\n if (matNode) {\r\n polyMaterialIndices = extractMaterialIndices(matNode, polygons.length);\r\n }\r\n\r\n // Build final indexed mesh with expanded per-triangle-vertex attributes\r\n const result = buildTriangleMesh(rawPositions, triangles, polyVertexList, normals, uvs, uvSets, colors, tangents, binormals);\r\n\r\n // Expand per-polygon material indices to per-triangle\r\n let materialIndices: Int32Array | null = null;\r\n if (polyMaterialIndices) {\r\n // Check if all polygons use the same material (optimization)\r\n let allSame = true;\r\n const firstMat = polyMaterialIndices[0];\r\n for (let i = 1; i < polyMaterialIndices.length; i++) {\r\n if (polyMaterialIndices[i] !== firstMat) {\r\n allSame = false;\r\n break;\r\n }\r\n }\r\n\r\n if (!allSame || firstMat !== 0) {\r\n const triCount = result.indices.length / 3;\r\n materialIndices = new Int32Array(triCount);\r\n for (let ti = 0; ti < triangles.length; ti++) {\r\n materialIndices[ti] = polyMaterialIndices[triangles[ti].polyIndex] ?? 0;\r\n }\r\n }\r\n }\r\n\r\n return {\r\n id: nodeId,\r\n name,\r\n positions: result.positions,\r\n indices: result.indices,\r\n normals: result.normals,\r\n uvs: result.uvs,\r\n uvSets: result.uvSets,\r\n colors: result.colors,\r\n tangents: result.tangents,\r\n binormals: result.binormals,\r\n controlPointIndices: result.controlPointIndices,\r\n materialIndices,\r\n diagnostics,\r\n };\r\n}\r\n\r\n// ── Polygon Parsing ────────────────────────────────────────────────────────────\r\n\r\ninterface Polygon {\r\n /** Control point indices for this polygon */\r\n indices: number[];\r\n /** Starting index in the original PolygonVertexIndex array */\r\n startIndex: number;\r\n}\r\n\r\ninterface Triangle {\r\n vertices: [number, number, number];\r\n polyIndex: number;\r\n}\r\n\r\nfunction parsePolygons(rawIndices: Int32Array): Polygon[] {\r\n const polygons: Polygon[] = [];\r\n let currentPoly: number[] = [];\r\n let startIndex = 0;\r\n\r\n for (let i = 0; i < rawIndices.length; i++) {\r\n const idx = rawIndices[i];\r\n if (idx < 0) {\r\n // End of polygon: actual index is -(idx + 1)\r\n currentPoly.push(-(idx + 1));\r\n polygons.push({ indices: currentPoly, startIndex });\r\n currentPoly = [];\r\n startIndex = i + 1;\r\n } else {\r\n currentPoly.push(idx);\r\n }\r\n }\r\n\r\n return polygons;\r\n}\r\n\r\nfunction triangulatePolygons(polygons: Polygon[], rawPositions: Float64Array, diagnostics: FBXGeometryDiagnostic[]): Triangle[] {\r\n const triangles: Triangle[] = [];\r\n\r\n for (let polyIndex = 0; polyIndex < polygons.length; polyIndex++) {\r\n const poly = polygons[polyIndex];\r\n triangles.push(...triangulatePolygon(poly, polyIndex, rawPositions, diagnostics));\r\n }\r\n\r\n return triangles;\r\n}\r\n\r\nfunction triangulatePolygon(poly: Polygon, polyIndex: number, rawPositions: Float64Array, diagnostics: FBXGeometryDiagnostic[]): Triangle[] {\r\n if (poly.indices.length < 3) {\r\n diagnostics.push({\r\n type: \"degenerate-polygon\",\r\n message: `Polygon ${polyIndex} has fewer than three vertices.`,\r\n polygonIndex: polyIndex,\r\n });\r\n return [];\r\n }\r\n if (poly.indices.length === 3) {\r\n return [{ vertices: [poly.startIndex, poly.startIndex + 1, poly.startIndex + 2], polyIndex }];\r\n }\r\n\r\n const projected = projectPolygonTo2D(poly, rawPositions);\r\n if (!projected) {\r\n diagnostics.push({\r\n type: \"degenerate-polygon\",\r\n message: `Polygon ${polyIndex} has a near-zero normal; using fan triangulation.`,\r\n polygonIndex: polyIndex,\r\n });\r\n return fanTriangulate(poly, polyIndex);\r\n }\r\n\r\n const polygonArea = signedArea2D(projected);\r\n if (Math.abs(polygonArea) < 1e-12) {\r\n diagnostics.push({\r\n type: \"degenerate-polygon\",\r\n message: `Polygon ${polyIndex} projects to near-zero area; using fan triangulation.`,\r\n polygonIndex: polyIndex,\r\n });\r\n return fanTriangulate(poly, polyIndex);\r\n }\r\n\r\n const isCCW = polygonArea > 0;\r\n const remaining = poly.indices.map((_, i) => i);\r\n const clipped: Triangle[] = [];\r\n let guard = 0;\r\n\r\n while (remaining.length > 3 && guard++ < poly.indices.length * poly.indices.length) {\r\n let clippedEar = false;\r\n\r\n for (let i = 0; i < remaining.length; i++) {\r\n const prev = remaining[(i + remaining.length - 1) % remaining.length];\r\n const curr = remaining[i];\r\n const next = remaining[(i + 1) % remaining.length];\r\n\r\n if (!isConvex(projected[prev], projected[curr], projected[next], isCCW)) {\r\n continue;\r\n }\r\n if (containsAnyPoint(projected, remaining, prev, curr, next)) {\r\n continue;\r\n }\r\n\r\n clipped.push({\r\n vertices: [poly.startIndex + prev, poly.startIndex + curr, poly.startIndex + next],\r\n polyIndex,\r\n });\r\n remaining.splice(i, 1);\r\n clippedEar = true;\r\n break;\r\n }\r\n\r\n if (!clippedEar) {\r\n diagnostics.push({\r\n type: \"triangulation-fallback\",\r\n message: `Polygon ${polyIndex} could not be fully ear-clipped; using fan triangulation.`,\r\n polygonIndex: polyIndex,\r\n });\r\n return fanTriangulate(poly, polyIndex);\r\n }\r\n }\r\n\r\n clipped.push({\r\n vertices: [poly.startIndex + remaining[0], poly.startIndex + remaining[1], poly.startIndex + remaining[2]],\r\n polyIndex,\r\n });\r\n return clipped;\r\n}\r\n\r\nfunction fanTriangulate(poly: Polygon, polyIndex: number): Triangle[] {\r\n const triangles: Triangle[] = [];\r\n for (let i = 1; i < poly.indices.length - 1; i++) {\r\n triangles.push({\r\n vertices: [poly.startIndex, poly.startIndex + i, poly.startIndex + i + 1],\r\n polyIndex,\r\n });\r\n }\r\n return triangles;\r\n}\r\n\r\nfunction projectPolygonTo2D(poly: Polygon, rawPositions: Float64Array): [number, number][] | null {\r\n const normal = computeNewellNormal(poly, rawPositions);\r\n const ax = Math.abs(normal[0]);\r\n const ay = Math.abs(normal[1]);\r\n const az = Math.abs(normal[2]);\r\n if (ax + ay + az < 1e-12) {\r\n return null;\r\n }\r\n\r\n const dropAxis = ax > ay && ax > az ? 0 : ay > az ? 1 : 2;\r\n return poly.indices.map((cp) => {\r\n const x = rawPositions[cp * 3];\r\n const y = rawPositions[cp * 3 + 1];\r\n const z = rawPositions[cp * 3 + 2];\r\n if (dropAxis === 0) {\r\n return normal[0] >= 0 ? [y, z] : [z, y];\r\n }\r\n if (dropAxis === 1) {\r\n return normal[1] >= 0 ? [z, x] : [x, z];\r\n }\r\n return normal[2] >= 0 ? [x, y] : [y, x];\r\n });\r\n}\r\n\r\nfunction computeNewellNormal(poly: Polygon, rawPositions: Float64Array): [number, number, number] {\r\n let nx = 0;\r\n let ny = 0;\r\n let nz = 0;\r\n for (let i = 0; i < poly.indices.length; i++) {\r\n const current = poly.indices[i] * 3;\r\n const next = poly.indices[(i + 1) % poly.indices.length] * 3;\r\n const x0 = rawPositions[current];\r\n const y0 = rawPositions[current + 1];\r\n const z0 = rawPositions[current + 2];\r\n const x1 = rawPositions[next];\r\n const y1 = rawPositions[next + 1];\r\n const z1 = rawPositions[next + 2];\r\n nx += (y0 - y1) * (z0 + z1);\r\n ny += (z0 - z1) * (x0 + x1);\r\n nz += (x0 - x1) * (y0 + y1);\r\n }\r\n return [nx, ny, nz];\r\n}\r\n\r\nfunction signedArea2D(points: [number, number][]): number {\r\n let area = 0;\r\n for (let i = 0; i < points.length; i++) {\r\n const a = points[i];\r\n const b = points[(i + 1) % points.length];\r\n area += a[0] * b[1] - b[0] * a[1];\r\n }\r\n return area / 2;\r\n}\r\n\r\nfunction isConvex(a: [number, number], b: [number, number], c: [number, number], isCCW: boolean): boolean {\r\n const cross = (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);\r\n return isCCW ? cross > 1e-12 : cross < -1e-12;\r\n}\r\n\r\nfunction containsAnyPoint(points: [number, number][], remaining: number[], prev: number, curr: number, next: number): boolean {\r\n for (const index of remaining) {\r\n if (index === prev || index === curr || index === next) {\r\n continue;\r\n }\r\n if (pointInTriangle(points[index], points[prev], points[curr], points[next])) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\nfunction pointInTriangle(p: [number, number], a: [number, number], b: [number, number], c: [number, number]): boolean {\r\n const area = Math.abs(cross2D(a, b, c));\r\n const area1 = Math.abs(cross2D(p, a, b));\r\n const area2 = Math.abs(cross2D(p, b, c));\r\n const area3 = Math.abs(cross2D(p, c, a));\r\n return Math.abs(area - (area1 + area2 + area3)) < 1e-10;\r\n}\r\n\r\nfunction cross2D(a: [number, number], b: [number, number], c: [number, number]): number {\r\n return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);\r\n}\r\n\r\n/** Build a flat list of (polygonIndex, vertexInPolygon, controlPointIndex) for each polygon vertex */\r\ninterface PolyVertex {\r\n polyIndex: number;\r\n vertexInPoly: number;\r\n controlPointIndex: number;\r\n /** Global polygon-vertex index (position in the original PolygonVertexIndex array) */\r\n globalIndex: number;\r\n}\r\n\r\nfunction buildPolygonVertexList(polygons: Polygon[]): PolyVertex[] {\r\n const list: PolyVertex[] = [];\r\n for (let pi = 0; pi < polygons.length; pi++) {\r\n const poly = polygons[pi];\r\n for (let vi = 0; vi < poly.indices.length; vi++) {\r\n list.push({\r\n polyIndex: pi,\r\n vertexInPoly: vi,\r\n controlPointIndex: poly.indices[vi],\r\n globalIndex: poly.startIndex + vi,\r\n });\r\n }\r\n }\r\n return list;\r\n}\r\n\r\n// ── Layer Element Expansion ────────────────────────────────────────────────────\r\n\r\n/**\r\n * Extract per-polygon material indices from LayerElementMaterial.\r\n * Returns an Int32Array with one material index per polygon.\r\n */\r\nfunction extractMaterialIndices(matNode: FBXNode, polygonCount: number): Int32Array | null {\r\n const mappingNode = findChildByName(matNode, \"MappingInformationType\");\r\n const referenceNode = findChildByName(matNode, \"ReferenceInformationType\");\r\n\r\n if (!mappingNode || !referenceNode) {\r\n return null;\r\n }\r\n\r\n const mapping = getPropertyValue<string>(mappingNode, 0) ?? \"\";\r\n const reference = getPropertyValue<string>(referenceNode, 0) ?? \"\";\r\n\r\n if (mapping === \"AllSame\") {\r\n const materialsNode = findChildByName(matNode, \"Materials\");\r\n const rawIndices = materialsNode ? toInt32Array(getNodeArrayValue(materialsNode)) : null;\r\n const materialIndex = rawIndices && rawIndices.length > 0 ? rawIndices[0] : 0;\r\n const indices = new Int32Array(polygonCount);\r\n if (materialIndex !== 0) {\r\n indices.fill(materialIndex);\r\n }\r\n return indices;\r\n }\r\n\r\n if (mapping === \"ByPolygon\") {\r\n const materialsNode = findChildByName(matNode, \"Materials\");\r\n if (!materialsNode) {\r\n return null;\r\n }\r\n const rawIndices = toInt32Array(getNodeArrayValue(materialsNode));\r\n // For Direct reference, the Materials array has one index per polygon\r\n if (reference === \"Direct\" || reference === \"IndexToDirect\") {\r\n return rawIndices;\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction expandLayerElement(\r\n layerNode: FBXNode,\r\n dataChildName: string,\r\n indexChildName: string,\r\n polyVertexList: PolyVertex[],\r\n controlPointCount: number,\r\n stride: number,\r\n diagnostics: FBXGeometryDiagnostic[]\r\n): Float64Array | null {\r\n const mappingNode = findChildByName(layerNode, \"MappingInformationType\");\r\n const referenceNode = findChildByName(layerNode, \"ReferenceInformationType\");\r\n\r\n if (!mappingNode || !referenceNode) {\r\n return null;\r\n }\r\n\r\n const mapping = getPropertyValue<string>(mappingNode, 0) ?? \"\";\r\n const reference = getPropertyValue<string>(referenceNode, 0) ?? \"\";\r\n\r\n const dataNode = findChildByName(layerNode, dataChildName);\r\n if (!dataNode) {\r\n return null;\r\n }\r\n const data = toFloat64Array(getNodeArrayValue(dataNode));\r\n\r\n let indexData: Int32Array | null = null;\r\n if (reference === \"IndexToDirect\") {\r\n const indexNode = findChildByName(layerNode, indexChildName);\r\n if (indexNode) {\r\n indexData = toInt32Array(getNodeArrayValue(indexNode));\r\n }\r\n }\r\n\r\n // Expand to per-polygon-vertex\r\n const result = new Float64Array(polyVertexList.length * stride);\r\n\r\n for (let i = 0; i < polyVertexList.length; i++) {\r\n const pv = polyVertexList[i];\r\n let dataIndex: number;\r\n\r\n if (mapping === \"ByPolygonVertex\") {\r\n if (reference === \"IndexToDirect\" && indexData) {\r\n dataIndex = indexData[pv.globalIndex];\r\n } else {\r\n // Direct\r\n dataIndex = pv.globalIndex;\r\n }\r\n } else if (mapping === \"ByControlPoint\" || mapping === \"ByVertice\") {\r\n if (reference === \"IndexToDirect\" && indexData) {\r\n dataIndex = indexData[pv.controlPointIndex];\r\n } else {\r\n dataIndex = pv.controlPointIndex;\r\n }\r\n } else if (mapping === \"ByPolygon\") {\r\n if (reference === \"IndexToDirect\" && indexData) {\r\n dataIndex = indexData[pv.polyIndex];\r\n } else {\r\n dataIndex = pv.polyIndex;\r\n }\r\n } else if (mapping === \"AllSame\") {\r\n dataIndex = 0;\r\n } else {\r\n dataIndex = pv.globalIndex;\r\n }\r\n\r\n for (let s = 0; s < stride; s++) {\r\n const sourceIndex = dataIndex * stride + s;\r\n if (dataIndex < 0 || sourceIndex >= data.length) {\r\n diagnostics.push({\r\n type: sourceIndex >= data.length ? \"layer-data-too-short\" : \"layer-index-out-of-bounds\",\r\n message: `Layer '${layerNode.name}' references unavailable element ${dataIndex}.`,\r\n layerName: layerNode.name,\r\n index: dataIndex,\r\n });\r\n result[i * stride + s] = 0;\r\n } else {\r\n result[i * stride + s] = data[sourceIndex];\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction expandTangentLayer(\r\n tangentNode: FBXNode,\r\n polyVertexList: PolyVertex[],\r\n controlPointCount: number,\r\n normals: Float64Array | null,\r\n binormals: Float64Array | null,\r\n diagnostics: FBXGeometryDiagnostic[]\r\n): Float64Array | null {\r\n const sourceStride = inferLayerElementStride(tangentNode, \"Tangents\", \"TangentsIndex\", polyVertexList, controlPointCount, diagnostics);\r\n const expanded = expandLayerElement(tangentNode, \"Tangents\", \"TangentsIndex\", polyVertexList, controlPointCount, sourceStride, diagnostics);\r\n if (!expanded) {\r\n return null;\r\n }\r\n\r\n const tangents = new Float64Array(polyVertexList.length * 4);\r\n for (let i = 0; i < polyVertexList.length; i++) {\r\n const sourceOffset = i * sourceStride;\r\n const destOffset = i * 4;\r\n tangents[destOffset] = expanded[sourceOffset];\r\n tangents[destOffset + 1] = expanded[sourceOffset + 1];\r\n tangents[destOffset + 2] = expanded[sourceOffset + 2];\r\n tangents[destOffset + 3] = sourceStride >= 4 ? expanded[sourceOffset + 3] : computeTangentHandedness(i, tangents, normals, binormals);\r\n }\r\n return tangents;\r\n}\r\n\r\nfunction inferLayerElementStride(\r\n layerNode: FBXNode,\r\n dataChildName: string,\r\n indexChildName: string,\r\n polyVertexList: PolyVertex[],\r\n controlPointCount: number,\r\n diagnostics: FBXGeometryDiagnostic[]\r\n): number {\r\n const dataNode = findChildByName(layerNode, dataChildName);\r\n if (!dataNode) {\r\n return 3;\r\n }\r\n const data = toFloat64Array(getNodeArrayValue(dataNode));\r\n const mapping = getPropertyValue<string>(findChildByName(layerNode, \"MappingInformationType\") ?? { name: \"\", properties: [], children: [] }, 0) ?? \"\";\r\n const reference = getPropertyValue<string>(findChildByName(layerNode, \"ReferenceInformationType\") ?? { name: \"\", properties: [], children: [] }, 0) ?? \"\";\r\n const indexNode = findChildByName(layerNode, indexChildName);\r\n const indexData = indexNode ? toInt32Array(getNodeArrayValue(indexNode)) : null;\r\n const directCount =\r\n reference === \"IndexToDirect\" && indexData\r\n ? Math.max(...Array.from(indexData), 0) + 1\r\n : mapping === \"ByControlPoint\" || mapping === \"ByVertice\"\r\n ? controlPointCount\r\n : mapping === \"AllSame\"\r\n ? 1\r\n : polyVertexList.length;\r\n\r\n if (directCount > 0 && data.length % directCount === 0) {\r\n const stride = data.length / directCount;\r\n if (stride === 3 || stride === 4) {\r\n return stride;\r\n }\r\n }\r\n\r\n diagnostics.push({\r\n type: \"layer-data-too-short\",\r\n message: `Could not infer stride for layer '${layerNode.name}', defaulting to 3.`,\r\n layerName: layerNode.name,\r\n });\r\n return 3;\r\n}\r\n\r\nfunction computeTangentHandedness(vertexIndex: number, tangents: Float64Array, normals: Float64Array | null, binormals: Float64Array | null): number {\r\n if (!normals || !binormals) {\r\n return 1;\r\n }\r\n const to = vertexIndex * 4;\r\n const no = vertexIndex * 3;\r\n const nx = normals[no];\r\n const ny = normals[no + 1];\r\n const nz = normals[no + 2];\r\n const tx = tangents[to];\r\n const ty = tangents[to + 1];\r\n const tz = tangents[to + 2];\r\n const bx = binormals[no];\r\n const by = binormals[no + 1];\r\n const bz = binormals[no + 2];\r\n const cx = ny * tz - nz * ty;\r\n const cy = nz * tx - nx * tz;\r\n const cz = nx * ty - ny * tx;\r\n return cx * bx + cy * by + cz * bz < 0 ? -1 : 1;\r\n}\r\n\r\n// ── Final Mesh Assembly ────────────────────────────────────────────────────────\r\n\r\ninterface TriangleMeshData {\r\n positions: Float64Array;\r\n indices: Uint32Array;\r\n normals: Float64Array | null;\r\n uvs: Float64Array | null;\r\n uvSets: FBXUVSet[];\r\n colors: Float32Array | null;\r\n tangents: Float64Array | null;\r\n binormals: Float64Array | null;\r\n controlPointIndices: Uint32Array;\r\n}\r\n\r\n/**\r\n * Build the final triangle mesh. Since normals/UVs are per-polygon-vertex,\r\n * we need to create unique vertices for each polygon-vertex combination.\r\n */\r\nfunction buildTriangleMesh(\r\n rawPositions: Float64Array,\r\n triangles: Triangle[],\r\n polyVertexList: PolyVertex[],\r\n expandedNormals: Float64Array | null,\r\n expandedUVs: Float64Array | null,\r\n expandedUVSets: FBXUVSet[],\r\n expandedColors: Float32Array | null,\r\n expandedTangents: Float64Array | null,\r\n expandedBinormals: Float64Array | null\r\n): TriangleMeshData {\r\n // Each polygon-vertex becomes a unique vertex in the output\r\n const vertexCount = polyVertexList.length;\r\n const positions = new Float64Array(vertexCount * 3);\r\n const controlPointIndices = new Uint32Array(vertexCount);\r\n\r\n // Copy positions — keep in original RH space (root node handles RH→LH conversion)\r\n for (let i = 0; i < polyVertexList.length; i++) {\r\n const cp = polyVertexList[i].controlPointIndex;\r\n positions[i * 3] = rawPositions[cp * 3];\r\n positions[i * 3 + 1] = rawPositions[cp * 3 + 1];\r\n positions[i * 3 + 2] = rawPositions[cp * 3 + 2];\r\n controlPointIndices[i] = cp;\r\n }\r\n\r\n // Normals stay in RH space (root node handles conversion)\r\n if (expandedNormals) {\r\n // No transformation needed\r\n }\r\n\r\n // Keep original winding order — Z negation handles handedness\r\n const indexCount = triangles.length * 3;\r\n const indices = new Uint32Array(indexCount);\r\n for (let i = 0; i < triangles.length; i++) {\r\n indices[i * 3] = triangles[i].vertices[0];\r\n indices[i * 3 + 1] = triangles[i].vertices[1];\r\n indices[i * 3 + 2] = triangles[i].vertices[2];\r\n }\r\n\r\n return {\r\n positions,\r\n indices,\r\n normals: expandedNormals,\r\n uvs: expandedUVs,\r\n uvSets: expandedUVSets,\r\n colors: expandedColors,\r\n tangents: expandedTangents,\r\n binormals: expandedBinormals,\r\n controlPointIndices,\r\n };\r\n}\r\n\r\n// ── Utilities ──────────────────────────────────────────────────────────────────\r\n\r\nfunction toFloat64Array(value: unknown): Float64Array {\r\n if (value instanceof Float64Array) {\r\n return value;\r\n }\r\n if (value instanceof Float32Array) {\r\n return new Float64Array(value);\r\n }\r\n if (value instanceof Int32Array) {\r\n return new Float64Array(value);\r\n }\r\n if (Array.isArray(value)) {\r\n const result = new Float64Array(value.length);\r\n for (let i = 0; i < value.length; i++) {\r\n result[i] = Number(value[i]);\r\n }\r\n return result;\r\n }\r\n throw new Error(`Cannot convert ${typeof value} to Float64Array`);\r\n}\r\n\r\nfunction toInt32Array(value: unknown): Int32Array {\r\n if (value instanceof Int32Array) {\r\n return value;\r\n }\r\n if (value instanceof Float64Array) {\r\n const result = new Int32Array(value.length);\r\n for (let i = 0; i < value.length; i++) {\r\n result[i] = Math.round(value[i]);\r\n }\r\n return result;\r\n }\r\n if (value instanceof Float32Array) {\r\n const result = new Int32Array(value.length);\r\n for (let i = 0; i < value.length; i++) {\r\n result[i] = Math.round(value[i]);\r\n }\r\n return result;\r\n }\r\n if (Array.isArray(value)) {\r\n const result = new Int32Array(value.length);\r\n for (let i = 0; i < value.length; i++) {\r\n result[i] = Math.round(Number(value[i]));\r\n }\r\n return result;\r\n }\r\n throw new Error(`Cannot convert ${typeof value} to Int32Array`);\r\n}\r\n\r\nfunction getNodeArrayValue(node: FBXNode): unknown {\r\n if (node.properties.length === 1) {\r\n return node.properties[0].value;\r\n }\r\n return node.properties.map((property) => property.value);\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"geometry.js","sourceRoot":"","sources":["../../../../../dev/loaders/src/FBX/interpreter/geometry.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention, jsdoc/require-param, jsdoc/require-returns */\nimport { type FBXNode, findChildByName, findChildrenByName, getPropertyValue, cleanFBXName, getNodeArray } from \"../types/fbxTypes\";\n\n/** A named UV set */\nexport interface FBXUVSet {\n /** UV set name (e.g. \"UVMap\", \"lightmap\") */\n name: string;\n /** Per-vertex UV data [u,v, ...] (expanded to match triangle vertices) */\n data: Float64Array;\n}\n\n/** Recoverable geometry import issue. */\nexport interface FBXGeometryDiagnostic {\n /** Diagnostic category. */\n type:\n \"degenerate-polygon\" | \"triangulation-fallback\" | \"layer-index-out-of-bounds\" | \"layer-data-too-short\" | \"nurbs-invalid\" | \"nurbs-trim-ignored\" | \"nurbs-deformer-ignored\";\n /** Human-readable diagnostic message. */\n message: string;\n /** Polygon index associated with the diagnostic, if applicable. */\n polygonIndex?: number;\n /** Layer element name associated with the diagnostic, if applicable. */\n layerName?: string;\n /** Source data index associated with the diagnostic, if applicable. */\n index?: number;\n}\n\n/** Parsed geometry data ready for Babylon consumption */\nexport interface FBXGeometryData {\n /** Node ID from the FBX document */\n id: number;\n /** Geometry name */\n name: string;\n /** Flat array of vertex positions [x,y,z, x,y,z, ...] */\n positions: Float64Array;\n /** Triangle indices (already triangulated from n-gons) */\n indices: Uint32Array;\n /** Per-vertex normals [x,y,z, ...] (expanded to match triangle vertices) */\n normals: Float64Array | null;\n /** Per-vertex UVs [u,v, ...] (expanded to match triangle vertices) — first UV set for convenience */\n uvs: Float64Array | null;\n /** All UV sets (including the first) */\n uvSets: FBXUVSet[];\n /** Per-vertex colors [r,g,b,a, ...] (expanded to match triangle vertices) */\n colors: Float32Array | null;\n /** Per-vertex tangents [x,y,z,w, ...] expanded to match triangle vertices */\n tangents: Float64Array | null;\n /** Per-vertex binormals [x,y,z, ...] expanded to match triangle vertices */\n binormals: Float64Array | null;\n /** Control point index for each polygon-vertex (for skinning lookup) */\n controlPointIndices: Uint32Array | null;\n /** Per-triangle material index (which material each triangle belongs to) */\n materialIndices: Int32Array | null;\n /** Recoverable geometry import issues */\n diagnostics: FBXGeometryDiagnostic[];\n}\n\n/**\n * Extract geometry data from an FBX Geometry node.\n * Handles polygon triangulation and layer element expansion.\n */\nexport function extractGeometry(geometryNode: FBXNode, nodeId: number): FBXGeometryData {\n const name = cleanFBXName(getPropertyValue<string>(geometryNode, 1) ?? \"Geometry\");\n\n // Extract raw vertices\n // Edge-only meshes (e.g. Blender edge circles) and empty placeholders have no vertices or polygons; they\n // become geometry with zero triangles rather than errors.\n const verticesNode = findChildByName(geometryNode, \"Vertices\");\n const rawPositions = verticesNode ? toFloat64Array(getNodeArrayValue(verticesNode)) : new Float64Array(0);\n\n // Extract polygon vertex indices\n const pviNode = findChildByName(geometryNode, \"PolygonVertexIndex\");\n const rawIndices = pviNode ? toInt32Array(getNodeArrayValue(pviNode)) : new Int32Array(0);\n const diagnostics: FBXGeometryDiagnostic[] = [];\n\n // Parse polygons from the FBX negative-index convention\n const polygons = parsePolygons(rawIndices);\n\n // Triangulate polygons while preserving polygon-vertex indices for layer data.\n const triangles = triangulatePolygons(polygons, rawPositions, diagnostics);\n\n // Build the list of polygon-vertex pairs for layer element expansion\n const polyVertexList = buildPolygonVertexList(polygons);\n\n // Extract normals\n const normalNode = findChildByName(geometryNode, \"LayerElementNormal\");\n let normals: Float64Array | null = null;\n if (normalNode) {\n normals = expandLayerElement(normalNode, \"Normals\", \"NormalsIndex\", polyVertexList, rawPositions.length / 3, 3, diagnostics);\n }\n\n // Extract all UV sets\n const uvNodes = findChildrenByName(geometryNode, \"LayerElementUV\");\n const uvSets: FBXUVSet[] = [];\n for (const uvNode of uvNodes) {\n const nameNode = findChildByName(uvNode, \"Name\");\n const setName = nameNode ? (getPropertyValue<string>(nameNode, 0) ?? `UVSet${uvSets.length}`) : `UVSet${uvSets.length}`;\n const data = expandLayerElement(uvNode, \"UV\", \"UVIndex\", polyVertexList, rawPositions.length / 3, 2, diagnostics);\n if (data) {\n uvSets.push({ name: setName, data });\n }\n }\n const uvs = uvSets.length > 0 ? uvSets[0].data : null;\n\n // Extract vertex colors\n const colorNode = findChildByName(geometryNode, \"LayerElementColor\");\n let colors: Float32Array | null = null;\n if (colorNode) {\n const colorData = expandLayerElement(colorNode, \"Colors\", \"ColorIndex\", polyVertexList, rawPositions.length / 3, 4, diagnostics);\n if (colorData) {\n colors = new Float32Array(colorData.length);\n for (let i = 0; i < colorData.length; i++) {\n colors[i] = colorData[i];\n }\n }\n }\n\n const tangentNode = findChildByName(geometryNode, \"LayerElementTangent\");\n const binormalNode = findChildByName(geometryNode, \"LayerElementBinormal\");\n const binormals = binormalNode ? expandLayerElement(binormalNode, \"Binormals\", \"BinormalsIndex\", polyVertexList, rawPositions.length / 3, 3, diagnostics) : null;\n const tangents = tangentNode ? expandTangentLayer(tangentNode, polyVertexList, rawPositions.length / 3, normals, binormals, diagnostics) : null;\n\n // Extract per-polygon material indices\n const matNode = findChildByName(geometryNode, \"LayerElementMaterial\");\n let polyMaterialIndices: Int32Array | null = null;\n if (matNode) {\n polyMaterialIndices = extractMaterialIndices(matNode, polygons.length);\n }\n\n // Build final indexed mesh with expanded per-triangle-vertex attributes\n const result = buildTriangleMesh(rawPositions, triangles, polyVertexList, normals, uvs, uvSets, colors, tangents, binormals);\n\n // Expand per-polygon material indices to per-triangle\n let materialIndices: Int32Array | null = null;\n if (polyMaterialIndices) {\n // Check if all polygons use the same material (optimization)\n let allSame = true;\n const firstMat = polyMaterialIndices[0];\n for (let i = 1; i < polyMaterialIndices.length; i++) {\n if (polyMaterialIndices[i] !== firstMat) {\n allSame = false;\n break;\n }\n }\n\n if (!allSame || firstMat !== 0) {\n const triCount = result.indices.length / 3;\n materialIndices = new Int32Array(triCount);\n for (let ti = 0; ti < triangles.length; ti++) {\n materialIndices[ti] = polyMaterialIndices[triangles[ti].polyIndex] ?? 0;\n }\n }\n }\n\n return {\n id: nodeId,\n name,\n positions: result.positions,\n indices: result.indices,\n normals: result.normals,\n uvs: result.uvs,\n uvSets: result.uvSets,\n colors: result.colors,\n tangents: result.tangents,\n binormals: result.binormals,\n controlPointIndices: result.controlPointIndices,\n materialIndices,\n diagnostics,\n };\n}\n\n// ── Polygon Parsing ────────────────────────────────────────────────────────────\n\ninterface Polygon {\n /** Control point indices for this polygon */\n indices: number[];\n /** Starting index in the original PolygonVertexIndex array */\n startIndex: number;\n}\n\ninterface Triangle {\n vertices: [number, number, number];\n polyIndex: number;\n}\n\nfunction parsePolygons(rawIndices: Int32Array): Polygon[] {\n const polygons: Polygon[] = [];\n let currentPoly: number[] = [];\n let startIndex = 0;\n\n for (let i = 0; i < rawIndices.length; i++) {\n const idx = rawIndices[i];\n if (idx < 0) {\n // End of polygon: actual index is -(idx + 1)\n currentPoly.push(-(idx + 1));\n polygons.push({ indices: currentPoly, startIndex });\n currentPoly = [];\n startIndex = i + 1;\n } else {\n currentPoly.push(idx);\n }\n }\n\n return polygons;\n}\n\nfunction triangulatePolygons(polygons: Polygon[], rawPositions: Float64Array, diagnostics: FBXGeometryDiagnostic[]): Triangle[] {\n const triangles: Triangle[] = [];\n\n for (let polyIndex = 0; polyIndex < polygons.length; polyIndex++) {\n const poly = polygons[polyIndex];\n triangles.push(...triangulatePolygon(poly, polyIndex, rawPositions, diagnostics));\n }\n\n return triangles;\n}\n\nfunction triangulatePolygon(poly: Polygon, polyIndex: number, rawPositions: Float64Array, diagnostics: FBXGeometryDiagnostic[]): Triangle[] {\n if (poly.indices.length < 3) {\n diagnostics.push({\n type: \"degenerate-polygon\",\n message: `Polygon ${polyIndex} has fewer than three vertices.`,\n polygonIndex: polyIndex,\n });\n return [];\n }\n if (poly.indices.length === 3) {\n return [{ vertices: [poly.startIndex, poly.startIndex + 1, poly.startIndex + 2], polyIndex }];\n }\n\n const projected = projectPolygonTo2D(poly, rawPositions);\n if (!projected) {\n diagnostics.push({\n type: \"degenerate-polygon\",\n message: `Polygon ${polyIndex} has a near-zero normal; using fan triangulation.`,\n polygonIndex: polyIndex,\n });\n return fanTriangulate(poly, polyIndex);\n }\n\n const polygonArea = signedArea2D(projected);\n if (Math.abs(polygonArea) < 1e-12) {\n diagnostics.push({\n type: \"degenerate-polygon\",\n message: `Polygon ${polyIndex} projects to near-zero area; using fan triangulation.`,\n polygonIndex: polyIndex,\n });\n return fanTriangulate(poly, polyIndex);\n }\n\n const isCCW = polygonArea > 0;\n const clipped = earClip(projected, isCCW, polygonArea);\n if (!clipped) {\n diagnostics.push({\n type: \"triangulation-fallback\",\n message: `Polygon ${polyIndex} could not be fully ear-clipped; using fan triangulation.`,\n polygonIndex: polyIndex,\n });\n return fanTriangulate(poly, polyIndex);\n }\n return clipped.map(([a, b, c]) => ({ vertices: [poly.startIndex + a, poly.startIndex + b, poly.startIndex + c] as [number, number, number], polyIndex }));\n}\n\n/**\n * Ear clipping on a doubly linked vertex ring. Only reflex vertices can lie inside a candidate ear, so the\n * containment test walks the reflex vertices alone, and the scan resumes after the last clipped ear instead of\n * restarting, which keeps large n-gons (thousands of vertices) at roughly quadratic cost in the reflex count.\n * @returns triangles as local vertex indices, or null when no ear can be found (self-intersecting input)\n */\nfunction earClip(points: [number, number][], isCCW: boolean, polygonArea: number): [number, number, number][] | null {\n const n = points.length;\n const prev = new Int32Array(n);\n const next = new Int32Array(n);\n for (let i = 0; i < n; i++) {\n prev[i] = (i + n - 1) % n;\n next[i] = (i + 1) % n;\n }\n // Tolerances scale with the polygon so huge and tiny coordinates behave the same.\n const eps = Math.abs(polygonArea) * 1e-12 + 1e-300;\n const sign = isCCW ? 1 : -1;\n const turn = (i: number): number => sign * cross2D(points[prev[i]], points[i], points[next[i]]);\n const reflex = new Uint8Array(n);\n for (let i = 0; i < n; i++) {\n reflex[i] = turn(i) < -eps ? 1 : 0;\n }\n const inside = (p: [number, number], a: [number, number], b: [number, number], c: [number, number]): boolean => {\n // Inside or on the boundary of the (consistently oriented) triangle\n return sign * cross2D(a, b, p) >= -eps && sign * cross2D(b, c, p) >= -eps && sign * cross2D(c, a, p) >= -eps;\n };\n\n const triangles: [number, number, number][] = [];\n let remaining = n;\n let i = 0;\n let visitedSinceClip = 0;\n while (remaining > 3) {\n const a = prev[i];\n const c = next[i];\n let clip = false;\n if (!reflex[i]) {\n const t = turn(i);\n if (t <= eps) {\n // Collinear vertex: its ear is a zero-area sliver, kept so every n-gon still yields n - 2 triangles.\n clip = true;\n triangles.push([a, i, c]);\n } else {\n clip = true;\n for (let j = next[c]; j !== a; j = next[j]) {\n if (reflex[j] && inside(points[j], points[a], points[i], points[c])) {\n clip = false;\n break;\n }\n }\n if (clip) {\n triangles.push([a, i, c]);\n }\n }\n }\n if (clip) {\n next[a] = c;\n prev[c] = a;\n remaining--;\n reflex[a] = turn(a) < -eps ? 1 : 0;\n reflex[c] = turn(c) < -eps ? 1 : 0;\n i = c;\n visitedSinceClip = 0;\n continue;\n }\n i = c;\n if (++visitedSinceClip > remaining) {\n return null;\n }\n }\n const last = i;\n triangles.push([prev[last], last, next[last]]);\n return triangles;\n}\n\nfunction fanTriangulate(poly: Polygon, polyIndex: number): Triangle[] {\n const triangles: Triangle[] = [];\n for (let i = 1; i < poly.indices.length - 1; i++) {\n triangles.push({\n vertices: [poly.startIndex, poly.startIndex + i, poly.startIndex + i + 1],\n polyIndex,\n });\n }\n return triangles;\n}\n\nfunction projectPolygonTo2D(poly: Polygon, rawPositions: Float64Array): [number, number][] | null {\n const normal = computeNewellNormal(poly, rawPositions);\n const ax = Math.abs(normal[0]);\n const ay = Math.abs(normal[1]);\n const az = Math.abs(normal[2]);\n if (ax + ay + az < 1e-12) {\n return null;\n }\n\n const dropAxis = ax > ay && ax > az ? 0 : ay > az ? 1 : 2;\n return poly.indices.map((cp) => {\n const x = rawPositions[cp * 3];\n const y = rawPositions[cp * 3 + 1];\n const z = rawPositions[cp * 3 + 2];\n if (dropAxis === 0) {\n return normal[0] >= 0 ? [y, z] : [z, y];\n }\n if (dropAxis === 1) {\n return normal[1] >= 0 ? [z, x] : [x, z];\n }\n return normal[2] >= 0 ? [x, y] : [y, x];\n });\n}\n\nfunction computeNewellNormal(poly: Polygon, rawPositions: Float64Array): [number, number, number] {\n let nx = 0;\n let ny = 0;\n let nz = 0;\n for (let i = 0; i < poly.indices.length; i++) {\n const current = poly.indices[i] * 3;\n const next = poly.indices[(i + 1) % poly.indices.length] * 3;\n const x0 = rawPositions[current];\n const y0 = rawPositions[current + 1];\n const z0 = rawPositions[current + 2];\n const x1 = rawPositions[next];\n const y1 = rawPositions[next + 1];\n const z1 = rawPositions[next + 2];\n nx += (y0 - y1) * (z0 + z1);\n ny += (z0 - z1) * (x0 + x1);\n nz += (x0 - x1) * (y0 + y1);\n }\n return [nx, ny, nz];\n}\n\nfunction signedArea2D(points: [number, number][]): number {\n let area = 0;\n for (let i = 0; i < points.length; i++) {\n const a = points[i];\n const b = points[(i + 1) % points.length];\n area += a[0] * b[1] - b[0] * a[1];\n }\n return area / 2;\n}\n\nfunction cross2D(a: [number, number], b: [number, number], c: [number, number]): number {\n return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);\n}\n\n/** Build a flat list of (polygonIndex, vertexInPolygon, controlPointIndex) for each polygon vertex */\ninterface PolyVertex {\n polyIndex: number;\n vertexInPoly: number;\n controlPointIndex: number;\n /** Global polygon-vertex index (position in the original PolygonVertexIndex array) */\n globalIndex: number;\n}\n\nfunction buildPolygonVertexList(polygons: Polygon[]): PolyVertex[] {\n const list: PolyVertex[] = [];\n for (let pi = 0; pi < polygons.length; pi++) {\n const poly = polygons[pi];\n for (let vi = 0; vi < poly.indices.length; vi++) {\n list.push({\n polyIndex: pi,\n vertexInPoly: vi,\n controlPointIndex: poly.indices[vi],\n globalIndex: poly.startIndex + vi,\n });\n }\n }\n return list;\n}\n\n// ── Layer Element Expansion ────────────────────────────────────────────────────\n\n/**\n * Extract per-polygon material indices from LayerElementMaterial.\n * Returns an Int32Array with one material index per polygon.\n */\nfunction extractMaterialIndices(matNode: FBXNode, polygonCount: number): Int32Array | null {\n const mappingNode = findChildByName(matNode, \"MappingInformationType\");\n const referenceNode = findChildByName(matNode, \"ReferenceInformationType\");\n\n if (!mappingNode || !referenceNode) {\n return null;\n }\n\n const mapping = getPropertyValue<string>(mappingNode, 0) ?? \"\";\n const reference = getPropertyValue<string>(referenceNode, 0) ?? \"\";\n\n if (mapping === \"AllSame\") {\n const materialsNode = findChildByName(matNode, \"Materials\");\n const rawIndices = materialsNode ? toInt32Array(getNodeArrayValue(materialsNode)) : null;\n const materialIndex = rawIndices && rawIndices.length > 0 ? rawIndices[0] : 0;\n const indices = new Int32Array(polygonCount);\n if (materialIndex !== 0) {\n indices.fill(materialIndex);\n }\n return indices;\n }\n\n if (mapping === \"ByPolygon\") {\n const materialsNode = findChildByName(matNode, \"Materials\");\n if (!materialsNode) {\n return null;\n }\n const rawIndices = toInt32Array(getNodeArrayValue(materialsNode));\n // For Direct reference, the Materials array has one index per polygon\n if (reference === \"Direct\" || reference === \"IndexToDirect\") {\n return rawIndices;\n }\n }\n\n return null;\n}\n\nfunction expandLayerElement(\n layerNode: FBXNode,\n dataChildName: string,\n indexChildName: string,\n polyVertexList: PolyVertex[],\n controlPointCount: number,\n stride: number,\n diagnostics: FBXGeometryDiagnostic[]\n): Float64Array | null {\n const mappingNode = findChildByName(layerNode, \"MappingInformationType\");\n const referenceNode = findChildByName(layerNode, \"ReferenceInformationType\");\n\n if (!mappingNode || !referenceNode) {\n return null;\n }\n\n const mapping = getPropertyValue<string>(mappingNode, 0) ?? \"\";\n const reference = getPropertyValue<string>(referenceNode, 0) ?? \"\";\n\n const dataNode = findChildByName(layerNode, dataChildName);\n if (!dataNode) {\n return null;\n }\n const data = toFloat64Array(getNodeArrayValue(dataNode));\n\n let indexData: Int32Array | null = null;\n if (reference === \"IndexToDirect\") {\n const indexNode = findChildByName(layerNode, indexChildName);\n if (indexNode) {\n indexData = toInt32Array(getNodeArrayValue(indexNode));\n }\n }\n\n // Expand to per-polygon-vertex\n const result = new Float64Array(polyVertexList.length * stride);\n\n for (let i = 0; i < polyVertexList.length; i++) {\n const pv = polyVertexList[i];\n let dataIndex: number;\n\n if (mapping === \"ByPolygonVertex\") {\n if (reference === \"IndexToDirect\" && indexData) {\n dataIndex = indexData[pv.globalIndex];\n } else {\n // Direct\n dataIndex = pv.globalIndex;\n }\n } else if (mapping === \"ByControlPoint\" || mapping === \"ByVertice\") {\n if (reference === \"IndexToDirect\" && indexData) {\n dataIndex = indexData[pv.controlPointIndex];\n } else {\n dataIndex = pv.controlPointIndex;\n }\n } else if (mapping === \"ByPolygon\") {\n if (reference === \"IndexToDirect\" && indexData) {\n dataIndex = indexData[pv.polyIndex];\n } else {\n dataIndex = pv.polyIndex;\n }\n } else if (mapping === \"AllSame\") {\n dataIndex = 0;\n } else {\n dataIndex = pv.globalIndex;\n }\n\n for (let s = 0; s < stride; s++) {\n const sourceIndex = dataIndex * stride + s;\n if (dataIndex < 0 || sourceIndex >= data.length) {\n diagnostics.push({\n type: sourceIndex >= data.length ? \"layer-data-too-short\" : \"layer-index-out-of-bounds\",\n message: `Layer '${layerNode.name}' references unavailable element ${dataIndex}.`,\n layerName: layerNode.name,\n index: dataIndex,\n });\n result[i * stride + s] = 0;\n } else {\n result[i * stride + s] = data[sourceIndex];\n }\n }\n }\n\n return result;\n}\n\nfunction expandTangentLayer(\n tangentNode: FBXNode,\n polyVertexList: PolyVertex[],\n controlPointCount: number,\n normals: Float64Array | null,\n binormals: Float64Array | null,\n diagnostics: FBXGeometryDiagnostic[]\n): Float64Array | null {\n const sourceStride = inferLayerElementStride(tangentNode, \"Tangents\", \"TangentsIndex\", polyVertexList, controlPointCount, diagnostics);\n const expanded = expandLayerElement(tangentNode, \"Tangents\", \"TangentsIndex\", polyVertexList, controlPointCount, sourceStride, diagnostics);\n if (!expanded) {\n return null;\n }\n\n const tangents = new Float64Array(polyVertexList.length * 4);\n for (let i = 0; i < polyVertexList.length; i++) {\n const sourceOffset = i * sourceStride;\n const destOffset = i * 4;\n tangents[destOffset] = expanded[sourceOffset];\n tangents[destOffset + 1] = expanded[sourceOffset + 1];\n tangents[destOffset + 2] = expanded[sourceOffset + 2];\n tangents[destOffset + 3] = sourceStride >= 4 ? expanded[sourceOffset + 3] : computeTangentHandedness(i, tangents, normals, binormals);\n }\n return tangents;\n}\n\nfunction inferLayerElementStride(\n layerNode: FBXNode,\n dataChildName: string,\n indexChildName: string,\n polyVertexList: PolyVertex[],\n controlPointCount: number,\n diagnostics: FBXGeometryDiagnostic[]\n): number {\n const dataNode = findChildByName(layerNode, dataChildName);\n if (!dataNode) {\n return 3;\n }\n const data = toFloat64Array(getNodeArrayValue(dataNode));\n const mapping = getPropertyValue<string>(findChildByName(layerNode, \"MappingInformationType\") ?? { name: \"\", properties: [], children: [] }, 0) ?? \"\";\n const reference = getPropertyValue<string>(findChildByName(layerNode, \"ReferenceInformationType\") ?? { name: \"\", properties: [], children: [] }, 0) ?? \"\";\n const indexNode = findChildByName(layerNode, indexChildName);\n const indexData = indexNode ? toInt32Array(getNodeArrayValue(indexNode)) : null;\n const directCount =\n reference === \"IndexToDirect\" && indexData\n ? Math.max(...Array.from(indexData), 0) + 1\n : mapping === \"ByControlPoint\" || mapping === \"ByVertice\"\n ? controlPointCount\n : mapping === \"AllSame\"\n ? 1\n : polyVertexList.length;\n\n if (directCount > 0 && data.length % directCount === 0) {\n const stride = data.length / directCount;\n if (stride === 3 || stride === 4) {\n return stride;\n }\n }\n\n diagnostics.push({\n type: \"layer-data-too-short\",\n message: `Could not infer stride for layer '${layerNode.name}', defaulting to 3.`,\n layerName: layerNode.name,\n });\n return 3;\n}\n\nfunction computeTangentHandedness(vertexIndex: number, tangents: Float64Array, normals: Float64Array | null, binormals: Float64Array | null): number {\n if (!normals || !binormals) {\n return 1;\n }\n const to = vertexIndex * 4;\n const no = vertexIndex * 3;\n const nx = normals[no];\n const ny = normals[no + 1];\n const nz = normals[no + 2];\n const tx = tangents[to];\n const ty = tangents[to + 1];\n const tz = tangents[to + 2];\n const bx = binormals[no];\n const by = binormals[no + 1];\n const bz = binormals[no + 2];\n const cx = ny * tz - nz * ty;\n const cy = nz * tx - nx * tz;\n const cz = nx * ty - ny * tx;\n return cx * bx + cy * by + cz * bz < 0 ? -1 : 1;\n}\n\n// ── Final Mesh Assembly ────────────────────────────────────────────────────────\n\ninterface TriangleMeshData {\n positions: Float64Array;\n indices: Uint32Array;\n normals: Float64Array | null;\n uvs: Float64Array | null;\n uvSets: FBXUVSet[];\n colors: Float32Array | null;\n tangents: Float64Array | null;\n binormals: Float64Array | null;\n controlPointIndices: Uint32Array;\n}\n\n/**\n * Build the final triangle mesh. Since normals/UVs are per-polygon-vertex,\n * we need to create unique vertices for each polygon-vertex combination.\n */\nfunction buildTriangleMesh(\n rawPositions: Float64Array,\n triangles: Triangle[],\n polyVertexList: PolyVertex[],\n expandedNormals: Float64Array | null,\n expandedUVs: Float64Array | null,\n expandedUVSets: FBXUVSet[],\n expandedColors: Float32Array | null,\n expandedTangents: Float64Array | null,\n expandedBinormals: Float64Array | null\n): TriangleMeshData {\n // FBX stores every attribute per polygon-vertex. Polygon-vertices that share the control point and all attribute\n // values are welded into one output vertex (this is what every DCC does on import); polygon-vertices that differ\n // in any attribute (hard edges, UV seams) stay separate. Skinning and blend shapes index by control point, so\n // welding is transparent to them.\n const polyVertexCount = polyVertexList.length;\n const remap = new Uint32Array(polyVertexCount);\n const unique: number[] = [];\n const keyToIndex = new Map<string, number>();\n const uvSetCount = expandedUVSets.length;\n for (let i = 0; i < polyVertexCount; i++) {\n let key = String(polyVertexList[i].controlPointIndex);\n if (expandedNormals) {\n key += `|${expandedNormals[i * 3]},${expandedNormals[i * 3 + 1]},${expandedNormals[i * 3 + 2]}`;\n }\n for (let u = 0; u < uvSetCount; u++) {\n const d = expandedUVSets[u].data;\n key += `|${d[i * 2]},${d[i * 2 + 1]}`;\n }\n if (expandedColors) {\n key += `|${expandedColors[i * 4]},${expandedColors[i * 4 + 1]},${expandedColors[i * 4 + 2]},${expandedColors[i * 4 + 3]}`;\n }\n if (expandedTangents) {\n key += `|${expandedTangents[i * 4]},${expandedTangents[i * 4 + 1]},${expandedTangents[i * 4 + 2]},${expandedTangents[i * 4 + 3]}`;\n }\n let index = keyToIndex.get(key);\n if (index === undefined) {\n index = unique.length;\n keyToIndex.set(key, index);\n unique.push(i);\n }\n remap[i] = index;\n }\n\n const vertexCount = unique.length;\n const positions = new Float64Array(vertexCount * 3);\n const controlPointIndices = new Uint32Array(vertexCount);\n const gather = (src: Float64Array | Float32Array | null, stride: number, ctor: typeof Float64Array | typeof Float32Array) => {\n if (!src) {\n return null;\n }\n const out = new ctor(vertexCount * stride);\n for (let v = 0; v < vertexCount; v++) {\n const srcIndex = unique[v] * stride;\n for (let k = 0; k < stride; k++) {\n out[v * stride + k] = src[srcIndex + k];\n }\n }\n return out;\n };\n\n // Positions come from control points — keep in original RH space (root node handles RH→LH conversion)\n for (let v = 0; v < vertexCount; v++) {\n const cp = polyVertexList[unique[v]].controlPointIndex;\n positions[v * 3] = rawPositions[cp * 3];\n positions[v * 3 + 1] = rawPositions[cp * 3 + 1];\n positions[v * 3 + 2] = rawPositions[cp * 3 + 2];\n controlPointIndices[v] = cp;\n }\n\n // Keep original winding order — Z negation handles handedness\n const indexCount = triangles.length * 3;\n const indices = new Uint32Array(indexCount);\n for (let i = 0; i < triangles.length; i++) {\n indices[i * 3] = remap[triangles[i].vertices[0]];\n indices[i * 3 + 1] = remap[triangles[i].vertices[1]];\n indices[i * 3 + 2] = remap[triangles[i].vertices[2]];\n }\n\n const uvSets: FBXUVSet[] = expandedUVSets.map((set) => ({ name: set.name, data: gather(set.data, 2, Float64Array) as Float64Array }));\n\n return {\n positions,\n indices,\n normals: gather(expandedNormals, 3, Float64Array) as Float64Array | null,\n uvs: uvSets.length > 0 ? uvSets[0].data : (gather(expandedUVs, 2, Float64Array) as Float64Array | null),\n uvSets,\n colors: gather(expandedColors, 4, Float32Array) as Float32Array | null,\n tangents: gather(expandedTangents, 4, Float64Array) as Float64Array | null,\n binormals: gather(expandedBinormals, 3, Float64Array) as Float64Array | null,\n controlPointIndices,\n };\n}\n\n// ── Utilities ──────────────────────────────────────────────────────────────────\n\nfunction toFloat64Array(value: unknown): Float64Array {\n if (value instanceof Float64Array) {\n return value;\n }\n if (value instanceof Float32Array) {\n return new Float64Array(value);\n }\n if (value instanceof Int32Array || value instanceof Uint8Array) {\n return new Float64Array(value);\n }\n if (Array.isArray(value)) {\n const result = new Float64Array(value.length);\n for (let i = 0; i < value.length; i++) {\n result[i] = Number(value[i]);\n }\n return result;\n }\n throw new Error(`Cannot convert ${typeof value} to Float64Array`);\n}\n\nfunction toInt32Array(value: unknown): Int32Array {\n if (value instanceof Int32Array) {\n return value;\n }\n if (value instanceof Float64Array) {\n const result = new Int32Array(value.length);\n for (let i = 0; i < value.length; i++) {\n result[i] = Math.round(value[i]);\n }\n return result;\n }\n if (value instanceof Float32Array || value instanceof Uint8Array) {\n const result = new Int32Array(value.length);\n for (let i = 0; i < value.length; i++) {\n result[i] = Math.round(value[i]);\n }\n return result;\n }\n if (Array.isArray(value)) {\n const result = new Int32Array(value.length);\n for (let i = 0; i < value.length; i++) {\n result[i] = Math.round(Number(value[i]));\n }\n return result;\n }\n throw new Error(`Cannot convert ${typeof value} to Int32Array`);\n}\n\nfunction getNodeArrayValue(node: FBXNode): unknown {\n return getNodeArray(node) ?? new Float64Array(0);\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FBX 5.x (and older) documents store everything at the top level: one `Model` node per object with inline
|
|
3
|
+
* geometry, materials, skin links, lights and cameras, and `Children` lists instead of connections. This module
|
|
4
|
+
* rewrites such a document into the 6.x layout (`Objects`, `Connections`, `Takes`) so the rest of the importer
|
|
5
|
+
* can treat both the same way. The rules follow the FBX SDK's legacy reader as implemented by ufbx.
|
|
6
|
+
*/
|
|
7
|
+
import { type FBXDocument } from "../types/fbxTypes.js";
|
|
8
|
+
/** True for pre-6000 files: no `Objects` section but top-level `Model` nodes. */
|
|
9
|
+
export declare function isLegacyDocument(doc: FBXDocument): boolean;
|
|
10
|
+
/** Rewrites a legacy document into the 6.x object/connection layout. */
|
|
11
|
+
export declare function upgradeLegacyDocument(doc: FBXDocument): FBXDocument;
|