* Extract geometry from FBX Geometry node * 从 FBX Geometry 节点提取几何数据
(node: FBXNode)
| 688 | * 从 FBX Geometry 节点提取几何数据 |
| 689 | */ |
| 690 | private extractGeometry(node: FBXNode): FBXGeometry | null { |
| 691 | // Get geometry ID and name |
| 692 | // 获取几何 ID 和名称 |
| 693 | const id = node.properties[0] as bigint; |
| 694 | const nameProp = node.properties[1]; |
| 695 | let name = 'Geometry'; |
| 696 | if (typeof nameProp === 'string') { |
| 697 | // FBX name format: "Name\x00\x01Geometry" |
| 698 | name = nameProp.split('\x00')[0] || name; |
| 699 | } |
| 700 | |
| 701 | // Find Vertices, PolygonVertexIndex, etc. |
| 702 | // 查找 Vertices、PolygonVertexIndex 等 |
| 703 | let vertices: number[] = []; |
| 704 | let indices: number[] = []; |
| 705 | let normals: number[] | undefined; |
| 706 | let uvs: number[] | undefined; |
| 707 | |
| 708 | for (const child of node.children) { |
| 709 | if (child.name === 'Vertices') { |
| 710 | const prop = child.properties[0]; |
| 711 | vertices = this.toNumberArray(prop); |
| 712 | } else if (child.name === 'PolygonVertexIndex') { |
| 713 | // FBX uses negative indices for polygon end markers |
| 714 | // FBX 使用负索引作为多边形结束标记 |
| 715 | const prop = child.properties[0]; |
| 716 | const polyIndices = this.toNumberArray(prop); |
| 717 | |
| 718 | // Convert polygon indices to triangles |
| 719 | // 将多边形索引转换为三角形 |
| 720 | indices = this.triangulatePolygons(polyIndices); |
| 721 | } else if (child.name === 'LayerElementNormal') { |
| 722 | normals = this.extractLayerElement(child, 'Normals'); |
| 723 | } else if (child.name === 'LayerElementUV') { |
| 724 | uvs = this.extractLayerElement(child, 'UV'); |
| 725 | } |
| 726 | } |
| 727 | |
| 728 | if (vertices.length === 0) return null; |
| 729 | |
| 730 | return { id, name, vertices, indices, normals, uvs }; |
| 731 | } |
| 732 | |
| 733 | /** |
| 734 | * Convert FBX property to number array |
no test coverage detected