UNPKG

suzanne

Version:
124 lines (123 loc) 5.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Vec2_1 = require("./Vector/Vec2"); const Vec3_1 = require("./Vector/Vec3"); const VecShorthands_1 = require("./Vector/VecShorthands"); var ModelLoader; (function (ModelLoader) { const parseVertex = (line) => { // ex: "v 1.000000 -1.000000 -1.000000" const coords = line.substr(2).split(' ').map(x => parseFloat(x)); return new Vec3_1.Vec3(coords[0], 1 - coords[1], coords[2]); }; const parseUV = (line) => { // ex: vt 1.000000 0.000000 const uvs = line.substr(3).split(' ').map(x => parseFloat(x)); return new Vec2_1.Vec2(uvs[0], uvs[1]); }; const parseNormal = (line) => { // ex: vn 0.000000 1.000000 0.000000 const coords = line.substr(3).split(' ').map(x => parseFloat(x)); return new Vec3_1.Vec3(coords[0], coords[1], coords[2]); }; ModelLoader.parseOBJ = (obj_str) => { const lines = obj_str.split('\n'); const vertices = []; const uvs = []; const normals = []; const indices = []; const faces_cache = new Map(); let max_idx = 0; const mesh = { vertices: [], indices: null, attributes: { uv: [], normal: [] }, bounding_box: { min: VecShorthands_1.vec3(Infinity), max: VecShorthands_1.vec3(0) } }; for (let line of lines) { line = line.trim(); switch (line.charAt(0)) { case 'v': switch (line.charAt(1)) { case ' ': const v = parseVertex(line); if (v.x > mesh.bounding_box.max.x) { mesh.bounding_box.max.x = v.x; } if (v.y > mesh.bounding_box.max.y) { mesh.bounding_box.max.y = v.y; } if (v.z > mesh.bounding_box.max.z) { mesh.bounding_box.max.z = v.z; } if (v.x < mesh.bounding_box.min.x) { mesh.bounding_box.min.x = v.x; } if (v.y < mesh.bounding_box.min.y) { mesh.bounding_box.min.y = v.y; } if (v.z < mesh.bounding_box.min.z) { mesh.bounding_box.min.z = v.z; } vertices.push(v); break; case 't': uvs.push(parseUV(line)); break; case 'n': normals.push(parseNormal(line)); break; } break; case 'f': // ex: f 1/1/1 2/2/1 3/3/1 4/4/1 const faces = line.substr(2).split(' '); let face_indices = []; for (const face of faces) { if (faces_cache.has(face)) { face_indices.push(faces_cache.get(face)); continue; } const [vert_idx, uv_idx, normal_idx] = face.split('/').map(x => parseInt(x) - 1); mesh.vertices.push(vertices[vert_idx]); if (uv_idx !== undefined) mesh.attributes.uv.push(uvs[uv_idx]); if (normal_idx !== undefined) mesh.attributes.normal.push(normals[normal_idx]); faces_cache.set(face, max_idx); face_indices.push(max_idx); max_idx++; } // triangulate the quad if (faces.length === 4) { const fourth = face_indices[3]; face_indices[3] = face_indices[2]; face_indices[4] = fourth; face_indices[5] = face_indices[0]; } indices.push(...face_indices); break; } } mesh.indices = max_idx < 256 ? new Uint8Array(indices) : max_idx < 65536 ? new Uint16Array(indices) : new Uint32Array(indices); return mesh; }; // export const load = (source: string): Promise<VertexData> => { // return new Promise<VertexData>(async (resolve, reject) => { // try { // const data = await (await fetch(source)).text(); // const model = parseOBJ(data); // resolve(model); // } catch (e) { // reject(e); // } // }); // } })(ModelLoader = exports.ModelLoader || (exports.ModelLoader = {}));