119 lines
2.5 KiB
JavaScript
119 lines
2.5 KiB
JavaScript
export default function convert (objText) {
|
|
const lines = objText.split("\n");
|
|
|
|
let smoothing = false;
|
|
|
|
const positions = [];
|
|
const uvs = [];
|
|
const normals = [];
|
|
|
|
const vertices = [];
|
|
const indices = [];
|
|
|
|
for (let i = 0; i < lines.length; i++) {
|
|
const line = lines[i];
|
|
if (line != '')
|
|
{
|
|
const rawchunks = line.split(" ").map(x => x.trim());
|
|
const chunks = [];
|
|
|
|
for (let i = 0; i < rawchunks.length; i++) {
|
|
if (rawchunks[i] != '') {
|
|
chunks.push(rawchunks[i]);
|
|
}
|
|
}
|
|
|
|
switch (chunks[0]) {
|
|
case "v": {
|
|
positions.push(chunks.splice(1).map(parseFloat));
|
|
break;
|
|
}
|
|
case "vt": {
|
|
const uv = chunks.splice(1);
|
|
uvs.push([parseFloat(uv[0]), parseFloat(uv[1])]);
|
|
break;
|
|
}
|
|
case "vn": {
|
|
normals.push(chunks.splice(1).map(parseFloat));
|
|
break;
|
|
}
|
|
case "s": {
|
|
if (chunks[1] > 0) {
|
|
smoothing = true;
|
|
} else {
|
|
smoothing = false;
|
|
|
|
}
|
|
break;
|
|
}
|
|
case "f": {
|
|
const c1 = (smoothing ? "s" : "") + chunks[1];
|
|
const c2 = (smoothing ? "s" : "") + chunks[2];
|
|
const c3 = (smoothing ? "s" : "") + chunks[3];
|
|
|
|
|
|
let index1 = vertices.indexOf(c1);
|
|
if (index1 === -1) {
|
|
index1 = vertices.length;
|
|
vertices.push(c1);
|
|
}
|
|
|
|
let index2 = vertices.indexOf(c2);
|
|
if (index2 === -1) {
|
|
index2 = vertices.length;
|
|
vertices.push(c2);
|
|
}
|
|
|
|
let index3 = vertices.indexOf(c3);
|
|
if (index3 === -1) {
|
|
index3 = vertices.length;
|
|
vertices.push(c3);
|
|
}
|
|
|
|
indices.push(index1, index2, index3);
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
}
|
|
}
|
|
|
|
const avgNormals = [];
|
|
for (let i = 0; i < vertices.length; i++) {
|
|
if (vertices[i].startsWith("s")) {
|
|
const d = vertices[i].substr(1).split("/");
|
|
const normal = normals[d[2] - 1];
|
|
const index = d[0] - 1;
|
|
|
|
if (avgNormals[index]) {
|
|
avgNormals[index][0] += normal[0];
|
|
avgNormals[index][1] += normal[1];
|
|
avgNormals[index][2] += normal[2];
|
|
} else {
|
|
avgNormals[index] = normal;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (let n of avgNormals) {
|
|
const len = Math.hypot(...n);
|
|
avgNormals[avgNormals.indexOf(n)] = n.map(x => x / len);
|
|
}
|
|
|
|
const outPositions = [];
|
|
const outNormals = [];
|
|
const outUVs = [];
|
|
|
|
for (let i = 0; i < vertices.length; i++) {
|
|
const d = (vertices[i].startsWith("s") ? vertices[i].substr(1) : vertices[i]).split("/");
|
|
|
|
outPositions.push(...positions[d[0] - 1]);
|
|
if (normals.length) {
|
|
outNormals.push(...normals[d[2] - 1]);
|
|
}
|
|
if (uvs.length) {
|
|
outUVs.push(...uvs[d[1] - 1]);
|
|
}
|
|
}
|
|
return [outPositions, outNormals, outUVs, indices];
|
|
}; |