Browse Source

ObjectLoader/ObjectExporter using matrix instead of position/(rotation|quaternion)/scale. See #3591.

Mr.doob 12 years ago
parent
commit
4a369a6ae7
3 changed files with 84 additions and 85 deletions
  1. 3 15
      examples/js/exporters/ObjectExporter.js
  2. 54 57
      src/loaders/ObjectLoader.js
  3. 27 13
      src/math/Matrix4.js

+ 3 - 15
examples/js/exporters/ObjectExporter.js

@@ -14,7 +14,7 @@ THREE.ObjectExporter.prototype = {
 
 
 		var output = {
 		var output = {
 			metadata: {
 			metadata: {
-				version: 4.2,
+				version: 4.3,
 				type: 'object',
 				type: 'object',
 				generator: 'ObjectExporter'
 				generator: 'ObjectExporter'
 			}
 			}
@@ -177,8 +177,6 @@ THREE.ObjectExporter.prototype = {
 				data.aspect = object.aspect;
 				data.aspect = object.aspect;
 				data.near = object.near;
 				data.near = object.near;
 				data.far = object.far;
 				data.far = object.far;
-				data.position = object.position.toArray();
-				data.rotation = object.rotation.toArray();
 
 
 			} else if ( object instanceof THREE.OrthographicCamera ) {
 			} else if ( object instanceof THREE.OrthographicCamera ) {
 
 
@@ -189,8 +187,6 @@ THREE.ObjectExporter.prototype = {
 				data.bottom = object.bottom;
 				data.bottom = object.bottom;
 				data.near = object.near;
 				data.near = object.near;
 				data.far = object.far;
 				data.far = object.far;
-				data.position = object.position.toArray();
-				data.rotation = object.rotation.toArray();
 
 
 			} else if ( object instanceof THREE.AmbientLight ) {
 			} else if ( object instanceof THREE.AmbientLight ) {
 
 
@@ -202,7 +198,6 @@ THREE.ObjectExporter.prototype = {
 				data.type = 'DirectionalLight';
 				data.type = 'DirectionalLight';
 				data.color = object.color.getHex();
 				data.color = object.color.getHex();
 				data.intensity = object.intensity;
 				data.intensity = object.intensity;
-				data.position = object.position.toArray();
 
 
 			} else if ( object instanceof THREE.PointLight ) {
 			} else if ( object instanceof THREE.PointLight ) {
 
 
@@ -210,7 +205,6 @@ THREE.ObjectExporter.prototype = {
 				data.color = object.color.getHex();
 				data.color = object.color.getHex();
 				data.intensity = object.intensity;
 				data.intensity = object.intensity;
 				data.distance = object.distance;
 				data.distance = object.distance;
-				data.position = object.position.toArray();
 
 
 			} else if ( object instanceof THREE.SpotLight ) {
 			} else if ( object instanceof THREE.SpotLight ) {
 
 
@@ -220,33 +214,27 @@ THREE.ObjectExporter.prototype = {
 				data.distance = object.distance;
 				data.distance = object.distance;
 				data.angle = object.angle;
 				data.angle = object.angle;
 				data.exponent = object.exponent;
 				data.exponent = object.exponent;
-				data.position = object.position.toArray();
 
 
 			} else if ( object instanceof THREE.HemisphereLight ) {
 			} else if ( object instanceof THREE.HemisphereLight ) {
 
 
 				data.type = 'HemisphereLight';
 				data.type = 'HemisphereLight';
 				data.color = object.color.getHex();
 				data.color = object.color.getHex();
 				data.groundColor = object.groundColor.getHex();
 				data.groundColor = object.groundColor.getHex();
-				data.position = object.position.toArray();
 
 
 			} else if ( object instanceof THREE.Mesh ) {
 			} else if ( object instanceof THREE.Mesh ) {
 
 
 				data.type = 'Mesh';
 				data.type = 'Mesh';
-				data.position = object.position.toArray();
-				data.rotation = object.rotation.toArray();
-				data.scale = object.scale.toArray();
 				data.geometry = parseGeometry( object.geometry );
 				data.geometry = parseGeometry( object.geometry );
 				data.material = parseMaterial( object.material );
 				data.material = parseMaterial( object.material );
 
 
 			} else {
 			} else {
 
 
 				data.type = 'Object3D';
 				data.type = 'Object3D';
-				data.position = object.position.toArray();
-				data.rotation = object.rotation.toArray();
-				data.scale = object.scale.toArray();
 
 
 			}
 			}
 
 
+			data.matrix = object.matrix.toArray();
+
 			if ( object.children.length > 0 ) {
 			if ( object.children.length > 0 ) {
 
 
 				data.children = [];
 				data.children = [];

+ 54 - 57
src/loaders/ObjectLoader.js

@@ -190,103 +190,100 @@ THREE.ObjectLoader.prototype = {
 
 
 	},
 	},
 
 
-	parseObject: function ( data, geometries, materials ) {
+	parseObject: function () {
 
 
-		var object;
+		var matrix = new THREE.Matrix4();
 
 
-		switch ( data.type ) {
+		return function ( data, geometries, materials ) {
 
 
-			case 'Scene':
+			var object;
 
 
-				object = new THREE.Scene();
+			switch ( data.type ) {
 
 
-				break;
+				case 'Scene':
 
 
-			case 'PerspectiveCamera':
+					object = new THREE.Scene();
 
 
-				object = new THREE.PerspectiveCamera( data.fov, data.aspect, data.near, data.far );
-				object.position.fromArray( data.position );
-				object.rotation.fromArray( data.rotation );
+					break;
 
 
-				break;
+				case 'PerspectiveCamera':
 
 
-			case 'OrthographicCamera':
+					object = new THREE.PerspectiveCamera( data.fov, data.aspect, data.near, data.far );
 
 
-				object = new THREE.OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );
-				object.position.fromArray( data.position );
-				object.rotation.fromArray( data.rotation );
+					break;
 
 
-				break;
+				case 'OrthographicCamera':
 
 
-			case 'AmbientLight':
+					object = new THREE.OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );
 
 
-				object = new THREE.AmbientLight( data.color );
+					break;
 
 
-				break;
+				case 'AmbientLight':
 
 
-			case 'DirectionalLight':
+					object = new THREE.AmbientLight( data.color );
 
 
-				object = new THREE.DirectionalLight( data.color, data.intensity );
-				object.position.fromArray( data.position );
+					break;
 
 
-				break;
+				case 'DirectionalLight':
 
 
-			case 'PointLight':
+					object = new THREE.DirectionalLight( data.color, data.intensity );
 
 
-				object = new THREE.PointLight( data.color, data.intensity, data.distance );
-				object.position.fromArray( data.position );
+					break;
 
 
-				break;
+				case 'PointLight':
 
 
-			case 'SpotLight':
+					object = new THREE.PointLight( data.color, data.intensity, data.distance );
 
 
-				object = new THREE.SpotLight( data.color, data.intensity, data.distance, data.angle, data.exponent );
-				object.position.fromArray( data.position );
+					break;
 
 
-				break;
+				case 'SpotLight':
 
 
-			case 'HemisphereLight':
+					object = new THREE.SpotLight( data.color, data.intensity, data.distance, data.angle, data.exponent );
 
 
-				object = new THREE.HemisphereLight( data.color, data.groundColor, data.intensity );
-				object.position.fromArray( data.position );
+					break;
 
 
-				break;
+				case 'HemisphereLight':
 
 
-			case 'Mesh':
+					object = new THREE.HemisphereLight( data.color, data.groundColor, data.intensity );
 
 
-				object = new THREE.Mesh( geometries[ data.geometry ], materials[ data.material ] );
-				object.position.fromArray( data.position );
-				object.rotation.fromArray( data.rotation );
-				object.scale.fromArray( data.scale );
+					break;
 
 
-				break;
+				case 'Mesh':
 
 
-			default:
+					object = new THREE.Mesh( geometries[ data.geometry ], materials[ data.material ] );
 
 
-				object = new THREE.Object3D();
-				object.position.fromArray( data.position );
-				object.rotation.fromArray( data.rotation );
-				object.scale.fromArray( data.scale );
+					break;
 
 
-		}
+				default:
+
+					object = new THREE.Object3D();
+
+			}
+
+			matrix.fromArray( data.matrix );
+			matrix.decompose( object.position, object.quaternion, object.scale );
+
+			object.rotation.updateEuler();
 
 
-		if ( data.id !== undefined ) object.id = data.id;
-		if ( data.name !== undefined ) object.name = data.name;
-		if ( data.visible !== undefined ) object.visible = data.visible;
-		if ( data.userData !== undefined ) object.userData = data.userData;
+			if ( data.id !== undefined ) object.id = data.id;
+			if ( data.name !== undefined ) object.name = data.name;
+			if ( data.visible !== undefined ) object.visible = data.visible;
+			if ( data.userData !== undefined ) object.userData = data.userData;
 
 
-		if ( data.children !== undefined ) {
+			if ( data.children !== undefined ) {
 
 
-			for ( var child in data.children ) {
+				for ( var child in data.children ) {
 
 
-				object.add( this.parseObject( data.children[ child ], geometries, materials ) );
+					object.add( this.parseObject( data.children[ child ], geometries, materials ) );
+
+				}
 
 
 			}
 			}
 
 
-		}
+			return object;
 
 
-		return object;
+		}
 
 
-	}
+	}()
 
 
 };
 };

+ 27 - 13
src/math/Matrix4.js

@@ -14,11 +14,13 @@
 
 
 THREE.Matrix4 = function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
 THREE.Matrix4 = function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
 
 
-	var te = this.elements = new Float32Array( 16 );
+	this.elements = new Float32Array( 16 );
 
 
 	// TODO: if n11 is undefined, then just set to identity, otherwise copy all other values into matrix
 	// TODO: if n11 is undefined, then just set to identity, otherwise copy all other values into matrix
 	//   we should not support semi specification of Matrix4, it is just weird.
 	//   we should not support semi specification of Matrix4, it is just weird.
 
 
+	var te = this.elements;
+
 	te[0] = ( n11 !== undefined ) ? n11 : 1; te[4] = n12 || 0; te[8] = n13 || 0; te[12] = n14 || 0;
 	te[0] = ( n11 !== undefined ) ? n11 : 1; te[4] = n12 || 0; te[8] = n13 || 0; te[12] = n14 || 0;
 	te[1] = n21 || 0; te[5] = ( n22 !== undefined ) ? n22 : 1; te[9] = n23 || 0; te[13] = n24 || 0;
 	te[1] = n21 || 0; te[5] = ( n22 !== undefined ) ? n22 : 1; te[9] = n23 || 0; te[13] = n24 || 0;
 	te[2] = n31 || 0; te[6] = n32 || 0; te[10] = ( n33 !== undefined ) ? n33 : 1; te[14] = n34 || 0;
 	te[2] = n31 || 0; te[6] = n32 || 0; te[10] = ( n33 !== undefined ) ? n33 : 1; te[14] = n34 || 0;
@@ -60,16 +62,7 @@ THREE.Matrix4.prototype = {
 
 
 	copy: function ( m ) {
 	copy: function ( m ) {
 
 
-		var me = m.elements;
-
-		this.set(
-
-			me[0], me[4], me[8], me[12],
-			me[1], me[5], me[9], me[13],
-			me[2], me[6], me[10], me[14],
-			me[3], me[7], me[11], me[15]
-
-		);
+		this.elements.set( m.elements );
 
 
 		return this;
 		return this;
 
 
@@ -637,7 +630,7 @@ THREE.Matrix4.prototype = {
 		te[15] = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33;
 		te[15] = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33;
 
 
 		var det = n11 * te[ 0 ] + n21 * te[ 4 ] + n31 * te[ 8 ] + n41 * te[ 12 ];
 		var det = n11 * te[ 0 ] + n21 * te[ 4 ] + n31 * te[ 8 ] + n41 * te[ 12 ];
-	
+
 		if ( det == 0 ) {
 		if ( det == 0 ) {
 
 
 			var msg = "Matrix4.getInverse(): can't invert matrix, determinant is 0";
 			var msg = "Matrix4.getInverse(): can't invert matrix, determinant is 0";
@@ -906,6 +899,27 @@ THREE.Matrix4.prototype = {
 
 
 	},
 	},
 
 
+	fromArray: function ( array ) {
+
+		this.elements.set( array );
+
+		return this;
+
+	},
+
+	toArray: function () {
+
+		var te = this.elements;
+
+		return [
+			te[ 0 ], te[ 1 ], te[ 2 ], te[ 3 ],
+			te[ 4 ], te[ 5 ], te[ 6 ], te[ 7 ],
+			te[ 8 ], te[ 9 ], te[ 10 ], te[ 11 ],
+			te[ 12 ], te[ 13 ], te[ 14 ], te[ 15 ]
+		];
+
+	},
+
 	clone: function () {
 	clone: function () {
 
 
 		var te = this.elements;
 		var te = this.elements;
@@ -925,7 +939,7 @@ THREE.Matrix4.prototype = {
 
 
 THREE.extend( THREE.Matrix4.prototype, {
 THREE.extend( THREE.Matrix4.prototype, {
 
 
-	decompose: function() {
+	decompose: function () {
 
 
 		var x = new THREE.Vector3();
 		var x = new THREE.Vector3();
 		var y = new THREE.Vector3();
 		var y = new THREE.Vector3();