obja/src/Model.js

188 lines
6.2 KiB
JavaScript
Raw Normal View History

2019-12-09 18:41:42 +01:00
class Model extends THREE.Mesh {
2019-12-11 17:06:34 +01:00
constructor(path) {
2019-12-11 14:41:04 +01:00
let geometry = new THREE.Geometry();
2019-12-11 15:44:21 +01:00
let materials = [
new THREE.MeshLambertMaterial( { color: 0xffffff, side: THREE.DoubleSide } ),
new THREE.MeshBasicMaterial( { transparent: true, opacity: 0 } )
];
2021-01-21 08:35:09 +01:00
materials[0].vertexColors = true;
2019-12-11 15:44:21 +01:00
super(geometry, materials);
2019-12-09 18:41:42 +01:00
this.frustumCulled = false;
2019-12-11 17:06:34 +01:00
this.path = path;
2019-12-09 18:41:42 +01:00
this.vertices = [];
2019-12-11 17:06:34 +01:00
this.currentLine = 1;
}
throwError(message) {
let e = new Error("In " + this.path + ":L" + this.currentLine + " " + message);
e.type = "custom";
throw e;
}
checkVertex(id) {
if (this.geometry.vertices[id] === undefined) {
this.throwError("EditVertex requires vertex " + (id + 1) + " but there is no such vertex");
}
}
checkFaceId(id) {
if (this.geometry.faces[id] === undefined) {
this.throwError("EditFace requires face " + (id + 1) + " but there is no such face");
}
}
checkFace(f) {
let vertices = this.geometry.vertices;
if (vertices[f.a] === undefined) {
this.throwError("Face requires vertex " + (f.a + 1) + " but there is no such vertex");
}
if (vertices[f.b] === undefined) {
this.throwError("Face requires vertex " + (f.b + 1) + " but there is no such vertex");
}
if (vertices[f.c] === undefined) {
this.throwError("Face requires vertex " + (f.c + 1) + " but there is no such vertex");
}
2019-12-09 18:41:42 +01:00
}
2019-12-12 12:05:09 +01:00
checkVertexPrediction(f) {
let vertices = this.geometry.vertices;
if (vertices[f.a] === undefined) {
this.throwError("Vertex prediction requires vertex " + (f.a + 1) + " but there is no such vertex");
}
if (vertices[f.b] === undefined) {
this.throwError("Vertex prediction requires vertex " + (f.b + 1) + " but there is no such vertex");
}
if (vertices[f.c] === undefined) {
this.throwError("Vertex prediction requires vertex " + (f.c + 1) + " but there is no such vertex");
}
}
2019-12-09 18:41:42 +01:00
manageElement(element) {
2019-12-11 16:48:29 +01:00
let vertices = this.geometry.vertices;
2019-12-11 17:06:34 +01:00
let f, normal;
2019-12-11 16:48:29 +01:00
2019-12-09 18:41:42 +01:00
switch (element.type) {
case Element.AddVertex:
2019-12-11 14:41:04 +01:00
this.geometry.vertices.push(element.value);
this.geometry.verticesNeedUpdate = true;
break;
case Element.EditVertex:
2019-12-11 17:06:34 +01:00
this.checkVertex(element.id);
2019-12-11 14:41:04 +01:00
this.geometry.vertices[element.id].copy(element.value);
this.geometry.verticesNeedUpdate = true;
2019-12-09 18:41:42 +01:00
break;
2019-12-11 23:22:50 +01:00
case Element.TranslateVertex:
this.checkVertex(element.id);
this.geometry.vertices[element.id].add(element.value);
this.geometry.verticesNeedUpdate = true;
break;
2019-12-09 18:41:42 +01:00
case Element.AddFace:
2019-12-11 17:06:34 +01:00
f = element.value;
this.checkFace(f);
normal =
2019-12-11 14:41:04 +01:00
vertices[f.b].clone().sub(vertices[f.a])
.cross(vertices[f.c].clone().sub(vertices[f.a]));
2019-12-09 18:41:42 +01:00
normal.normalize();
2019-12-11 14:41:04 +01:00
f.normal = normal;
2019-12-11 15:44:21 +01:00
f.materialIndex = 0;
2019-12-11 14:41:04 +01:00
this.geometry.faces.push(f);
this.geometry.elementsNeedUpdate = true;
2019-12-09 18:41:42 +01:00
break;
2019-12-11 16:48:29 +01:00
case Element.AddTriangleStrip:
case Element.AddTriangleFan:
for (let f of element.value) {
2019-12-11 17:06:34 +01:00
this.checkFace(f);
2019-12-11 16:48:29 +01:00
let normal =
vertices[f.b].clone().sub(vertices[f.a])
.cross(vertices[f.c].clone().sub(vertices[f.a]));
normal.normalize();
f.normal = normal;
f.materialIndex = 0;
this.geometry.faces.push(f);
}
this.geometry.elementsNeedUpdate = true;
break;
2019-12-11 15:44:21 +01:00
case Element.EditFace:
f = element.value;
2019-12-11 17:06:34 +01:00
this.checkFaceId(element.id);
this.checkFace(f);
2019-12-11 15:44:21 +01:00
normal =
vertices[f.b].clone().sub(vertices[f.a])
.cross(vertices[f.c].clone().sub(vertices[f.a]));
normal.normalize();
f.normal = normal;
2021-07-22 15:19:40 +02:00
f.color = this.geometry.faces[element.id].color;
2019-12-11 17:06:34 +01:00
2019-12-11 15:44:21 +01:00
this.geometry.faces[element.id] = f;
this.geometry.elementsNeedUpdate = true;
break;
2019-12-11 23:22:50 +01:00
case Element.EditFaceVertex:
this.checkFaceId(element.id);
switch (element.oldIndex) {
case 0: this.geometry.faces[element.id].a = element.value; break;
case 1: this.geometry.faces[element.id].b = element.value; break;
case 2: this.geometry.faces[element.id].c = element.value; break;
default: this.throwError("Old vertex id in EditFaceVertex must be 1, 2 or 3, but was " + element.oldIndex + 1);
}
this.geometry.elementsNeedUpdate = true;
break;
2019-12-11 15:44:21 +01:00
case Element.DeleteFace:
this.geometry.faces[element.id].materialIndex = 1;
this.geometry.elementsNeedUpdate = true;
break;
2021-01-21 08:35:09 +01:00
case Element.SetFaceColor:
this.geometry.faces[element.id].color.r = element.value.r;
this.geometry.faces[element.id].color.g = element.value.g;
this.geometry.faces[element.id].color.b = element.value.b;
this.geometry.colorsNeedUpdate = true;
break;
2019-12-12 12:05:09 +01:00
case Element.PredictVertex:
this.checkVertexPrediction(element.value);
vertices.push(vertices[element.value.a].clone()
.add(vertices[element.value.c])
.sub(vertices[element.value.b]));
this.geometry.verticesNeedUpdate = true;
break;
2019-12-11 15:44:21 +01:00
2019-12-09 18:41:42 +01:00
default:
throw new Error("unknown element type: " + element.type);
}
2019-12-11 17:06:34 +01:00
this.currentLine++;
2019-12-09 18:41:42 +01:00
}
}