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