1 | /**
|
---|
2 | * @author bhouston / http://exocortex.com
|
---|
3 | */
|
---|
4 |
|
---|
5 | module( "Matrix3" );
|
---|
6 |
|
---|
7 | var matrixEquals3 = function( a, b, tolerance ) {
|
---|
8 | tolerance = tolerance || 0.0001;
|
---|
9 | if( a.elements.length != b.elements.length ) {
|
---|
10 | return false;
|
---|
11 | }
|
---|
12 | for( var i = 0, il = a.elements.length; i < il; i ++ ) {
|
---|
13 | var delta = a.elements[i] - b.elements[i];
|
---|
14 | if( delta > tolerance ) {
|
---|
15 | return false;
|
---|
16 | }
|
---|
17 | }
|
---|
18 | return true;
|
---|
19 | };
|
---|
20 |
|
---|
21 |
|
---|
22 | var toMatrix4 = function( m3 ) {
|
---|
23 | var result = new THREE.Matrix4();
|
---|
24 | var re = result.elements;
|
---|
25 | var me = m3.elements;
|
---|
26 | re[0] = me[0];
|
---|
27 | re[1] = me[1];
|
---|
28 | re[2] = me[2];
|
---|
29 | re[4] = me[3];
|
---|
30 | re[5] = me[4];
|
---|
31 | re[6] = me[5];
|
---|
32 | re[8] = me[6];
|
---|
33 | re[9] = me[7];
|
---|
34 | re[10] = me[8];
|
---|
35 |
|
---|
36 | return result;
|
---|
37 | };
|
---|
38 |
|
---|
39 | test( "constructor", function() {
|
---|
40 | var a = new THREE.Matrix3();
|
---|
41 | ok( a.determinant() == 1, "Passed!" );
|
---|
42 |
|
---|
43 | var b = new THREE.Matrix3( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
|
---|
44 | ok( b.elements[0] == 0 );
|
---|
45 | ok( b.elements[1] == 3 );
|
---|
46 | ok( b.elements[2] == 6 );
|
---|
47 | ok( b.elements[3] == 1 );
|
---|
48 | ok( b.elements[4] == 4 );
|
---|
49 | ok( b.elements[5] == 7 );
|
---|
50 | ok( b.elements[6] == 2 );
|
---|
51 | ok( b.elements[7] == 5 );
|
---|
52 | ok( b.elements[8] == 8 );
|
---|
53 |
|
---|
54 | ok( ! matrixEquals3( a, b ), "Passed!" );
|
---|
55 | });
|
---|
56 |
|
---|
57 | test( "copy", function() {
|
---|
58 | var a = new THREE.Matrix3( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
|
---|
59 | var b = new THREE.Matrix3().copy( a );
|
---|
60 |
|
---|
61 | ok( matrixEquals3( a, b ), "Passed!" );
|
---|
62 |
|
---|
63 | // ensure that it is a true copy
|
---|
64 | a.elements[0] = 2;
|
---|
65 | ok( ! matrixEquals3( a, b ), "Passed!" );
|
---|
66 | });
|
---|
67 |
|
---|
68 | test( "set", function() {
|
---|
69 | var b = new THREE.Matrix3();
|
---|
70 | ok( b.determinant() == 1, "Passed!" );
|
---|
71 |
|
---|
72 | b.set( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
|
---|
73 | ok( b.elements[0] == 0 );
|
---|
74 | ok( b.elements[1] == 3 );
|
---|
75 | ok( b.elements[2] == 6 );
|
---|
76 | ok( b.elements[3] == 1 );
|
---|
77 | ok( b.elements[4] == 4 );
|
---|
78 | ok( b.elements[5] == 7 );
|
---|
79 | ok( b.elements[6] == 2 );
|
---|
80 | ok( b.elements[7] == 5 );
|
---|
81 | ok( b.elements[8] == 8 );
|
---|
82 | });
|
---|
83 |
|
---|
84 | test( "identity", function() {
|
---|
85 | var b = new THREE.Matrix3( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
|
---|
86 | ok( b.elements[0] == 0 );
|
---|
87 | ok( b.elements[1] == 3 );
|
---|
88 | ok( b.elements[2] == 6 );
|
---|
89 | ok( b.elements[3] == 1 );
|
---|
90 | ok( b.elements[4] == 4 );
|
---|
91 | ok( b.elements[5] == 7 );
|
---|
92 | ok( b.elements[6] == 2 );
|
---|
93 | ok( b.elements[7] == 5 );
|
---|
94 | ok( b.elements[8] == 8 );
|
---|
95 |
|
---|
96 | var a = new THREE.Matrix3();
|
---|
97 | ok( ! matrixEquals3( a, b ), "Passed!" );
|
---|
98 |
|
---|
99 | b.identity();
|
---|
100 | ok( matrixEquals3( a, b ), "Passed!" );
|
---|
101 | });
|
---|
102 |
|
---|
103 | test( "multiplyScalar", function() {
|
---|
104 | var b = new THREE.Matrix3( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
|
---|
105 | ok( b.elements[0] == 0 );
|
---|
106 | ok( b.elements[1] == 3 );
|
---|
107 | ok( b.elements[2] == 6 );
|
---|
108 | ok( b.elements[3] == 1 );
|
---|
109 | ok( b.elements[4] == 4 );
|
---|
110 | ok( b.elements[5] == 7 );
|
---|
111 | ok( b.elements[6] == 2 );
|
---|
112 | ok( b.elements[7] == 5 );
|
---|
113 | ok( b.elements[8] == 8 );
|
---|
114 |
|
---|
115 | b.multiplyScalar( 2 );
|
---|
116 | ok( b.elements[0] == 0*2 );
|
---|
117 | ok( b.elements[1] == 3*2 );
|
---|
118 | ok( b.elements[2] == 6*2 );
|
---|
119 | ok( b.elements[3] == 1*2 );
|
---|
120 | ok( b.elements[4] == 4*2 );
|
---|
121 | ok( b.elements[5] == 7*2 );
|
---|
122 | ok( b.elements[6] == 2*2 );
|
---|
123 | ok( b.elements[7] == 5*2 );
|
---|
124 | ok( b.elements[8] == 8*2 );
|
---|
125 | });
|
---|
126 |
|
---|
127 | test( "determinant", function() {
|
---|
128 | var a = new THREE.Matrix3();
|
---|
129 | ok( a.determinant() == 1, "Passed!" );
|
---|
130 |
|
---|
131 | a.elements[0] = 2;
|
---|
132 | ok( a.determinant() == 2, "Passed!" );
|
---|
133 |
|
---|
134 | a.elements[0] = 0;
|
---|
135 | ok( a.determinant() == 0, "Passed!" );
|
---|
136 |
|
---|
137 | // calculated via http://www.euclideanspace.com/maths/algebra/matrix/functions/determinant/threeD/index.htm
|
---|
138 | a.set( 2, 3, 4, 5, 13, 7, 8, 9, 11 );
|
---|
139 | ok( a.determinant() == -73, "Passed!" );
|
---|
140 | });
|
---|
141 |
|
---|
142 |
|
---|
143 | test( "getInverse", function() {
|
---|
144 | var identity = new THREE.Matrix4();
|
---|
145 | var a = new THREE.Matrix4();
|
---|
146 | var b = new THREE.Matrix3( 0, 0, 0, 0, 0, 0, 0, 0, 0 );
|
---|
147 | var c = new THREE.Matrix4( 0, 0, 0, 0, 0, 0, 0, 0, 0 );
|
---|
148 |
|
---|
149 | ok( ! matrixEquals3( a, b ), "Passed!" );
|
---|
150 | b.getInverse( a, false );
|
---|
151 | ok( matrixEquals3( b, new THREE.Matrix3() ), "Passed!" );
|
---|
152 |
|
---|
153 | try {
|
---|
154 | b.getInverse( c, true );
|
---|
155 | ok( false, "Passed!" ); // should never get here.
|
---|
156 | }
|
---|
157 | catch( err ) {
|
---|
158 | ok( true, "Passed!" );
|
---|
159 | }
|
---|
160 |
|
---|
161 | var testMatrices = [
|
---|
162 | new THREE.Matrix4().makeRotationX( 0.3 ),
|
---|
163 | new THREE.Matrix4().makeRotationX( -0.3 ),
|
---|
164 | new THREE.Matrix4().makeRotationY( 0.3 ),
|
---|
165 | new THREE.Matrix4().makeRotationY( -0.3 ),
|
---|
166 | new THREE.Matrix4().makeRotationZ( 0.3 ),
|
---|
167 | new THREE.Matrix4().makeRotationZ( -0.3 ),
|
---|
168 | new THREE.Matrix4().makeScale( 1, 2, 3 ),
|
---|
169 | new THREE.Matrix4().makeScale( 1/8, 1/2, 1/3 )
|
---|
170 | ];
|
---|
171 |
|
---|
172 | for( var i = 0, il = testMatrices.length; i < il; i ++ ) {
|
---|
173 | var m = testMatrices[i];
|
---|
174 | var mInverse3 = new THREE.Matrix3().getInverse( m );
|
---|
175 |
|
---|
176 | var mInverse = toMatrix4( mInverse3 );
|
---|
177 |
|
---|
178 | // the determinant of the inverse should be the reciprocal
|
---|
179 | ok( Math.abs( m.determinant() * mInverse3.determinant() - 1 ) < 0.0001, "Passed!" );
|
---|
180 | ok( Math.abs( m.determinant() * mInverse.determinant() - 1 ) < 0.0001, "Passed!" );
|
---|
181 |
|
---|
182 | var mProduct = new THREE.Matrix4().multiplyMatrices( m, mInverse );
|
---|
183 | ok( Math.abs( mProduct.determinant() - 1 ) < 0.0001, "Passed!" );
|
---|
184 | ok( matrixEquals3( mProduct, identity ), "Passed!" );
|
---|
185 | }
|
---|
186 | });
|
---|
187 |
|
---|
188 | test( "transpose", function() {
|
---|
189 | var a = new THREE.Matrix3();
|
---|
190 | var b = a.clone().transpose();
|
---|
191 | ok( matrixEquals3( a, b ), "Passed!" );
|
---|
192 |
|
---|
193 | b = new THREE.Matrix3( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
|
---|
194 | var c = b.clone().transpose();
|
---|
195 | ok( ! matrixEquals3( b, c ), "Passed!" );
|
---|
196 | c.transpose();
|
---|
197 | ok( matrixEquals3( b, c ), "Passed!" );
|
---|
198 | });
|
---|
199 |
|
---|
200 | test( "clone", function() {
|
---|
201 | var a = new THREE.Matrix3( 0, 1, 2, 3, 4, 5, 6, 7, 8 );
|
---|
202 | var b = a.clone();
|
---|
203 |
|
---|
204 | ok( matrixEquals3( a, b ), "Passed!" );
|
---|
205 |
|
---|
206 | // ensure that it is a true copy
|
---|
207 | a.elements[0] = 2;
|
---|
208 | ok( ! matrixEquals3( a, b ), "Passed!" );
|
---|
209 | });
|
---|