MCPcopy Create free account
hub / github.com/Bloom-Engine/engine / parseOBJ

Function parseOBJ

src/models/index.ts:64–126  ·  view source on GitHub ↗
(text: string)

Source from the content-addressed store, hash-verified

62
63// OBJ parser (pure TypeScript)
64function parseOBJ(text: string): { vertices: number[]; indices: number[] } | null {
65 const positions: number[][] = [];
66 const normals: number[][] = [];
67 const texcoords: number[][] = [];
68 const vertexMap = new Map<string, number>();
69 const vertices: number[] = [];
70 const indices: number[] = [];
71 let vertexCount = 0;
72
73 const lines = text.split('\n');
74 for (let i = 0; i < lines.length; i++) {
75 const line = lines[i].trim();
76 if (line.length === 0 || line[0] === '#') continue;
77
78 const parts = line.split(/\s+/);
79 const cmd = parts[0];
80
81 if (cmd === 'v' && parts.length >= 4) {
82 positions.push([parseFloat(parts[1]), parseFloat(parts[2]), parseFloat(parts[3])]);
83 } else if (cmd === 'vn' && parts.length >= 4) {
84 normals.push([parseFloat(parts[1]), parseFloat(parts[2]), parseFloat(parts[3])]);
85 } else if (cmd === 'vt' && parts.length >= 3) {
86 texcoords.push([parseFloat(parts[1]), parseFloat(parts[2])]);
87 } else if (cmd === 'f') {
88 // Triangulate face (fan from first vertex)
89 const faceIndices: number[] = [];
90 for (let j = 1; j < parts.length; j++) {
91 const key = parts[j];
92 if (vertexMap.has(key)) {
93 faceIndices.push(vertexMap.get(key)!);
94 } else {
95 const segs = key.split('/');
96 const pi = parseInt(segs[0]) - 1;
97 const ti = segs.length > 1 && segs[1] !== '' ? parseInt(segs[1]) - 1 : -1;
98 const ni = segs.length > 2 ? parseInt(segs[2]) - 1 : -1;
99
100 const pos = pi >= 0 && pi < positions.length ? positions[pi] : [0, 0, 0];
101 const norm = ni >= 0 && ni < normals.length ? normals[ni] : [0, 1, 0];
102 const uv = ti >= 0 && ti < texcoords.length ? texcoords[ti] : [0, 0];
103
104 // Format: x,y,z, nx,ny,nz, r,g,b,a, u,v (12 floats per vertex)
105 vertices.push(pos[0], pos[1], pos[2]);
106 vertices.push(norm[0], norm[1], norm[2]);
107 vertices.push(1, 1, 1, 1); // white color
108 vertices.push(uv[0], uv[1]);
109
110 const idx = vertexCount;
111 vertexCount++;
112 vertexMap.set(key, idx);
113 faceIndices.push(idx);
114 }
115 }
116
117 // Fan triangulation
118 for (let j = 2; j < faceIndices.length; j++) {
119 indices.push(faceIndices[0], faceIndices[j - 1], faceIndices[j]);
120 }
121 }

Callers 2

loadModelFunction · 0.85
loadModelAsyncFunction · 0.85

Calls 2

pushMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected