function parseObj(docStr) { const bufPositions = []; const bufNormals = []; const out = []; var vertCount = 0; const ops = { v(str) { var xyz = str.match(/[0-9.-]+/g).map(Number); bufPositions.push(xyz); }, vn(str) { var xyz = str.match(/[0-9.-]+/g).map(Number); bufNormals.push(xyz); }, f(str) { const pts = []; for (var faceStr of str.split(" ")) { var [iV, iVt, iVn] = faceStr.split("/").map(Number); /* obj uses 1-based indices */ iV--; iVt--; iVn--; pts.push({ iV: iV, // iVt: iVt, iVn: iVn, }); } /* triangulate. */ for (var i = 0; i < pts.length - 2; i++) { out.push( bufPositions[pts[0].iV], bufNormals[pts[0].iVn], bufPositions[pts[i + 1].iV], bufNormals[pts[i + 1].iVn], bufPositions[pts[i + 2].iV], bufNormals[pts[i + 2].iVn], ); vertCount += 3; } } }; for (var line of docStr.split("\n")) { /* if you use crlf that sucks lol */ if (line == "" || line.startsWith("#")) { continue; } var tks = line.split(" "); var op = tks.shift(); var cont = tks.join(" "); var opFunc = ops[op]; if (opFunc) opFunc(cont); } return [new Float32Array(out.flat()), vertCount]; }