Mat4.cpp 27 KB

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