72 lines
2.1 KiB
JavaScript
72 lines
2.1 KiB
JavaScript
function parseObjLine(line, obj) {
|
|
line = line.trim();
|
|
if (line[0] === '#' || line.length < 1) {
|
|
return;
|
|
}
|
|
const elements = line.split(/\s+/);
|
|
obj[elements[0]].push(elements.slice(1));
|
|
}
|
|
|
|
function getFaces(obj) {
|
|
return obj.f.map(f => {
|
|
const face = {
|
|
'vertices': [],
|
|
'normals': [],
|
|
'textures': [],
|
|
};
|
|
if (f.length === 4) { // add duplicate vertices to make triangles
|
|
f.splice(3, 0, f[0]);
|
|
f.splice(4, 0, f[2]);
|
|
}
|
|
f.forEach(v => {
|
|
const [vidx, vtidx, vnidx] = v.split('/');
|
|
face.vertices.push((obj.v[vidx - 1] || []).map(Number));
|
|
face.normals.push((obj.vn[vnidx - 1] || []).map(Number));
|
|
//face.textures.push((obj.vt[vtidx] || []).map(Number));
|
|
face.textures.push([0, 0]);
|
|
});
|
|
return face;
|
|
});
|
|
}
|
|
|
|
export async function loadObjModel(url) {
|
|
const stlDataStream = (await fetch(url)).body;
|
|
const faces = [];
|
|
const obj = new Proxy({}, {
|
|
get: (target, name) =>{
|
|
if (!(name in target)) {
|
|
target[name] = [];
|
|
}
|
|
return target[name];
|
|
},
|
|
});
|
|
|
|
return new Promise((resolve, reject) => {
|
|
let partialLine = "";
|
|
const reader = stlDataStream.getReader();
|
|
const decoder = new TextDecoder();
|
|
|
|
function pump() {
|
|
reader.read().then(({ done, value }) => {
|
|
if (done) {
|
|
parseObjLine(partialLine, obj);
|
|
return resolve(getFaces(obj));
|
|
}
|
|
|
|
const textInput = decoder.decode(value);
|
|
const lines = textInput.split('\n');
|
|
|
|
if (lines.length > 1) {
|
|
parseObjLine(partialLine + lines[0], obj);
|
|
partialLine = "";
|
|
lines.slice(0, -1).forEach(line => {
|
|
parseObjLine(line, obj);
|
|
});
|
|
}
|
|
partialLine = partialLine + lines.at(-1);
|
|
pump();
|
|
});
|
|
}
|
|
pump();
|
|
});
|
|
} |