diff --git a/geo/Mesh.js b/geo/Mesh.js index d8c1bfd..ad4f57e 100644 --- a/geo/Mesh.js +++ b/geo/Mesh.js @@ -4,59 +4,57 @@ var geo = geo || {}; geo.MeshStreamer = function(path, callback) { this.vertices = []; + this.textureCoords = []; this.faces = []; this.orderedElements = []; this.index = 0; if (path !== undefined) { var self = this; - this.loadFromFile(path, callback); + this.loadFromFile(path, function() { + + self.orderedElements = self.tryMerge(); + + if (typeof callback === 'function') + callback(); + + }); } } geo.MeshStreamer.prototype.loadFromFile = function(path, callback) { var self = this; fs.readFile(path, function(err, data) { + + // Get lines from file var lines = data.toString('utf-8').split("\n"); - var vertexCounter = 0; - var faceCounter = 0; - - // - var vertex_face = []; + // For each line for (var i = 0; i < lines.length; i++) { var line = lines[i]; if (line[0] === 'v') { - var vertex = self.vertices[self.vertices.push(new geo.Vertex(line)) - 1]; - vertex_face.push([]); - vertexCounter ++; + if (line[1] === 't') { + + // Texture coord + var texCoord = self.textureCoords[self.textureCoords.push(new geo.TextureCoord(line)) - 1]; + + } else { + + // Just a simple vertex + var vertex = self.vertices[self.vertices.push(new geo.Vertex(line)) - 1]; + + } } else if (line[0] === 'f') { + // Create face var face = self.faces[self.faces.push(new geo.Face(line)) - 1]; - vertex_face[face.a].push(faceCounter); - vertex_face[face.b].push(faceCounter); - vertex_face[face.c].push(faceCounter); - if (vertex_face[face.d]) { - vertex_face[face.d].push(faceCounter); - } - - faceCounter ++; } - } - for (var vertex = 0; vertex < self.vertices.length; vertex++) { - self.orderedElements.push(self.vertices[vertex]); - for (var face = 0; face < vertex_face[vertex].length; face++) { - var faceToAdd = self.faces[vertex_face[vertex][face]]; - if (faceToAdd.max() <= vertex) { - self.orderedElements.push(faceToAdd); - } - } } if (typeof callback === 'function') { @@ -65,6 +63,73 @@ geo.MeshStreamer.prototype.loadFromFile = function(path, callback) { }); } +geo.MeshStreamer.prototype.tryMerge = function() { + if (this.faces[0].aTexture) { + return; + } else { + return this.merge(); + } +} + +geo.MeshStreamer.prototype.merge = function(callback) { + // Gives for each vertex the indices of the faces in which it is present + var vertexFace = []; + + // Result variable + var orderedElements = []; + + // For each vertex + for (var i = 0; i < this.vertices.length; i++) { + + // Init the list of faces where this vertex is + vertexFace.push([]); + + } + + + // For each face + for (var i = 0; i < this.faces.length; i++) { + + var face = this.faces[i]; + + // For each vertex of the face, and the face to the list of the correspondant vertex + vertexFace[face.a].push(i); + vertexFace[face.b].push(i); + vertexFace[face.c].push(i); + + if (vertexFace[face.d]) { + vertexFace[face.d].push(i); + } + + } + + // For each vertex + for (var vertex = 0; vertex < this.vertices.length; vertex++) { + + // Print the vertex + orderedElements.push(this.vertices[vertex]); + + // For each face that contains this vertex + for (var face = 0; face < vertexFace[vertex].length; face++) { + + var faceToAdd = this.faces[vertexFace[vertex][face]]; + + // If the face can be given (that means that all vertices have already been pushed) + if (faceToAdd.max() <= vertex) { + + // Add it now + orderedElements.push(faceToAdd); + } + } + } + + if (typeof callback === 'function') + callback(); + + return orderedElements; + +} + geo.Vertex = function() { if (typeof arguments[0] === 'string' || arguments[0] instanceof String) { var split = arguments[0].split(' '); @@ -91,12 +156,53 @@ geo.Vertex.prototype.toString = function() { return 'v ' + this.x + ' ' + this.y + ' ' + this.z; } -geo.Face = function() { +geo.TextureCoord = function() { if (typeof arguments[0] === 'string' || arguments[0] instanceof String) { var split = arguments[0].split(' '); - this.a = parseInt(split[1]) - 1; - this.b = parseInt(split[2]) - 1; - this.c = parseInt(split[3]) - 1; + this.x = parseFloat(split[1]); + this.y = parseFloat(split[2]); + } else if (arguments.length === 3) { + this.x = arguments[0]; + this.y = arguments[1]; + } else { + this.x = 0; + this.y = 0; + } + this.sent = false; +} + +geo.TextureCoord.prototype.toList = function() { + return ['v', this.x, this.y]; +} + +geo.TextureCoord.prototype.toString = function() { + return 'v ' + this.x + ' ' + this.y; +} + +geo.Face = function() { + 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" + var split = arguments[0].split(' '); + this.a = parseInt(split[1]) - 1; + this.b = parseInt(split[2]) - 1; + this.c = parseInt(split[3]) - 1; + } else { + // There might be textures coords + var split = arugments[0].split(' '); + + // Split elements + var split1 = split[1].split('/'); + var split2 = split[2].split('/'); + var split3 = split[3].split('/'); + + var vIndex = 0; + var tIndex = split1.length === 2 ? 1 : 2; + + this.a = split1[vIndex]; this.aTexture = split1[tIndex]; + this.b = split2[vIndex]; this.bTexture = split2[tIndex]; + this.c = split3[vIndex]; this.cTexture = split3[tIndex]; + } if (split.length === 5) this.d = parseInt(split[4]) - 1; diff --git a/socket.js b/socket.js index 93516d5..464a982 100644 --- a/socket.js +++ b/socket.js @@ -40,9 +40,9 @@ module.exports = function(io) { // console.log(socket.conn.remoteAddress + " connected !"); - socket.on('disconnect', function() { - console.log(socket.conn.remoteAddress + " disconnected !"); - }); + // socket.on('disconnect', function() { + // console.log(socket.conn.remoteAddress + " disconnected !"); + // }); socket.on("request", function(res) { // console.log('Asking for static/data/spheres/' + res + '.obj'); @@ -51,7 +51,14 @@ module.exports = function(io) { mesh = new geo.MeshStreamer(path, function() { socket.emit('ok'); + + // console.log("Display mesh !"); + // for (var i = 0; i < mesh.orderedElements.length; i++) { + // console.log(mesh.orderedElements[i].toString()); + // } + }); + }); socket.on('next', function() {