1 /**
  2  Copyright (c) 2010-2012 cocos2d-x.org
  3  Copyright (c) 2008, Luke Benstead.
  4  All rights reserved.
  5 
  6  Redistribution and use in source and binary forms, with or without modification,
  7  are permitted provided that the following conditions are met:
  8 
  9  Redistributions of source code must retain the above copyright notice,
 10  this list of conditions and the following disclaimer.
 11  Redistributions in binary form must reproduce the above copyright notice,
 12  this list of conditions and the following disclaimer in the documentation
 13  and/or other materials provided with the distribution.
 14 
 15  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 16  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 17  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 18  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 19  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 20  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 21  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 22  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 23  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 24  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 25  */
 26 
 27 var Float32Array = Float32Array || Array;
 28 
 29 cc.kmMat3 = function () {
 30     this.mat = new Float32Array([0, 0, 0,
 31         0, 0, 0,
 32         0, 0, 0]);
 33 };
 34 
 35 cc.kmMat3Fill = function (pOut, pMat) {
 36     for (var i = 0; i < 9; i++) {
 37         pOut.mat[i] = pMat;
 38     }
 39     return pOut;
 40 };
 41 
 42 cc.kmMat3Adjugate = function (pOut, pIn) {
 43     pOut.mat[0] = pIn.mat[4] * pIn.mat[8] - pIn.mat[5] * pIn.mat[7];
 44     pOut.mat[1] = pIn.mat[2] * pIn.mat[7] - pIn.mat[1] * pIn.mat[8];
 45     pOut.mat[2] = pIn.mat[1] * pIn.mat[5] - pIn.mat[2] * pIn.mat[4];
 46     pOut.mat[3] = pIn.mat[5] * pIn.mat[6] - pIn.mat[3] * pIn.mat[8];
 47     pOut.mat[4] = pIn.mat[0] * pIn.mat[8] - pIn.mat[2] * pIn.mat[6];
 48     pOut.mat[5] = pIn.mat[2] * pIn.mat[3] - pIn.mat[0] * pIn.mat[5];
 49     pOut.mat[6] = pIn.mat[3] * pIn.mat[7] - pIn.mat[4] * pIn.mat[6];
 50 
 51     // XXX: pIn.mat[9] is invalid!
 52 //    pOut.mat[7] = pIn.mat[1] * pIn.mat[6] - pIn.mat[9] * pIn.mat[7];
 53     pOut.mat[8] = pIn.mat[0] * pIn.mat[4] - pIn.mat[1] * pIn.mat[3];
 54 
 55     return pOut;
 56 };
 57 
 58 cc.kmMat3Identity = function (pOut) {
 59     pOut.mat[1] = pOut.mat[2] = pOut.mat[3] =
 60         pOut.mat[5] = pOut.mat[6] = pOut.mat[7] = 0;
 61     pOut.mat[0] = pOut.mat[4] = pOut.mat[8] = 1.0;
 62     return pOut;
 63 };
 64 
 65 cc.kmMat3Inverse = function (pOut, pDeterminate, pM) {
 66     var detInv;
 67     var adjugate = new cc.kmMat3();
 68 
 69     if (pDeterminate === 0.0)
 70         return null;
 71 
 72     detInv = 1.0 / pDeterminate;
 73 
 74     cc.kmMat3Adjugate(adjugate, pM);
 75     cc.kmMat3ScalarMultiply(pOut, adjugate, detInv);
 76 
 77     return pOut;
 78 };
 79 
 80 cc.kmMat3._identity =
 81     new Float32Array([1.0, 0.0, 0.0,
 82         0.0, 1.0, 0.0,
 83         0.0, 0.0, 1.0]);
 84 
 85 cc.kmMat3IsIdentity = function (pIn) {
 86     for (var i = 0; i < 9; i++) {
 87         if (cc.kmMat3._identity[i] !== pIn.mat[i])
 88             return false;
 89     }
 90     return true;
 91 };
 92 
 93 cc.kmMat3Transpose = function (pOut, pIn) {
 94     var z, x;
 95     for (z = 0; z < 3; ++z) {
 96         for (x = 0; x < 3; ++x)
 97             pOut.mat[(z * 3) + x] = pIn.mat[(x * 3) + z];
 98     }
 99 
100     return pOut;
101 };
102 
103 cc.kmMat3Determinant = function (pIn) {
104     var output;
105     /*
106      calculating the determinant following the rule of sarus,
107      | 0  3  6 | 0  3 |
108      m = | 1  4  7 | 1  4 |
109      | 2  5  8 | 2  5 |
110      now sum up the products of the diagonals going to the right (i.e. 0,4,8)
111      and substract the products of the other diagonals (i.e. 2,4,6)
112      */
113 
114     output = pIn.mat[0] * pIn.mat[4] * pIn.mat[8] + pIn.mat[1] * pIn.mat[5] * pIn.mat[6] + pIn.mat[2] * pIn.mat[3] * pIn.mat[7];
115     output -= pIn.mat[2] * pIn.mat[4] * pIn.mat[6] + pIn.mat[0] * pIn.mat[5] * pIn.mat[7] + pIn.mat[1] * pIn.mat[3] * pIn.mat[8];
116 
117     return output;
118 };
119 
120 cc.kmMat3Multiply = function (pOut, pM1, pM2) {
121     var m1 = pM1.mat, m2 = pM2.mat;
122 
123     pOut.mat[0] = m1[0] * m2[0] + m1[3] * m2[1] + m1[6] * m2[2];
124     pOut.mat[1] = m1[1] * m2[0] + m1[4] * m2[1] + m1[7] * m2[2];
125     pOut.mat[2] = m1[2] * m2[0] + m1[5] * m2[1] + m1[8] * m2[2];
126 
127     pOut.mat[3] = m1[0] * m2[3] + m1[3] * m2[4] + m1[6] * m2[5];
128     pOut.mat[4] = m1[1] * m2[3] + m1[4] * m2[4] + m1[7] * m2[5];
129     pOut.mat[5] = m1[2] * m2[3] + m1[5] * m2[4] + m1[8] * m2[5];
130 
131     pOut.mat[6] = m1[0] * m2[6] + m1[3] * m2[7] + m1[6] * m2[8];
132     pOut.mat[7] = m1[1] * m2[6] + m1[4] * m2[7] + m1[7] * m2[8];
133     pOut.mat[8] = m1[2] * m2[6] + m1[5] * m2[7] + m1[8] * m2[8];
134 
135     return pOut;
136 };
137 
138 cc.kmMat3ScalarMultiply = function (pOut, pM, pFactor) {
139     for (var i = 0; i < 9; i++) {
140         pOut.mat[i] = pM.mat[i] * pFactor;
141     }
142     return pOut;
143 };
144 
145 cc.kmMat3RotationAxisAngle = function (pOut, axis, radians) {
146     var rcos = Math.cos(radians);
147     var rsin = Math.sin(radians);
148 
149     pOut.mat[0] = rcos + axis.x * axis.x * (1 - rcos);
150     pOut.mat[1] = axis.z * rsin + axis.y * axis.x * (1 - rcos);
151     pOut.mat[2] = -axis.y * rsin + axis.z * axis.x * (1 - rcos);
152 
153     pOut.mat[3] = -axis.z * rsin + axis.x * axis.y * (1 - rcos);
154     pOut.mat[4] = rcos + axis.y * axis.y * (1 - rcos);
155     pOut.mat[5] = axis.x * rsin + axis.z * axis.y * (1 - rcos);
156 
157     pOut.mat[6] = axis.y * rsin + axis.x * axis.z * (1 - rcos);
158     pOut.mat[7] = -axis.x * rsin + axis.y * axis.z * (1 - rcos);
159     pOut.mat[8] = rcos + axis.z * axis.z * (1 - rcos);
160 
161     return pOut;
162 };
163 
164 cc.kmMat3Assign = function (pOut, pIn) {
165     if(pOut == pIn) {
166         cc.log("cc.kmMat3Assign(): pOut equals pIn");
167         return pOut;
168     }
169 
170     for (var i = 0; i < 9; i++)
171         pOut.mat[i] = pIn.mat[i];
172     return pOut;
173 };
174 
175 cc.kmMat3AreEqual = function (pMat1, pMat2) {
176     if (pMat1 == pMat2)
177         return true;
178 
179     for (var i = 0; i < 9; ++i) {
180         if (!(pMat1.mat[i] + cc.kmEpsilon > pMat2.mat[i] &&
181             pMat1.mat[i] - cc.kmEpsilon < pMat2.mat[i])) {
182             return false;
183         }
184     }
185 
186     return true;
187 };
188 
189 cc.kmMat3RotationX = function (pOut, radians) {
190     /*
191      |  1  0       0      |
192      M = |  0  cos(A) -sin(A) |
193      |  0  sin(A)  cos(A) |
194 
195      */
196 
197     pOut.mat[0] = 1.0;
198     pOut.mat[1] = 0.0;
199     pOut.mat[2] = 0.0;
200 
201     pOut.mat[3] = 0.0;
202     pOut.mat[4] = Math.cos(radians);
203     pOut.mat[5] = Math.sin(radians);
204 
205     pOut.mat[6] = 0.0;
206     pOut.mat[7] = -Math.sin(radians);
207     pOut.mat[8] = Math.cos(radians);
208 
209     return pOut;
210 };
211 
212 cc.kmMat3RotationY = function (pOut, radians) {
213     /*
214      |  cos(A)  0   sin(A) |
215      M = |  0       1   0      |
216      | -sin(A)  0   cos(A) |
217      */
218 
219     pOut.mat[0] = Math.cos(radians);
220     pOut.mat[1] = 0.0;
221     pOut.mat[2] = -Math.sin(radians);
222 
223     pOut.mat[3] = 0.0;
224     pOut.mat[4] = 1.0;
225     pOut.mat[5] = 0.0;
226 
227     pOut.mat[6] = Math.sin(radians);
228     pOut.mat[7] = 0.0;
229     pOut.mat[8] = Math.cos(radians);
230 
231     return pOut;
232 };
233 
234 cc.kmMat3RotationZ = function (pOut, radians) {
235     /*
236      |  cos(A)  -sin(A)   0  |
237      M = |  sin(A)   cos(A)   0  |
238      |  0        0        1  |
239      */
240     pOut.mat[0] = Math.cos(radians);
241     pOut.mat[1] = -Math.sin(radians);
242     pOut.mat[2] = 0.0;
243 
244     pOut.mat[3] = Math.sin(radians);
245     pOut.mat[4] = Math.cos(radians);
246     pOut.mat[5] = 0.0;
247 
248     pOut.mat[6] = 0.0;
249     pOut.mat[7] = 0.0;
250     pOut.mat[8] = 1.0;
251 
252     return pOut;
253 };
254 
255 cc.kmMat3Rotation = function (pOut, radians) {
256     /*
257      |  cos(A)  -sin(A)   0  |
258      M = |  sin(A)   cos(A)   0  |
259      |  0        0        1  |
260      */
261     pOut.mat[0] = Math.cos(radians);
262     pOut.mat[1] = Math.sin(radians);
263     pOut.mat[2] = 0.0;
264 
265     pOut.mat[3] = -Math.sin(radians);
266     pOut.mat[4] = Math.cos(radians);
267     pOut.mat[5] = 0.0;
268 
269     pOut.mat[6] = 0.0;
270     pOut.mat[7] = 0.0;
271     pOut.mat[8] = 1.0;
272     return pOut;
273 };
274 
275 cc.kmMat3Scaling = function (pOut, x, y) {
276 //    memset(pOut.mat, 0, sizeof(float) * 9);
277     cc.kmMat3Identity(pOut);
278     pOut.mat[0] = x;
279     pOut.mat[4] = y;
280 
281     return pOut;
282 };
283 
284 cc.kmMat3Translation = function (pOut, x, y) {
285 //    memset(pOut.mat, 0, sizeof(float) * 9);
286     cc.kmMat3Identity(pOut);
287     pOut.mat[6] = x;
288     pOut.mat[7] = y;
289 //    pOut.mat[8] = 1.0;
290 
291     return pOut;
292 };
293 
294 cc.kmMat3RotationQuaternion = function (pOut, pIn) {
295     if (!pIn || !pOut)
296         return null;
297 
298     // First row
299     pOut.mat[0] = 1.0 - 2.0 * (pIn.y * pIn.y + pIn.z * pIn.z);
300     pOut.mat[1] = 2.0 * (pIn.x * pIn.y - pIn.w * pIn.z);
301     pOut.mat[2] = 2.0 * (pIn.x * pIn.z + pIn.w * pIn.y);
302 
303     // Second row
304     pOut.mat[3] = 2.0 * (pIn.x * pIn.y + pIn.w * pIn.z);
305     pOut.mat[4] = 1.0 - 2.0 * (pIn.x * pIn.x + pIn.z * pIn.z);
306     pOut.mat[5] = 2.0 * (pIn.y * pIn.z - pIn.w * pIn.x);
307 
308     // Third row
309     pOut.mat[6] = 2.0 * (pIn.x * pIn.z - pIn.w * pIn.y);
310     pOut.mat[7] = 2.0 * (pIn.y * pIn.z + pIn.w * pIn.x);
311     pOut.mat[8] = 1.0 - 2.0 * (pIn.x * pIn.x + pIn.y * pIn.y);
312 
313     return pOut;
314 };
315 
316 cc.kmMat3RotationToAxisAngle = function (pAxis, radians, pIn) {
317     /*Surely not this easy?*/
318     var temp;
319     cc.kmQuaternionRotationMatrix(temp, pIn);
320     cc.kmQuaternionToAxisAngle(temp, pAxis, radians);
321     return pAxis;
322 };
323 
324 
325 
326 
327 
328