From f89e52dc5aea09779804c733a873136df958afaa Mon Sep 17 00:00:00 2001 From: Thomas FORGIONE Date: Mon, 15 Jun 2015 17:04:19 +0200 Subject: [PATCH] A lot of work, cleaning streaming --- geo/Mesh.js | 278 ++++++++++++------------------ geo/MeshStreamer.js | 173 +++++++++++++++++++ js/ProgressiveLoader.js | 362 +++++++++++++++++++--------------------- js/stream/main.js | 7 +- socket.js | 69 +------- 5 files changed, 465 insertions(+), 424 deletions(-) create mode 100644 geo/MeshStreamer.js diff --git a/geo/Mesh.js b/geo/Mesh.js index b5bdd72..c2022b1 100644 --- a/geo/Mesh.js +++ b/geo/Mesh.js @@ -1,152 +1,71 @@ -var fs = require('fs'); +var mesh = {}; -var geo = {}; - -geo.MeshStreamer = function(path, callback) { +// Mesh +mesh.Mesh = function() { this.vertices = []; - this.textureCoords = []; this.faces = []; - this.orderedElements = []; - this.index = 0; - - if (path !== undefined) { - var self = this; - this.loadFromFile(path, function() { - - self.orderedElements = self.tryMerge(); - - if (typeof callback === 'function') - callback(); - - }); - } + this.texCoords = []; + this.faceIndex = 0; + this.material = null; } -geo.MeshStreamer.prototype.loadFromFile = function(path, callback) { - var self = this; - fs.readFile(path, function(err, data) { +mesh.Mesh.prototype.addVertex = function(vertex) { - // Get lines from file - var lines = data.toString('utf-8').split("\n"); - - // For each line - for (var i = 0; i < lines.length; i++) { - - var line = lines[i]; - - if (line[0] === 'v') { - - if (line[1] === 't') { - - // Texture coord - var texCoord = self.textureCoords[self.textureCoords.push(new geo.TextureCoord(line)) - 1]; - self.orderedElements.push(texCoord); - - } else if (line[1] === 'n') { - - // Ignore normals - - } else { - - // Just a simple vertex - var vertex = self.vertices[self.vertices.push(new geo.Vertex(line)) - 1]; - self.orderedElements.push(vertex); - - } - - } else if (line[0] === 'f') { - - // Create face - var face = self.faces[self.faces.push(new geo.Face(line)) - 1]; - self.orderedElements.push(face); - - // Check - // if (face.max() >= self.vertices.length || face.maxTexture() >= self.textureCoords.length) { - // console.log("Error"); - // } - - } else if (line[0] === 'u') { - - // usemtl - self.orderedElements.push(new geo.Usemtl(line)); - - } - - } - - if (typeof callback === 'function') { - callback(); - } - }); -} - -geo.MeshStreamer.prototype.tryMerge = function() { - if (this.faces[0].aTexture !== undefined) { - return this.orderedElements; + if (vertex instanceof mesh.Vertex) { + this.vertices.push(vertex); + } else if (typeof vertex === 'string' || vertex instanceof String) { + this.vertices.push(new mesh.Vertex(vertex)); } else { - return this.merge(); + console.error("Can only add vertex from mesh.Vertex or string"); + return; + } + + return this.vertices[this.vertices.length - 1]; +} + +mesh.Mesh.prototype.addFaces = function(face) { + this.index = this.faces.length; + + var faces; + + 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; + } + + if (faces === undefined) { + return this.faces[this.faces.length - 1]; + } else { + return faces; } } -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([]); +mesh.Mesh.prototype.addTexCoord = function(texCoord) { + this.index = this.texCoords.length; + 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; } - // 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; - + return this.texCoords[this.texCoords.length - 1]; } -geo.Vertex = function() { +mesh.Mesh.prototype.isFinished = function() { + return this.faces.length === this.faceIndex; +} + +// Vertex +mesh.Vertex = function() { if (typeof arguments[0] === 'string' || arguments[0] instanceof String) { var split = arguments[0].replace(/\s+/g, " ").split(' '); this.x = parseFloat(split[1]); @@ -156,15 +75,17 @@ geo.Vertex = function() { this.sent = false; } -geo.Vertex.prototype.toList = function() { - return ['v', this.x, this.y, this.z]; +mesh.Vertex.prototype.toList = function() { + return ['v', this.index, this.x, this.y, this.z]; } -geo.Vertex.prototype.toString = function() { +mesh.Vertex.prototype.toString = function() { return 'v ' + this.x + ' ' + this.y + ' ' + this.z; } -geo.TextureCoord = function() { + +// TexCoord : texture coordinates +mesh.TexCoord = function() { if (typeof arguments[0] === 'string' || arguments[0] instanceof String) { var split = arguments[0].replace(/\s+/g, " ").split(' '); this.x = parseFloat(split[1]); @@ -173,15 +94,17 @@ geo.TextureCoord = function() { this.sent = false; } -geo.TextureCoord.prototype.toList = function() { - return ['vt', this.x, this.y]; +mesh.TexCoord.prototype.toList = function() { + return ['vt', this.index, this.x, this.y]; } -geo.TextureCoord.prototype.toString = function() { +mesh.TexCoord.prototype.toString = function() { return 'vt ' + this.x + ' ' + this.y; } -geo.Face = function() { + +// Face +mesh.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" @@ -190,9 +113,6 @@ geo.Face = function() { this.b = parseInt(split[2]) - 1; this.c = parseInt(split[3]) - 1; - if (split.length === 5) - this.d = parseInt(split[4]) - 1; - } else { // There might be textures coords var split = arguments[0].replace(/\s+/g, ' ').trim().split(' '); @@ -210,18 +130,38 @@ geo.Face = function() { this.b = parseInt(split2[vIndex]) - 1; this.bTexture = parseInt(split2[tIndex]) - 1; this.c = parseInt(split3[vIndex]) - 1; this.cTexture = parseInt(split3[tIndex]) - 1; - if (split.length === 5) { - var split4 = split[4].split('/'); - this.d = parseInt(split4[vIndex]) - 1; this.dTexture = parseInt(split4[tIndex]) - 1; - } } - } this.sent = false; + } -geo.Face.prototype.max = function() { + +var parseFace = function(arg) { + var split = arg.split(' '); + var ret = []; + + // Face3 + if (split.length >= 4) { + ret.push(new mesh.Face(arg)); + } + + 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() { if (this.d !== undefined) { return Math.max(this.a, this.b, this.c, this.d); } else { @@ -229,7 +169,7 @@ geo.Face.prototype.max = function() { } } -geo.Face.prototype.maxTexture = function() { +mesh.Face.prototype.maxTexture = function() { if (this.dTexture) { return Math.max(this.aTexture, this.bTexture, this.cTexture, this.dTexture); } else { @@ -237,38 +177,40 @@ geo.Face.prototype.maxTexture = function() { } } -geo.Face.prototype.toList = function() { - var l = ['f', this.a, this.b, this.c]; - if (this.d !== undefined) - l.push(this.d); +mesh.Face.prototype.toList = function() { + var l = ['f', this.index, this.a, this.b, this.c]; - if (this.aTexture !== undefined) { - l.push(this.aTexture); - l.push(this.bTexture); - l.push(this.cTexture); - } + // if (this.d !== undefined) + // l.push(this.d); - if (this.dTexture !== undefined) - l.push(this.dTexture); + // if (this.aTexture !== undefined) { + // l.push(this.aTexture); + // l.push(this.bTexture); + // l.push(this.cTexture); + // } + + // if (this.dTexture !== undefined) + // l.push(this.dTexture); return l; } -geo.Face.prototype.toString = function() { +mesh.Face.prototype.toString = function() { return 'f ' + this.a + ' ' + this.b + ' ' + this.c + (this.d !== undefined ? ' ' + this.d : ''); } -geo.Usemtl = function() { +// Material +mesh.Material = function() { var split = arguments[0].replace(/\s+/g, ' ').split(' '); this.name = split[1]; } -geo.Usemtl.prototype.toString = function() { +mesh.Material.prototype.toString = function() { return 'usemtl ' + this.name; } -geo.Usemtl.prototype.toList = function() { +mesh.Material.prototype.toList = function() { return ['u', this.name]; } -module.exports = geo; +module.exports = mesh; diff --git a/geo/MeshStreamer.js b/geo/MeshStreamer.js new file mode 100644 index 0000000..1677e6f --- /dev/null +++ b/geo/MeshStreamer.js @@ -0,0 +1,173 @@ +var fs = require('fs'); +var mesh = require('./Mesh.js'); + +var geo = {}; + +geo.MeshStreamer = function(path, callback) { + // Different parts of a obj (a mesh per material) + this.meshes = []; + + // In meshes, vertices and texture coords are shared + this.vertices = []; + this.faces = []; + this.texCoords = []; + + // Chunk size + this.chunk = 1000; + + if (path !== undefined) { + var self = this; + this.loadFromFile(path, function() { + + if (typeof callback === 'function') + callback(); + + }); + } +} + +geo.MeshStreamer.prototype.loadFromFile = function(path, callback) { + var self = this; + fs.readFile(path, function(err, data) { + + var currentMesh; + + // Get lines from file + var lines = data.toString('utf-8').split("\n"); + + // For each line + for (var i = 0; i < lines.length; i++) { + + var line = lines[i]; + + if (line[0] === 'v') { + + if (line[1] === 't') { + + // Texture coord + self.texCoords.push(new mesh.TexCoord(line)); + + } else if (line[1] === 'n') { + + // Ignore normals + + } else { + + // Just a simple vertex + if (currentMesh === undefined) { + // Chances are that we won't use any material in this case + currentMesh = new mesh.Mesh(); + self.meshes.push(currentMesh); + } + var vertex = currentMesh.addVertex(line); + vertex.index = self.vertices.length; + self.vertices.push(vertex); + + } + + } else if (line[0] === 'f') { + + // Create faces (two if Face4) + var faces = currentMesh.addFaces(line); + + faces[0].index = self.faces.length; + self.faces.push(faces[0]); + if (faces.length === 2) { + faces[1].index = self.faces.length; + self.faces.push(faces[1]); + } + + } else if (line[0] === 'u') { + + // usemtl + + // Create a new mesh + currentMesh = new mesh.Mesh(); + self.meshes.push(currentMesh); + currentMesh.material = mesh.Material(line); + self.orderedElements.push(new mesh.Usemtl(line)); + + } + + } + + if (typeof callback === 'function') { + callback(); + } + }); +} + +geo.MeshStreamer.prototype.start = function(socket) { + + this.meshIndex = -1; + + var self = this; + + socket.on('request', function(path) { + console.log('Asking for ' + path); + + var regex = /.*\.\..*/; + + if (regex.test(path)) { + socket.emit('refused'); + socket.disconnect(); + return; + } + + self.loadFromFile(path, function() { + socket.emit('ok'); + }); + + }); + + socket.on('next', function() { + + // Send next elements + var currentMesh = self.meshes[self.meshIndex]; + + if (currentMesh === undefined || currentMesh.isFinished()) { + currentMesh = self.meshes[++self.meshIndex]; + + if (currentMesh === undefined) { + socket.emit('finished'); + socket.disconnect(); + return; + } + + socket.emit( + 'usemtl', + currentMesh.material, + currentMesh.vertices.length, + currentMesh.faces.length, + currentMesh.texCoords.length + ); + + } else { + + var data = []; + + for (var limit = Math.min(currentMesh.faceIndex + self.chunk, currentMesh.faces.length); + currentMesh.faceIndex < limit; + currentMesh.faceIndex++) + { + + var currentFace = currentMesh.faces[currentMesh.faceIndex]; + var vertex1 = self.vertices[currentFace.a]; + var vertex2 = self.vertices[currentFace.b]; + var vertex3 = self.vertices[currentFace.c]; + + if (!vertex1.sent) { data.push(vertex1.toList()); vertex1.sent = true;} + if (!vertex2.sent) { data.push(vertex2.toList()); vertex2.sent = true;} + if (!vertex3.sent) { data.push(vertex3.toList()); vertex3.sent = true;} + + data.push(currentFace.toList()); currentFace.sent = true; + } + + // Emit self.chunk faces (and the corresponding vertices if not emitted) + socket.emit('elements', data); + + } + }); +} + +module.exports = geo; diff --git a/js/ProgressiveLoader.js b/js/ProgressiveLoader.js index 6eed38c..aa518c7 100644 --- a/js/ProgressiveLoader.js +++ b/js/ProgressiveLoader.js @@ -1,194 +1,182 @@ +var _parseList = function(arr) { + + // For example + // arr = [ 'f', 0, 0, 1, 2]; + // type index first second third + + var ret = {}; + ret.index = arr[1]; + + if (arr[0] === 'v') { + ret.type = 'vertex'; + ret.x = arr[2]; + ret.y = arr[3]; + ret.z = arr[4]; + } else if (arr[0] === 'vt') { + ret.type = 'texCoord'; + ret.x = arr[2]; + ret.y = arr[3]; + } else if (arr[0] === 'f') { + ret.type = 'face'; + + if (arr.length === 5 ) { + + // Simple Face3 + ret.a = arr[2]; + ret.b = arr[3]; + ret.c = arr[4]; + + } else if (arr.length === 8) { + + // Face3 with textures and maybe normals + ret.a = arr[2]; + ret.b = arr[3]; + ret.c = arr[4]; + + } + } + + return ret; +} + var ProgressiveLoader = function(path, scene, callback) { - // Create MTLLoader - var loader = new THREE.MTLLoader(path.substring(0, path.lastIndexOf('/')) + '/'); - loader.load(path.replace('.obj', '.mtl'), function(materialCreator) { + // Init attributes + this.objPath = path; + this.texturesPath = path.substring(0, path.lastIndexOf('/')) + '/'; + this.mtlPath = path.replace('.obj', '.mtl'); + this.scene = scene; + this.callback = callback; + this.counter = 0; + + this.obj = new THREE.Object3D(); + + scene.add(this.obj); + + this.vertices = []; + this.texCoords = []; + + // Init MTLLoader + this.loader = new THREE.MTLLoader(this.texturesPath); + + // Init io stuff + this.socket = io(); + this.initIOCallbacks(); + +} + +ProgressiveLoader.prototype.load = function() { + + var self = this; + + this.loader.load(self.mtlPath, function(materialCreator) { materialCreator.preload(); - // Create mesh - var obj = new THREE.Object3D(); - obj.up = new THREE.Vector3(0,0,1); - glob = obj; - - var currentMesh; - var currentMaterial; - - var added = false; - var finished = false; - - var socket = io(); - - var vertices = []; - var textCoords = []; - var uvs = []; - var faces = []; - - // Init streaming with socket - socket.emit('request', path.substring(1, path.length)); - - // When server's ready, start asking for the mesh - socket.on('ok', function() { - socket.emit('next'); - }); - - // When receiving elements - socket.on('elements', function(arr) { - - console.log("Got stuff"); - - if (!finished) { - socket.emit('next'); - } - - // Launch this code in async - setTimeout(function() { - - // We'll receive an array of string (obj) - for (var i = 0; i < arr.length; i++) { - - var elts = arr[i]; - - // console.log(line); - - if (elts[0] === 'v') { - - vertices.push(new THREE.Vector3( - elts[1], - elts[2], - elts[3] - )); - - } else if (elts[0] === 'vt') { - - textCoords.push(new THREE.Vector2( - elts[1], - elts[2] - )); - - } else if (elts[0] === 'f') { - - faces.push(new THREE.Face3( - elts[1], - elts[2], - elts[3] - )); - - // If the face has 4 vertices, create second triangle - if (elts.length === 5 || elts.length === 9) { - - faces.push(new THREE.Face3( - elts[1], - elts[3], - elts[4] - )); - - } - - // Add texture - if (elts.length === 7) { - uvs.push([ - textCoords[elts[4]], - textCoords[elts[5]], - textCoords[elts[6]] - ]); - } - - if (elts.length === 9) { - uvs.push([ - textCoords[elts[5]], - textCoords[elts[6]], - textCoords[elts[7]] - ]); - } - - if (elts.length === 9) { - uvs.push([ - textCoords[elts[5]], - textCoords[elts[7]], - textCoords[elts[8]] - ]); - } - - // Add currentMesh to scene one there are a few faces in it - if (!added) { - scene.add(obj); - added = true; - } - - if (!currentMesh) { - var geo = new THREE.Geometry(); - geo.vertices = vertices; - geo.faces = faces; - geo.faceVertexUvs = [uvs]; - - - var material, tmp = currentMaterial; - if (currentMaterial === undefined || currentMaterial === null) { - material = new THREE.MeshLambertMaterial({color: 'red'}); - } else { - material = materialCreator.materials[currentMaterial.trim()]; - material.side = THREE.DoubleSide; - if (material.map) - material.map.wrapS = material.map.wrapT = THREE.RepeatWrapping; - - currentMaterial = null; - } - currentMesh = new THREE.Mesh(geo, material); - - if (typeof callback === 'function') { - callback(currentMesh, obj); - } - - currentMesh.geometry.computeFaceNormals(); - } - obj.add(currentMesh); - - } else if (elts[0] === 'u') { - - // Add current mesh - // if (currentMesh) { - // obj.add(currentMesh); - // } - - // Prepare new mesh - faces = []; - uvs = []; - // currentMesh.geometry.computeFaceNormals(); - if (currentMesh) { - currentMesh.geometry.computeFaceNormals(); - currentMesh.geometry.computeBoundingSphere(); - currentMesh.geometry.groupsNeedUpdate = true; - currentMesh.geometry.elementsNeedUpdate = true; - currentMesh.geometry.normalsNeedUpdate = true; - currentMesh.geometry.uvsNeedUpdate = true; - } - currentMaterial = elts[1]; - currentMesh = null; - - // console.log(material.map); - // currentMesh = new THREE.Mesh(geo, material); - - } - - } - - if (currentMesh) { - currentMesh.material.side = THREE.DoubleSide; - currentMesh.geometry.computeFaceNormals(); - currentMesh.geometry.computeBoundingSphere(); - currentMesh.geometry.groupsNeedUpdate = true; - currentMesh.geometry.elementsNeedUpdate = true; - currentMesh.geometry.normalsNeedUpdate = true; - currentMesh.geometry.uvsNeedUpdate = true; - } - - },0); - }); - - socket.on('disconnect', function() { - console.log("Finished"); - finished = true; - }); + self.start(); }); } + +ProgressiveLoader.prototype.initIOCallbacks = function() { + + var self = this; + + this.socket.on('usemtl', function(materialName, verticesNumber, facesNumber, texCoordsNumber) { + + // Create mesh material + var material; + + if (materialName === null) { + + // If no material, create a default material + material = new THREE.MeshLambertMaterial({color: 'red'}); + + } else { + + // If material name exists, load if from material, and do a couple of settings + material = materialCreator.materials[currentMaterial.trim()]; + + material.side = THREE.DoubleSide; + + if (material.map) + material.map.wrapS = material.map.wrapT = THREE.RepeatWrapping; + } + + // Create mesh geometry + var geometry = new THREE.BufferGeometry(); + geometry.dynamic = true; + + var positionArray = new Float32Array(facesNumber * 3 * 3); + var positionAttribute = new THREE.BufferAttribute(positionArray, 3); + + geometry.addAttribute('position', positionAttribute); + + // Create mesh + var mesh = new THREE.Mesh(geometry, material); + + // Add mesh to obj + self.currentMesh = mesh; + self.obj.add(mesh); + + // Ask for next + self.socket.emit('next'); + }); + + this.socket.on('ok', function() { + console.log('ok'); + self.socket.emit('next'); + }); + + this.socket.on('elements', function(arr) { + + console.log("Received elements for the " + (++self.counter) + "th time !"); + + for (var i = 0; i < arr.length; i++) { + + var elt = _parseList(arr[i]); + + // console.log(elts); + if (elt.type === 'vertex') { + + // New vertex arrived + self.vertices[elt.index] = [elt.x, elt.y, elt.z]; + + } else if (elt.type === 'texCoord') { + + // New texCoord arrived + self.texCoords[elt.index] = [elt.x, elt.y, elt.z]; + + } else if (elt.type === 'face') { + + // New face arrived : add it into current mesh + self.currentMesh.geometry.attributes.position.array[elt.index * 9 ] = self.vertices[elt.a][0]; + self.currentMesh.geometry.attributes.position.array[elt.index * 9 + 1] = self.vertices[elt.a][1]; + self.currentMesh.geometry.attributes.position.array[elt.index * 9 + 2] = self.vertices[elt.a][2]; + + self.currentMesh.geometry.attributes.position.array[elt.index * 9 + 3] = self.vertices[elt.b][0]; + self.currentMesh.geometry.attributes.position.array[elt.index * 9 + 4] = self.vertices[elt.b][1]; + self.currentMesh.geometry.attributes.position.array[elt.index * 9 + 5] = self.vertices[elt.b][2]; + + self.currentMesh.geometry.attributes.position.array[elt.index * 9 + 6] = self.vertices[elt.c][0]; + self.currentMesh.geometry.attributes.position.array[elt.index * 9 + 7] = self.vertices[elt.c][1]; + self.currentMesh.geometry.attributes.position.array[elt.index * 9 + 8] = self.vertices[elt.c][2]; + + self.currentMesh.geometry.attributes.position.needsUpdate = true; + + } + } + + // Ask for next elements + self.socket.emit('next'); + }); + + this.socket.on('disconnect', function() { + console.log('Finished !'); + self.finished = true; + }); +} + +ProgressiveLoader.prototype.start = function() { + this.socket.emit('request', this.objPath); +} + diff --git a/js/stream/main.js b/js/stream/main.js index c705add..a72ad07 100644 --- a/js/stream/main.js +++ b/js/stream/main.js @@ -1,5 +1,5 @@ var mesh_number = 25; -var renderer, scene, controls, cube, container, plane, mouse= {x:0, y:0}, sphere; +var renderer, scene, controls, cube, container, plane, mouse= {x:0, y:0}, sphere, sphereLoader; var bigmesh; var raycaster; var objects = []; @@ -45,7 +45,9 @@ function init() { // Load the scene // loader = new THREE.OBJLoader(); - sphere = ProgressiveLoader('static/data/spheres/' + params.get.res + '.obj', scene); + sphereLoader = new ProgressiveLoader('static/data/spheres/' + params.get.res + '.obj', scene); + sphereLoader.load(); + sphere = sphereLoader.obj; plane = new Plane(1000,1000); plane.translate(0,0,-100); @@ -54,7 +56,6 @@ function init() { } function animate() { - // on appelle la fonction animate() récursivement à chaque frame requestAnimationFrame(animate); var currentTime = Date.now() - previousTime; diff --git a/socket.js b/socket.js index 54dac6e..f0aedb8 100644 --- a/socket.js +++ b/socket.js @@ -1,76 +1,13 @@ var fs = require('fs'); var sleep = require('sleep'); -var geo = require('./geo/Mesh.js'); +var geo = require('./geo/MeshStreamer.js'); module.exports = function(io) { io.on('connection', function(socket) { - var index = 0; - var vIndex = 0; - var fIndex = 0; - var mesh; + var streamer = new geo.MeshStreamer(); - // console.log(socket.conn.remoteAddress + " connected !"); + streamer.start(socket); - // socket.on('disconnect', function() { - // console.log(socket.conn.remoteAddress + " disconnected !"); - // }); - - socket.on("request", function(path) { - // console.log('Asking for static/data/spheres/' + res + '.obj'); - - var regex = /.*\.\..*/; - - if (regex.test(path)) { - socket.emit('error'); - socket.disconnect(); - } - - 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()); - // } - - // var counter = 0; - // for (var i = 0; i < mesh.orderedElements.length; i++) { - // if (mesh.orderedElements[i] instanceof geo.Usemtl) { - // counter++; - // } - // } - // console.log(counter); - - }); - - }); - - socket.on('next', function() { - - var bound = 500; - var toSend = []; - var elt; - - for (var limit = mesh.index + bound; mesh.index < limit; mesh.index++) { - - elt = mesh.orderedElements[mesh.index]; - - if (elt) { - elt.sent = true; - toSend.push(elt.toList()); - } else { - break; - } - - } - - socket.emit('elements', toSend); - - if (!elt) { - socket.disconnect(); - } - - }); }); }