var Log = require('../lib/NodeLog.js'); /** * Represents a mesh. All meshes are loaded once in geo.availableMesh to avoid * loading at each mesh request * @constructor * @memberOf geo */ geo.MeshContainer = function(path, callback) { /** * array of each part of the mesh * @type {geo.Mesh[]} */ this.meshes = []; /** * array of the vertices of the meshes (all merged) * @type {geo.Vertex[]} */ this.vertices = []; /** * array of the faces of the meshes (all merged) * @type {geo.Face[]} */ this.faces = []; /** * array of the normals of the meshes (all merged) * @type {geo.Normal[]} */ this.normals = []; /** * array of the texture coordinates (all merged) * @type {geo.TexCoord[]} */ this.texCoords = []; /** * Number of elements to stream in the mesh * @type {Number} */ this.numberOfFaces = 0; this.callback = callback; if (path !== undefined) { this.loadFromFile(path); } }; /** * Loads a obj file * @param {string} path the path to the file */ geo.MeshContainer.prototype.loadFromFile = function(path) { var self = this; fs.readFile(path, {encoding: 'utf-8'}, 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 var texCoord = new geo.TexCoord(line); texCoord.index = self.texCoords.length; self.texCoords.push(texCoord); } else if (line[1] === 'n') { var normal = new geo.Normal(line); normal.index = self.normals.length; self.normals.push(normal); } else { // Just a simple vertex var vertex = new geo.Vertex(line); vertex.index = self.vertices.length; self.vertices.push(vertex); } } else if (line[0] === 'f') { self.numberOfFaces++; // Create mesh if it doesn't exist if (currentMesh === undefined) { currentMesh = new geo.Mesh(); self.meshes.push(currentMesh); } // Create faces (two if Face4) var faces = currentMesh.addFaces(line); faces[0].index = self.faces.length; faces[0].meshIndex = self.meshes.length - 1; self.faces.push(faces[0]); if (faces.length === 2) { self.numberOfFaces++; faces[1].index = self.faces.length; faces[1].meshIndex = self.meshes.length - 1; self.faces.push(faces[1]); } } else if (line[0] === 'u') { // usemtl // If a current mesh exists, finish it // Create a new mesh currentMesh = new geo.Mesh(); self.meshes.push(currentMesh); currentMesh.material = (new geo.Material(line)).name; // console.log(currentMesh.material); } } if (typeof self.callback === 'function') { self.callback(); } }); }; function trySetLoaded() { for (var name in availableMeshNames) { if (availableMeshNames[name] === false) { return; } } Log.ready("All meshes are ready"); } var availableMeshNames = { '/static/data/castle/princess peaches castle (outside).obj':false, '/static/data/mountain/coocoolmountain.obj':false, '/static/data/whomp/Whomps Fortress.obj':false, '/static/data/bobomb/bobomb battlefeild.obj':false, '/static/data/sponza/sponza.obj':false }; for (var i = 1; i < 26; i++) { availableMeshNames['/static/data/spheres/' + i + '.obj'] = false; } geo.availableMeshes = {}; function pushMesh(name) { geo.availableMeshes[name] = new geo.MeshContainer(name.substring(1, name.length), function() { availableMeshNames[name] = true; trySetLoaded(); }); } for (var name in availableMeshNames) { pushMesh(name); }