function parseObj(docStr) { const positions = []; const normals = []; const indices = []; const ops = { v(str) { var xyz = str.match(/[0-9.-]+/g).map(Number); positions.push(xyz); }, vn(str) { var xyz = str.match(/[0-9.-]+/g).map(Number); normals.push(xyz); }, f(str) { const ind = []; for (var faceStr of str.split(" ")) { var [iV, iVt, iVn] = faceStr.split("/").map(Number); /* obj uses 1-based indices */ iV--; iVt--; iVn--; ind.push({ iV: iV, // iVt: iVt, iVn: iVn, }); } /* triangulate. */ for (var i = 0; i < ind.length - 2; i++) { indices.push( ind[0].iV, ind[i + 1].iV, ind[i + 2].iV, ); } } }; 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(positions.flat()), new Float32Array(normals.flat()), new Uint16Array(indices), ] }