1
0

Mat4.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982
  1. /**
  2. Copyright 2013 BlackBerry Inc.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. Original file from GamePlay3D: http://gameplay3d.org
  13. This file was modified to fit the cocos2d-x project
  14. */
  15. #include "math/Mat4.h"
  16. #include <cmath>
  17. #include "math/Quaternion.h"
  18. #include "math/MathUtil.h"
  19. #include "base/ccMacros.h"
  20. NS_CC_MATH_BEGIN
  21. Mat4::Mat4()
  22. {
  23. *this = IDENTITY;
  24. }
  25. Mat4::Mat4(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24,
  26. float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)
  27. {
  28. set(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
  29. }
  30. Mat4::Mat4(const float* mat)
  31. {
  32. set(mat);
  33. }
  34. Mat4::Mat4(const Mat4& copy)
  35. {
  36. memcpy(m, copy.m, MATRIX_SIZE);
  37. }
  38. Mat4::~Mat4()
  39. {
  40. }
  41. void Mat4::createLookAt(const Vec3& eyePosition, const Vec3& targetPosition, const Vec3& up, Mat4* dst)
  42. {
  43. createLookAt(eyePosition.x, eyePosition.y, eyePosition.z, targetPosition.x, targetPosition.y, targetPosition.z,
  44. up.x, up.y, up.z, dst);
  45. }
  46. void Mat4::createLookAt(float eyePositionX, float eyePositionY, float eyePositionZ,
  47. float targetPositionX, float targetPositionY, float targetPositionZ,
  48. float upX, float upY, float upZ, Mat4* dst)
  49. {
  50. GP_ASSERT(dst);
  51. Vec3 eye(eyePositionX, eyePositionY, eyePositionZ);
  52. Vec3 target(targetPositionX, targetPositionY, targetPositionZ);
  53. Vec3 up(upX, upY, upZ);
  54. up.normalize();
  55. Vec3 zaxis;
  56. Vec3::subtract(eye, target, &zaxis);
  57. zaxis.normalize();
  58. Vec3 xaxis;
  59. Vec3::cross(up, zaxis, &xaxis);
  60. xaxis.normalize();
  61. Vec3 yaxis;
  62. Vec3::cross(zaxis, xaxis, &yaxis);
  63. yaxis.normalize();
  64. dst->m[0] = xaxis.x;
  65. dst->m[1] = yaxis.x;
  66. dst->m[2] = zaxis.x;
  67. dst->m[3] = 0.0f;
  68. dst->m[4] = xaxis.y;
  69. dst->m[5] = yaxis.y;
  70. dst->m[6] = zaxis.y;
  71. dst->m[7] = 0.0f;
  72. dst->m[8] = xaxis.z;
  73. dst->m[9] = yaxis.z;
  74. dst->m[10] = zaxis.z;
  75. dst->m[11] = 0.0f;
  76. dst->m[12] = -Vec3::dot(xaxis, eye);
  77. dst->m[13] = -Vec3::dot(yaxis, eye);
  78. dst->m[14] = -Vec3::dot(zaxis, eye);
  79. dst->m[15] = 1.0f;
  80. }
  81. void Mat4::createPerspective(float fieldOfView, float aspectRatio,
  82. float zNearPlane, float zFarPlane, Mat4* dst)
  83. {
  84. GP_ASSERT(dst);
  85. GP_ASSERT(zFarPlane != zNearPlane);
  86. float f_n = 1.0f / (zFarPlane - zNearPlane);
  87. float theta = MATH_DEG_TO_RAD(fieldOfView) * 0.5f;
  88. if (std::abs(std::fmod(theta, MATH_PIOVER2)) < MATH_EPSILON)
  89. {
  90. CCLOGERROR("Invalid field of view value (%f) causes attempted calculation tan(%f), which is undefined.", fieldOfView, theta);
  91. return;
  92. }
  93. float divisor = std::tan(theta);
  94. GP_ASSERT(divisor);
  95. float factor = 1.0f / divisor;
  96. memset(dst, 0, MATRIX_SIZE);
  97. GP_ASSERT(aspectRatio);
  98. dst->m[0] = (1.0f / aspectRatio) * factor;
  99. dst->m[5] = factor;
  100. dst->m[10] = (-(zFarPlane + zNearPlane)) * f_n;
  101. dst->m[11] = -1.0f;
  102. dst->m[14] = -2.0f * zFarPlane * zNearPlane * f_n;
  103. }
  104. void Mat4::createOrthographic(float width, float height, float zNearPlane, float zFarPlane, Mat4* dst)
  105. {
  106. float halfWidth = width / 2.0f;
  107. float halfHeight = height / 2.0f;
  108. createOrthographicOffCenter(-halfWidth, halfWidth, -halfHeight, halfHeight, zNearPlane, zFarPlane, dst);
  109. }
  110. void Mat4::createOrthographicOffCenter(float left, float right, float bottom, float top,
  111. float zNearPlane, float zFarPlane, Mat4* dst)
  112. {
  113. GP_ASSERT(dst);
  114. GP_ASSERT(right != left);
  115. GP_ASSERT(top != bottom);
  116. GP_ASSERT(zFarPlane != zNearPlane);
  117. memset(dst, 0, MATRIX_SIZE);
  118. dst->m[0] = 2 / (right - left);
  119. dst->m[5] = 2 / (top - bottom);
  120. dst->m[10] = 2 / (zNearPlane - zFarPlane);
  121. dst->m[12] = (left + right) / (left - right);
  122. dst->m[13] = (top + bottom) / (bottom - top);
  123. dst->m[14] = (zNearPlane + zFarPlane) / (zNearPlane - zFarPlane);
  124. dst->m[15] = 1;
  125. }
  126. void Mat4::createBillboard(const Vec3& objectPosition, const Vec3& cameraPosition,
  127. const Vec3& cameraUpVector, Mat4* dst)
  128. {
  129. createBillboardHelper(objectPosition, cameraPosition, cameraUpVector, nullptr, dst);
  130. }
  131. void Mat4::createBillboard(const Vec3& objectPosition, const Vec3& cameraPosition,
  132. const Vec3& cameraUpVector, const Vec3& cameraForwardVector,
  133. Mat4* dst)
  134. {
  135. createBillboardHelper(objectPosition, cameraPosition, cameraUpVector, &cameraForwardVector, dst);
  136. }
  137. void Mat4::createBillboardHelper(const Vec3& objectPosition, const Vec3& cameraPosition,
  138. const Vec3& cameraUpVector, const Vec3* cameraForwardVector,
  139. Mat4* dst)
  140. {
  141. Vec3 delta(objectPosition, cameraPosition);
  142. bool isSufficientDelta = delta.lengthSquared() > MATH_EPSILON;
  143. dst->setIdentity();
  144. dst->m[3] = objectPosition.x;
  145. dst->m[7] = objectPosition.y;
  146. dst->m[11] = objectPosition.z;
  147. // As per the contracts for the 2 variants of createBillboard, we need
  148. // either a safe default or a sufficient distance between object and camera.
  149. if (cameraForwardVector || isSufficientDelta)
  150. {
  151. Vec3 target = isSufficientDelta ? cameraPosition : (objectPosition - *cameraForwardVector);
  152. // A billboard is the inverse of a lookAt rotation
  153. Mat4 lookAt;
  154. createLookAt(objectPosition, target, cameraUpVector, &lookAt);
  155. dst->m[0] = lookAt.m[0];
  156. dst->m[1] = lookAt.m[4];
  157. dst->m[2] = lookAt.m[8];
  158. dst->m[4] = lookAt.m[1];
  159. dst->m[5] = lookAt.m[5];
  160. dst->m[6] = lookAt.m[9];
  161. dst->m[8] = lookAt.m[2];
  162. dst->m[9] = lookAt.m[6];
  163. dst->m[10] = lookAt.m[10];
  164. }
  165. }
  166. // void Mat4::createReflection(const Plane& plane, Mat4* dst)
  167. // {
  168. // Vec3 normal(plane.getNormal());
  169. // float k = -2.0f * plane.getDistance();
  170. // dst->setIdentity();
  171. // dst->m[0] -= 2.0f * normal.x * normal.x;
  172. // dst->m[5] -= 2.0f * normal.y * normal.y;
  173. // dst->m[10] -= 2.0f * normal.z * normal.z;
  174. // dst->m[1] = dst->m[4] = -2.0f * normal.x * normal.y;
  175. // dst->m[2] = dst->m[8] = -2.0f * normal.x * normal.z;
  176. // dst->m[6] = dst->m[9] = -2.0f * normal.y * normal.z;
  177. // dst->m[3] = k * normal.x;
  178. // dst->m[7] = k * normal.y;
  179. // dst->m[11] = k * normal.z;
  180. // }
  181. void Mat4::createScale(const Vec3& scale, Mat4* dst)
  182. {
  183. GP_ASSERT(dst);
  184. memcpy(dst, &IDENTITY, MATRIX_SIZE);
  185. dst->m[0] = scale.x;
  186. dst->m[5] = scale.y;
  187. dst->m[10] = scale.z;
  188. }
  189. void Mat4::createScale(float xScale, float yScale, float zScale, Mat4* dst)
  190. {
  191. GP_ASSERT(dst);
  192. memcpy(dst, &IDENTITY, MATRIX_SIZE);
  193. dst->m[0] = xScale;
  194. dst->m[5] = yScale;
  195. dst->m[10] = zScale;
  196. }
  197. void Mat4::createRotation(const Quaternion& q, Mat4* dst)
  198. {
  199. GP_ASSERT(dst);
  200. float x2 = q.x + q.x;
  201. float y2 = q.y + q.y;
  202. float z2 = q.z + q.z;
  203. float xx2 = q.x * x2;
  204. float yy2 = q.y * y2;
  205. float zz2 = q.z * z2;
  206. float xy2 = q.x * y2;
  207. float xz2 = q.x * z2;
  208. float yz2 = q.y * z2;
  209. float wx2 = q.w * x2;
  210. float wy2 = q.w * y2;
  211. float wz2 = q.w * z2;
  212. dst->m[0] = 1.0f - yy2 - zz2;
  213. dst->m[1] = xy2 + wz2;
  214. dst->m[2] = xz2 - wy2;
  215. dst->m[3] = 0.0f;
  216. dst->m[4] = xy2 - wz2;
  217. dst->m[5] = 1.0f - xx2 - zz2;
  218. dst->m[6] = yz2 + wx2;
  219. dst->m[7] = 0.0f;
  220. dst->m[8] = xz2 + wy2;
  221. dst->m[9] = yz2 - wx2;
  222. dst->m[10] = 1.0f - xx2 - yy2;
  223. dst->m[11] = 0.0f;
  224. dst->m[12] = 0.0f;
  225. dst->m[13] = 0.0f;
  226. dst->m[14] = 0.0f;
  227. dst->m[15] = 1.0f;
  228. }
  229. void Mat4::createRotation(const Vec3& axis, float angle, Mat4* dst)
  230. {
  231. GP_ASSERT(dst);
  232. float x = axis.x;
  233. float y = axis.y;
  234. float z = axis.z;
  235. // Make sure the input axis is normalized.
  236. float n = x*x + y*y + z*z;
  237. if (n != 1.0f)
  238. {
  239. // Not normalized.
  240. n = std::sqrt(n);
  241. // Prevent divide too close to zero.
  242. if (n > 0.000001f)
  243. {
  244. n = 1.0f / n;
  245. x *= n;
  246. y *= n;
  247. z *= n;
  248. }
  249. }
  250. float c = std::cos(angle);
  251. float s = std::sin(angle);
  252. float t = 1.0f - c;
  253. float tx = t * x;
  254. float ty = t * y;
  255. float tz = t * z;
  256. float txy = tx * y;
  257. float txz = tx * z;
  258. float tyz = ty * z;
  259. float sx = s * x;
  260. float sy = s * y;
  261. float sz = s * z;
  262. dst->m[0] = c + tx*x;
  263. dst->m[1] = txy + sz;
  264. dst->m[2] = txz - sy;
  265. dst->m[3] = 0.0f;
  266. dst->m[4] = txy - sz;
  267. dst->m[5] = c + ty*y;
  268. dst->m[6] = tyz + sx;
  269. dst->m[7] = 0.0f;
  270. dst->m[8] = txz + sy;
  271. dst->m[9] = tyz - sx;
  272. dst->m[10] = c + tz*z;
  273. dst->m[11] = 0.0f;
  274. dst->m[12] = 0.0f;
  275. dst->m[13] = 0.0f;
  276. dst->m[14] = 0.0f;
  277. dst->m[15] = 1.0f;
  278. }
  279. void Mat4::createRotationX(float angle, Mat4* dst)
  280. {
  281. GP_ASSERT(dst);
  282. memcpy(dst, &IDENTITY, MATRIX_SIZE);
  283. float c = std::cos(angle);
  284. float s = std::sin(angle);
  285. dst->m[5] = c;
  286. dst->m[6] = s;
  287. dst->m[9] = -s;
  288. dst->m[10] = c;
  289. }
  290. void Mat4::createRotationY(float angle, Mat4* dst)
  291. {
  292. GP_ASSERT(dst);
  293. memcpy(dst, &IDENTITY, MATRIX_SIZE);
  294. float c = std::cos(angle);
  295. float s = std::sin(angle);
  296. dst->m[0] = c;
  297. dst->m[2] = -s;
  298. dst->m[8] = s;
  299. dst->m[10] = c;
  300. }
  301. void Mat4::createRotationZ(float angle, Mat4* dst)
  302. {
  303. GP_ASSERT(dst);
  304. memcpy(dst, &IDENTITY, MATRIX_SIZE);
  305. float c = std::cos(angle);
  306. float s = std::sin(angle);
  307. dst->m[0] = c;
  308. dst->m[1] = s;
  309. dst->m[4] = -s;
  310. dst->m[5] = c;
  311. }
  312. void Mat4::createTranslation(const Vec3& translation, Mat4* dst)
  313. {
  314. GP_ASSERT(dst);
  315. memcpy(dst, &IDENTITY, MATRIX_SIZE);
  316. dst->m[12] = translation.x;
  317. dst->m[13] = translation.y;
  318. dst->m[14] = translation.z;
  319. }
  320. void Mat4::createTranslation(float xTranslation, float yTranslation, float zTranslation, Mat4* dst)
  321. {
  322. GP_ASSERT(dst);
  323. memcpy(dst, &IDENTITY, MATRIX_SIZE);
  324. dst->m[12] = xTranslation;
  325. dst->m[13] = yTranslation;
  326. dst->m[14] = zTranslation;
  327. }
  328. void Mat4::add(float scalar)
  329. {
  330. add(scalar, this);
  331. }
  332. void Mat4::add(float scalar, Mat4* dst)
  333. {
  334. GP_ASSERT(dst);
  335. #ifdef __SSE__
  336. MathUtil::addMatrix(col, scalar, dst->col);
  337. #else
  338. MathUtil::addMatrix(m, scalar, dst->m);
  339. #endif
  340. }
  341. void Mat4::add(const Mat4& mat)
  342. {
  343. add(*this, mat, this);
  344. }
  345. void Mat4::add(const Mat4& m1, const Mat4& m2, Mat4* dst)
  346. {
  347. GP_ASSERT(dst);
  348. #ifdef __SSE__
  349. MathUtil::addMatrix(m1.col, m2.col, dst->col);
  350. #else
  351. MathUtil::addMatrix(m1.m, m2.m, dst->m);
  352. #endif
  353. }
  354. bool Mat4::decompose(Vec3* scale, Quaternion* rotation, Vec3* translation) const
  355. {
  356. if (translation)
  357. {
  358. // Extract the translation.
  359. translation->x = m[12];
  360. translation->y = m[13];
  361. translation->z = m[14];
  362. }
  363. // Nothing left to do.
  364. if (scale == nullptr && rotation == nullptr)
  365. return true;
  366. // Extract the scale.
  367. // This is simply the length of each axis (row/column) in the matrix.
  368. Vec3 xaxis(m[0], m[1], m[2]);
  369. float scaleX = xaxis.length();
  370. Vec3 yaxis(m[4], m[5], m[6]);
  371. float scaleY = yaxis.length();
  372. Vec3 zaxis(m[8], m[9], m[10]);
  373. float scaleZ = zaxis.length();
  374. // Determine if we have a negative scale (true if determinant is less than zero).
  375. // In this case, we simply negate a single axis of the scale.
  376. float det = determinant();
  377. if (det < 0)
  378. scaleZ = -scaleZ;
  379. if (scale)
  380. {
  381. scale->x = scaleX;
  382. scale->y = scaleY;
  383. scale->z = scaleZ;
  384. }
  385. // Nothing left to do.
  386. if (rotation == nullptr)
  387. return true;
  388. // Scale too close to zero, can't decompose rotation.
  389. if (scaleX < MATH_TOLERANCE || scaleY < MATH_TOLERANCE || std::abs(scaleZ) < MATH_TOLERANCE)
  390. return false;
  391. float rn;
  392. // Factor the scale out of the matrix axes.
  393. rn = 1.0f / scaleX;
  394. xaxis.x *= rn;
  395. xaxis.y *= rn;
  396. xaxis.z *= rn;
  397. rn = 1.0f / scaleY;
  398. yaxis.x *= rn;
  399. yaxis.y *= rn;
  400. yaxis.z *= rn;
  401. rn = 1.0f / scaleZ;
  402. zaxis.x *= rn;
  403. zaxis.y *= rn;
  404. zaxis.z *= rn;
  405. // Now calculate the rotation from the resulting matrix (axes).
  406. float trace = xaxis.x + yaxis.y + zaxis.z + 1.0f;
  407. if (trace > MATH_EPSILON)
  408. {
  409. float s = 0.5f / std::sqrt(trace);
  410. rotation->w = 0.25f / s;
  411. rotation->x = (yaxis.z - zaxis.y) * s;
  412. rotation->y = (zaxis.x - xaxis.z) * s;
  413. rotation->z = (xaxis.y - yaxis.x) * s;
  414. }
  415. else
  416. {
  417. // Note: since xaxis, yaxis, and zaxis are normalized,
  418. // we will never divide by zero in the code below.
  419. if (xaxis.x > yaxis.y && xaxis.x > zaxis.z)
  420. {
  421. float s = 0.5f / std::sqrt(1.0f + xaxis.x - yaxis.y - zaxis.z);
  422. rotation->w = (yaxis.z - zaxis.y) * s;
  423. rotation->x = 0.25f / s;
  424. rotation->y = (yaxis.x + xaxis.y) * s;
  425. rotation->z = (zaxis.x + xaxis.z) * s;
  426. }
  427. else if (yaxis.y > zaxis.z)
  428. {
  429. float s = 0.5f / std::sqrt(1.0f + yaxis.y - xaxis.x - zaxis.z);
  430. rotation->w = (zaxis.x - xaxis.z) * s;
  431. rotation->x = (yaxis.x + xaxis.y) * s;
  432. rotation->y = 0.25f / s;
  433. rotation->z = (zaxis.y + yaxis.z) * s;
  434. }
  435. else
  436. {
  437. float s = 0.5f / std::sqrt(1.0f + zaxis.z - xaxis.x - yaxis.y);
  438. rotation->w = (xaxis.y - yaxis.x ) * s;
  439. rotation->x = (zaxis.x + xaxis.z ) * s;
  440. rotation->y = (zaxis.y + yaxis.z ) * s;
  441. rotation->z = 0.25f / s;
  442. }
  443. }
  444. return true;
  445. }
  446. float Mat4::determinant() const
  447. {
  448. float a0 = m[0] * m[5] - m[1] * m[4];
  449. float a1 = m[0] * m[6] - m[2] * m[4];
  450. float a2 = m[0] * m[7] - m[3] * m[4];
  451. float a3 = m[1] * m[6] - m[2] * m[5];
  452. float a4 = m[1] * m[7] - m[3] * m[5];
  453. float a5 = m[2] * m[7] - m[3] * m[6];
  454. float b0 = m[8] * m[13] - m[9] * m[12];
  455. float b1 = m[8] * m[14] - m[10] * m[12];
  456. float b2 = m[8] * m[15] - m[11] * m[12];
  457. float b3 = m[9] * m[14] - m[10] * m[13];
  458. float b4 = m[9] * m[15] - m[11] * m[13];
  459. float b5 = m[10] * m[15] - m[11] * m[14];
  460. // Calculate the determinant.
  461. return (a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0);
  462. }
  463. void Mat4::getScale(Vec3* scale) const
  464. {
  465. decompose(scale, nullptr, nullptr);
  466. }
  467. bool Mat4::getRotation(Quaternion* rotation) const
  468. {
  469. return decompose(nullptr, rotation, nullptr);
  470. }
  471. void Mat4::getTranslation(Vec3* translation) const
  472. {
  473. decompose(nullptr, nullptr, translation);
  474. }
  475. void Mat4::getUpVector(Vec3* dst) const
  476. {
  477. GP_ASSERT(dst);
  478. dst->x = m[4];
  479. dst->y = m[5];
  480. dst->z = m[6];
  481. }
  482. void Mat4::getDownVector(Vec3* dst) const
  483. {
  484. GP_ASSERT(dst);
  485. dst->x = -m[4];
  486. dst->y = -m[5];
  487. dst->z = -m[6];
  488. }
  489. void Mat4::getLeftVector(Vec3* dst) const
  490. {
  491. GP_ASSERT(dst);
  492. dst->x = -m[0];
  493. dst->y = -m[1];
  494. dst->z = -m[2];
  495. }
  496. void Mat4::getRightVector(Vec3* dst) const
  497. {
  498. GP_ASSERT(dst);
  499. dst->x = m[0];
  500. dst->y = m[1];
  501. dst->z = m[2];
  502. }
  503. void Mat4::getForwardVector(Vec3* dst) const
  504. {
  505. GP_ASSERT(dst);
  506. dst->x = -m[8];
  507. dst->y = -m[9];
  508. dst->z = -m[10];
  509. }
  510. void Mat4::getBackVector(Vec3* dst) const
  511. {
  512. GP_ASSERT(dst);
  513. dst->x = m[8];
  514. dst->y = m[9];
  515. dst->z = m[10];
  516. }
  517. Mat4 Mat4::getInversed() const
  518. {
  519. Mat4 mat(*this);
  520. mat.inverse();
  521. return mat;
  522. }
  523. bool Mat4::inverse()
  524. {
  525. float a0 = m[0] * m[5] - m[1] * m[4];
  526. float a1 = m[0] * m[6] - m[2] * m[4];
  527. float a2 = m[0] * m[7] - m[3] * m[4];
  528. float a3 = m[1] * m[6] - m[2] * m[5];
  529. float a4 = m[1] * m[7] - m[3] * m[5];
  530. float a5 = m[2] * m[7] - m[3] * m[6];
  531. float b0 = m[8] * m[13] - m[9] * m[12];
  532. float b1 = m[8] * m[14] - m[10] * m[12];
  533. float b2 = m[8] * m[15] - m[11] * m[12];
  534. float b3 = m[9] * m[14] - m[10] * m[13];
  535. float b4 = m[9] * m[15] - m[11] * m[13];
  536. float b5 = m[10] * m[15] - m[11] * m[14];
  537. // Calculate the determinant.
  538. float det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;
  539. // Close to zero, can't invert.
  540. if (std::abs(det) <= MATH_TOLERANCE)
  541. return false;
  542. // Support the case where m == dst.
  543. Mat4 inverse;
  544. inverse.m[0] = m[5] * b5 - m[6] * b4 + m[7] * b3;
  545. inverse.m[1] = -m[1] * b5 + m[2] * b4 - m[3] * b3;
  546. inverse.m[2] = m[13] * a5 - m[14] * a4 + m[15] * a3;
  547. inverse.m[3] = -m[9] * a5 + m[10] * a4 - m[11] * a3;
  548. inverse.m[4] = -m[4] * b5 + m[6] * b2 - m[7] * b1;
  549. inverse.m[5] = m[0] * b5 - m[2] * b2 + m[3] * b1;
  550. inverse.m[6] = -m[12] * a5 + m[14] * a2 - m[15] * a1;
  551. inverse.m[7] = m[8] * a5 - m[10] * a2 + m[11] * a1;
  552. inverse.m[8] = m[4] * b4 - m[5] * b2 + m[7] * b0;
  553. inverse.m[9] = -m[0] * b4 + m[1] * b2 - m[3] * b0;
  554. inverse.m[10] = m[12] * a4 - m[13] * a2 + m[15] * a0;
  555. inverse.m[11] = -m[8] * a4 + m[9] * a2 - m[11] * a0;
  556. inverse.m[12] = -m[4] * b3 + m[5] * b1 - m[6] * b0;
  557. inverse.m[13] = m[0] * b3 - m[1] * b1 + m[2] * b0;
  558. inverse.m[14] = -m[12] * a3 + m[13] * a1 - m[14] * a0;
  559. inverse.m[15] = m[8] * a3 - m[9] * a1 + m[10] * a0;
  560. multiply(inverse, 1.0f / det, this);
  561. return true;
  562. }
  563. bool Mat4::isIdentity() const
  564. {
  565. return (memcmp(m, &IDENTITY, MATRIX_SIZE) == 0);
  566. }
  567. void Mat4::multiply(float scalar)
  568. {
  569. multiply(scalar, this);
  570. }
  571. void Mat4::multiply(float scalar, Mat4* dst) const
  572. {
  573. multiply(*this, scalar, dst);
  574. }
  575. void Mat4::multiply(const Mat4& m, float scalar, Mat4* dst)
  576. {
  577. GP_ASSERT(dst);
  578. #ifdef __SSE__
  579. MathUtil::multiplyMatrix(m.col, scalar, dst->col);
  580. #else
  581. MathUtil::multiplyMatrix(m.m, scalar, dst->m);
  582. #endif
  583. }
  584. void Mat4::multiply(const Mat4& mat)
  585. {
  586. multiply(*this, mat, this);
  587. }
  588. void Mat4::multiply(const Mat4& m1, const Mat4& m2, Mat4* dst)
  589. {
  590. GP_ASSERT(dst);
  591. #ifdef __SSE__
  592. MathUtil::multiplyMatrix(m1.col, m2.col, dst->col);
  593. #else
  594. MathUtil::multiplyMatrix(m1.m, m2.m, dst->m);
  595. #endif
  596. }
  597. void Mat4::negate()
  598. {
  599. #ifdef __SSE__
  600. MathUtil::negateMatrix(col, col);
  601. #else
  602. MathUtil::negateMatrix(m, m);
  603. #endif
  604. }
  605. Mat4 Mat4::getNegated() const
  606. {
  607. Mat4 mat(*this);
  608. mat.negate();
  609. return mat;
  610. }
  611. void Mat4::rotate(const Quaternion& q)
  612. {
  613. rotate(q, this);
  614. }
  615. void Mat4::rotate(const Quaternion& q, Mat4* dst) const
  616. {
  617. Mat4 r;
  618. createRotation(q, &r);
  619. multiply(*this, r, dst);
  620. }
  621. void Mat4::rotate(const Vec3& axis, float angle)
  622. {
  623. rotate(axis, angle, this);
  624. }
  625. void Mat4::rotate(const Vec3& axis, float angle, Mat4* dst) const
  626. {
  627. Mat4 r;
  628. createRotation(axis, angle, &r);
  629. multiply(*this, r, dst);
  630. }
  631. void Mat4::rotateX(float angle)
  632. {
  633. rotateX(angle, this);
  634. }
  635. void Mat4::rotateX(float angle, Mat4* dst) const
  636. {
  637. Mat4 r;
  638. createRotationX(angle, &r);
  639. multiply(*this, r, dst);
  640. }
  641. void Mat4::rotateY(float angle)
  642. {
  643. rotateY(angle, this);
  644. }
  645. void Mat4::rotateY(float angle, Mat4* dst) const
  646. {
  647. Mat4 r;
  648. createRotationY(angle, &r);
  649. multiply(*this, r, dst);
  650. }
  651. void Mat4::rotateZ(float angle)
  652. {
  653. rotateZ(angle, this);
  654. }
  655. void Mat4::rotateZ(float angle, Mat4* dst) const
  656. {
  657. Mat4 r;
  658. createRotationZ(angle, &r);
  659. multiply(*this, r, dst);
  660. }
  661. void Mat4::scale(float value)
  662. {
  663. scale(value, this);
  664. }
  665. void Mat4::scale(float value, Mat4* dst) const
  666. {
  667. scale(value, value, value, dst);
  668. }
  669. void Mat4::scale(float xScale, float yScale, float zScale)
  670. {
  671. scale(xScale, yScale, zScale, this);
  672. }
  673. void Mat4::scale(float xScale, float yScale, float zScale, Mat4* dst) const
  674. {
  675. Mat4 s;
  676. createScale(xScale, yScale, zScale, &s);
  677. multiply(*this, s, dst);
  678. }
  679. void Mat4::scale(const Vec3& s)
  680. {
  681. scale(s.x, s.y, s.z, this);
  682. }
  683. void Mat4::scale(const Vec3& s, Mat4* dst) const
  684. {
  685. scale(s.x, s.y, s.z, dst);
  686. }
  687. void Mat4::set(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24,
  688. float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)
  689. {
  690. m[0] = m11;
  691. m[1] = m21;
  692. m[2] = m31;
  693. m[3] = m41;
  694. m[4] = m12;
  695. m[5] = m22;
  696. m[6] = m32;
  697. m[7] = m42;
  698. m[8] = m13;
  699. m[9] = m23;
  700. m[10] = m33;
  701. m[11] = m43;
  702. m[12] = m14;
  703. m[13] = m24;
  704. m[14] = m34;
  705. m[15] = m44;
  706. }
  707. void Mat4::set(const float* mat)
  708. {
  709. GP_ASSERT(mat);
  710. memcpy(this->m, mat, MATRIX_SIZE);
  711. }
  712. void Mat4::set(const Mat4& mat)
  713. {
  714. memcpy(this->m, mat.m, MATRIX_SIZE);
  715. }
  716. void Mat4::setIdentity()
  717. {
  718. memcpy(m, &IDENTITY, MATRIX_SIZE);
  719. }
  720. void Mat4::setZero()
  721. {
  722. memset(m, 0, MATRIX_SIZE);
  723. }
  724. void Mat4::subtract(const Mat4& mat)
  725. {
  726. subtract(*this, mat, this);
  727. }
  728. void Mat4::subtract(const Mat4& m1, const Mat4& m2, Mat4* dst)
  729. {
  730. GP_ASSERT(dst);
  731. #ifdef __SSE__
  732. MathUtil::subtractMatrix(m1.col, m2.col, dst->col);
  733. #else
  734. MathUtil::subtractMatrix(m1.m, m2.m, dst->m);
  735. #endif
  736. }
  737. void Mat4::transformVector(Vec3* vector) const
  738. {
  739. GP_ASSERT(vector);
  740. transformVector(vector->x, vector->y, vector->z, 0.0f, vector);
  741. }
  742. void Mat4::transformVector(const Vec3& vector, Vec3* dst) const
  743. {
  744. transformVector(vector.x, vector.y, vector.z, 0.0f, dst);
  745. }
  746. void Mat4::transformVector(float x, float y, float z, float w, Vec3* dst) const
  747. {
  748. GP_ASSERT(dst);
  749. MathUtil::transformVec4(m, x, y, z, w, (float*)dst);
  750. }
  751. void Mat4::transformVector(Vec4* vector) const
  752. {
  753. GP_ASSERT(vector);
  754. transformVector(*vector, vector);
  755. }
  756. void Mat4::transformVector(const Vec4& vector, Vec4* dst) const
  757. {
  758. GP_ASSERT(dst);
  759. #ifdef __SSE__
  760. MathUtil::transformVec4(col, vector.v, dst->v);
  761. #else
  762. MathUtil::transformVec4(m, (const float*) &vector, (float*)dst);
  763. #endif
  764. }
  765. void Mat4::translate(float x, float y, float z)
  766. {
  767. translate(x, y, z, this);
  768. }
  769. void Mat4::translate(float x, float y, float z, Mat4* dst) const
  770. {
  771. Mat4 t;
  772. createTranslation(x, y, z, &t);
  773. multiply(*this, t, dst);
  774. }
  775. void Mat4::translate(const Vec3& t)
  776. {
  777. translate(t.x, t.y, t.z, this);
  778. }
  779. void Mat4::translate(const Vec3& t, Mat4* dst) const
  780. {
  781. translate(t.x, t.y, t.z, dst);
  782. }
  783. void Mat4::transpose()
  784. {
  785. #ifdef __SSE__
  786. MathUtil::transposeMatrix(col, col);
  787. #else
  788. MathUtil::transposeMatrix(m, m);
  789. #endif
  790. }
  791. Mat4 Mat4::getTransposed() const
  792. {
  793. Mat4 mat(*this);
  794. mat.transpose();
  795. return mat;
  796. }
  797. const Mat4 Mat4::IDENTITY = Mat4(
  798. 1.0f, 0.0f, 0.0f, 0.0f,
  799. 0.0f, 1.0f, 0.0f, 0.0f,
  800. 0.0f, 0.0f, 1.0f, 0.0f,
  801. 0.0f, 0.0f, 0.0f, 1.0f);
  802. const Mat4 Mat4::ZERO = Mat4(
  803. 0, 0, 0, 0,
  804. 0, 0, 0, 0,
  805. 0, 0, 0, 0,
  806. 0, 0, 0, 0 );
  807. NS_CC_MATH_END