Some cleaning 😢
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
var fs = require('fs');
|
||||
|
||||
/**
|
||||
* @namespace
|
||||
*/
|
||||
var geo = {};
|
||||
|
||||
if (typeof module === 'object') {
|
||||
|
||||
module.exports = geo;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
OPT=--compilation_level SIMPLE_OPTIMIZATIONS
|
||||
|
||||
ifeq ($(TYPE),RELEASE)
|
||||
CLOSURE=java -jar ../../utils/closure-compiler/closure-compiler.jar
|
||||
else
|
||||
CLOSURE=../../utils/simple-compiler/compiler.sh
|
||||
endif
|
||||
|
||||
all: Geo
|
||||
|
||||
Geo:
|
||||
$(CLOSURE) $(OPT) \
|
||||
--js Geo.js \
|
||||
--js Mesh.js \
|
||||
--js MeshContainer.js \
|
||||
--js MeshStreamer.js \
|
||||
--js_output_file ../lib/geo.min.js
|
||||
@@ -0,0 +1,504 @@
|
||||
/**
|
||||
* Reprensents a mesh
|
||||
* @constructor
|
||||
* @memberOf geo
|
||||
*/
|
||||
geo.Mesh = function() {
|
||||
this.vertices = [];
|
||||
this.faces = [];
|
||||
this.texCoords = [];
|
||||
this.normals = [];
|
||||
this.faceIndex = 0;
|
||||
this.material = null;
|
||||
this.started = false;
|
||||
this.finished = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if there are normals in the mesh
|
||||
* @returns {Boolean} true if there are normals in the mesh, false otherwise
|
||||
*/
|
||||
geo.Mesh.prototype.hasNormals = function() {
|
||||
return this.normals.length > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if there are texture coordinates in the mesh
|
||||
* @returns {Boolean} true if there are texture coordinates in the mesh, false otherwise
|
||||
*/
|
||||
geo.Mesh.prototype.hasTexCoords = function() {
|
||||
return this.texCoords.length > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a vertex to a mesh
|
||||
* @param {geo.Vertex|String} A Vertex object or its string representation
|
||||
*/
|
||||
geo.Mesh.prototype.addVertex = function(vertex) {
|
||||
|
||||
if (vertex instanceof geo.Vertex) {
|
||||
this.vertices.push(vertex);
|
||||
} else if (typeof vertex === 'string' || vertex instanceof String) {
|
||||
this.vertices.push(new geo.Vertex(vertex));
|
||||
} else {
|
||||
console.error("Can only add vertex from geo.Vertex or string");
|
||||
return;
|
||||
}
|
||||
|
||||
return this.vertices[this.vertices.length - 1];
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a face to a mesh
|
||||
* @param {geo.Face|String} A Face object or its string representation
|
||||
*/
|
||||
geo.Mesh.prototype.addFaces = function(face) {
|
||||
var faces;
|
||||
|
||||
if (face instanceof geo.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 geo.Face or string");
|
||||
return;
|
||||
}
|
||||
|
||||
if (faces === undefined) {
|
||||
return this.faces[this.faces.length - 1];
|
||||
} else {
|
||||
return faces;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a texture coordinate to a mesh
|
||||
* @param {geo.TexCoord|String} A TexCoord object or its string representation
|
||||
*/
|
||||
geo.Mesh.prototype.addTexCoord = function(texCoord) {
|
||||
if (texCoord instanceof geo.TexCoord) {
|
||||
this.texCoords.push(texCoord);
|
||||
} else if (typeof texCoord === 'string' || texCoord instanceof String) {
|
||||
this.texCoords.push(new geo.TexCoord(texCoord));
|
||||
} else {
|
||||
console.error("Can only add texCoord from geo.TexCoord or string");
|
||||
return;
|
||||
}
|
||||
|
||||
return this.texCoords[this.texCoords.length - 1];
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a normal to a mesh
|
||||
* @param {geo.Normal|String} A Normal object or its string representation
|
||||
*/
|
||||
geo.Mesh.prototype.addNormal = function(normal) {
|
||||
if (normal instanceof geo.Normal) {
|
||||
this.normals.push(normal);
|
||||
} else if (typeof normal === 'string' || normal instanceof String) {
|
||||
this.normals.push(new geo.Normal(normal));
|
||||
} else {
|
||||
console.error("Can only add normal from geo.Normal of string");
|
||||
return;
|
||||
}
|
||||
|
||||
return this.normals[this.normals.length - 1];
|
||||
};
|
||||
|
||||
geo.Mesh.prototype.isFinished = function() {
|
||||
return this.faceIndex === this.faces.length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represent a 3D vertex
|
||||
* @constructor
|
||||
* @memberOf geo
|
||||
*/
|
||||
geo.Vertex = function() {
|
||||
if (typeof arguments[0] === 'string' || arguments[0] instanceof String) {
|
||||
var split = arguments[0].replace(/\s+/g, " ").split(' ');
|
||||
|
||||
/**
|
||||
* x coordinate of the vertex
|
||||
* @type {Number}
|
||||
*/
|
||||
this.x = parseFloat(split[1]);
|
||||
|
||||
/**
|
||||
* y coordinate of the vertex
|
||||
* @type {Number}
|
||||
*/
|
||||
this.y = parseFloat(split[2]);
|
||||
|
||||
/**
|
||||
* z coordinate of the vertex
|
||||
* @type {Number}
|
||||
*/
|
||||
this.z = parseFloat(split[3]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the vertex has been sent or not
|
||||
* @type {Boolean}
|
||||
*/
|
||||
this.sent = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gives a list representation of the vertex
|
||||
* @returns {Array} An array representing the vertex
|
||||
*
|
||||
* @example
|
||||
* var vertex = new geo.Vertex('v 3.5 3.6 3.7');
|
||||
* vertex.index = 5;
|
||||
* console.log(vertex.toList()); // Prints ['v', 5, 3.5, 3.6, 3.7]
|
||||
*/
|
||||
geo.Vertex.prototype.toList = function() {
|
||||
return ['v', this.index, this.x, this.y, this.z];
|
||||
};
|
||||
|
||||
/**
|
||||
* Gives a string representation of the vertex
|
||||
* @returns {string} A string representing the vertex
|
||||
*
|
||||
* @example
|
||||
* var vertex = new geo.Vertex('v 3.5 3.6 3.7');
|
||||
* console.log(vertex.toString()); // Prints v 3.5 3.6 3.7
|
||||
*/
|
||||
geo.Vertex.prototype.toString = function() {
|
||||
return 'v ' + this.x + ' ' + this.y + ' ' + this.z;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represent a 3D normal
|
||||
* @constructor
|
||||
* @memberOf geo
|
||||
* @augments geo.Vertex
|
||||
*/
|
||||
geo.Normal = function() {
|
||||
geo.Vertex.apply(this, arguments);
|
||||
};
|
||||
|
||||
geo.Normal.prototype = Object.create(geo.Vertex.prototype);
|
||||
geo.Normal.prototype.constructor = geo.Normal;
|
||||
|
||||
/**
|
||||
* Gives a list representation of the normal
|
||||
* @returns {Array} An array representing the normal
|
||||
*
|
||||
* @example
|
||||
* var normal = new geo.Normal('vn 3.5 3.6 3.7');
|
||||
* normal.index = 5;
|
||||
* console.log(normal.toList()); // Prints ['vn', 5, 3.5, 3.6, 3.7]
|
||||
*/
|
||||
geo.Normal.prototype.toList = function() {
|
||||
var superObject = geo.Vertex.prototype.toList.call(this);
|
||||
superObject[0] = 'vn';
|
||||
return superObject;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gives a string representation of the normal
|
||||
* @returns {string} A string representing the normal
|
||||
*
|
||||
* @example
|
||||
* var normal = new geo.Normal('vn 3.5 3.6 3.7');
|
||||
* console.log(normal.toString()); // Prints vn 3.5 3.6 3.7
|
||||
*/
|
||||
geo.Normal.prototype.toString = function() {
|
||||
var superObject = geo.Vertex.prototype.toString.call(this);
|
||||
superObject.replace('v', 'vn');
|
||||
return superObject;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represent a texture coordinate element
|
||||
* @constructor
|
||||
* @memberOf geo
|
||||
*/
|
||||
geo.TexCoord = function() {
|
||||
if (typeof arguments[0] === 'string' || arguments[0] instanceof String) {
|
||||
var split = arguments[0].replace(/\s+/g, " ").split(' ');
|
||||
|
||||
/**
|
||||
* x coordinate of the texture
|
||||
* @type {Number}
|
||||
*/
|
||||
this.x = parseFloat(split[1]);
|
||||
|
||||
/**
|
||||
* y coordinate of the texture
|
||||
* @type {Number}
|
||||
*/
|
||||
this.y = parseFloat(split[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the vertex has been sent or not
|
||||
* @type {Boolean}
|
||||
*/
|
||||
this.sent = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gives a list representation of the texture coordinate
|
||||
* @returns {Array} An array representing the texture coordinate
|
||||
*
|
||||
* @example
|
||||
* var texCoord = new geo.TexCoord('vt 3.5 3.6');
|
||||
* texture coordinate.index = 5;
|
||||
* console.log(texture coordinate.toList()); // Prints ['vt', 5, 3.5, 3.6]
|
||||
*/
|
||||
geo.TexCoord.prototype.toList = function() {
|
||||
return ['vt', this.index, this.x, this.y];
|
||||
};
|
||||
|
||||
/**
|
||||
* Gives a string representation of the texture coordinate
|
||||
* @returns {string} A string representing the texture coordinate
|
||||
*
|
||||
* @example
|
||||
* var texCoord = new geo.TexCoord('vt 3.5 3.6');
|
||||
* console.log(texCoord.toString()); // Prints vt 3.5 3.6
|
||||
*/
|
||||
geo.TexCoord.prototype.toString = function() {
|
||||
return 'vt ' + this.x + ' ' + this.y;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Represents a face
|
||||
* @constructor
|
||||
* @memberOf geo
|
||||
*/
|
||||
geo.Face = function() {
|
||||
var split;
|
||||
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"
|
||||
split = arguments[0].replace(/\s+/g, ' ').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
|
||||
split = arguments[0].replace(/\s+/g, ' ').trim().split(' ');
|
||||
|
||||
// Split elements
|
||||
var split1 = split[1].split('/');
|
||||
var split2 = split[2].split('/');
|
||||
var split3 = split[3].split('/');
|
||||
|
||||
var vIndex = 0;
|
||||
var tIndex = 1;
|
||||
var nIndex = 2;
|
||||
|
||||
/**
|
||||
* index of the first vertex of the face
|
||||
* @type {Number}
|
||||
*/
|
||||
this.a = parseInt(split1[vIndex]) - 1;
|
||||
|
||||
/**
|
||||
* index of the second vertex of the face
|
||||
* @type {Number}
|
||||
*/
|
||||
this.b = parseInt(split2[vIndex]) - 1;
|
||||
|
||||
/**
|
||||
* index of the third vertex of the face
|
||||
* @type {Number}
|
||||
*/
|
||||
this.c = parseInt(split3[vIndex]) - 1;
|
||||
|
||||
/**
|
||||
* index of the texture coordinate of the first vertex of the face
|
||||
* @type {Number}
|
||||
*/
|
||||
this.aTexture = parseInt(split1[tIndex]) - 1;
|
||||
|
||||
/**
|
||||
* index of the texture coordinate of the second vertex of the face
|
||||
* @type {Number}
|
||||
*/
|
||||
this.bTexture = parseInt(split2[tIndex]) - 1;
|
||||
|
||||
/**
|
||||
* index of the texture coordinate of the third vertex of the face
|
||||
* @type {Number}
|
||||
*/
|
||||
this.cTexture = parseInt(split3[tIndex]) - 1;
|
||||
|
||||
/**
|
||||
* index of the normal of the first vertex of the face
|
||||
* @type {Number}
|
||||
*/
|
||||
this.aNormal = parseInt(split1[nIndex]) - 1;
|
||||
|
||||
/**
|
||||
* index of the normal of the second vertex of the face
|
||||
* @type {Number}
|
||||
*/
|
||||
this.bNormal = parseInt(split2[nIndex]) - 1;
|
||||
|
||||
/**
|
||||
* index of the normal of the third vertex of the face
|
||||
* @type {Number}
|
||||
*/
|
||||
this.cNormal = parseInt(split3[nIndex]) - 1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the vertex has been sent or not
|
||||
* @type {Boolean}
|
||||
*/
|
||||
this.sent = false;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse a face line and returns an array of faces
|
||||
*
|
||||
* @private
|
||||
* @param {String} a string representing a face
|
||||
* @returns {Face[]} a single 3-vertices face or two 3-vertices face if it was
|
||||
* a 4-vertices face
|
||||
*/
|
||||
var parseFace = function(arg) {
|
||||
|
||||
var split = arg.trim().split(' ');
|
||||
var ret = [];
|
||||
|
||||
// Face3
|
||||
if (split.length >= 4) {
|
||||
ret.push(new geo.Face(arg));
|
||||
}
|
||||
|
||||
// Face3 == 2 * Face3
|
||||
if (split.length >= 5) {
|
||||
ret.push(new geo.Face(
|
||||
[
|
||||
split[0],
|
||||
split[1],
|
||||
split[3],
|
||||
split[4]
|
||||
].join(' ')
|
||||
));
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the max index of the vertices of the face
|
||||
* @returns {Number} the max index of the vertices
|
||||
*/
|
||||
geo.Face.prototype.max = function() {
|
||||
if (this.d !== undefined) {
|
||||
return Math.max(this.a, this.b, this.c, this.d);
|
||||
} else {
|
||||
return Math.max(this.a, this.b, this.c);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the max index of the texture coordinates of the face
|
||||
* @returns {Number} the max index of the texture coordinates
|
||||
*/
|
||||
geo.Face.prototype.maxTexture = function() {
|
||||
if (this.dTexture) {
|
||||
return Math.max(this.aTexture, this.bTexture, this.cTexture, this.dTexture);
|
||||
} else {
|
||||
return Math.max(this.aTexture, this.bTexture, this.cTexture);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gives a list representation of the face
|
||||
* @returns {Array} An array representing the texture coordinate
|
||||
* <ol start=0>
|
||||
* <li>'f'</li>
|
||||
* <li>the index of the face</li>
|
||||
* <li>a list containing the indices of the vertex of the face</li>
|
||||
* <li>a list containing the indices of the texture coordinates</li>
|
||||
* <li>a list containing the indices of the normals</li>
|
||||
* </ol>
|
||||
*
|
||||
* @example
|
||||
* var face = new geo.Face('f 1/2/3 4/5/6 7/8/9');
|
||||
* texture coordinate.index = 5;
|
||||
* console.log(texture coordinate.toList()); // Prints ['f', 5, [1,4,7], [2,5,8], [3,6,9]]
|
||||
*/
|
||||
geo.Face.prototype.toList = function() {
|
||||
var l = ['f', this.index, this.meshIndex,
|
||||
[this.a, this.b, this.c ],
|
||||
isNaN(this.aTexture) ? [] : [this.aTexture, this.bTexture, this.cTexture],
|
||||
isNaN(this.aNormal ) ? [] : [this.aNormal, this.bNormal, this.cNormal ]
|
||||
];
|
||||
|
||||
// if (this.d !== undefined)
|
||||
// l.push(this.d);
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gives a string representation of the face
|
||||
* @returns {string} A string representing the face
|
||||
*
|
||||
* @example
|
||||
* var face = new geo.Face('f 3 5 6');
|
||||
* console.log(face.toString()); // Prints f 3 5 6
|
||||
*/
|
||||
geo.Face.prototype.toString = function() {
|
||||
return 'f ' + this.a + ' ' + this.b + ' ' + this.c + (this.d !== undefined ? ' ' + this.d : '');
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a material name
|
||||
* @constructor
|
||||
* @param {string} line the string representing the material
|
||||
* @memberOf geo
|
||||
*/
|
||||
geo.Material = function() {
|
||||
var split = arguments[0].replace(/\s+/g, ' ').trim().split(' ');
|
||||
|
||||
/**
|
||||
* The name of the material
|
||||
* @type {string}
|
||||
*/
|
||||
this.name = split[1];
|
||||
};
|
||||
|
||||
/**
|
||||
* Gives a string representation of the material
|
||||
* @returns {string} obj representation of usemtl
|
||||
*/
|
||||
geo.Material.prototype.toString = function() {
|
||||
return 'usemtl ' + this.name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gives a list representation of the material
|
||||
* @returns {array} an array representing the material
|
||||
* @example
|
||||
* var material = new geo.Material('usemtl MyMaterial');
|
||||
* console.log(material.toList()); // Logs ['u', 'MyMaterial']
|
||||
*/
|
||||
geo.Material.prototype.toList = function() {
|
||||
return ['u', this.name];
|
||||
};
|
||||
|
||||
@@ -0,0 +1,381 @@
|
||||
var Log = require('../lib/NodeLog.js');
|
||||
var L3D = require('../../static/js/l3d.min.js');
|
||||
var THREE = require('three');
|
||||
|
||||
function clone(vec) {
|
||||
return {x : vec.x, y : vec.y, z : vec.z};
|
||||
}
|
||||
|
||||
function rotation(vec1, x, y, z) {
|
||||
|
||||
var cos = Math.cos(z);
|
||||
var sin = Math.sin(z);
|
||||
|
||||
var newVec = {x:0, y:0, z:0};
|
||||
oldVec = clone(vec1);
|
||||
|
||||
newVec.x = cos * oldVec.x - sin * oldVec.y;
|
||||
newVec.y = sin * oldVec.x + cos * oldVec.y;
|
||||
newVec.z = oldVec.z;
|
||||
|
||||
oldVec = clone(newVec);
|
||||
|
||||
cos = Math.cos(y);
|
||||
sin = Math.sin(y);
|
||||
|
||||
newVec.x = cos * oldVec.x + sin * oldVec.z;
|
||||
newVec.y = oldVec.y;
|
||||
newVec.z = - sin * oldVec.x + cos * oldVec.z;
|
||||
|
||||
cos = Math.cos(x);
|
||||
sin = Math.sin(x);
|
||||
|
||||
oldVec = clone(newVec);
|
||||
|
||||
newVec.x = oldVec.x;
|
||||
newVec.y = oldVec.y * cos - oldVec.z * sin;
|
||||
newVec.z = oldVec.y * sin + oldVec.z * cos;
|
||||
|
||||
return clone(newVec);
|
||||
}
|
||||
|
||||
function applyTransformation(vector, transfo) {
|
||||
|
||||
var ret = rotation(vector, transfo.rotation.x, transfo.rotation.y, transfo.rotation.z);
|
||||
var scale = transfo.scale || 1;
|
||||
|
||||
return {
|
||||
x: (ret.x + transfo.translation.x) * scale,
|
||||
y: (ret.y + transfo.translation.y) * scale,
|
||||
z: (ret.z + transfo.translation.z) * scale
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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, transfo, callback) {
|
||||
|
||||
if (callback === undefined && typeof transfo === 'function') {
|
||||
callback = transfo;
|
||||
transfo = {translation: {x:0,y:0,z:0}, rotation: {x:0,y:0,z:0}};
|
||||
}
|
||||
|
||||
if (transfo === undefined) {
|
||||
transfo = {translation: {x:0,y:0,z:0}, rotation: {x:0,y:0,z:0}};
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.transfo = transfo;
|
||||
|
||||
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);
|
||||
var vertexTransformed = applyTransformation(vertex, self.transfo);
|
||||
|
||||
vertex.x = vertexTransformed.x;
|
||||
vertex.y = vertexTransformed.y;
|
||||
vertex.z = vertexTransformed.z;
|
||||
|
||||
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].done === false) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Log.ready("Meshes loaded in " + (Date.now() - start) + 'ms');
|
||||
}
|
||||
|
||||
var availableMeshNames = {
|
||||
'/static/data/castle/princess peaches castle (outside).obj': {
|
||||
done: false,
|
||||
recommendations : L3D.createPeachRecommendations(1134, 768)
|
||||
|
||||
},
|
||||
'/static/data/mountain/coocoolmountain.obj': {
|
||||
done: false,
|
||||
recommendations : L3D.createMountainRecommendations(1134, 768)
|
||||
},
|
||||
'/static/data/mountain/coocoolmountain_sub.obj': {
|
||||
done: false,
|
||||
recommendations : L3D.createMountainRecommendations(1134, 768)
|
||||
},
|
||||
'/static/data/whomp/Whomps Fortress.obj': {
|
||||
done: false,
|
||||
transfo: {
|
||||
rotation: {
|
||||
x: -Math.PI / 2,
|
||||
y: 0,
|
||||
z: Math.PI / 2
|
||||
},
|
||||
translation: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
},
|
||||
scale: 0.1
|
||||
},
|
||||
recommendations : L3D.createWhompRecommendations(1134, 768)
|
||||
},
|
||||
'/static/data/whomp/Whomps Fortress_sub.obj': {
|
||||
done: false,
|
||||
transfo: {
|
||||
rotation: {
|
||||
x: -Math.PI / 2,
|
||||
y: 0,
|
||||
z: Math.PI / 2
|
||||
},
|
||||
translation: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
},
|
||||
scale: 0.1
|
||||
},
|
||||
recommendations : L3D.createWhompRecommendations(1134, 768)
|
||||
},
|
||||
'/static/data/bobomb/bobomb battlefeild.obj': {
|
||||
done: false,
|
||||
transfo: {
|
||||
rotation: {
|
||||
x: 0,
|
||||
y: Math.PI - 0.27,
|
||||
z: 0
|
||||
},
|
||||
translation: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
}
|
||||
},
|
||||
recommendations : L3D.createBobombRecommendations(1134, 768)
|
||||
},
|
||||
|
||||
'/static/data/bobomb/bobomb battlefeild_sub.obj': {
|
||||
done: false,
|
||||
transfo: {
|
||||
rotation: {
|
||||
x: 0,
|
||||
y: Math.PI - 0.27,
|
||||
z: 0
|
||||
},
|
||||
translation: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
}
|
||||
},
|
||||
recommendations : L3D.createBobombRecommendations(1134, 768)
|
||||
},
|
||||
|
||||
'/static/data/sponza/sponza.obj': {
|
||||
done: false
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
for (var i = 1; i < 26; i++) {
|
||||
|
||||
availableMeshNames['/static/data/spheres/' + i + '.obj'] = { done: false};
|
||||
|
||||
}
|
||||
|
||||
geo.availableMeshes = {};
|
||||
|
||||
var start = Date.now();
|
||||
|
||||
function pushMesh(name) {
|
||||
|
||||
geo.availableMeshes[name] = new geo.MeshContainer(
|
||||
name.substring(1, name.length),
|
||||
availableMeshNames[name].transfo,
|
||||
function() {
|
||||
geo.availableMeshes[name].recommendations = [];
|
||||
|
||||
if (availableMeshNames[name].recommendations !== undefined) {
|
||||
|
||||
for (var i = 0; i < availableMeshNames[name].recommendations.length; i++) {
|
||||
|
||||
var reco = availableMeshNames[name].recommendations[i].camera;
|
||||
|
||||
reco.lookAt(reco.target);
|
||||
|
||||
reco.updateMatrix();
|
||||
reco.updateProjectionMatrix();
|
||||
reco.updateMatrixWorld();
|
||||
|
||||
reco.matrixWorldInverse.getInverse( reco.matrixWorld );
|
||||
|
||||
var frustum = new THREE.Frustum();
|
||||
var projScreenMatrix = new THREE.Matrix4();
|
||||
projScreenMatrix.multiplyMatrices(reco.projectionMatrix, reco.matrixWorldInverse);
|
||||
|
||||
frustum.setFromMatrix(new THREE.Matrix4().multiplyMatrices(reco.projectionMatrix, reco.matrixWorldInverse));
|
||||
|
||||
geo.availableMeshes[name].recommendations.push({
|
||||
position: reco.position,
|
||||
frustum: frustum.planes
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
availableMeshNames[name].done = true;
|
||||
trySetLoaded();
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
for (var name in availableMeshNames) {
|
||||
|
||||
pushMesh(name);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,553 @@
|
||||
var THREE = require('three');
|
||||
var L3D = require('../../static/js/l3d.min.js');
|
||||
|
||||
function isInFrustum(element, planes) {
|
||||
|
||||
if (element instanceof Array) {
|
||||
|
||||
var outcodes = [];
|
||||
|
||||
for (var i = 0; i < element.length; i++) {
|
||||
|
||||
var vertex = element[i];
|
||||
var currentOutcode = "";
|
||||
|
||||
for (var j = 0; j < planes.length; j++) {
|
||||
|
||||
var plane = planes[j];
|
||||
|
||||
distance =
|
||||
plane.normal.x * vertex.x +
|
||||
plane.normal.y * vertex.y +
|
||||
plane.normal.z * vertex.z +
|
||||
plane.constant;
|
||||
|
||||
// if (distance < 0) {
|
||||
// exitToContinue = true;
|
||||
// break;
|
||||
// }
|
||||
|
||||
currentOutcode += distance > 0 ? '0' : '1';
|
||||
|
||||
}
|
||||
|
||||
outcodes.push(parseInt(currentOutcode,2));
|
||||
|
||||
}
|
||||
|
||||
// http://vterrain.org/LOD/culling.html
|
||||
// I have no idea what i'm doing
|
||||
// http://i.kinja-img.com/gawker-media/image/upload/japbcvpavbzau9dbuaxf.jpg
|
||||
// But it seems to work
|
||||
// EDIT : Not, this should be ok http://www.cs.unc.edu/~blloyd/comp770/Lecture07.pdf
|
||||
|
||||
if ((outcodes[0] | outcodes[1] | outcodes[2]) === 0) {
|
||||
return true;
|
||||
} else if ((outcodes[0] & outcodes[1] & outcodes[2]) !== 0) {
|
||||
return false;
|
||||
} else {
|
||||
// part of the triangle is inside the viewing volume
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function bisect(items, x, lo, hi) {
|
||||
var mid;
|
||||
if (typeof(lo) == 'undefined') lo = 0;
|
||||
if (typeof(hi) == 'undefined') hi = items.length;
|
||||
while (lo < hi) {
|
||||
mid = Math.floor((lo + hi) / 2);
|
||||
if (x < items[mid]) hi = mid;
|
||||
else lo = mid + 1;
|
||||
}
|
||||
return lo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function insort(items, x) {
|
||||
items.splice(bisect(items, x), 0, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function partialSort(items, k, comparator) {
|
||||
var smallest = items.slice(0, k).sort(),
|
||||
max = smallest[k-1];
|
||||
|
||||
for (var i = k, len = items.length; i < len; ++i) {
|
||||
var item = items[i];
|
||||
var cond = comparator === undefined ? item < max : comparator(item, max) < 0;
|
||||
if (cond) {
|
||||
insort(smallest, item);
|
||||
smallest.length = k;
|
||||
max = smallest[k-1];
|
||||
}
|
||||
}
|
||||
return smallest;
|
||||
}
|
||||
|
||||
/**
|
||||
* A class that streams easily a mesh via socket.io
|
||||
* @memberOf geo
|
||||
* @constructor
|
||||
* @param {string} path to the mesh
|
||||
*/
|
||||
geo.MeshStreamer = function(path) {
|
||||
|
||||
/**
|
||||
* array of array telling if the jth face of the ith mesh has already been sent
|
||||
*
|
||||
* For each mesh, there is an object containing
|
||||
* <ul>
|
||||
* <li>`counter` : the number of faces currently sent</li>
|
||||
* <li>`array` : an array boolean telling if the ith face has already been sent</li>
|
||||
* </ul>
|
||||
* @type {Object[]}
|
||||
*/
|
||||
this.meshFaces = [];
|
||||
|
||||
/**
|
||||
* array of booleans telling if the ith vertex has already been sent
|
||||
* @type {Boolean[]}
|
||||
*/
|
||||
this.vertices = [];
|
||||
|
||||
/**
|
||||
* array of booleans telling if the ith face has already been sent
|
||||
* @type {Boolean[]}
|
||||
*/
|
||||
this.faces = [];
|
||||
|
||||
/**
|
||||
* array of booleans telling if the ith normal has already been sent
|
||||
* @type {Boolean[]}
|
||||
*/
|
||||
this.normals = [];
|
||||
|
||||
/**
|
||||
* array of booleans telling if the ith texCoord has already been sent
|
||||
* @type {Boolean[]}
|
||||
*/
|
||||
this.texCoords = [];
|
||||
|
||||
/**
|
||||
* Number of element to send by packet
|
||||
* @type {Number}
|
||||
*/
|
||||
this.chunk = 1000;
|
||||
|
||||
if (path !== undefined) {
|
||||
|
||||
this.mesh = geo.availableMeshes[path];
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
geo.MeshStreamer.prototype.isBackFace = function(camera, face) {
|
||||
|
||||
var directionCamera = L3D.Tools.diff(camera.target, camera.position);
|
||||
|
||||
var v1 = L3D.Tools.diff(this.mesh.vertices[face.b], this.mesh.vertices[face.a]);
|
||||
var v2 = L3D.Tools.diff(this.mesh.vertices[face.c], this.mesh.vertices[face.a]);
|
||||
|
||||
var normal = L3D.Tools.cross(v1, v2);
|
||||
|
||||
return L3D.Tools.dot(directionCamera, normal) > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute a function that can compare two faces
|
||||
* @param {Camera} camera a camera seeing or not face
|
||||
* @returns {function} the function that compares two faces : the higher face is the most interesting for the camera
|
||||
*/
|
||||
geo.MeshStreamer.prototype.faceComparator = function(camera) {
|
||||
|
||||
var self = this;
|
||||
|
||||
var direction = {
|
||||
x: camera.target.x - camera.position.x,
|
||||
y: camera.target.y - camera.position.y,
|
||||
z: camera.target.z - camera.position.z
|
||||
};
|
||||
|
||||
var norm = Math.sqrt(direction.x * direction.x + direction.y * direction.y + direction.z * direction.z);
|
||||
|
||||
direction.x /= norm;
|
||||
direction.y /= norm;
|
||||
direction.z /= norm;
|
||||
|
||||
return function(face1, face2) {
|
||||
|
||||
var center1 = {
|
||||
x: (self.mesh.vertices[face1.a].x + self.mesh.vertices[face1.b].x + self.mesh.vertices[face1.b].x) / 3,
|
||||
y: (self.mesh.vertices[face1.a].y + self.mesh.vertices[face1.b].y + self.mesh.vertices[face1.b].y) / 3,
|
||||
z: (self.mesh.vertices[face1.a].z + self.mesh.vertices[face1.b].z + self.mesh.vertices[face1.b].z) / 3
|
||||
|
||||
};
|
||||
|
||||
var dir1 = {
|
||||
x: center1.x - camera.position.x,
|
||||
y: center1.y - camera.position.y,
|
||||
z: center1.z - camera.position.z
|
||||
};
|
||||
|
||||
var norm1 = Math.sqrt(dir1.x * dir1.x + dir1.y * dir1.y + dir1.z + dir1.z);
|
||||
|
||||
dir1.x /= norm1;
|
||||
dir1.y /= norm1;
|
||||
dir1.z /= norm1;
|
||||
|
||||
var dot1 = direction.x * dir1.x + direction.y * dir1.y + direction.z * dir1.z;
|
||||
|
||||
var center2 = {
|
||||
x: (self.mesh.vertices[face2.a].x + self.mesh.vertices[face2.b].x + self.mesh.vertices[face2.b].x) / 3,
|
||||
y: (self.mesh.vertices[face2.a].y + self.mesh.vertices[face2.b].y + self.mesh.vertices[face2.b].y) / 3,
|
||||
z: (self.mesh.vertices[face2.a].z + self.mesh.vertices[face2.b].z + self.mesh.vertices[face2.b].z) / 3
|
||||
};
|
||||
|
||||
var dir2 = {
|
||||
x: center2.x - camera.position.x,
|
||||
y: center2.y - camera.position.y,
|
||||
z: center2.z - camera.position.z
|
||||
};
|
||||
|
||||
var norm2 = Math.sqrt(dir2.x * dir2.x + dir2.y * dir2.y + dir2.z + dir2.z);
|
||||
|
||||
dir2.x /= norm2;
|
||||
dir2.y /= norm2;
|
||||
dir2.z /= norm2;
|
||||
|
||||
var dot2 = direction.x * dir2.x + direction.y * dir2.y + direction.z * dir2.z;
|
||||
|
||||
// Decreasing order
|
||||
if (dot1 > dot2) {
|
||||
return -1;
|
||||
}
|
||||
if (dot1 < dot2) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the socket.io callback
|
||||
* @param {socket} socket the socket to initialize
|
||||
*/
|
||||
geo.MeshStreamer.prototype.start = function(socket) {
|
||||
|
||||
this.meshIndex = 0;
|
||||
this.socket = socket;
|
||||
|
||||
var self = this;
|
||||
|
||||
socket.on('request', function(path, laggy) {
|
||||
|
||||
if (laggy === true) {
|
||||
self.chunk = 1;
|
||||
}
|
||||
|
||||
self.mesh = geo.availableMeshes[path];
|
||||
|
||||
if (self.mesh === undefined) {
|
||||
process.stderr.write('Wrong path for model : ' + path);
|
||||
socket.emit('refused');
|
||||
socket.disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
self.meshFaces = new Array(self.mesh.meshes.length);
|
||||
|
||||
for (var i = 0; i < self.meshFaces.length; i++) {
|
||||
|
||||
self.meshFaces[i] = {
|
||||
counter: 0,
|
||||
array: new Array(self.mesh.meshes[i].faces.length)
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
socket.emit('ok');
|
||||
|
||||
});
|
||||
|
||||
socket.on('materials', function() {
|
||||
|
||||
var data = self.nextMaterials();
|
||||
|
||||
socket.emit('elements', data);
|
||||
|
||||
});
|
||||
|
||||
socket.on('next', function(camera) {
|
||||
|
||||
|
||||
// Send next elements
|
||||
var next = self.nextElements(camera);
|
||||
|
||||
if (next.data.length === 0) {
|
||||
|
||||
// If nothing, just serve stuff
|
||||
var tmp = self.nextElements(camera, true);
|
||||
next.data = tmp.data;
|
||||
|
||||
}
|
||||
|
||||
socket.emit('elements', next.data);
|
||||
|
||||
if (next.finished) {
|
||||
|
||||
socket.disconnect();
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Prepare the array of materials
|
||||
* @return array the array to send with all materials of the current mesh
|
||||
*/
|
||||
geo.MeshStreamer.prototype.nextMaterials = function() {
|
||||
|
||||
var data = [];
|
||||
|
||||
data.push(['g', this.mesh.numberOfFaces]);
|
||||
|
||||
|
||||
for (var i = 0; i < this.mesh.meshes.length; i++) {
|
||||
|
||||
var currentMesh = this.mesh.meshes[i];
|
||||
|
||||
// Send usemtl
|
||||
data.push([
|
||||
'u',
|
||||
currentMesh.material,
|
||||
currentMesh.vertices.length,
|
||||
currentMesh.faces.length,
|
||||
this.mesh.texCoords.length > 0,
|
||||
this.mesh.normals.length > 0
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Prepare the next elements
|
||||
* @param {camera} _camera a camera that can be usefull to do smart streaming (stream
|
||||
* only interesting parts according to the camera
|
||||
* @returns {array} an array of elements ready to send
|
||||
*/
|
||||
geo.MeshStreamer.prototype.nextElements = function(_camera, force) {
|
||||
|
||||
var i;
|
||||
|
||||
if (force === undefined) {
|
||||
|
||||
force = false;
|
||||
|
||||
}
|
||||
|
||||
// Prepare camera (and scale to model)
|
||||
var camera = null;
|
||||
var planes = [];
|
||||
var direction;
|
||||
|
||||
if (_camera !== null) {
|
||||
|
||||
camera = {
|
||||
position: {
|
||||
x: _camera[0][0],
|
||||
y: _camera[0][1],
|
||||
z: _camera[0][2]
|
||||
},
|
||||
target: {
|
||||
x: _camera[1][0],
|
||||
y: _camera[1][1],
|
||||
z: _camera[1][2]
|
||||
}
|
||||
};
|
||||
|
||||
for (i = 2; i < _camera.length; i++) {
|
||||
|
||||
planes.push({
|
||||
normal: {
|
||||
x: _camera[i][0],
|
||||
y: _camera[i][1],
|
||||
z: _camera[i][2]
|
||||
},
|
||||
constant: _camera[i][3]
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Compute camera direction
|
||||
direction = {
|
||||
x: camera.target.x - camera.position.x,
|
||||
y: camera.target.y - camera.position.y,
|
||||
z: camera.target.z - camera.position.z
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
var sent = 0;
|
||||
var data = [];
|
||||
|
||||
var mightBeCompletetlyFinished = true;
|
||||
|
||||
// BOOM
|
||||
// if (camera != null)
|
||||
// this.mesh.faces.sort(this.faceComparator(camera));
|
||||
|
||||
for (var faceIndex = 0; faceIndex < this.mesh.faces.length; faceIndex++) {
|
||||
|
||||
var currentFace = this.mesh.faces[faceIndex];
|
||||
|
||||
if (this.faces[currentFace.index] === true) {
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
mightBeCompletetlyFinished = false;
|
||||
|
||||
var vertex1 = this.mesh.vertices[currentFace.a];
|
||||
var vertex2 = this.mesh.vertices[currentFace.b];
|
||||
var vertex3 = this.mesh.vertices[currentFace.c];
|
||||
|
||||
if (!force && camera !== null) {
|
||||
|
||||
var display = false;
|
||||
var exitToContinue = false;
|
||||
threeVertices = [vertex1, vertex2, vertex3];
|
||||
|
||||
// Frustum culling
|
||||
if (!isInFrustum(threeVertices, planes)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Backface culling
|
||||
if (this.isBackFace(camera, currentFace)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!this.vertices[currentFace.a]) {
|
||||
|
||||
data.push(vertex1.toList());
|
||||
this.vertices[currentFace.a] = true;
|
||||
sent++;
|
||||
|
||||
}
|
||||
|
||||
if (!this.vertices[currentFace.b]) {
|
||||
|
||||
data.push(vertex2.toList());
|
||||
this.vertices[currentFace.b] = true;
|
||||
sent++;
|
||||
|
||||
}
|
||||
|
||||
if (!this.vertices[currentFace.c]) {
|
||||
|
||||
data.push(vertex3.toList());
|
||||
this.vertices[currentFace.c] = true;
|
||||
sent++;
|
||||
|
||||
}
|
||||
|
||||
var normal1 = this.mesh.normals[currentFace.aNormal];
|
||||
var normal2 = this.mesh.normals[currentFace.bNormal];
|
||||
var normal3 = this.mesh.normals[currentFace.cNormal];
|
||||
|
||||
if (normal1 !== undefined && !this.normals[currentFace.aNormal]) {
|
||||
|
||||
data.push(normal1.toList());
|
||||
this.normals[currentFace.aNormal] = true;
|
||||
sent++;
|
||||
|
||||
}
|
||||
|
||||
if (normal2 !== undefined && !this.normals[currentFace.bNormal]) {
|
||||
|
||||
data.push(normal2.toList());
|
||||
this.normals[currentFace.bNormal] = true;
|
||||
sent++;
|
||||
|
||||
}
|
||||
|
||||
if (normal3 !== undefined && !this.normals[currentFace.cNormal]) {
|
||||
|
||||
data.push(normal3.toList());
|
||||
this.normals[currentFace.cNormal] = true;
|
||||
sent++;
|
||||
|
||||
}
|
||||
|
||||
var tex1 = this.mesh.texCoords[currentFace.aTexture];
|
||||
var tex2 = this.mesh.texCoords[currentFace.bTexture];
|
||||
var tex3 = this.mesh.texCoords[currentFace.cTexture];
|
||||
|
||||
if (tex1 !== undefined && !this.texCoords[currentFace.aTexture]) {
|
||||
|
||||
data.push(tex1.toList());
|
||||
this.texCoords[currentFace.aTexture] = true;
|
||||
sent++;
|
||||
|
||||
}
|
||||
|
||||
if (tex2 !== undefined && !this.texCoords[currentFace.bTexture]) {
|
||||
|
||||
data.push(tex2.toList());
|
||||
this.texCoords[currentFace.bTexture] = true;
|
||||
sent++;
|
||||
|
||||
}
|
||||
|
||||
if (tex3 !== undefined && !this.texCoords[currentFace.cTexture]) {
|
||||
|
||||
data.push(tex3.toList());
|
||||
this.texCoords[currentFace.cTexture] = true;
|
||||
sent++;
|
||||
|
||||
}
|
||||
|
||||
data.push(currentFace.toList());
|
||||
// this.meshFaces[meshIndex] = this.meshFaces[meshIndex] || [];
|
||||
this.faces[currentFace.index] = true;
|
||||
// this.meshFaces[meshIndex].counter++;
|
||||
// currentMesh.faceIndex++;
|
||||
|
||||
sent++;
|
||||
|
||||
if (sent > this.chunk) {
|
||||
|
||||
return {data: data, finished: false};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return {data: data, finished: mightBeCompletetlyFinished};
|
||||
|
||||
};
|
||||
|
||||
geo.MeshStreamer.prototype.isFinished = function(i) {
|
||||
|
||||
return this.meshFaces[i].counter === this.meshFaces[i].array.length;
|
||||
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
[[0,0.07894736842105263,0.18421052631578946,0,0.02631578947368421,0.02631578947368421,0,0.02631578947368421,0,0.13157894736842105,0.2894736842105263,0.2631578947368421],[0,0,0.10526315789473684,0.15789473684210525,0.18421052631578946,0.02631578947368421,0,0.07894736842105263,0.02631578947368421,0.05263157894736842,0.05263157894736842,0.05263157894736842],[0,0.02631578947368421,0,0.5,0.02631578947368421,0.02631578947368421,0.02631578947368421,0.07894736842105263,0.02631578947368421,0.07894736842105263,0.07894736842105263,0.05263157894736842],[0,0.05263157894736842,0.07894736842105263,0,0.4473684210526316,0.02631578947368421,0.13157894736842105,0.02631578947368421,0,0.07894736842105263,0,0.13157894736842105],[0,0,0.02631578947368421,0.15789473684210525,0,0.3157894736842105,0.21052631578947367,0.05263157894736842,0,0.07894736842105263,0,0.10526315789473684],[0,0.10526315789473684,0,0.05263157894736842,0.13157894736842105,0,0.13157894736842105,0.05263157894736842,0.15789473684210525,0.02631578947368421,0.02631578947368421,0.02631578947368421],[0,0.15789473684210525,0.10526315789473684,0,0,0.10526315789473684,0,0.05263157894736842,0.21052631578947367,0.13157894736842105,0,0],[0,0.07894736842105263,0.05263157894736842,0.02631578947368421,0.07894736842105263,0.07894736842105263,0.10526315789473684,0,0.07894736842105263,0.02631578947368421,0.02631578947368421,0.05263157894736842],[0,0,0.10526315789473684,0.02631578947368421,0.02631578947368421,0.18421052631578946,0.15789473684210525,0,0,0.21052631578947367,0.07894736842105263,0.07894736842105263],[0,0.07894736842105263,0.10526315789473684,0.02631578947368421,0,0,0.07894736842105263,0.15789473684210525,0.13157894736842105,0,0.21052631578947367,0.07894736842105263],[0,0.02631578947368421,0.10526315789473684,0.07894736842105263,0.05263157894736842,0.02631578947368421,0,0.02631578947368421,0.23684210526315788,0.07894736842105263,0,0.10526315789473684],[0,0.18421052631578946,0.13157894736842105,0.13157894736842105,0.10526315789473684,0.02631578947368421,0,0.13157894736842105,0.02631578947368421,0.05263157894736842,0.07894736842105263,0]]
|
||||
@@ -0,0 +1 @@
|
||||
[[0,0,602,0,0,0,0,0,0,151,191,0],[0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,1116,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0],[0,87,0,0,0,0,0,0,0,0,0,82],[0,0,0,0,0,0,0,0,195,0,0,0],[0,86,41,0,0,0,0,0,0,563,74,72],[0,0,59,0,0,0,0,0,0,0,0,49],[0,147,151,0,0,0,0,0,0,0,0,110],[0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0]]
|
||||
@@ -0,0 +1 @@
|
||||
[[0,0.03125,0.09375,0.5,0.21875,0.03125,0.09375,0.1875,0,0.125,0.15625,0],[0,0,0.15625,0.0625,0.21875,0.0625,0.15625,0.09375,0,0.0625,0.03125,0],[0,0.21875,0,0.0625,0.0625,0,0,0,0,0,0.03125,0.0625],[0,0.09375,0.0625,0,0.25,0.03125,0.1875,0.1875,0.03125,0.25,0,0.03125],[0,0.125,0.0625,0.125,0,0.03125,0,0,0.1875,0.09375,0.15625,0.0625],[0,0.03125,0,0,0,0,0.21875,0,0.25,0,0,0.1875],[0,0.03125,0.0625,0.0625,0.03125,0.34375,0,0.125,0.34375,0,0.40625,0.0625],[0,0.125,0,0.15625,0,0.0625,0.25,0,0.03125,0.09375,0,0],[0,0.125,0.03125,0.0625,0,0.1875,0.15625,0.03125,0,0.0625,0,0.25],[0,0.1875,0,0.125,0.125,0,0.0625,0.03125,0,0,0.03125,0.125],[0,0.0625,0.0625,0.03125,0.09375,0,0.46875,0.09375,0.03125,0.09375,0,0.1875],[0,0,0.0625,0.0625,0,0,0,0.03125,0.1875,0.125,0.46875,0]]
|
||||
@@ -0,0 +1 @@
|
||||
[[0,0,0,218,0,0,0,0,0,0,0,0],[0,0,0,106,36,0,0,182,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,3,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,72],[0,0,0,0,0,0,0,0,0,0,0,0]]
|
||||
@@ -0,0 +1 @@
|
||||
[[0,0.05555555555555555,0.08333333333333333,0,0.16666666666666666,0.027777777777777776,0.5,0,0.05555555555555555,0.027777777777777776,0],[0,0,0.05555555555555555,0.08333333333333333,0.08333333333333333,0,0.08333333333333333,0,0.027777777777777776,0.027777777777777776,0],[0,0.05555555555555555,0,0.1111111111111111,0.027777777777777776,0,0.027777777777777776,0,0.027777777777777776,0.027777777777777776,0],[0,0.05555555555555555,0.027777777777777776,0,0.1111111111111111,0,0.027777777777777776,0.027777777777777776,0.08333333333333333,0.027777777777777776,0],[0,0.08333333333333333,0,0.1111111111111111,0,0.3888888888888889,0,0.16666666666666666,0.05555555555555555,0.027777777777777776,0.05555555555555555],[0,0,0,0.027777777777777776,0.25,0,0.1111111111111111,0.1388888888888889,0,0,0.2222222222222222],[0,0.05555555555555555,0.08333333333333333,0.1388888888888889,0,0.027777777777777776,0,0.027777777777777776,0.08333333333333333,0.16666666666666666,0.3055555555555556],[0,0.027777777777777776,0.027777777777777776,0,0.027777777777777776,0.1388888888888889,0.05555555555555555,0,0.08333333333333333,0.05555555555555555,0.027777777777777776],[0,0,0,0,0.08333333333333333,0.05555555555555555,0.1111111111111111,0.05555555555555555,0,0.1111111111111111,0.1111111111111111],[0,0.027777777777777776,0.027777777777777776,0.027777777777777776,0.16666666666666666,0,0.05555555555555555,0.027777777777777776,0.1388888888888889,0,0],[0,0,0.027777777777777776,0,0.1388888888888889,0.16666666666666666,0.1111111111111111,0.08333333333333333,0.1111111111111111,0,0]]
|
||||
@@ -0,0 +1 @@
|
||||
[[0,0,0,0,0,0,70,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,12,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,10,0,0,0,0,0,0,0],[0,0,0,0,0,83,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,64],[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,36,0,0,0,16,0,0]]
|
||||
@@ -0,0 +1 @@
|
||||
[[0,0.1,0.3,0,0,0,0,0,0,0.1,0.4,0.5],[0,0,0.1,0.2,0.2,0,0,0.2,0,0.1,0.1,0],[0,0.1,0,0.4,0,0,0.1,0.3,0.1,0.1,0.1,0],[0,0.1,0,0,0.4,0.1,0.2,0,0,0.1,0,0.2],[0,0,0,0.2,0,0.5,0.1,0,0,0.1,0,0],[0,0,0,0,0.3,0,0.1,0,0.3,0.1,0.1,0.1],[0,0.3,0.1,0,0,0,0,0.1,0.4,0.1,0,0],[0,0.1,0.1,0,0.1,0,0.4,0,0,0,0.1,0.2],[0,0,0.3,0,0,0.3,0.1,0,0,0.3,0.1,0],[0,0.1,0.1,0,0,0,0.1,0.4,0,0,0.2,0.1],[0,0,0.2,0.2,0.1,0.1,0,0.1,0.3,0,0,0],[0,0.2,0.2,0.3,0,0,0,0.1,0,0.1,0.1,0]]
|
||||
@@ -0,0 +1 @@
|
||||
[[0,0,0.1,0.5,0.3,0,0.1,0.1,0,0.2,0,0],[0,0,0.2,0.1,0.1,0,0.3,0.2,0,0.2,0,0],[0,0.2,0,0.1,0.2,0,0,0,0,0,0,0.1],[0,0.1,0.1,0,0.4,0,0,0.2,0,0.3,0,0],[0,0.2,0,0,0,0.1,0,0,0.4,0.1,0.2,0.1],[0,0.1,0,0,0,0,0.1,0,0.4,0,0,0.2],[0,0.1,0,0,0.1,0.4,0,0.1,0.1,0,0.3,0.1],[0,0,0,0.3,0,0.1,0.2,0,0,0,0,0],[0,0.2,0.1,0.1,0,0.2,0.2,0,0,0,0,0.2],[0,0.3,0,0.1,0.1,0,0.1,0,0,0,0.1,0],[0,0.1,0.1,0,0,0,0.3,0.1,0,0.1,0,0.2],[0,0,0.1,0.1,0,0,0,0,0.1,0,0.5,0]]
|
||||
@@ -0,0 +1 @@
|
||||
[[0,0.16666666666666666,0.16666666666666666,0,0.16666666666666666,0,0.5,0,0,0,0],[0,0,0.16666666666666666,0.16666666666666666,0,0,0,0,0.16666666666666666,0.16666666666666666,0],[0,0.16666666666666666,0,0.16666666666666666,0.16666666666666666,0,0.16666666666666666,0,0,0,0],[0,0.16666666666666666,0.16666666666666666,0,0,0,0,0.16666666666666666,0.16666666666666666,0.16666666666666666,0],[0,0,0,0.3333333333333333,0,0.16666666666666666,0,0.16666666666666666,0.16666666666666666,0,0],[0,0,0,0.16666666666666666,0.5,0,0,0,0,0,0.3333333333333333],[0,0,0.16666666666666666,0.16666666666666666,0,0,0,0,0,0,0.5],[0,0,0,0,0,0.3333333333333333,0.16666666666666666,0,0.16666666666666666,0,0],[0,0,0,0,0,0.16666666666666666,0.16666666666666666,0,0,0.5,0.16666666666666666],[0,0.16666666666666666,0,0.16666666666666666,0.16666666666666666,0,0,0,0.3333333333333333,0,0],[0,0,0,0,0,0.3333333333333333,0.16666666666666666,0.3333333333333333,0.16666666666666666,0,0]]
|
||||
Reference in New Issue
Block a user