Browse Source

big fix to geometry generation

timk 14 years ago
parent
commit
9662094dfd
3 changed files with 127 additions and 260 deletions
  1. 4 3
      examples/webgl_collada.html
  2. 17 0
      src/core/Quaternion.js
  3. 106 257
      src/extras/collada/dae.js

+ 4 - 3
examples/webgl_collada.html

@@ -6,7 +6,7 @@
 		<style type="text/css">
 		<style type="text/css">
 			body {
 			body {
 				font-family: Monospace;
 				font-family: Monospace;
-				background-color: #ffffff;
+				background-color: #000000;
 				margin: 0px;
 				margin: 0px;
 				overflow: hidden;
 				overflow: hidden;
 			}
 			}
@@ -33,11 +33,12 @@
 			var particleLight, pointLight;
 			var particleLight, pointLight;
 			var dae;
 			var dae;
 			
 			
-			DAE.load('./models/monster.dae', colladaReady);
+			DAE.load('./models/Seymour-tim.dae', colladaReady);
 			
 			
 			function colladaReady(collada) {
 			function colladaReady(collada) {
 				dae = collada.scene;
 				dae = collada.scene;
-				dae.scale.x = dae.scale.y = dae.scale.z = 0.002;
+				dae.scale.x = dae.scale.y = dae.scale.z = 1;
+				dae.rotation.x = -Math.PI/2;
 				dae.updateMatrix();
 				dae.updateMatrix();
 
 
 				init();
 				init();

+ 17 - 0
src/core/Quaternion.js

@@ -85,6 +85,23 @@ THREE.Quaternion.prototype = {
 
 
 	},
 	},
 	
 	
+	setFromRotationMatrix: function ( m ) {
+		// Adapted from: http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
+		function copySign(a, b) {
+			return b < 0 ? -Math.abs(a) : Math.abs(a);
+		}
+		var absQ = Math.pow(m.determinant(), 1.0 / 3.0);
+		this.w = Math.sqrt( Math.max( 0, absQ + m.n11 + m.n22 + m.n33 ) ) / 2; 
+		this.x = Math.sqrt( Math.max( 0, absQ + m.n11 - m.n22 - m.n33 ) ) / 2; 
+		this.y = Math.sqrt( Math.max( 0, absQ - m.n11 + m.n22 - m.n33 ) ) / 2; 
+		this.z = Math.sqrt( Math.max( 0, absQ - m.n11 - m.n22 + m.n33 ) ) / 2; 
+		this.x = copySign( this.x, ( m.n32 - m.n23 ) );
+		this.y = copySign( this.y, ( m.n13 - m.n31 ) );
+		this.z = copySign( this.z, ( m.n21 - m.n12 ) );
+		this.normalize();
+		return this;
+	},
+	
 	calculateW : function () {
 	calculateW : function () {
 
 
 		this.w = - Math.sqrt( Math.abs( 1.0 - this.x * this.x - this.y * this.y - this.z * this.z ) );
 		this.w = - Math.sqrt( Math.abs( 1.0 - this.x * this.x - this.y * this.y - this.z * this.z ) );

+ 106 - 257
src/extras/collada/dae.js

@@ -280,8 +280,10 @@ var DAE = (function() {
 			var instance_geometry = node.geometries[i];
 			var instance_geometry = node.geometries[i];
 			var instance_materials = instance_geometry.instance_material;
 			var instance_materials = instance_geometry.instance_material;
 			var geometry = geometries[instance_geometry.url];
 			var geometry = geometries[instance_geometry.url];
-			var used_effects = {};
-
+			var used_materials = {};
+			var num_materials = 0;
+			var first_material;
+			
 			if (geometry) {
 			if (geometry) {
 				if (!geometry.mesh || !geometry.mesh.primitives)
 				if (!geometry.mesh || !geometry.mesh.primitives)
 					continue;
 					continue;
@@ -295,41 +297,43 @@ var DAE = (function() {
 					for (j = 0; j < instance_materials.length; j++) {
 					for (j = 0; j < instance_materials.length; j++) {
 						var inst_material = instance_materials[j];
 						var inst_material = instance_materials[j];
 						var effect_id = materials[inst_material.target].instance_effect.url;
 						var effect_id = materials[inst_material.target].instance_effect.url;
-						used_effects[inst_material.symbol] = effects[effect_id];
+						var shader = effects[effect_id].shader;
+						
+						shader.material.opacity = !shader.material.opacity ? 1 : shader.material.opacity;
+						used_materials[inst_material.symbol] = shader.material;
+						first_material = shader.material;
+						num_materials++;
 					}
 					}
 				}
 				}
 				
 				
-				var primitives = geometry.mesh.primitives;
-				
-				for (j = 0; j < primitives.length; j++) {
-					var effect = used_effects[ primitives[j].material ];
-					var shader = effect.shader;
-					var geom = primitives[j].geometry;
-					var material = shader.material;
-					var mesh;
-					
-					if (skinController !== undefined && j == 0) {
-						//createSkin(geom, skinController);
-						//material.skinning = true;
-						mesh = new THREE.SkinnedMesh( geom, material );
-						mesh.skeleton = skinController.skeleton;
-						mesh.skinController = controllers[skinController.url];
-						mesh.name = 'skin_' + skins.length;
-						skins.push(mesh);
-					} else {
-						if (morphController !== undefined) {
-							console.log("morphing")
-							createMorph(geom, morphController);
-							material.morphTargets = true;
-							mesh = new THREE.Mesh( geom, material );
-							mesh.name = 'morph_' + morphs.length;
-							morphs.push(mesh);
-						} else {
-							mesh = new THREE.Mesh( geom, material );
-						}
+				var mesh;
+				var material = first_material || new THREE.MeshLambertMaterial({ color: 0xdddddd, shading: THREE.FlatShading });
+				var geom = geometry.mesh.geometry3js;
+				if (num_materials > 1) {
+					material = new THREE.MeshFaceMaterial();
+					for (j = 0; j < geom.faces.length; j++) {
+						var face = geom.faces[j];
+						face.materials = [ used_materials[face.daeMaterial] ];
 					}
 					}
-					obj.addChild(mesh);
 				}
 				}
+				
+				if (skinController !== undefined) {
+					mesh = new THREE.SkinnedMesh( geom, material );
+					mesh.skeleton = skinController.skeleton;
+					mesh.skinController = controllers[skinController.url];
+					mesh.name = 'skin_' + skins.length;
+					skins.push(mesh);
+				} else if (morphController !== undefined) {
+					createMorph(geom, morphController);
+					material.morphTargets = true;
+					mesh = new THREE.Mesh( geom, material );
+					mesh.name = 'morph_' + morphs.length;
+					morphs.push(mesh);
+				} else {
+					mesh = new THREE.Mesh( geom, material );
+				}
+						
+				obj.addChild(mesh);
 			}
 			}
 		}
 		}
 		
 		
@@ -998,10 +1002,11 @@ var DAE = (function() {
 		this.geometry = geometry.id;
 		this.geometry = geometry.id;
 		this.primitives = [];
 		this.primitives = [];
 		this.vertices = null;
 		this.vertices = null;
+		this.geometry3js;
 	}
 	}
 	Mesh.prototype.parse = function(element) {
 	Mesh.prototype.parse = function(element) {
 		this.primitives = [];
 		this.primitives = [];
-		var i;
+		var i, j;
 		for (i = 0; i < element.childNodes.length; i++) {
 		for (i = 0; i < element.childNodes.length; i++) {
 			var child = element.childNodes[i];
 			var child = element.childNodes[i];
 			switch (child.nodeName) {
 			switch (child.nodeName) {
@@ -1023,146 +1028,42 @@ var DAE = (function() {
 					break;
 					break;
 			}
 			}
 		}
 		}
-		for (i = 0; i < this.primitives.length; i++) {
-			primitive = this.primitives[i];
-			primitive.setVertices(this.vertices);
-			primitive.create();
-		}
-		return this;
-	}
-	
-	function Polylist() {
-	}
-	Polylist.prototype = new Triangles();
-	Polylist.prototype.constructor = Polylist;
-	Polylist.prototype.create = function() {
-		var p = this.p, inputs = this.inputs, num_inputs = this.inputs.length;
-		var idx = 0, input;
-		var i, j, k, v, n, t;
-		var texture_sets = [];
-		var polygons = [];
 		
 		
-		for (j = 0; j < inputs.length; j++) {
-			input = inputs[j];
-			if (input.semantic == 'TEXCOORD') {
-				texture_sets.push(input.set);
-			}
-		}
-		
-		for (i = 0; i < this.vcount.length; i++) {
-			var num_verts = this.vcount[i]
-			var vs = [], ns = [], ts = [];
-			for (j = 0; j < num_verts; j++) {
-				for (k = 0; k < num_inputs; k++) {
-					input = inputs[k];
-					source = sources[input.source];
-					index = p[idx + input.offset];
-					numParams = source.accessor.params.length;
-					idx32 = index * numParams;
-					switch (input.semantic) {
-						case 'VERTEX':
-							v = new THREE.Vertex(new THREE.Vector3(source.data[idx32+0], source.data[idx32+1], source.data[idx32+2]));
-							v.daeId = index;
-							vs.push(v);
-							break;
-						case 'NORMAL':
-							n = new THREE.Vector3(source.data[idx32+0], source.data[idx32+1], source.data[idx32+2]);
-							n.daeId = ns.length;
-							ns.push(n);
-							break;
-						case 'TEXCOORD':
-							if (ts[input.set] == undefined) ts[input.set] = [];
-							t = new THREE.UV(source.data[idx32+0], (flip_uv ? 1-source.data[idx32+1] : source.data[idx32+1]));
-							t.daeId = ts[input.set].length;
-							ts[input.set].push(t);
-							break;
-						default:
-							break;
-					}
-				}
-				idx += num_inputs;
-			}
-			polygons.push([vs, ns, ts])
-		}
-		
-		this.geometry = new THREE.Geometry();
-		this.triangulate(polygons, texture_sets);
-	}
-	Polylist.prototype.triangulate = function(polygons, texture_sets) {
-		var i, j, k;
 		var vertex_store = {};
 		var vertex_store = {};
-		var last_index = 0;
-		
-		function get_vertex(v)  {
+		function get_vertex(v, index)  {
 			var hash = _hash_vector3(v.position);
 			var hash = _hash_vector3(v.position);
 			if (vertex_store[hash] === undefined) {
 			if (vertex_store[hash] === undefined) {
-				vertex_store[hash] = {v:v, index:last_index++};
+				vertex_store[hash] = {v:v, index:index};
 			}
 			}
 			return vertex_store[hash];
 			return vertex_store[hash];
 		}
 		}
 		
 		
-		for (i = 0; i < polygons.length; i++) {
-			var polygon = polygons[i];
-			var v = polygon[0];
-			var n = polygon[1];
-			var t = polygon[2];
-			var uvs = [];
-			for (j = 0; j < texture_sets.length; j++) {
-				uvs.push(t[texture_sets[j]]);
-			}
-			var has_uv = (uvs.length > 0 && uvs[0].length > 0);
-			if (v.length < 3) continue;
-			var va = get_vertex(v[0]);
-			var na = n[0];
-			for (j = 1; j < v.length - 1; j++) {
-				var vb = get_vertex(v[j]);
-				var vc = get_vertex(v[j+1]);
-				var a = va.v.daeId;
-				var b = vb.v.daeId;
-				var c = vc.v.daeId;
-				var nb = n[j];
-				var nc = n[j+1];
-				this.geometry.faces.push( new THREE.Face3(a, b, c, [na, nb, nc] ) );
-				if (has_uv) {
-					for (k = 0; k < uvs.length; k++) {
-						this.geometry.faceVertexUvs[ k ].push( [uvs[k][0], uvs[k][j], uvs[k][j+1]] );
-					}
-				}
-			}
+		this.geometry3js = new THREE.Geometry();
+		var vertexData = sources[this.vertices.input['POSITION'].source].data;
+		for (i = 0, j = 0; i < vertexData.length; i += 3, j++) {
+			var v = new THREE.Vertex(new THREE.Vector3(vertexData[i], vertexData[i+1], vertexData[i+2]));
+			get_vertex(v, j);
+			this.geometry3js.vertices.push(v);
 		}
 		}
-		for (var hash in vertex_store) {
-			this.geometry.vertices[vertex_store[hash].v.daeId] = vertex_store[hash].v;
+
+		for (i = 0; i < this.primitives.length; i++) {
+			primitive = this.primitives[i];
+			primitive.setVertices(this.vertices);
+			this.handlePrimitive(primitive, this.geometry3js, vertex_store);
 		}
 		}
-		this.geometry.material = this.material;
-		this.geometry.computeCentroids();
-		this.geometry.computeFaceNormals();
-		this.geometry.computeVertexNormals();
-		this.geometry.computeBoundingBox();
-	}
-	
-	function Triangles(flip_uv) {
-		this.material = "";
-		this.count = 0;
-		this.inputs = [];
-		this.vcount;
-		this.p = [];
-		this.aabb = new AABB();
-		this.geometry = new THREE.Geometry();
+		
+		this.geometry3js.computeCentroids();
+		this.geometry3js.computeFaceNormals();
+		this.geometry3js.computeVertexNormals();
+		this.geometry3js.computeBoundingBox();
+		
+		return this;
 	}
 	}
-	Triangles.prototype.create = function() {
-		var i = 0, j, k, p = this.p, inputs = this.inputs, input, index;
-		var v, n, t;
+	Mesh.prototype.handlePrimitive = function(primitive, geom, vertex_store) {
+		var i = 0, j, k, p = primitive.p, inputs = primitive.inputs;
+		var input, index, idx32;
+		var vcIndex = 0, vcount = 3;
 		var texture_sets = [];
 		var texture_sets = [];
-		var vertex_store = {};
-		var last_index = 0;
-		
-		function get_vertex(v)  {
-			var hash = _hash_vector3(v.position);
-			if (vertex_store[hash] === undefined) {
-				vertex_store[hash] = {v:v, index:last_index++};
-			}
-			return vertex_store[hash];
-		}
 		
 		
 		for (j = 0; j < inputs.length; j++) {
 		for (j = 0; j < inputs.length; j++) {
 			input = inputs[j];
 			input = inputs[j];
@@ -1171,14 +1072,14 @@ var DAE = (function() {
 			}
 			}
 		}
 		}
 		
 		
-		this.geometry = new THREE.Geometry();
-		var daeIdx = 0;
-		
 		while (i < p.length) {
 		while (i < p.length) {
-			vs = [];
-			ns = [];
-			ts = {};
-			for (j = 0; j < 3; j++) {
+			var vs = [];
+			var ns = [];
+			var ts = {};
+			if (primitive.vcount) {
+				vcount = primitive.vcount[vcIndex++];
+			}
+			for (j = 0; j < vcount; j++) {
 				for (k = 0; k < inputs.length; k++) {
 				for (k = 0; k < inputs.length; k++) {
 					input = inputs[k];
 					input = inputs[k];
 					source = sources[input.source];
 					source = sources[input.source];
@@ -1187,51 +1088,57 @@ var DAE = (function() {
 					idx32 = index * numParams;
 					idx32 = index * numParams;
 					switch (input.semantic) {
 					switch (input.semantic) {
 						case 'VERTEX':
 						case 'VERTEX':
-							v = new THREE.Vertex(new THREE.Vector3(source.data[idx32+0], source.data[idx32+1], source.data[idx32+2]));
-							v.daeId = index;
-							vs.push(v);
+							var hash = _hash_vector3(geom.vertices[index].position);
+							vs.push(vertex_store[hash].index);
 							break;
 							break;
 						case 'NORMAL':
 						case 'NORMAL':
-							n = new THREE.Vector3(source.data[idx32+0], source.data[idx32+1], source.data[idx32+2]);
-							n.daeId = daeIdx;
-							ns.push(n);
+							ns.push(new THREE.Vector3(source.data[idx32+0], source.data[idx32+1], source.data[idx32+2]));
 							break;
 							break;
 						case 'TEXCOORD':
 						case 'TEXCOORD':
 							if (ts[input.set] == undefined) ts[input.set] = [];
 							if (ts[input.set] == undefined) ts[input.set] = [];
-							t = new THREE.UV(source.data[idx32+0], source.data[idx32+1]);
-							t.daeId = daeIdx;
-							ts[input.set].push(t);
+							ts[input.set].push(new THREE.UV(source.data[idx32+0], source.data[idx32+1]));
 							break;
 							break;
 						default:
 						default:
 							break;
 							break;
 					}
 					}
 				}
 				}
-				
 			}
 			}
-
-			var has_v = (vs.length == 3);
-			var has_t = (texture_sets.length > 0 && ts[texture_sets[0]].length == 3);
-			if (has_v) {
-				var a = get_vertex(vs[0]);
-				var b = get_vertex(vs[1]);
-				var c = get_vertex(vs[2]);
-				this.geometry.faces.push( new THREE.Face3(a.v.daeId, b.v.daeId, c.v.daeId, ns ) );
-				if (has_t) {
+			var face = new THREE.Face3(vs[0], vs[1], vs[2], [ns[0], ns[1], ns[2]]);
+			var uv;
+			face.daeMaterial = primitive.material;
+			geom.faces.push(face);
+			for (k = 0; k < texture_sets.length; k++) {
+				uv = ts[texture_sets[k]];
+				geom.faceVertexUvs[ k ].push( [uv[0], uv[1], uv[2]] );
+			}
+			if (vcount > 3) {
+				for (j = 2; j < vs.length -1; j++) {
+					face = new THREE.Face3(vs[0], vs[j], vs[j+1], [ns[0], ns[j], ns[j+1]]);
+					face.daeMaterial = primitive.material;
+					geom.faces.push(face);
 					for (k = 0; k < texture_sets.length; k++) {
 					for (k = 0; k < texture_sets.length; k++) {
-						this.geometry.faceVertexUvs[ k ].push( ts[texture_sets[k]] );
+						uv = ts[texture_sets[k]];
+						geom.faceVertexUvs[ k ].push( [uv[0], uv[j], uv[j+1]] );
 					}
 					}
 				}
 				}
 			}
 			}
-			i += 3 * inputs.length;
-		}
-		for (var hash in vertex_store) {
-			this.geometry.vertices[vertex_store[hash].v.daeId] = vertex_store[hash].v;
+			
+			i += inputs.length * vcount;
 		}
 		}
-		this.geometry.material = this.material;
-		this.geometry.computeCentroids();
-		this.geometry.computeFaceNormals();
-		this.geometry.computeVertexNormals();
-		this.geometry.computeBoundingBox();	
+	}
+	
+	function Polylist() {
+	}
+	Polylist.prototype = new Triangles();
+	Polylist.prototype.constructor = Polylist;
+	
+	function Triangles(flip_uv) {
+		this.material = "";
+		this.count = 0;
+		this.inputs = [];
+		this.vcount;
+		this.p = [];
+		this.geometry = new THREE.Geometry();
 	}
 	}
 	Triangles.prototype.setVertices = function(vertices) {
 	Triangles.prototype.setVertices = function(vertices) {
 		for (var i = 0; i < this.inputs.length; i++) {
 		for (var i = 0; i < this.inputs.length; i++) {
@@ -1262,63 +1169,6 @@ var DAE = (function() {
 		}
 		}
 		return this;
 		return this;
 	}
 	}
-	Triangles.prototype.calcNormals = function(v, n) {
-		var i;
-		var v0 = [0, 0, 0];
-		var v1 = [0, 0, 0];
-		var v2 = [0, 0, 0];
-		var n0 = [0, 0, 0];
-		for (i = 0; i < v.length; i += 9) {
-			v0[0] = v[i+0]; v0[1] = v[i+1]; v0[2] = v[i+2];
-			v1[0] = v[i+3]; v1[1] = v[i+4]; v1[2] = v[i+5];
-			v2[0] = v[i+6]; v2[1] = v[i+7]; v2[2] = v[i+8];
-			// sub
-			v1[0] = v1[0] - v0[0];
-			v1[1] = v1[1] - v0[1];
-			v1[2] = v1[2] - v0[2];
-			v2[0] = v2[0] - v0[0];
-			v2[1] = v2[1] - v0[1];
-			v2[2] = v2[2] - v0[2];
-			// cross
-			n0[0] = v1[1] * v2[2] - v1[2] * v2[1];
-			n0[1] = v1[2] * v2[0] - v1[0] * v2[2];
-			n0[2] = v1[0] * v2[1] - v1[1] * v2[0];
-			// normalize
-			length = 1.0 / Math.sqrt(n0[0]*n0[0]+n0[1]*n0[1]+n0[2]*n0[2]);
-			if (length == 0) length = 1.0;
-			n[i+0] = n[i+3] = n[i+6] = n0[0] * length;
-			n[i+1] = n[i+4] = n[i+7] = n0[1] * length;
-			n[i+2] = n[i+5] = n[i+8] = n0[2] * length;
-		}
-	}
-	
-	function AABB() {
-		this.minx = 0;	this.miny = 0;	this.minz = 0;
-		this.maxx = 0;	this.maxy = 0;	this.maxz = 0;
-	}
-	AABB.prototype.reset = function() {
-		this.minx = this.miny = this.minz = Number.MAX_VALUE;
-		this.maxx = this.maxy = this.maxz = Number.MIN_VALUE;
-		return this;
-	}
-	AABB.prototype.setTriangles = function(positions) {
-		this.reset();
-		for (var i = 0; i < positions.length; i += 3) {
-			this.minx = Math.min(this.minx, positions[i+0]); 
-			this.miny = Math.min(this.miny, positions[i+1]);
-			this.minz = Math.min(this.minz, positions[i+2]);
-			this.maxx = Math.max(this.maxx, positions[i+0]);
-			this.maxy = Math.max(this.maxy, positions[i+1]);
-			this.maxz = Math.max(this.maxz, positions[i+2]);
-		}
-		return this;
-	}
-	AABB.prototype.centerX = function() { return this.minx + (this.sizeX() / 2); }
-	AABB.prototype.centerY = function() { return this.miny + (this.sizeY() / 2); }
-	AABB.prototype.centerZ = function() { return this.minz + (this.sizeZ() / 2); }
-	AABB.prototype.sizeX = function() { return this.maxx - this.minx; }
-	AABB.prototype.sizeY = function() { return this.maxy - this.miny; }
-	AABB.prototype.sizeZ = function() { return this.maxz - this.minz; }
 	
 	
 	function Accessor() {
 	function Accessor() {
 		this.source = "";
 		this.source = "";
@@ -1547,8 +1397,8 @@ var DAE = (function() {
 										props['map'] = THREE.ImageUtils.loadTexture(baseUrl + image.init_from);
 										props['map'] = THREE.ImageUtils.loadTexture(baseUrl + image.init_from);
 										props['map'].wrapS = THREE.RepeatWrapping;
 										props['map'].wrapS = THREE.RepeatWrapping;
 										props['map'].wrapT = THREE.RepeatWrapping;
 										props['map'].wrapT = THREE.RepeatWrapping;
-									//	props['map'].repeat.x = 1;
-									//	props['map'].repeat.y = 1;
+										props['map'].repeat.x = 1;
+										props['map'].repeat.y = -1;
 									}
 									}
 								}
 								}
 							}
 							}
@@ -2046,4 +1896,3 @@ var DAE = (function() {
 		geometries : geometries
 		geometries : geometries
 	};
 	};
 })();
 })();
-