UNPKG

gsots3d

Version:

Getting S**t On The Screen in 3D. A library for doing 3D graphics in the browser.

201 lines (200 loc) 4.76 kB
// src/parsers/mtl-parser.ts function parseMTL(mtlFile) { const materials = /* @__PURE__ */ new Map(); let material = {}; const keywords = { newmtl(_, unparsedArgs) { material = {}; materials.set(unparsedArgs, material); }, Ns(parts) { material.ns = parseFloat(parts[0]); }, Ka(parts) { material.ka = parts.map(parseFloat); }, Kd(parts) { material.kd = parts.map(parseFloat); }, Ks(parts) { material.ks = parts.map(parseFloat); }, // This is a non-standard addition, but semi-official Ke(parts) { material.ke = parts.map(parseFloat); }, Ni() { }, d(parts) { material.d = parseFloat(parts[0]); }, illum(parts) { material.illum = parseInt(parts[0]); }, map_Kd(_, unparsedArgs) { material.texDiffuse = unparsedArgs; }, map_Ks(_, unparsedArgs) { material.texSpecular = unparsedArgs; }, map_bump(_, unparsedArgs) { material.texNormal = unparsedArgs; }, map_Bump(_, unparsedArgs) { material.texNormal = unparsedArgs; } }; const keywordRE2 = /(\w*)(?: )*(.*)/; const lines = mtlFile.split("\n"); for (let lineNo = 0; lineNo < lines.length; ++lineNo) { const line = lines[lineNo].trim(); if (line === "" || line.startsWith("#")) { continue; } const m = keywordRE2.exec(line); if (!m) { continue; } const [, keyword, unparsedArgs] = m; const parts = line.split(/\s+/).slice(1); const handler = keywords[keyword]; if (!handler) { continue; } handler(parts, unparsedArgs); } return materials; } // src/parsers/obj-parser.ts var keywordRE = /(\w*)(?: )*(.*)/; function parseOBJ(objFile, flipUV) { const lines = objFile.split("\n"); const objPositions = [[0, 0, 0]]; const objTexcoords = [[0, 0]]; const objNormals = [[0, 0, 0]]; const objVertexData = [objPositions, objTexcoords, objNormals]; let triangles = 0; let webglVertexData = [ [], // Position [], // Texcoord [] // Normal ]; const geometries = Array(); let geometry = {}; let material = "__default"; const materialLibs = Array(); const keywords = { v(parts) { objPositions.push(parts.map(parseFloat)); }, vn(parts) { objNormals.push(parts.map(parseFloat)); }, vt(parts) { if (flipUV) { objTexcoords.push([parseFloat(parts[0]), 1 - parseFloat(parts[1])]); } else { objTexcoords.push([parseFloat(parts[0]), parseFloat(parts[1])]); } }, f(parts) { triangles++; setGeometry(); const numTriangles = parts.length - 2; for (let tri = 0; tri < numTriangles; ++tri) { addVertex(parts[0]); addVertex(parts[tri + 1]); addVertex(parts[tri + 2]); } }, usemtl(_, unparsedArgs) { material = unparsedArgs; newGeometry(); }, mtllib(_, unparsedArgs) { materialLibs.push(unparsedArgs); }, // Not used, but suppress warnings s() { return; }, o() { return; }, g() { return; }, l() { return; } }; function addVertex(vert) { const ptn = vert.split("/"); ptn.forEach((objIndexStr, i) => { if (!objIndexStr) { return; } const objIndex = parseInt(objIndexStr); const index = objIndex + (objIndex >= 0 ? 0 : objVertexData[i].length); webglVertexData[i].push(...objVertexData[i][index]); }); } function newGeometry() { if (geometry.material) { geometry = {}; } } function setGeometry() { if (!geometry.material) { const position = []; const texcoord = []; const normal = []; webglVertexData = [position, texcoord, normal]; geometry = { material, data: { position, texcoord, normal } }; geometries.push(geometry); } } for (let lineNo = 0; lineNo < lines.length; ++lineNo) { const line = lines[lineNo].trim(); if (line === "" || line.startsWith("#")) { continue; } const m = keywordRE.exec(line); if (!m) { continue; } const [, keyword, unparsedArgs] = m; const parts = line.split(/\s+/).slice(1); const handler = keywords[keyword]; if (!handler) { console.warn("unhandled keyword:", keyword, "at line", lineNo + 1); continue; } handler(parts, unparsedArgs); } for (const g of geometries) { if (g.data.texcoord && g.data.texcoord.length <= 0) { delete g.data.texcoord; } } return { matLibNames: materialLibs, geometries, triangles }; } export { parseMTL, parseOBJ }; //# sourceMappingURL=index.js.map