@babylonjs/loaders 9.12.0 → 9.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/FBX/fbxFileLoader.d.ts +194 -0
  2. package/FBX/fbxFileLoader.js +2440 -0
  3. package/FBX/fbxFileLoader.js.map +1 -0
  4. package/FBX/fbxFileLoader.metadata.d.ts +11 -0
  5. package/FBX/fbxFileLoader.metadata.js +11 -0
  6. package/FBX/fbxFileLoader.metadata.js.map +1 -0
  7. package/FBX/index.d.ts +3 -0
  8. package/FBX/index.js +3 -0
  9. package/FBX/index.js.map +1 -0
  10. package/FBX/interpreter/animation.d.ts +122 -0
  11. package/FBX/interpreter/animation.js +648 -0
  12. package/FBX/interpreter/animation.js.map +1 -0
  13. package/FBX/interpreter/blendShapes.d.ts +44 -0
  14. package/FBX/interpreter/blendShapes.js +192 -0
  15. package/FBX/interpreter/blendShapes.js.map +1 -0
  16. package/FBX/interpreter/connections.d.ts +95 -0
  17. package/FBX/interpreter/connections.js +233 -0
  18. package/FBX/interpreter/connections.js.map +1 -0
  19. package/FBX/interpreter/fbxInterpreter.d.ts +149 -0
  20. package/FBX/interpreter/fbxInterpreter.js +496 -0
  21. package/FBX/interpreter/fbxInterpreter.js.map +1 -0
  22. package/FBX/interpreter/geometry.d.ts +55 -0
  23. package/FBX/interpreter/geometry.js +573 -0
  24. package/FBX/interpreter/geometry.js.map +1 -0
  25. package/FBX/interpreter/materials.d.ts +50 -0
  26. package/FBX/interpreter/materials.js +144 -0
  27. package/FBX/interpreter/materials.js.map +1 -0
  28. package/FBX/interpreter/propertyTemplates.d.ts +22 -0
  29. package/FBX/interpreter/propertyTemplates.js +125 -0
  30. package/FBX/interpreter/propertyTemplates.js.map +1 -0
  31. package/FBX/interpreter/rig.d.ts +20 -0
  32. package/FBX/interpreter/rig.js +259 -0
  33. package/FBX/interpreter/rig.js.map +1 -0
  34. package/FBX/interpreter/sceneDiagnostics.d.ts +14 -0
  35. package/FBX/interpreter/sceneDiagnostics.js +55 -0
  36. package/FBX/interpreter/sceneDiagnostics.js.map +1 -0
  37. package/FBX/interpreter/skeleton.d.ts +93 -0
  38. package/FBX/interpreter/skeleton.js +515 -0
  39. package/FBX/interpreter/skeleton.js.map +1 -0
  40. package/FBX/interpreter/transform.d.ts +21 -0
  41. package/FBX/interpreter/transform.js +92 -0
  42. package/FBX/interpreter/transform.js.map +1 -0
  43. package/FBX/parsers/fbxAsciiParser.d.ts +5 -0
  44. package/FBX/parsers/fbxAsciiParser.js +330 -0
  45. package/FBX/parsers/fbxAsciiParser.js.map +1 -0
  46. package/FBX/parsers/fbxBinaryParser.d.ts +6 -0
  47. package/FBX/parsers/fbxBinaryParser.js +255 -0
  48. package/FBX/parsers/fbxBinaryParser.js.map +1 -0
  49. package/FBX/parsers/zlibInflate.d.ts +7 -0
  50. package/FBX/parsers/zlibInflate.js +350 -0
  51. package/FBX/parsers/zlibInflate.js.map +1 -0
  52. package/FBX/types/fbxTypes.d.ts +54 -0
  53. package/FBX/types/fbxTypes.js +66 -0
  54. package/FBX/types/fbxTypes.js.map +1 -0
  55. package/SPLAT/gaussianSplattingStream.d.ts +341 -0
  56. package/SPLAT/gaussianSplattingStream.js +976 -0
  57. package/SPLAT/gaussianSplattingStream.js.map +1 -0
  58. package/SPLAT/gaussianSplattingWorkBuffer.d.ts +51 -0
  59. package/SPLAT/gaussianSplattingWorkBuffer.js +159 -0
  60. package/SPLAT/gaussianSplattingWorkBuffer.js.map +1 -0
  61. package/SPLAT/gaussianSplattingWorkBufferShaders.d.ts +25 -0
  62. package/SPLAT/gaussianSplattingWorkBufferShaders.js +255 -0
  63. package/SPLAT/gaussianSplattingWorkBufferShaders.js.map +1 -0
  64. package/SPLAT/index.d.ts +1 -0
  65. package/SPLAT/index.js +1 -0
  66. package/SPLAT/index.js.map +1 -1
  67. package/SPLAT/sog.js +18 -16
  68. package/SPLAT/sog.js.map +1 -1
  69. package/SPLAT/splatFileLoader.d.ts +8 -0
  70. package/SPLAT/splatFileLoader.js +49 -0
  71. package/SPLAT/splatFileLoader.js.map +1 -1
  72. package/dynamic.js +9 -0
  73. package/dynamic.js.map +1 -1
  74. package/index.d.ts +1 -0
  75. package/index.js +1 -0
  76. package/index.js.map +1 -1
  77. package/package.json +3 -3
@@ -0,0 +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"]}
@@ -0,0 +1,50 @@
1
+ import { type FBXNode } from "../types/fbxTypes.js";
2
+ import { type FBXObjectMap } from "./connections.js";
3
+ import { type FBXPropertyTemplateMap } from "./propertyTemplates.js";
4
+ /** Parsed material data */
5
+ export interface FBXMaterialData {
6
+ id: number;
7
+ name: string;
8
+ type: "Lambert" | "Phong";
9
+ properties: FBXMaterialProperties;
10
+ textures: FBXTextureRef[];
11
+ }
12
+ export interface FBXMaterialProperties {
13
+ diffuseColor?: [number, number, number];
14
+ diffuseFactor?: number;
15
+ ambientColor?: [number, number, number];
16
+ ambientFactor?: number;
17
+ specularColor?: [number, number, number];
18
+ specularFactor?: number;
19
+ shininess?: number;
20
+ emissiveColor?: [number, number, number];
21
+ emissiveFactor?: number;
22
+ opacity?: number;
23
+ transparencyFactor?: number;
24
+ }
25
+ export interface FBXTextureRef {
26
+ /** Which material property this texture is connected to */
27
+ propertyName: string;
28
+ /** Absolute file path from the FBX */
29
+ fileName: string;
30
+ /** Relative file path from the FBX */
31
+ relativeFileName: string;
32
+ /** Texture node ID */
33
+ id: number;
34
+ /** Embedded texture data (from Video node Content), if available */
35
+ embeddedData: Uint8Array | null;
36
+ /** UV translation [u, v] */
37
+ uvTranslation?: [number, number];
38
+ /** UV scaling [u, v] */
39
+ uvScaling?: [number, number];
40
+ /** UV rotation in degrees */
41
+ uvRotation?: number;
42
+ /** Which UV set index this texture uses */
43
+ uvSetIndex?: number;
44
+ /** Which named UV set this texture uses */
45
+ uvSetName?: string;
46
+ }
47
+ /**
48
+ * Extract material data from an FBX Material node.
49
+ */
50
+ export declare function extractMaterial(materialNode: FBXNode, materialId: number, objectMap: FBXObjectMap, templates?: FBXPropertyTemplateMap): FBXMaterialData;
@@ -0,0 +1,144 @@
1
+ /* eslint-disable @typescript-eslint/naming-convention, jsdoc/require-param, jsdoc/require-returns */
2
+ import { findChildByName, getPropertyValue, cleanFBXName } from "../types/fbxTypes.js";
3
+ import { getChildren } from "./connections.js";
4
+ import { getPropertyTemplate, resolvePropertyValue, resolvePropertyValues } from "./propertyTemplates.js";
5
+ /**
6
+ * Extract material data from an FBX Material node.
7
+ */
8
+ export function extractMaterial(materialNode, materialId, objectMap, templates) {
9
+ const name = cleanFBXName(getPropertyValue(materialNode, 1) ?? "Material");
10
+ const template = getMaterialTemplate(materialNode, templates);
11
+ // Determine Lambert vs Phong from ShadingModel property
12
+ const shadingModel = findChildByName(materialNode, "ShadingModel");
13
+ const shadingType = shadingModel
14
+ ? (getPropertyValue(shadingModel, 0) ?? "Lambert")
15
+ : (resolvePropertyValue(materialNode, template, "ShadingModel") ?? "Lambert");
16
+ const type = shadingType.toLowerCase() === "phong" ? "Phong" : "Lambert";
17
+ // Extract properties from Properties70
18
+ const properties = extractMaterialProperties(materialNode, template);
19
+ // Find connected textures
20
+ const textureTemplate = templates ? (getPropertyTemplate(templates, "Texture", "FbxFileTexture") ?? getPropertyTemplate(templates, "Texture")) : undefined;
21
+ const textures = extractTextures(materialId, objectMap, textureTemplate);
22
+ return { id: materialId, name, type, properties, textures };
23
+ }
24
+ function extractMaterialProperties(materialNode, template) {
25
+ const props = {};
26
+ props.diffuseColor = getColorProperty(materialNode, template, "DiffuseColor") ?? getColorProperty(materialNode, template, "Diffuse");
27
+ props.diffuseFactor = getNumberProperty(materialNode, template, "DiffuseFactor");
28
+ props.ambientColor = getColorProperty(materialNode, template, "AmbientColor") ?? getColorProperty(materialNode, template, "Ambient");
29
+ props.ambientFactor = getNumberProperty(materialNode, template, "AmbientFactor");
30
+ props.specularColor = getColorProperty(materialNode, template, "SpecularColor") ?? getColorProperty(materialNode, template, "Specular");
31
+ props.specularFactor = getNumberProperty(materialNode, template, "SpecularFactor");
32
+ props.shininess = getNumberProperty(materialNode, template, "Shininess") ?? getNumberProperty(materialNode, template, "ShininessExponent");
33
+ props.emissiveColor = getColorProperty(materialNode, template, "EmissiveColor") ?? getColorProperty(materialNode, template, "Emissive");
34
+ props.emissiveFactor = getNumberProperty(materialNode, template, "EmissiveFactor");
35
+ props.opacity = getNumberProperty(materialNode, template, "Opacity");
36
+ props.transparencyFactor = getNumberProperty(materialNode, template, "TransparencyFactor");
37
+ return props;
38
+ }
39
+ function extractTextures(materialId, objectMap, template) {
40
+ const textures = [];
41
+ const textureChildren = getChildren(objectMap, materialId, "Texture");
42
+ for (const { id, node, propertyName } of textureChildren) {
43
+ const fileNameNode = findChildByName(node, "FileName");
44
+ const relFileNameNode = findChildByName(node, "RelativeFilename");
45
+ const fileName = fileNameNode ? (getPropertyValue(fileNameNode, 0) ?? "") : "";
46
+ const relativeFileName = relFileNameNode ? (getPropertyValue(relFileNameNode, 0) ?? "") : "";
47
+ // Extract UV transform properties
48
+ let uvTranslation;
49
+ let uvScaling;
50
+ const uvRotation = getNumberProperty(node, template, "UVRotation") ?? getNumberProperty(node, template, "Rotation");
51
+ let uvSetName;
52
+ uvTranslation = getTextureVector2(node, template, "UVTranslation") ?? getTextureVector2(node, template, "Translation");
53
+ uvScaling = getTextureVector2(node, template, "UVScaling") ?? getTextureVector2(node, template, "Scaling");
54
+ const uvSet = resolvePropertyValue(node, template, "UVSet");
55
+ if (uvSet && uvSet.length > 0) {
56
+ uvSetName = uvSet;
57
+ }
58
+ uvTranslation ?? (uvTranslation = getNumberPairChild(node, "ModelUVTranslation"));
59
+ uvScaling ?? (uvScaling = getNumberPairChild(node, "ModelUVScaling"));
60
+ // Check for embedded texture data in connected Video node
61
+ let embeddedData = null;
62
+ const videoChildren = getChildren(objectMap, id, "Video");
63
+ for (const { node: videoNode } of videoChildren) {
64
+ const contentNode = findChildByName(videoNode, "Content");
65
+ if (contentNode && contentNode.properties.length > 0) {
66
+ const content = contentNode.properties[0].value;
67
+ if (content instanceof Uint8Array && content.length > 0) {
68
+ embeddedData = content;
69
+ }
70
+ else if (content instanceof ArrayBuffer && content.byteLength > 0) {
71
+ embeddedData = new Uint8Array(content);
72
+ }
73
+ }
74
+ }
75
+ textures.push({
76
+ propertyName: propertyName ?? "DiffuseColor",
77
+ fileName,
78
+ relativeFileName,
79
+ id,
80
+ embeddedData,
81
+ uvTranslation,
82
+ uvScaling,
83
+ uvRotation,
84
+ uvSetName,
85
+ });
86
+ }
87
+ return textures;
88
+ }
89
+ // ── Helpers ────────────────────────────────────────────────────────────────────
90
+ function getMaterialTemplate(materialNode, templates) {
91
+ if (!templates) {
92
+ return undefined;
93
+ }
94
+ const shadingModel = findChildByName(materialNode, "ShadingModel");
95
+ const shadingType = shadingModel ? getPropertyValue(shadingModel, 0) : undefined;
96
+ if (shadingType?.toLowerCase() === "phong") {
97
+ return getPropertyTemplate(templates, "Material", "FbxSurfacePhong") ?? getPropertyTemplate(templates, "Material");
98
+ }
99
+ if (shadingType?.toLowerCase() === "lambert") {
100
+ return getPropertyTemplate(templates, "Material", "FbxSurfaceLambert") ?? getPropertyTemplate(templates, "Material");
101
+ }
102
+ return getPropertyTemplate(templates, "Material");
103
+ }
104
+ function getColorProperty(node, template, propertyName) {
105
+ const values = resolvePropertyValues(node, template, propertyName);
106
+ if (!values || values.length < 3) {
107
+ return undefined;
108
+ }
109
+ const r = toNumber(values[0]);
110
+ const g = toNumber(values[1]);
111
+ const b = toNumber(values[2]);
112
+ if (r === undefined || g === undefined || b === undefined) {
113
+ return undefined;
114
+ }
115
+ return [r, g, b];
116
+ }
117
+ function getNumberProperty(node, template, propertyName) {
118
+ return toNumber(resolvePropertyValue(node, template, propertyName));
119
+ }
120
+ function getTextureVector2(node, template, propertyName) {
121
+ const values = resolvePropertyValues(node, template, propertyName);
122
+ if (!values) {
123
+ return undefined;
124
+ }
125
+ const u = toNumber(values[0]);
126
+ const v = toNumber(values[1]);
127
+ return u !== undefined && v !== undefined ? [u, v] : undefined;
128
+ }
129
+ function toNumber(value) {
130
+ if (typeof value === "number") {
131
+ return value;
132
+ }
133
+ return undefined;
134
+ }
135
+ function getNumberPairChild(node, childName) {
136
+ const child = findChildByName(node, childName);
137
+ if (!child) {
138
+ return undefined;
139
+ }
140
+ const u = toNumber(child.properties[0]?.value);
141
+ const v = toNumber(child.properties[1]?.value);
142
+ return u !== undefined && v !== undefined ? [u, v] : undefined;
143
+ }
144
+ //# sourceMappingURL=materials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"materials.js","sourceRoot":"","sources":["../../../../../dev/loaders/src/FBX/interpreter/materials.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, getPropertyValue, cleanFBXName } from \"../types/fbxTypes\";\r\n\r\nimport { type FBXObjectMap, getChildren } from \"./connections\";\r\n\r\nimport { getPropertyTemplate, resolvePropertyValue, resolvePropertyValues, type FBXPropertyTemplate, type FBXPropertyTemplateMap } from \"./propertyTemplates\";\r\n\r\n/** Parsed material data */\r\nexport interface FBXMaterialData {\r\n id: number;\r\n name: string;\r\n type: \"Lambert\" | \"Phong\";\r\n properties: FBXMaterialProperties;\r\n textures: FBXTextureRef[];\r\n}\r\n\r\nexport interface FBXMaterialProperties {\r\n diffuseColor?: [number, number, number];\r\n diffuseFactor?: number;\r\n ambientColor?: [number, number, number];\r\n ambientFactor?: number;\r\n specularColor?: [number, number, number];\r\n specularFactor?: number;\r\n shininess?: number;\r\n emissiveColor?: [number, number, number];\r\n emissiveFactor?: number;\r\n opacity?: number;\r\n transparencyFactor?: number;\r\n}\r\n\r\nexport interface FBXTextureRef {\r\n /** Which material property this texture is connected to */\r\n propertyName: string;\r\n /** Absolute file path from the FBX */\r\n fileName: string;\r\n /** Relative file path from the FBX */\r\n relativeFileName: string;\r\n /** Texture node ID */\r\n id: number;\r\n /** Embedded texture data (from Video node Content), if available */\r\n embeddedData: Uint8Array | null;\r\n /** UV translation [u, v] */\r\n uvTranslation?: [number, number];\r\n /** UV scaling [u, v] */\r\n uvScaling?: [number, number];\r\n /** UV rotation in degrees */\r\n uvRotation?: number;\r\n /** Which UV set index this texture uses */\r\n uvSetIndex?: number;\r\n /** Which named UV set this texture uses */\r\n uvSetName?: string;\r\n}\r\n\r\n/**\r\n * Extract material data from an FBX Material node.\r\n */\r\nexport function extractMaterial(materialNode: FBXNode, materialId: number, objectMap: FBXObjectMap, templates?: FBXPropertyTemplateMap): FBXMaterialData {\r\n const name = cleanFBXName(getPropertyValue<string>(materialNode, 1) ?? \"Material\");\r\n const template = getMaterialTemplate(materialNode, templates);\r\n\r\n // Determine Lambert vs Phong from ShadingModel property\r\n const shadingModel = findChildByName(materialNode, \"ShadingModel\");\r\n const shadingType = shadingModel\r\n ? (getPropertyValue<string>(shadingModel, 0) ?? \"Lambert\")\r\n : (resolvePropertyValue<string>(materialNode, template, \"ShadingModel\") ?? \"Lambert\");\r\n const type: \"Lambert\" | \"Phong\" = shadingType.toLowerCase() === \"phong\" ? \"Phong\" : \"Lambert\";\r\n\r\n // Extract properties from Properties70\r\n const properties = extractMaterialProperties(materialNode, template);\r\n\r\n // Find connected textures\r\n const textureTemplate = templates ? (getPropertyTemplate(templates, \"Texture\", \"FbxFileTexture\") ?? getPropertyTemplate(templates, \"Texture\")) : undefined;\r\n const textures = extractTextures(materialId, objectMap, textureTemplate);\r\n\r\n return { id: materialId, name, type, properties, textures };\r\n}\r\n\r\nfunction extractMaterialProperties(materialNode: FBXNode, template?: FBXPropertyTemplate): FBXMaterialProperties {\r\n const props: FBXMaterialProperties = {};\r\n props.diffuseColor = getColorProperty(materialNode, template, \"DiffuseColor\") ?? getColorProperty(materialNode, template, \"Diffuse\");\r\n props.diffuseFactor = getNumberProperty(materialNode, template, \"DiffuseFactor\");\r\n props.ambientColor = getColorProperty(materialNode, template, \"AmbientColor\") ?? getColorProperty(materialNode, template, \"Ambient\");\r\n props.ambientFactor = getNumberProperty(materialNode, template, \"AmbientFactor\");\r\n props.specularColor = getColorProperty(materialNode, template, \"SpecularColor\") ?? getColorProperty(materialNode, template, \"Specular\");\r\n props.specularFactor = getNumberProperty(materialNode, template, \"SpecularFactor\");\r\n props.shininess = getNumberProperty(materialNode, template, \"Shininess\") ?? getNumberProperty(materialNode, template, \"ShininessExponent\");\r\n props.emissiveColor = getColorProperty(materialNode, template, \"EmissiveColor\") ?? getColorProperty(materialNode, template, \"Emissive\");\r\n props.emissiveFactor = getNumberProperty(materialNode, template, \"EmissiveFactor\");\r\n props.opacity = getNumberProperty(materialNode, template, \"Opacity\");\r\n props.transparencyFactor = getNumberProperty(materialNode, template, \"TransparencyFactor\");\r\n\r\n return props;\r\n}\r\n\r\nfunction extractTextures(materialId: number, objectMap: FBXObjectMap, template?: FBXPropertyTemplate): FBXTextureRef[] {\r\n const textures: FBXTextureRef[] = [];\r\n const textureChildren = getChildren(objectMap, materialId, \"Texture\");\r\n\r\n for (const { id, node, propertyName } of textureChildren) {\r\n const fileNameNode = findChildByName(node, \"FileName\");\r\n const relFileNameNode = findChildByName(node, \"RelativeFilename\");\r\n\r\n const fileName = fileNameNode ? (getPropertyValue<string>(fileNameNode, 0) ?? \"\") : \"\";\r\n const relativeFileName = relFileNameNode ? (getPropertyValue<string>(relFileNameNode, 0) ?? \"\") : \"\";\r\n\r\n // Extract UV transform properties\r\n let uvTranslation: [number, number] | undefined;\r\n let uvScaling: [number, number] | undefined;\r\n const uvRotation = getNumberProperty(node, template, \"UVRotation\") ?? getNumberProperty(node, template, \"Rotation\");\r\n let uvSetName: string | undefined;\r\n uvTranslation = getTextureVector2(node, template, \"UVTranslation\") ?? getTextureVector2(node, template, \"Translation\");\r\n uvScaling = getTextureVector2(node, template, \"UVScaling\") ?? getTextureVector2(node, template, \"Scaling\");\r\n const uvSet = resolvePropertyValue<string>(node, template, \"UVSet\");\r\n if (uvSet && uvSet.length > 0) {\r\n uvSetName = uvSet;\r\n }\r\n uvTranslation ??= getNumberPairChild(node, \"ModelUVTranslation\");\r\n uvScaling ??= getNumberPairChild(node, \"ModelUVScaling\");\r\n\r\n // Check for embedded texture data in connected Video node\r\n let embeddedData: Uint8Array | null = null;\r\n const videoChildren = getChildren(objectMap, id, \"Video\");\r\n for (const { node: videoNode } of videoChildren) {\r\n const contentNode = findChildByName(videoNode, \"Content\");\r\n if (contentNode && contentNode.properties.length > 0) {\r\n const content = contentNode.properties[0].value;\r\n if (content instanceof Uint8Array && content.length > 0) {\r\n embeddedData = content;\r\n } else if (content instanceof ArrayBuffer && (content as ArrayBuffer).byteLength > 0) {\r\n embeddedData = new Uint8Array(content as ArrayBuffer);\r\n }\r\n }\r\n }\r\n\r\n textures.push({\r\n propertyName: propertyName ?? \"DiffuseColor\",\r\n fileName,\r\n relativeFileName,\r\n id,\r\n embeddedData,\r\n uvTranslation,\r\n uvScaling,\r\n uvRotation,\r\n uvSetName,\r\n });\r\n }\r\n\r\n return textures;\r\n}\r\n\r\n// ── Helpers ────────────────────────────────────────────────────────────────────\r\n\r\nfunction getMaterialTemplate(materialNode: FBXNode, templates: FBXPropertyTemplateMap | undefined): FBXPropertyTemplate | undefined {\r\n if (!templates) {\r\n return undefined;\r\n }\r\n\r\n const shadingModel = findChildByName(materialNode, \"ShadingModel\");\r\n const shadingType = shadingModel ? getPropertyValue<string>(shadingModel, 0) : undefined;\r\n if (shadingType?.toLowerCase() === \"phong\") {\r\n return getPropertyTemplate(templates, \"Material\", \"FbxSurfacePhong\") ?? getPropertyTemplate(templates, \"Material\");\r\n }\r\n if (shadingType?.toLowerCase() === \"lambert\") {\r\n return getPropertyTemplate(templates, \"Material\", \"FbxSurfaceLambert\") ?? getPropertyTemplate(templates, \"Material\");\r\n }\r\n\r\n return getPropertyTemplate(templates, \"Material\");\r\n}\r\n\r\nfunction getColorProperty(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string): [number, number, number] | undefined {\r\n const values = resolvePropertyValues(node, template, propertyName);\r\n if (!values || values.length < 3) {\r\n return undefined;\r\n }\r\n const r = toNumber(values[0]);\r\n const g = toNumber(values[1]);\r\n const b = toNumber(values[2]);\r\n if (r === undefined || g === undefined || b === undefined) {\r\n return undefined;\r\n }\r\n return [r, g, b];\r\n}\r\n\r\nfunction getNumberProperty(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string): number | undefined {\r\n return toNumber(resolvePropertyValue(node, template, propertyName));\r\n}\r\n\r\nfunction getTextureVector2(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string): [number, number] | undefined {\r\n const values = resolvePropertyValues(node, template, propertyName);\r\n if (!values) {\r\n return undefined;\r\n }\r\n const u = toNumber(values[0]);\r\n const v = toNumber(values[1]);\r\n return u !== undefined && v !== undefined ? [u, v] : undefined;\r\n}\r\n\r\nfunction toNumber(value: unknown): number | undefined {\r\n if (typeof value === \"number\") {\r\n return value;\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction getNumberPairChild(node: FBXNode, childName: string): [number, number] | undefined {\r\n const child = findChildByName(node, childName);\r\n if (!child) {\r\n return undefined;\r\n }\r\n const u = toNumber(child.properties[0]?.value);\r\n const v = toNumber(child.properties[1]?.value);\r\n return u !== undefined && v !== undefined ? [u, v] : undefined;\r\n}\r\n"]}
@@ -0,0 +1,22 @@
1
+ import { type FBXDocument, type FBXNode, type FBXPropertyValue } from "../types/fbxTypes.js";
2
+ export interface FBXTemplateProperty {
3
+ name: string;
4
+ propertyType: string;
5
+ label: string;
6
+ flags: string;
7
+ values: FBXPropertyValue[];
8
+ }
9
+ export interface FBXPropertyTemplate {
10
+ objectType: string;
11
+ templateName: string;
12
+ properties: Map<string, FBXTemplateProperty>;
13
+ }
14
+ export type FBXPropertyTemplateMap = Map<string, Map<string, FBXPropertyTemplate>>;
15
+ export declare function extractPropertyTemplates(doc: FBXDocument): FBXPropertyTemplateMap;
16
+ export declare function getPropertyTemplate(templates: FBXPropertyTemplateMap, objectType: string, templateName?: string): FBXPropertyTemplate | undefined;
17
+ export declare function getTemplatePropertyValue<T extends FBXPropertyValue>(template: FBXPropertyTemplate | undefined, propertyName: string, valueIndex?: number): T | undefined;
18
+ export declare function resolvePropertyValue<T extends FBXPropertyValue>(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string, valueIndex?: number): T | undefined;
19
+ export declare function resolveNumberProperty(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string, fallback: number): number;
20
+ export declare function resolveVector2Property(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string, fallback: [number, number]): [number, number];
21
+ export declare function resolveVector3Property(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string, fallback: [number, number, number]): [number, number, number];
22
+ export declare function resolvePropertyValues(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string): FBXPropertyValue[] | undefined;
@@ -0,0 +1,125 @@
1
+ /* eslint-disable @typescript-eslint/naming-convention, jsdoc/require-param, jsdoc/require-returns */
2
+ import { findChildByName, findDocumentNode, getPropertyValue } from "../types/fbxTypes.js";
3
+ export function extractPropertyTemplates(doc) {
4
+ const templates = new Map();
5
+ const definitions = findDocumentNode(doc, "Definitions");
6
+ if (!definitions) {
7
+ return templates;
8
+ }
9
+ for (const objectTypeNode of definitions.children) {
10
+ if (objectTypeNode.name !== "ObjectType") {
11
+ continue;
12
+ }
13
+ const objectType = getPropertyValue(objectTypeNode, 0);
14
+ if (!objectType) {
15
+ continue;
16
+ }
17
+ for (const templateNode of objectTypeNode.children) {
18
+ if (templateNode.name !== "PropertyTemplate") {
19
+ continue;
20
+ }
21
+ const templateName = getPropertyValue(templateNode, 0);
22
+ if (!templateName) {
23
+ continue;
24
+ }
25
+ const template = extractPropertyTemplate(objectType, templateName, templateNode);
26
+ let templatesByName = templates.get(objectType);
27
+ if (!templatesByName) {
28
+ templatesByName = new Map();
29
+ templates.set(objectType, templatesByName);
30
+ }
31
+ templatesByName.set(templateName, template);
32
+ }
33
+ }
34
+ return templates;
35
+ }
36
+ export function getPropertyTemplate(templates, objectType, templateName) {
37
+ const templatesByName = templates.get(objectType);
38
+ if (!templatesByName) {
39
+ return undefined;
40
+ }
41
+ if (templateName) {
42
+ return templatesByName.get(templateName);
43
+ }
44
+ return templatesByName.values().next().value;
45
+ }
46
+ export function getTemplatePropertyValue(template, propertyName, valueIndex = 0) {
47
+ return template?.properties.get(propertyName)?.values[valueIndex];
48
+ }
49
+ export function resolvePropertyValue(node, template, propertyName, valueIndex = 0) {
50
+ return resolvePropertyValues(node, template, propertyName)?.[valueIndex];
51
+ }
52
+ export function resolveNumberProperty(node, template, propertyName, fallback) {
53
+ return toNumber(resolvePropertyValue(node, template, propertyName)) ?? fallback;
54
+ }
55
+ export function resolveVector2Property(node, template, propertyName, fallback) {
56
+ const values = resolvePropertyValues(node, template, propertyName);
57
+ if (!values) {
58
+ return fallback;
59
+ }
60
+ const x = toNumber(values[0]);
61
+ const y = toNumber(values[1]);
62
+ return x !== undefined && y !== undefined ? [x, y] : fallback;
63
+ }
64
+ export function resolveVector3Property(node, template, propertyName, fallback) {
65
+ const values = resolvePropertyValues(node, template, propertyName);
66
+ if (!values) {
67
+ return fallback;
68
+ }
69
+ const x = toNumber(values[0]);
70
+ const y = toNumber(values[1]);
71
+ const z = toNumber(values[2]);
72
+ return x !== undefined && y !== undefined && z !== undefined ? [x, y, z] : fallback;
73
+ }
74
+ export function resolvePropertyValues(node, template, propertyName) {
75
+ return findLocalPropertyValues(node, propertyName) ?? template?.properties.get(propertyName)?.values;
76
+ }
77
+ function toNumber(value) {
78
+ if (typeof value === "number") {
79
+ return value;
80
+ }
81
+ return undefined;
82
+ }
83
+ function extractPropertyTemplate(objectType, templateName, templateNode) {
84
+ const properties = new Map();
85
+ const properties70 = findChildByName(templateNode, "Properties70");
86
+ for (const propertyNode of properties70?.children ?? []) {
87
+ if (propertyNode.name !== "P") {
88
+ continue;
89
+ }
90
+ const property = extractPropertyNode(propertyNode);
91
+ if (property) {
92
+ properties.set(property.name, property);
93
+ }
94
+ }
95
+ return { objectType, templateName, properties };
96
+ }
97
+ function findLocalPropertyValues(node, propertyName) {
98
+ const propertyContainers = [findChildByName(node, "Properties70"), findChildByName(node, "Properties60")].filter((child) => child !== undefined);
99
+ for (const container of propertyContainers) {
100
+ for (const propertyNode of container.children) {
101
+ if (propertyNode.name !== "P" && propertyNode.name !== "Property") {
102
+ continue;
103
+ }
104
+ if (getPropertyValue(propertyNode, 0) !== propertyName) {
105
+ continue;
106
+ }
107
+ return propertyNode.properties.slice(propertyNode.name === "Property" ? 3 : 4).map((property) => property.value);
108
+ }
109
+ }
110
+ return undefined;
111
+ }
112
+ function extractPropertyNode(node) {
113
+ const name = getPropertyValue(node, 0);
114
+ if (!name) {
115
+ return null;
116
+ }
117
+ return {
118
+ name,
119
+ propertyType: getPropertyValue(node, 1) ?? "",
120
+ label: getPropertyValue(node, 2) ?? "",
121
+ flags: getPropertyValue(node, 3) ?? "",
122
+ values: node.properties.slice(4).map((property) => property.value),
123
+ };
124
+ }
125
+ //# sourceMappingURL=propertyTemplates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"propertyTemplates.js","sourceRoot":"","sources":["../../../../../dev/loaders/src/FBX/interpreter/propertyTemplates.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,OAAO,EAAyD,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAkB/I,MAAM,UAAU,wBAAwB,CAAC,GAAgB;IACrD,MAAM,SAAS,GAA2B,IAAI,GAAG,EAAE,CAAC;IACpD,MAAM,WAAW,GAAG,gBAAgB,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IACzD,IAAI,CAAC,WAAW,EAAE,CAAC;QACf,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,KAAK,MAAM,cAAc,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;QAChD,IAAI,cAAc,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YACvC,SAAS;QACb,CAAC;QAED,MAAM,UAAU,GAAG,gBAAgB,CAAS,cAAc,EAAE,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,UAAU,EAAE,CAAC;YACd,SAAS;QACb,CAAC;QAED,KAAK,MAAM,YAAY,IAAI,cAAc,CAAC,QAAQ,EAAE,CAAC;YACjD,IAAI,YAAY,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBAC3C,SAAS;YACb,CAAC;YAED,MAAM,YAAY,GAAG,gBAAgB,CAAS,YAAY,EAAE,CAAC,CAAC,CAAC;YAC/D,IAAI,CAAC,YAAY,EAAE,CAAC;gBAChB,SAAS;YACb,CAAC;YAED,MAAM,QAAQ,GAAG,uBAAuB,CAAC,UAAU,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;YACjF,IAAI,eAAe,GAAG,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAChD,IAAI,CAAC,eAAe,EAAE,CAAC;gBACnB,eAAe,GAAG,IAAI,GAAG,EAAE,CAAC;gBAC5B,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;YAC/C,CAAC;YACD,eAAe,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAChD,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,SAAiC,EAAE,UAAkB,EAAE,YAAqB;IAC5G,MAAM,eAAe,GAAG,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAClD,IAAI,CAAC,eAAe,EAAE,CAAC;QACnB,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,IAAI,YAAY,EAAE,CAAC;QACf,OAAO,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,eAAe,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,wBAAwB,CAA6B,QAAyC,EAAE,YAAoB,EAAE,UAAU,GAAG,CAAC;IAChJ,OAAO,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,UAAU,CAAkB,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAA6B,IAAa,EAAE,QAAyC,EAAE,YAAoB,EAAE,UAAU,GAAG,CAAC;IAC3J,OAAO,qBAAqB,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,EAAE,CAAC,UAAU,CAAkB,CAAC;AAC9F,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAAa,EAAE,QAAyC,EAAE,YAAoB,EAAE,QAAgB;IAClI,OAAO,QAAQ,CAAC,oBAAoB,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,IAAI,QAAQ,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAa,EAAE,QAAyC,EAAE,YAAoB,EAAE,QAA0B;IAC7I,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IACnE,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,QAAQ,CAAC;IACpB,CAAC;IACD,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9B,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9B,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,sBAAsB,CAClC,IAAa,EACb,QAAyC,EACzC,YAAoB,EACpB,QAAkC;IAElC,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IACnE,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,QAAQ,CAAC;IACpB,CAAC;IACD,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9B,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9B,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9B,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAAa,EAAE,QAAyC,EAAE,YAAoB;IAChH,OAAO,uBAAuB,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;AACzG,CAAC;AAED,SAAS,QAAQ,CAAC,KAAmC;IACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,SAAS,uBAAuB,CAAC,UAAkB,EAAE,YAAoB,EAAE,YAAqB;IAC5F,MAAM,UAAU,GAAG,IAAI,GAAG,EAA+B,CAAC;IAC1D,MAAM,YAAY,GAAG,eAAe,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAEnE,KAAK,MAAM,YAAY,IAAI,YAAY,EAAE,QAAQ,IAAI,EAAE,EAAE,CAAC;QACtD,IAAI,YAAY,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;YAC5B,SAAS;QACb,CAAC;QAED,MAAM,QAAQ,GAAG,mBAAmB,CAAC,YAAY,CAAC,CAAC;QACnD,IAAI,QAAQ,EAAE,CAAC;YACX,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC5C,CAAC;IACL,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;AACpD,CAAC;AAED,SAAS,uBAAuB,CAAC,IAAa,EAAE,YAAoB;IAChE,MAAM,kBAAkB,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,eAAe,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAoB,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAEnK,KAAK,MAAM,SAAS,IAAI,kBAAkB,EAAE,CAAC;QACzC,KAAK,MAAM,YAAY,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;YAC5C,IAAI,YAAY,CAAC,IAAI,KAAK,GAAG,IAAI,YAAY,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAChE,SAAS;YACb,CAAC;YACD,IAAI,gBAAgB,CAAS,YAAY,EAAE,CAAC,CAAC,KAAK,YAAY,EAAE,CAAC;gBAC7D,SAAS;YACb,CAAC;YACD,OAAO,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACrH,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAa;IACtC,MAAM,IAAI,GAAG,gBAAgB,CAAS,IAAI,EAAE,CAAC,CAAC,CAAC;IAC/C,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,OAAO;QACH,IAAI;QACJ,YAAY,EAAE,gBAAgB,CAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QACrD,KAAK,EAAE,gBAAgB,CAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QAC9C,KAAK,EAAE,gBAAgB,CAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QAC9C,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;KACrE,CAAC;AACN,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention, jsdoc/require-param, jsdoc/require-returns */\r\nimport { type FBXDocument, type FBXNode, type FBXPropertyValue, findChildByName, findDocumentNode, getPropertyValue } from \"../types/fbxTypes\";\r\n\r\nexport interface FBXTemplateProperty {\r\n name: string;\r\n propertyType: string;\r\n label: string;\r\n flags: string;\r\n values: FBXPropertyValue[];\r\n}\r\n\r\nexport interface FBXPropertyTemplate {\r\n objectType: string;\r\n templateName: string;\r\n properties: Map<string, FBXTemplateProperty>;\r\n}\r\n\r\nexport type FBXPropertyTemplateMap = Map<string, Map<string, FBXPropertyTemplate>>;\r\n\r\nexport function extractPropertyTemplates(doc: FBXDocument): FBXPropertyTemplateMap {\r\n const templates: FBXPropertyTemplateMap = new Map();\r\n const definitions = findDocumentNode(doc, \"Definitions\");\r\n if (!definitions) {\r\n return templates;\r\n }\r\n\r\n for (const objectTypeNode of definitions.children) {\r\n if (objectTypeNode.name !== \"ObjectType\") {\r\n continue;\r\n }\r\n\r\n const objectType = getPropertyValue<string>(objectTypeNode, 0);\r\n if (!objectType) {\r\n continue;\r\n }\r\n\r\n for (const templateNode of objectTypeNode.children) {\r\n if (templateNode.name !== \"PropertyTemplate\") {\r\n continue;\r\n }\r\n\r\n const templateName = getPropertyValue<string>(templateNode, 0);\r\n if (!templateName) {\r\n continue;\r\n }\r\n\r\n const template = extractPropertyTemplate(objectType, templateName, templateNode);\r\n let templatesByName = templates.get(objectType);\r\n if (!templatesByName) {\r\n templatesByName = new Map();\r\n templates.set(objectType, templatesByName);\r\n }\r\n templatesByName.set(templateName, template);\r\n }\r\n }\r\n\r\n return templates;\r\n}\r\n\r\nexport function getPropertyTemplate(templates: FBXPropertyTemplateMap, objectType: string, templateName?: string): FBXPropertyTemplate | undefined {\r\n const templatesByName = templates.get(objectType);\r\n if (!templatesByName) {\r\n return undefined;\r\n }\r\n if (templateName) {\r\n return templatesByName.get(templateName);\r\n }\r\n return templatesByName.values().next().value;\r\n}\r\n\r\nexport function getTemplatePropertyValue<T extends FBXPropertyValue>(template: FBXPropertyTemplate | undefined, propertyName: string, valueIndex = 0): T | undefined {\r\n return template?.properties.get(propertyName)?.values[valueIndex] as T | undefined;\r\n}\r\n\r\nexport function resolvePropertyValue<T extends FBXPropertyValue>(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string, valueIndex = 0): T | undefined {\r\n return resolvePropertyValues(node, template, propertyName)?.[valueIndex] as T | undefined;\r\n}\r\n\r\nexport function resolveNumberProperty(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string, fallback: number): number {\r\n return toNumber(resolvePropertyValue(node, template, propertyName)) ?? fallback;\r\n}\r\n\r\nexport function resolveVector2Property(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string, fallback: [number, number]): [number, number] {\r\n const values = resolvePropertyValues(node, template, propertyName);\r\n if (!values) {\r\n return fallback;\r\n }\r\n const x = toNumber(values[0]);\r\n const y = toNumber(values[1]);\r\n return x !== undefined && y !== undefined ? [x, y] : fallback;\r\n}\r\n\r\nexport function resolveVector3Property(\r\n node: FBXNode,\r\n template: FBXPropertyTemplate | undefined,\r\n propertyName: string,\r\n fallback: [number, number, number]\r\n): [number, number, number] {\r\n const values = resolvePropertyValues(node, template, propertyName);\r\n if (!values) {\r\n return fallback;\r\n }\r\n const x = toNumber(values[0]);\r\n const y = toNumber(values[1]);\r\n const z = toNumber(values[2]);\r\n return x !== undefined && y !== undefined && z !== undefined ? [x, y, z] : fallback;\r\n}\r\n\r\nexport function resolvePropertyValues(node: FBXNode, template: FBXPropertyTemplate | undefined, propertyName: string): FBXPropertyValue[] | undefined {\r\n return findLocalPropertyValues(node, propertyName) ?? template?.properties.get(propertyName)?.values;\r\n}\r\n\r\nfunction toNumber(value: FBXPropertyValue | undefined): number | undefined {\r\n if (typeof value === \"number\") {\r\n return value;\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction extractPropertyTemplate(objectType: string, templateName: string, templateNode: FBXNode): FBXPropertyTemplate {\r\n const properties = new Map<string, FBXTemplateProperty>();\r\n const properties70 = findChildByName(templateNode, \"Properties70\");\r\n\r\n for (const propertyNode of properties70?.children ?? []) {\r\n if (propertyNode.name !== \"P\") {\r\n continue;\r\n }\r\n\r\n const property = extractPropertyNode(propertyNode);\r\n if (property) {\r\n properties.set(property.name, property);\r\n }\r\n }\r\n\r\n return { objectType, templateName, properties };\r\n}\r\n\r\nfunction findLocalPropertyValues(node: FBXNode, propertyName: string): FBXPropertyValue[] | undefined {\r\n const propertyContainers = [findChildByName(node, \"Properties70\"), findChildByName(node, \"Properties60\")].filter((child): child is FBXNode => child !== undefined);\r\n\r\n for (const container of propertyContainers) {\r\n for (const propertyNode of container.children) {\r\n if (propertyNode.name !== \"P\" && propertyNode.name !== \"Property\") {\r\n continue;\r\n }\r\n if (getPropertyValue<string>(propertyNode, 0) !== propertyName) {\r\n continue;\r\n }\r\n return propertyNode.properties.slice(propertyNode.name === \"Property\" ? 3 : 4).map((property) => property.value);\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\nfunction extractPropertyNode(node: FBXNode): FBXTemplateProperty | null {\r\n const name = getPropertyValue<string>(node, 0);\r\n if (!name) {\r\n return null;\r\n }\r\n\r\n return {\r\n name,\r\n propertyType: getPropertyValue<string>(node, 1) ?? \"\",\r\n label: getPropertyValue<string>(node, 2) ?? \"\",\r\n flags: getPropertyValue<string>(node, 3) ?? \"\",\r\n values: node.properties.slice(4).map((property) => property.value),\r\n };\r\n}\r\n"]}
@@ -0,0 +1,20 @@
1
+ import { type FBXObjectMap } from "./connections.js";
2
+ import { type FBXBoneData, type FBXSkinData } from "./skeleton.js";
3
+ export type FBXRigBoneData = FBXBoneData;
4
+ export interface FBXSkinBindingData {
5
+ skinId: number;
6
+ geometryId: number;
7
+ rigId: string;
8
+ skinBoneIndexToRigBoneIndex: number[];
9
+ clusterModelIds: Set<number>;
10
+ }
11
+ export interface FBXRigData {
12
+ id: string;
13
+ rootModelIds: number[];
14
+ bones: FBXRigBoneData[];
15
+ modelIdToBoneIndex: Map<number, number>;
16
+ clusterModelIds: Set<number>;
17
+ skinBindings: FBXSkinBindingData[];
18
+ warnings: string[];
19
+ }
20
+ export declare function resolveRigs(objectMap: FBXObjectMap, skins: FBXSkinData[]): FBXRigData[];