* Parse ASCII FBX format * 解析 ASCII FBX 格式
(text: string)
| 1661 | * 解析 ASCII FBX 格式 |
| 1662 | */ |
| 1663 | private parseASCII(text: string): { geometries: FBXGeometry[]; models: FBXModel[]; materials: FBXMaterial[] } { |
| 1664 | const geometries: FBXGeometry[] = []; |
| 1665 | const models: FBXModel[] = []; |
| 1666 | const materials: FBXMaterial[] = []; |
| 1667 | |
| 1668 | // Find Geometry sections using a safer approach |
| 1669 | // 使用更安全的方法查找 Geometry 部分 |
| 1670 | const geometryHeaderRegex = /Geometry:\s*(\d+),\s*"Geometry::([^"]*)",\s*"Mesh"\s*{/g; |
| 1671 | let match; |
| 1672 | |
| 1673 | while ((match = geometryHeaderRegex.exec(text)) !== null) { |
| 1674 | const name = match[2] || 'Geometry'; |
| 1675 | // Find matching closing brace by counting braces |
| 1676 | // 通过计数括号找到匹配的右括号 |
| 1677 | const startIdx = match.index + match[0].length; |
| 1678 | let braceCount = 1; |
| 1679 | let endIdx = startIdx; |
| 1680 | for (let i = startIdx; i < text.length && braceCount > 0; i++) { |
| 1681 | if (text[i] === '{') braceCount++; |
| 1682 | else if (text[i] === '}') braceCount--; |
| 1683 | endIdx = i; |
| 1684 | } |
| 1685 | const content = text.slice(startIdx, endIdx); |
| 1686 | |
| 1687 | // Extract vertices |
| 1688 | // 提取顶点 |
| 1689 | const verticesMatch = content.match(/Vertices:\s*\*\d+\s*{\s*a:\s*([\d\s.,eE+-]+)/); |
| 1690 | const vertices: number[] = []; |
| 1691 | if (verticesMatch) { |
| 1692 | const vertexStr = verticesMatch[1].replace(/\s+/g, ''); |
| 1693 | for (const v of vertexStr.split(',')) { |
| 1694 | const val = parseFloat(v); |
| 1695 | if (!isNaN(val)) vertices.push(val); |
| 1696 | } |
| 1697 | } |
| 1698 | |
| 1699 | // Extract polygon indices |
| 1700 | // 提取多边形索引 |
| 1701 | const indicesMatch = content.match(/PolygonVertexIndex:\s*\*\d+\s*{\s*a:\s*([\d\s.,-]+)/); |
| 1702 | let indices: number[] = []; |
| 1703 | if (indicesMatch) { |
| 1704 | const indexStr = indicesMatch[1].replace(/\s+/g, ''); |
| 1705 | const polyIndices: number[] = []; |
| 1706 | for (const i of indexStr.split(',')) { |
| 1707 | const val = parseInt(i, 10); |
| 1708 | if (!isNaN(val)) polyIndices.push(val); |
| 1709 | } |
| 1710 | indices = this.triangulatePolygons(polyIndices); |
| 1711 | } |
| 1712 | |
| 1713 | // Extract normals |
| 1714 | // 提取法线 |
| 1715 | let normals: number[] | undefined; |
| 1716 | const normalsMatch = content.match(/Normals:\s*\*\d+\s*{\s*a:\s*([\d\s.,eE+-]+)/); |
| 1717 | if (normalsMatch) { |
| 1718 | normals = []; |
| 1719 | const normalStr = normalsMatch[1].replace(/\s+/g, ''); |
| 1720 | for (const n of normalStr.split(',')) { |
no test coverage detected