2015-06-15 17:04:19 +02:00
|
|
|
var mesh = {};
|
2015-06-11 10:12:50 +02:00
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
// Mesh
|
|
|
|
mesh.Mesh = function() {
|
2015-06-11 10:12:50 +02:00
|
|
|
this.vertices = [];
|
|
|
|
this.faces = [];
|
2015-06-15 17:04:19 +02:00
|
|
|
this.texCoords = [];
|
2015-06-16 12:05:29 +02:00
|
|
|
this.normals = [];
|
2015-06-15 17:04:19 +02:00
|
|
|
this.faceIndex = 0;
|
|
|
|
this.material = null;
|
2015-06-11 10:12:50 +02:00
|
|
|
}
|
|
|
|
|
2015-06-16 12:05:29 +02:00
|
|
|
mesh.Mesh.prototype.hasNormals = function() {
|
|
|
|
return this.normals.length > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
mesh.Mesh.prototype.hasTexCoords = function() {
|
|
|
|
return this.texCoords.length > 0;
|
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
mesh.Mesh.prototype.addVertex = function(vertex) {
|
2015-06-11 10:12:50 +02:00
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
if (vertex instanceof mesh.Vertex) {
|
|
|
|
this.vertices.push(vertex);
|
|
|
|
} else if (typeof vertex === 'string' || vertex instanceof String) {
|
|
|
|
this.vertices.push(new mesh.Vertex(vertex));
|
2015-06-11 11:05:05 +02:00
|
|
|
} else {
|
2015-06-15 17:04:19 +02:00
|
|
|
console.error("Can only add vertex from mesh.Vertex or string");
|
|
|
|
return;
|
2015-06-11 11:05:05 +02:00
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
return this.vertices[this.vertices.length - 1];
|
|
|
|
}
|
2015-06-11 11:05:05 +02:00
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
mesh.Mesh.prototype.addFaces = function(face) {
|
|
|
|
var faces;
|
2015-06-11 11:05:05 +02:00
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
if (face instanceof mesh.Face) {
|
|
|
|
this.faces.push(face);
|
|
|
|
} else if (typeof face === 'string' || face instanceof String) {
|
|
|
|
faces = parseFace(face);
|
|
|
|
this.faces = this.faces.concat(faces);
|
|
|
|
} else {
|
|
|
|
console.error("Can only add face from mesh.Face or string");
|
|
|
|
return;
|
2015-06-11 11:05:05 +02:00
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
if (faces === undefined) {
|
|
|
|
return this.faces[this.faces.length - 1];
|
|
|
|
} else {
|
|
|
|
return faces;
|
2015-06-11 11:05:05 +02:00
|
|
|
}
|
2015-06-15 17:04:19 +02:00
|
|
|
}
|
2015-06-11 11:05:05 +02:00
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
mesh.Mesh.prototype.addTexCoord = function(texCoord) {
|
|
|
|
if (texCoord instanceof mesh.TexCoord) {
|
|
|
|
this.texCoords.push(texCoord);
|
|
|
|
} else if (typeof texCoord === 'string' || texCoord instanceof String) {
|
|
|
|
this.texCoords.push(new mesh.TexCoord(texCoord));
|
|
|
|
} else {
|
|
|
|
console.error("Can only add texCoord from mesh.TexCoord or string");
|
|
|
|
return;
|
2015-06-11 11:05:05 +02:00
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
return this.texCoords[this.texCoords.length - 1];
|
|
|
|
}
|
2015-06-11 11:05:05 +02:00
|
|
|
|
2015-06-16 12:05:29 +02:00
|
|
|
mesh.Mesh.prototype.addNormal = function(normal) {
|
|
|
|
if (normal instanceof mesh.Normal) {
|
|
|
|
this.normals.push(normal);
|
|
|
|
} else if (typeof normal === 'string' || normal instanceof String) {
|
|
|
|
this.normals.push(new mesh.Normal(normal));
|
|
|
|
} else {
|
|
|
|
console.error("Cann only add normal from mesh.Normal of string");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.normals[this.normals.length - 1];
|
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
mesh.Mesh.prototype.isFinished = function() {
|
|
|
|
return this.faces.length === this.faceIndex;
|
2015-06-11 11:05:05 +02:00
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
// Vertex
|
|
|
|
mesh.Vertex = function() {
|
2015-06-11 10:12:50 +02:00
|
|
|
if (typeof arguments[0] === 'string' || arguments[0] instanceof String) {
|
2015-06-12 19:19:38 +02:00
|
|
|
var split = arguments[0].replace(/\s+/g, " ").split(' ');
|
2015-06-11 10:12:50 +02:00
|
|
|
this.x = parseFloat(split[1]);
|
|
|
|
this.y = parseFloat(split[2]);
|
|
|
|
this.z = parseFloat(split[3]);
|
|
|
|
}
|
|
|
|
this.sent = false;
|
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
mesh.Vertex.prototype.toList = function() {
|
|
|
|
return ['v', this.index, this.x, this.y, this.z];
|
2015-06-11 10:12:50 +02:00
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
mesh.Vertex.prototype.toString = function() {
|
2015-06-11 10:12:50 +02:00
|
|
|
return 'v ' + this.x + ' ' + this.y + ' ' + this.z;
|
|
|
|
}
|
|
|
|
|
2015-06-16 12:05:29 +02:00
|
|
|
// Normal is the same as a vertex, except for toList and toString
|
|
|
|
mesh.Normal = function() {
|
|
|
|
mesh.Vertex.apply(this, arguments);
|
|
|
|
}
|
|
|
|
|
|
|
|
mesh.Normal.prototype = Object.create(mesh.Vertex.prototype);
|
|
|
|
mesh.Normal.prototype.constructor = mesh.Normal;
|
|
|
|
|
|
|
|
mesh.Normal.prototype.toList = function() {
|
|
|
|
var superObject = mesh.Vertex.prototype.toList.call(this);
|
|
|
|
superObject[0] = 'vn';
|
|
|
|
return superObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
mesh.Normal.toString = function() {
|
|
|
|
var superObject = mesh.Vertex.prototype.toString.call(this);
|
|
|
|
superObject.replace('v', 'vn');
|
|
|
|
return superObject;
|
|
|
|
}
|
2015-06-15 17:04:19 +02:00
|
|
|
|
|
|
|
// TexCoord : texture coordinates
|
|
|
|
mesh.TexCoord = function() {
|
2015-06-11 10:12:50 +02:00
|
|
|
if (typeof arguments[0] === 'string' || arguments[0] instanceof String) {
|
2015-06-12 19:19:38 +02:00
|
|
|
var split = arguments[0].replace(/\s+/g, " ").split(' ');
|
2015-06-11 11:05:05 +02:00
|
|
|
this.x = parseFloat(split[1]);
|
|
|
|
this.y = parseFloat(split[2]);
|
|
|
|
}
|
|
|
|
this.sent = false;
|
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
mesh.TexCoord.prototype.toList = function() {
|
|
|
|
return ['vt', this.index, this.x, this.y];
|
2015-06-11 11:05:05 +02:00
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
mesh.TexCoord.prototype.toString = function() {
|
2015-06-11 17:22:37 +02:00
|
|
|
return 'vt ' + this.x + ' ' + this.y;
|
2015-06-11 11:05:05 +02:00
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
|
|
|
|
// Face
|
|
|
|
mesh.Face = function() {
|
2015-06-11 11:05:05 +02:00
|
|
|
if (typeof arguments[0] === 'string' || arguments[0] instanceof String) {
|
|
|
|
if (arguments[0].indexOf('/') === -1) {
|
|
|
|
// No / : easy win : "f 1 2 3" or "f 1 2 3 4"
|
2015-06-12 19:19:38 +02:00
|
|
|
var split = arguments[0].replace(/\s+/g, ' ').split(' ');
|
2015-06-11 11:05:05 +02:00
|
|
|
this.a = parseInt(split[1]) - 1;
|
|
|
|
this.b = parseInt(split[2]) - 1;
|
|
|
|
this.c = parseInt(split[3]) - 1;
|
2015-06-12 11:07:05 +02:00
|
|
|
|
2015-06-11 11:05:05 +02:00
|
|
|
} else {
|
|
|
|
// There might be textures coords
|
2015-06-12 19:19:38 +02:00
|
|
|
var split = arguments[0].replace(/\s+/g, ' ').trim().split(' ');
|
2015-06-11 11:05:05 +02:00
|
|
|
|
|
|
|
// Split elements
|
|
|
|
var split1 = split[1].split('/');
|
|
|
|
var split2 = split[2].split('/');
|
|
|
|
var split3 = split[3].split('/');
|
|
|
|
|
|
|
|
var vIndex = 0;
|
2015-06-12 19:19:38 +02:00
|
|
|
var tIndex = 1;
|
2015-06-16 12:05:29 +02:00
|
|
|
var nIndex = 2;
|
|
|
|
|
|
|
|
this.a = parseInt(split1[vIndex]) - 1;
|
|
|
|
this.b = parseInt(split2[vIndex]) - 1;
|
|
|
|
this.c = parseInt(split3[vIndex]) - 1;
|
|
|
|
|
|
|
|
this.aTexture = parseInt(split1[tIndex]) - 1;
|
|
|
|
this.bTexture = parseInt(split2[tIndex]) - 1;
|
|
|
|
this.cTexture = parseInt(split3[tIndex]) - 1;
|
2015-06-11 11:05:05 +02:00
|
|
|
|
2015-06-16 12:05:29 +02:00
|
|
|
this.aNormal = parseInt(split1[nIndex]) - 1;
|
|
|
|
this.bNormal = parseInt(split2[nIndex]) - 1;
|
|
|
|
this.cNormal = parseInt(split3[nIndex]) - 1;
|
2015-06-11 17:22:37 +02:00
|
|
|
|
2015-06-11 11:05:05 +02:00
|
|
|
}
|
2015-06-11 10:12:50 +02:00
|
|
|
}
|
2015-06-12 19:19:38 +02:00
|
|
|
|
2015-06-11 10:12:50 +02:00
|
|
|
this.sent = false;
|
2015-06-15 17:04:19 +02:00
|
|
|
|
2015-06-11 10:12:50 +02:00
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
var parseFace = function(arg) {
|
2015-06-16 12:05:29 +02:00
|
|
|
|
|
|
|
var split = arg.trim().split(' ');
|
2015-06-15 17:04:19 +02:00
|
|
|
var ret = [];
|
|
|
|
|
|
|
|
// Face3
|
|
|
|
if (split.length >= 4) {
|
|
|
|
ret.push(new mesh.Face(arg));
|
|
|
|
}
|
|
|
|
|
2015-06-16 12:05:29 +02:00
|
|
|
// Face3 == 2 * Face3
|
2015-06-15 17:04:19 +02:00
|
|
|
if (split.length >= 5) {
|
|
|
|
ret.push(new mesh.Face(
|
|
|
|
[
|
|
|
|
split[0],
|
|
|
|
split[1],
|
|
|
|
split[3],
|
|
|
|
split[4]
|
|
|
|
].join(' ')
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
mesh.Face.prototype.max = function() {
|
2015-06-15 10:01:33 +02:00
|
|
|
if (this.d !== undefined) {
|
2015-06-11 10:12:50 +02:00
|
|
|
return Math.max(this.a, this.b, this.c, this.d);
|
|
|
|
} else {
|
|
|
|
return Math.max(this.a, this.b, this.c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
mesh.Face.prototype.maxTexture = function() {
|
2015-06-12 19:19:38 +02:00
|
|
|
if (this.dTexture) {
|
|
|
|
return Math.max(this.aTexture, this.bTexture, this.cTexture, this.dTexture);
|
|
|
|
} else {
|
|
|
|
return Math.max(this.aTexture, this.bTexture, this.cTexture);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
mesh.Face.prototype.toList = function() {
|
2015-06-16 12:05:29 +02:00
|
|
|
var l = ['f', this.index,
|
|
|
|
[this.a, this.b, this.c ],
|
|
|
|
isNaN(this.aTexture) ? [] : [this.aTexture, this.bTexture, this.cTexture],
|
|
|
|
isNaN(this.aNormal ) ? [] : [this.aNormal, this.bNormal, this.cNormal ]
|
|
|
|
];
|
2015-06-11 17:22:37 +02:00
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
// if (this.d !== undefined)
|
|
|
|
// l.push(this.d);
|
|
|
|
|
|
|
|
// if (this.aTexture !== undefined) {
|
|
|
|
// l.push(this.aTexture);
|
|
|
|
// l.push(this.bTexture);
|
|
|
|
// l.push(this.cTexture);
|
|
|
|
// }
|
2015-06-11 17:22:37 +02:00
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
// if (this.dTexture !== undefined)
|
|
|
|
// l.push(this.dTexture);
|
2015-06-12 11:07:05 +02:00
|
|
|
|
2015-06-11 10:12:50 +02:00
|
|
|
return l;
|
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
mesh.Face.prototype.toString = function() {
|
2015-06-15 10:01:33 +02:00
|
|
|
return 'f ' + this.a + ' ' + this.b + ' ' + this.c + (this.d !== undefined ? ' ' + this.d : '');
|
2015-06-11 10:12:50 +02:00
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
// Material
|
|
|
|
mesh.Material = function() {
|
2015-06-16 12:05:29 +02:00
|
|
|
var split = arguments[0].replace(/\s+/g, ' ').trim().split(' ');
|
2015-06-11 17:22:37 +02:00
|
|
|
this.name = split[1];
|
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
mesh.Material.prototype.toString = function() {
|
2015-06-11 17:22:37 +02:00
|
|
|
return 'usemtl ' + this.name;
|
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
mesh.Material.prototype.toList = function() {
|
2015-06-11 17:22:37 +02:00
|
|
|
return ['u', this.name];
|
|
|
|
}
|
|
|
|
|
2015-06-15 17:04:19 +02:00
|
|
|
module.exports = mesh;
|