Matrix3x4.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. //
  2. // Copyright (c) 2008-2013 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "Matrix4.h"
  24. namespace Urho3D
  25. {
  26. /// 3x4 matrix for scene node transform calculations.
  27. class URHO3D_API Matrix3x4
  28. {
  29. public:
  30. /// Construct undefined.
  31. Matrix3x4()
  32. {
  33. }
  34. /// Copy-construct from another matrix.
  35. Matrix3x4(const Matrix3x4& matrix) :
  36. m00_(matrix.m00_),
  37. m01_(matrix.m01_),
  38. m02_(matrix.m02_),
  39. m03_(matrix.m03_),
  40. m10_(matrix.m10_),
  41. m11_(matrix.m11_),
  42. m12_(matrix.m12_),
  43. m13_(matrix.m13_),
  44. m20_(matrix.m20_),
  45. m21_(matrix.m21_),
  46. m22_(matrix.m22_),
  47. m23_(matrix.m23_)
  48. {
  49. }
  50. /// Copy-construct from a 3x3 matrix and set the extra elements to identity.
  51. Matrix3x4(const Matrix3& matrix) :
  52. m00_(matrix.m00_),
  53. m01_(matrix.m01_),
  54. m02_(matrix.m02_),
  55. m03_(0.0f),
  56. m10_(matrix.m10_),
  57. m11_(matrix.m11_),
  58. m12_(matrix.m12_),
  59. m13_(0.0f),
  60. m20_(matrix.m20_),
  61. m21_(matrix.m21_),
  62. m22_(matrix.m22_),
  63. m23_(0.0f)
  64. {
  65. }
  66. /// Copy-construct from a 4x4 matrix which is assumed to contain no projection.
  67. Matrix3x4(const Matrix4& matrix) :
  68. m00_(matrix.m00_),
  69. m01_(matrix.m01_),
  70. m02_(matrix.m02_),
  71. m03_(matrix.m03_),
  72. m10_(matrix.m10_),
  73. m11_(matrix.m11_),
  74. m12_(matrix.m12_),
  75. m13_(matrix.m13_),
  76. m20_(matrix.m20_),
  77. m21_(matrix.m21_),
  78. m22_(matrix.m22_),
  79. m23_(matrix.m23_)
  80. {
  81. }
  82. // Construct from values.
  83. Matrix3x4(float v00, float v01, float v02, float v03,
  84. float v10, float v11, float v12, float v13,
  85. float v20, float v21, float v22, float v23) :
  86. m00_(v00),
  87. m01_(v01),
  88. m02_(v02),
  89. m03_(v03),
  90. m10_(v10),
  91. m11_(v11),
  92. m12_(v12),
  93. m13_(v13),
  94. m20_(v20),
  95. m21_(v21),
  96. m22_(v22),
  97. m23_(v23)
  98. {
  99. }
  100. /// Construct from a float array.
  101. Matrix3x4(const float* data) :
  102. m00_(data[0]),
  103. m01_(data[1]),
  104. m02_(data[2]),
  105. m03_(data[3]),
  106. m10_(data[4]),
  107. m11_(data[5]),
  108. m12_(data[6]),
  109. m13_(data[7]),
  110. m20_(data[8]),
  111. m21_(data[9]),
  112. m22_(data[10]),
  113. m23_(data[11])
  114. {
  115. }
  116. /// Construct from translation, rotation and uniform scale.
  117. Matrix3x4(const Vector3& translation, const Quaternion& rotation, float scale);
  118. /// Construct from translation, rotation and nonuniform scale.
  119. Matrix3x4(const Vector3& translation, const Quaternion& rotation, const Vector3& scale);
  120. /// Assign from another matrix.
  121. Matrix3x4& operator = (const Matrix3x4& rhs)
  122. {
  123. m00_ = rhs.m00_;
  124. m01_ = rhs.m01_;
  125. m02_ = rhs.m02_;
  126. m03_ = rhs.m03_;
  127. m10_ = rhs.m10_;
  128. m11_ = rhs.m11_;
  129. m12_ = rhs.m12_;
  130. m13_ = rhs.m13_;
  131. m20_ = rhs.m20_;
  132. m21_ = rhs.m21_;
  133. m22_ = rhs.m22_;
  134. m23_ = rhs.m23_;
  135. return *this;
  136. }
  137. /// Assign from a 3x3 matrix and set the extra elements to identity.
  138. Matrix3x4& operator = (const Matrix3& rhs)
  139. {
  140. m00_ = rhs.m00_;
  141. m01_ = rhs.m01_;
  142. m02_ = rhs.m02_;
  143. m03_ = 0.0;
  144. m10_ = rhs.m10_;
  145. m11_ = rhs.m11_;
  146. m12_ = rhs.m12_;
  147. m13_ = 0.0;
  148. m20_ = rhs.m20_;
  149. m21_ = rhs.m21_;
  150. m22_ = rhs.m22_;
  151. m23_ = 0.0;
  152. return *this;
  153. }
  154. /// Assign from a 4x4 matrix which is assumed to contain no projection.
  155. Matrix3x4& operator = (const Matrix4& rhs)
  156. {
  157. m00_ = rhs.m00_;
  158. m01_ = rhs.m01_;
  159. m02_ = rhs.m02_;
  160. m03_ = rhs.m03_;
  161. m10_ = rhs.m10_;
  162. m11_ = rhs.m11_;
  163. m12_ = rhs.m12_;
  164. m13_ = rhs.m13_;
  165. m20_ = rhs.m20_;
  166. m21_ = rhs.m21_;
  167. m22_ = rhs.m22_;
  168. m23_ = rhs.m23_;
  169. return *this;
  170. }
  171. /// Test for equality with another matrix without epsilon.
  172. bool operator == (const Matrix3x4& rhs) const
  173. {
  174. const float* leftData = Data();
  175. const float* rightData = rhs.Data();
  176. for (unsigned i = 0; i < 12; ++i)
  177. {
  178. if (leftData[i] != rightData[i])
  179. return false;
  180. }
  181. return true;
  182. }
  183. /// Test for inequality with another matrix without epsilon.
  184. bool operator != (const Matrix3x4& rhs) const { return !(*this == rhs); }
  185. /// Multiply a Vector3 which is assumed to represent position.
  186. Vector3 operator * (const Vector3& rhs) const
  187. {
  188. return Vector3(
  189. (m00_ * rhs.x_ + m01_ * rhs.y_ + m02_ * rhs.z_ + m03_),
  190. (m10_ * rhs.x_ + m11_ * rhs.y_ + m12_ * rhs.z_ + m13_),
  191. (m20_ * rhs.x_ + m21_ * rhs.y_ + m22_ * rhs.z_ + m23_)
  192. );
  193. }
  194. /// Multiply a Vector4.
  195. Vector3 operator * (const Vector4& rhs) const
  196. {
  197. return Vector3(
  198. (m00_ * rhs.x_ + m01_ * rhs.y_ + m02_ * rhs.z_ + m03_ * rhs.w_),
  199. (m10_ * rhs.x_ + m11_ * rhs.y_ + m12_ * rhs.z_ + m13_ * rhs.w_),
  200. (m20_ * rhs.x_ + m21_ * rhs.y_ + m22_ * rhs.z_ + m23_ * rhs.w_)
  201. );
  202. }
  203. /// Add a matrix.
  204. Matrix3x4 operator + (const Matrix3x4& rhs) const
  205. {
  206. return Matrix3x4(
  207. m00_ + rhs.m00_,
  208. m01_ + rhs.m01_,
  209. m02_ + rhs.m02_,
  210. m03_ + rhs.m03_,
  211. m10_ + rhs.m10_,
  212. m11_ + rhs.m11_,
  213. m12_ + rhs.m12_,
  214. m13_ + rhs.m13_,
  215. m20_ + rhs.m20_,
  216. m21_ + rhs.m21_,
  217. m22_ + rhs.m22_,
  218. m23_ + rhs.m23_
  219. );
  220. }
  221. /// Subtract a matrix.
  222. Matrix3x4 operator - (const Matrix3x4& rhs) const
  223. {
  224. return Matrix3x4(
  225. m00_ - rhs.m00_,
  226. m01_ - rhs.m01_,
  227. m02_ - rhs.m02_,
  228. m03_ - rhs.m03_,
  229. m10_ - rhs.m10_,
  230. m11_ - rhs.m11_,
  231. m12_ - rhs.m12_,
  232. m13_ - rhs.m13_,
  233. m20_ - rhs.m20_,
  234. m21_ - rhs.m21_,
  235. m22_ - rhs.m22_,
  236. m23_ - rhs.m23_
  237. );
  238. }
  239. /// Multiply with a scalar.
  240. Matrix3x4 operator * (float rhs) const
  241. {
  242. return Matrix3x4(
  243. m00_ * rhs,
  244. m01_ * rhs,
  245. m02_ * rhs,
  246. m03_ * rhs,
  247. m10_ * rhs,
  248. m11_ * rhs,
  249. m12_ * rhs,
  250. m13_ * rhs,
  251. m20_ * rhs,
  252. m21_ * rhs,
  253. m22_ * rhs,
  254. m23_ * rhs
  255. );
  256. }
  257. /// Multiply a matrix.
  258. Matrix3x4 operator * (const Matrix3x4& rhs) const
  259. {
  260. return Matrix3x4(
  261. m00_ * rhs.m00_ + m01_ * rhs.m10_ + m02_ * rhs.m20_,
  262. m00_ * rhs.m01_ + m01_ * rhs.m11_ + m02_ * rhs.m21_,
  263. m00_ * rhs.m02_ + m01_ * rhs.m12_ + m02_ * rhs.m22_,
  264. m00_ * rhs.m03_ + m01_ * rhs.m13_ + m02_ * rhs.m23_ + m03_,
  265. m10_ * rhs.m00_ + m11_ * rhs.m10_ + m12_ * rhs.m20_,
  266. m10_ * rhs.m01_ + m11_ * rhs.m11_ + m12_ * rhs.m21_,
  267. m10_ * rhs.m02_ + m11_ * rhs.m12_ + m12_ * rhs.m22_,
  268. m10_ * rhs.m03_ + m11_ * rhs.m13_ + m12_ * rhs.m23_ + m13_,
  269. m20_ * rhs.m00_ + m21_ * rhs.m10_ + m22_ * rhs.m20_,
  270. m20_ * rhs.m01_ + m21_ * rhs.m11_ + m22_ * rhs.m21_,
  271. m20_ * rhs.m02_ + m21_ * rhs.m12_ + m22_ * rhs.m22_,
  272. m20_ * rhs.m03_ + m21_ * rhs.m13_ + m22_ * rhs.m23_ + m23_
  273. );
  274. }
  275. /// Multiply a 4x4 matrix.
  276. Matrix4 operator * (const Matrix4& rhs) const
  277. {
  278. return Matrix4(
  279. m00_ * rhs.m00_ + m01_ * rhs.m10_ + m02_ * rhs.m20_ + m03_ * rhs.m30_,
  280. m00_ * rhs.m01_ + m01_ * rhs.m11_ + m02_ * rhs.m21_ + m03_ * rhs.m31_,
  281. m00_ * rhs.m02_ + m01_ * rhs.m12_ + m02_ * rhs.m22_ + m03_ * rhs.m32_,
  282. m00_ * rhs.m03_ + m01_ * rhs.m13_ + m02_ * rhs.m23_ + m03_ * rhs.m33_,
  283. m10_ * rhs.m00_ + m11_ * rhs.m10_ + m12_ * rhs.m20_ + m13_ * rhs.m30_,
  284. m10_ * rhs.m01_ + m11_ * rhs.m11_ + m12_ * rhs.m21_ + m13_ * rhs.m31_,
  285. m10_ * rhs.m02_ + m11_ * rhs.m12_ + m12_ * rhs.m22_ + m13_ * rhs.m32_,
  286. m10_ * rhs.m03_ + m11_ * rhs.m13_ + m12_ * rhs.m23_ + m13_ * rhs.m33_,
  287. m20_ * rhs.m00_ + m21_ * rhs.m10_ + m22_ * rhs.m20_ + m23_ * rhs.m30_,
  288. m20_ * rhs.m01_ + m21_ * rhs.m11_ + m22_ * rhs.m21_ + m23_ * rhs.m31_,
  289. m20_ * rhs.m02_ + m21_ * rhs.m12_ + m22_ * rhs.m22_ + m23_ * rhs.m32_,
  290. m20_ * rhs.m03_ + m21_ * rhs.m13_ + m22_ * rhs.m23_ + m23_ * rhs.m33_,
  291. rhs.m30_,
  292. rhs.m31_,
  293. rhs.m32_,
  294. rhs.m33_
  295. );
  296. }
  297. /// Set translation elements.
  298. void SetTranslation(const Vector3& translation)
  299. {
  300. m03_ = translation.x_;
  301. m13_ = translation.y_;
  302. m23_ = translation.z_;
  303. }
  304. /// Set rotation elements from a 3x3 matrix.
  305. void SetRotation(const Matrix3& rotation)
  306. {
  307. m00_ = rotation.m00_;
  308. m01_ = rotation.m01_;
  309. m02_ = rotation.m02_;
  310. m10_ = rotation.m10_;
  311. m11_ = rotation.m11_;
  312. m12_ = rotation.m12_;
  313. m20_ = rotation.m20_;
  314. m21_ = rotation.m21_;
  315. m22_ = rotation.m22_;
  316. }
  317. /// Set scaling elements.
  318. void SetScale(const Vector3& scale)
  319. {
  320. m00_ = scale.x_;
  321. m11_ = scale.y_;
  322. m22_ = scale.z_;
  323. }
  324. /// Set uniform scaling elements.
  325. void SetScale(float scale)
  326. {
  327. m00_ = scale;
  328. m11_ = scale;
  329. m22_ = scale;
  330. }
  331. /// Return the combined rotation and scaling matrix.
  332. Matrix3 ToMatrix3() const
  333. {
  334. return Matrix3(
  335. m00_,
  336. m01_,
  337. m02_,
  338. m10_,
  339. m11_,
  340. m12_,
  341. m20_,
  342. m21_,
  343. m22_
  344. );
  345. }
  346. /// Return the rotation matrix with scaling removed.
  347. Matrix3 RotationMatrix() const
  348. {
  349. Vector3 invScale(
  350. 1.0f / sqrtf(m00_ * m00_ + m10_ * m10_ + m20_ * m20_),
  351. 1.0f / sqrtf(m01_ * m01_ + m11_ * m11_ + m21_ * m21_),
  352. 1.0f / sqrtf(m02_ * m02_ + m12_ * m12_ + m22_ * m22_)
  353. );
  354. return ToMatrix3().Scaled(invScale);
  355. }
  356. /// Return the translation part.
  357. Vector3 Translation() const
  358. {
  359. return Vector3(
  360. m03_,
  361. m13_,
  362. m23_
  363. );
  364. }
  365. /// Return the rotation part.
  366. Quaternion Rotation() const { return Quaternion(RotationMatrix()); }
  367. /// Return the scaling part.
  368. Vector3 Scale() const
  369. {
  370. return Vector3(
  371. sqrtf(m00_ * m00_ + m10_ * m10_ + m20_ * m20_),
  372. sqrtf(m01_ * m01_ + m11_ * m11_ + m21_ * m21_),
  373. sqrtf(m02_ * m02_ + m12_ * m12_ + m22_ * m22_)
  374. );
  375. }
  376. /// Test for equality with another matrix with epsilon.
  377. bool Equals(const Matrix3x4& rhs) const
  378. {
  379. const float* leftData = Data();
  380. const float* rightData = rhs.Data();
  381. for (unsigned i = 0; i < 12; ++i)
  382. {
  383. if (!Urho3D::Equals(leftData[i], rightData[i]))
  384. return false;
  385. }
  386. return true;
  387. }
  388. /// Return decomposition to translation, rotation and scale.
  389. void Decompose(Vector3& translation, Quaternion& rotation, Vector3& scale) const;
  390. /// Return inverse.
  391. Matrix3x4 Inverse() const;
  392. /// Return float data.
  393. const float* Data() const { return &m00_; }
  394. float m00_;
  395. float m01_;
  396. float m02_;
  397. float m03_;
  398. float m10_;
  399. float m11_;
  400. float m12_;
  401. float m13_;
  402. float m20_;
  403. float m21_;
  404. float m22_;
  405. float m23_;
  406. /// Zero matrix.
  407. static const Matrix3x4 ZERO;
  408. /// Identity matrix.
  409. static const Matrix3x4 IDENTITY;
  410. };
  411. /// Multiply a 3x4 matrix with a scalar.
  412. inline Matrix3x4 operator * (float lhs, const Matrix3x4& rhs) { return rhs * lhs; }
  413. /// Multiply a 3x4 matrix with a 4x4 matrix.
  414. inline Matrix4 operator * (const Matrix4& lhs, const Matrix3x4& rhs)
  415. {
  416. return Matrix4(
  417. lhs.m00_ * rhs.m00_ + lhs.m01_ * rhs.m10_ + lhs.m02_ * rhs.m20_,
  418. lhs.m00_ * rhs.m01_ + lhs.m01_ * rhs.m11_ + lhs.m02_ * rhs.m21_,
  419. lhs.m00_ * rhs.m02_ + lhs.m01_ * rhs.m12_ + lhs.m02_ * rhs.m22_,
  420. lhs.m00_ * rhs.m03_ + lhs.m01_ * rhs.m13_ + lhs.m02_ * rhs.m23_ + lhs.m03_,
  421. lhs.m10_ * rhs.m00_ + lhs.m11_ * rhs.m10_ + lhs.m12_ * rhs.m20_,
  422. lhs.m10_ * rhs.m01_ + lhs.m11_ * rhs.m11_ + lhs.m12_ * rhs.m21_,
  423. lhs.m10_ * rhs.m02_ + lhs.m11_ * rhs.m12_ + lhs.m12_ * rhs.m22_,
  424. lhs.m10_ * rhs.m03_ + lhs.m11_ * rhs.m13_ + lhs.m12_ * rhs.m23_ + lhs.m13_,
  425. lhs.m20_ * rhs.m00_ + lhs.m21_ * rhs.m10_ + lhs.m22_ * rhs.m20_,
  426. lhs.m20_ * rhs.m01_ + lhs.m21_ * rhs.m11_ + lhs.m22_ * rhs.m21_,
  427. lhs.m20_ * rhs.m02_ + lhs.m21_ * rhs.m12_ + lhs.m22_ * rhs.m22_,
  428. lhs.m20_ * rhs.m03_ + lhs.m21_ * rhs.m13_ + lhs.m22_ * rhs.m23_ + lhs.m23_,
  429. lhs.m30_ * rhs.m00_ + lhs.m31_ * rhs.m10_ + lhs.m32_ * rhs.m20_,
  430. lhs.m30_ * rhs.m01_ + lhs.m31_ * rhs.m11_ + lhs.m32_ * rhs.m21_,
  431. lhs.m30_ * rhs.m02_ + lhs.m31_ * rhs.m12_ + lhs.m32_ * rhs.m22_,
  432. lhs.m30_ * rhs.m03_ + lhs.m31_ * rhs.m13_ + lhs.m32_ * rhs.m23_ + lhs.m33_
  433. );
  434. }
  435. }