فهرست منبع

Matrix4.decompose was incorrect, didn't account for a singular negative scale axis (also added unit test.)

Ben Houston 11 سال پیش
والد
کامیت
e437ae2699
2فایلهای تغییر یافته به همراه70 افزوده شده و 0 حذف شده
  1. 6 0
      src/math/Matrix4.js
  2. 64 0
      test/unit/math/Matrix4.js

+ 6 - 0
src/math/Matrix4.js

@@ -839,6 +839,12 @@ THREE.Matrix4.prototype = {
 			var sy = vector.set( te[4], te[5], te[6] ).length();
 			var sz = vector.set( te[8], te[9], te[10] ).length();
 
+			// if determine is negative, we need to invert one scale
+			var det = this.determinant();
+			if( det < 0 ) {
+				sx = -sx;
+			}
+
 			position.x = te[12];
 			position.y = te[13];
 			position.z = te[14];

+ 64 - 0
test/unit/math/Matrix4.js

@@ -233,3 +233,67 @@ test( "clone", function() {
 	a.elements[0] = 2;
 	ok( ! matrixEquals4( a, b ), "Passed!" );
 });
+
+
+test( "compose/decompose", function() {
+	var tValues = [
+		new THREE.Vector3(),
+		new THREE.Vector3( 3, 0, 0 ),
+		new THREE.Vector3( 0, 4, 0 ),
+		new THREE.Vector3( 0, 0, 5 ),
+		new THREE.Vector3( -6, 0, 0 ),
+		new THREE.Vector3( 0, -7, 0 ),
+		new THREE.Vector3( 0, 0, -8 ),
+		new THREE.Vector3( -2, 5, -9 ),
+		new THREE.Vector3( -2, -5, -9 )
+	];
+
+	var sValues = [
+		new THREE.Vector3( 1, 1, 1 ),
+		new THREE.Vector3( 2, 2, 2 ),
+		new THREE.Vector3( 1, -1, 1 ),
+		new THREE.Vector3( -1, 1, 1 ),
+		new THREE.Vector3( 1, 1, -1 ),
+		new THREE.Vector3( 2, -2, 1 ),
+		new THREE.Vector3( -1, 2, -2 ),
+		new THREE.Vector3( -1, -1, -1 ),
+		new THREE.Vector3( -2, -2, -2 )
+	];
+
+	var rValues = [
+		new THREE.Quaternion(),
+		new THREE.Quaternion().setFromEuler( new THREE.Euler( 1, 1, 0 ) ),
+		new THREE.Quaternion().setFromEuler( new THREE.Euler( 1, -1, 1 ) ),
+		new THREE.Quaternion( 0, 0.9238795292366128, 0, 0.38268342717215614 )
+	];
+
+
+	for( var ti = 0; ti < tValues.length; ti ++ ) {
+		for( var si = 0; si < sValues.length; si ++ ) {
+			for( var ri = 0; ri < rValues.length; ri ++ ) {
+				var t = tValues[ti];
+				var s = sValues[si];
+				var r = rValues[ri];
+
+				var m = new THREE.Matrix4().compose( t, r, s );
+				var t2 = new THREE.Vector3();
+				var r2 = new THREE.Quaternion();
+				var s2 = new THREE.Vector3();
+
+				m.decompose( t2, r2, s2 );
+
+				var m2 = new THREE.Matrix4().compose( t2, r2, s2 );
+			
+				// self-inverse should the same as inverse
+				var matrixIsSame = matrixEquals4( m, m2 );
+				if( ! matrixIsSame ) {
+					console.log( t, s, r );
+					console.log( t2, s2, r2 );
+					console.log( m, m2 );
+				}
+				ok( matrixEquals4( m, m2 ), "Passed!" );
+
+			}
+		}
+	}
+});