Matrix3x4.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. //
  2. // Copyright (c) 2008-2014 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 an identity matrix.
  31. Matrix3x4() :
  32. m00_(1.0f),
  33. m01_(0.0f),
  34. m02_(0.0f),
  35. m03_(0.0f),
  36. m10_(0.0f),
  37. m11_(1.0f),
  38. m12_(0.0f),
  39. m13_(0.0f),
  40. m20_(0.0f),
  41. m21_(0.0f),
  42. m22_(1.0f),
  43. m23_(0.0f)
  44. {
  45. }
  46. /// Copy-construct from another matrix.
  47. Matrix3x4(const Matrix3x4& matrix) :
  48. m00_(matrix.m00_),
  49. m01_(matrix.m01_),
  50. m02_(matrix.m02_),
  51. m03_(matrix.m03_),
  52. m10_(matrix.m10_),
  53. m11_(matrix.m11_),
  54. m12_(matrix.m12_),
  55. m13_(matrix.m13_),
  56. m20_(matrix.m20_),
  57. m21_(matrix.m21_),
  58. m22_(matrix.m22_),
  59. m23_(matrix.m23_)
  60. {
  61. }
  62. /// Copy-construct from a 3x3 matrix and set the extra elements to identity.
  63. Matrix3x4(const Matrix3& matrix) :
  64. m00_(matrix.m00_),
  65. m01_(matrix.m01_),
  66. m02_(matrix.m02_),
  67. m03_(0.0f),
  68. m10_(matrix.m10_),
  69. m11_(matrix.m11_),
  70. m12_(matrix.m12_),
  71. m13_(0.0f),
  72. m20_(matrix.m20_),
  73. m21_(matrix.m21_),
  74. m22_(matrix.m22_),
  75. m23_(0.0f)
  76. {
  77. }
  78. /// Copy-construct from a 4x4 matrix which is assumed to contain no projection.
  79. Matrix3x4(const Matrix4& matrix) :
  80. m00_(matrix.m00_),
  81. m01_(matrix.m01_),
  82. m02_(matrix.m02_),
  83. m03_(matrix.m03_),
  84. m10_(matrix.m10_),
  85. m11_(matrix.m11_),
  86. m12_(matrix.m12_),
  87. m13_(matrix.m13_),
  88. m20_(matrix.m20_),
  89. m21_(matrix.m21_),
  90. m22_(matrix.m22_),
  91. m23_(matrix.m23_)
  92. {
  93. }
  94. // Construct from values.
  95. Matrix3x4(float v00, float v01, float v02, float v03,
  96. float v10, float v11, float v12, float v13,
  97. float v20, float v21, float v22, float v23) :
  98. m00_(v00),
  99. m01_(v01),
  100. m02_(v02),
  101. m03_(v03),
  102. m10_(v10),
  103. m11_(v11),
  104. m12_(v12),
  105. m13_(v13),
  106. m20_(v20),
  107. m21_(v21),
  108. m22_(v22),
  109. m23_(v23)
  110. {
  111. }
  112. /// Construct from a float array.
  113. Matrix3x4(const float* data) :
  114. m00_(data[0]),
  115. m01_(data[1]),
  116. m02_(data[2]),
  117. m03_(data[3]),
  118. m10_(data[4]),
  119. m11_(data[5]),
  120. m12_(data[6]),
  121. m13_(data[7]),
  122. m20_(data[8]),
  123. m21_(data[9]),
  124. m22_(data[10]),
  125. m23_(data[11])
  126. {
  127. }
  128. /// Construct from translation, rotation and uniform scale.
  129. Matrix3x4(const Vector3& translation, const Quaternion& rotation, float scale);
  130. /// Construct from translation, rotation and nonuniform scale.
  131. Matrix3x4(const Vector3& translation, const Quaternion& rotation, const Vector3& scale);
  132. /// Assign from another matrix.
  133. Matrix3x4& operator = (const Matrix3x4& rhs)
  134. {
  135. m00_ = rhs.m00_;
  136. m01_ = rhs.m01_;
  137. m02_ = rhs.m02_;
  138. m03_ = rhs.m03_;
  139. m10_ = rhs.m10_;
  140. m11_ = rhs.m11_;
  141. m12_ = rhs.m12_;
  142. m13_ = rhs.m13_;
  143. m20_ = rhs.m20_;
  144. m21_ = rhs.m21_;
  145. m22_ = rhs.m22_;
  146. m23_ = rhs.m23_;
  147. return *this;
  148. }
  149. /// Assign from a 3x3 matrix and set the extra elements to identity.
  150. Matrix3x4& operator = (const Matrix3& rhs)
  151. {
  152. m00_ = rhs.m00_;
  153. m01_ = rhs.m01_;
  154. m02_ = rhs.m02_;
  155. m03_ = 0.0;
  156. m10_ = rhs.m10_;
  157. m11_ = rhs.m11_;
  158. m12_ = rhs.m12_;
  159. m13_ = 0.0;
  160. m20_ = rhs.m20_;
  161. m21_ = rhs.m21_;
  162. m22_ = rhs.m22_;
  163. m23_ = 0.0;
  164. return *this;
  165. }
  166. /// Assign from a 4x4 matrix which is assumed to contain no projection.
  167. Matrix3x4& operator = (const Matrix4& rhs)
  168. {
  169. m00_ = rhs.m00_;
  170. m01_ = rhs.m01_;
  171. m02_ = rhs.m02_;
  172. m03_ = rhs.m03_;
  173. m10_ = rhs.m10_;
  174. m11_ = rhs.m11_;
  175. m12_ = rhs.m12_;
  176. m13_ = rhs.m13_;
  177. m20_ = rhs.m20_;
  178. m21_ = rhs.m21_;
  179. m22_ = rhs.m22_;
  180. m23_ = rhs.m23_;
  181. return *this;
  182. }
  183. /// Test for equality with another matrix without epsilon.
  184. bool operator == (const Matrix3x4& rhs) const
  185. {
  186. const float* leftData = Data();
  187. const float* rightData = rhs.Data();
  188. for (unsigned i = 0; i < 12; ++i)
  189. {
  190. if (leftData[i] != rightData[i])
  191. return false;
  192. }
  193. return true;
  194. }
  195. /// Test for inequality with another matrix without epsilon.
  196. bool operator != (const Matrix3x4& rhs) const { return !(*this == rhs); }
  197. /// Multiply a Vector3 which is assumed to represent position.
  198. Vector3 operator * (const Vector3& rhs) const
  199. {
  200. return Vector3(
  201. (m00_ * rhs.x_ + m01_ * rhs.y_ + m02_ * rhs.z_ + m03_),
  202. (m10_ * rhs.x_ + m11_ * rhs.y_ + m12_ * rhs.z_ + m13_),
  203. (m20_ * rhs.x_ + m21_ * rhs.y_ + m22_ * rhs.z_ + m23_)
  204. );
  205. }
  206. /// Multiply a Vector4.
  207. Vector3 operator * (const Vector4& rhs) const
  208. {
  209. return Vector3(
  210. (m00_ * rhs.x_ + m01_ * rhs.y_ + m02_ * rhs.z_ + m03_ * rhs.w_),
  211. (m10_ * rhs.x_ + m11_ * rhs.y_ + m12_ * rhs.z_ + m13_ * rhs.w_),
  212. (m20_ * rhs.x_ + m21_ * rhs.y_ + m22_ * rhs.z_ + m23_ * rhs.w_)
  213. );
  214. }
  215. /// Add a matrix.
  216. Matrix3x4 operator + (const Matrix3x4& rhs) const
  217. {
  218. return Matrix3x4(
  219. m00_ + rhs.m00_,
  220. m01_ + rhs.m01_,
  221. m02_ + rhs.m02_,
  222. m03_ + rhs.m03_,
  223. m10_ + rhs.m10_,
  224. m11_ + rhs.m11_,
  225. m12_ + rhs.m12_,
  226. m13_ + rhs.m13_,
  227. m20_ + rhs.m20_,
  228. m21_ + rhs.m21_,
  229. m22_ + rhs.m22_,
  230. m23_ + rhs.m23_
  231. );
  232. }
  233. /// Subtract a matrix.
  234. Matrix3x4 operator - (const Matrix3x4& rhs) const
  235. {
  236. return Matrix3x4(
  237. m00_ - rhs.m00_,
  238. m01_ - rhs.m01_,
  239. m02_ - rhs.m02_,
  240. m03_ - rhs.m03_,
  241. m10_ - rhs.m10_,
  242. m11_ - rhs.m11_,
  243. m12_ - rhs.m12_,
  244. m13_ - rhs.m13_,
  245. m20_ - rhs.m20_,
  246. m21_ - rhs.m21_,
  247. m22_ - rhs.m22_,
  248. m23_ - rhs.m23_
  249. );
  250. }
  251. /// Multiply with a scalar.
  252. Matrix3x4 operator * (float rhs) const
  253. {
  254. return Matrix3x4(
  255. m00_ * rhs,
  256. m01_ * rhs,
  257. m02_ * rhs,
  258. m03_ * rhs,
  259. m10_ * rhs,
  260. m11_ * rhs,
  261. m12_ * rhs,
  262. m13_ * rhs,
  263. m20_ * rhs,
  264. m21_ * rhs,
  265. m22_ * rhs,
  266. m23_ * rhs
  267. );
  268. }
  269. /// Multiply a matrix.
  270. Matrix3x4 operator * (const Matrix3x4& rhs) const
  271. {
  272. return Matrix3x4(
  273. m00_ * rhs.m00_ + m01_ * rhs.m10_ + m02_ * rhs.m20_,
  274. m00_ * rhs.m01_ + m01_ * rhs.m11_ + m02_ * rhs.m21_,
  275. m00_ * rhs.m02_ + m01_ * rhs.m12_ + m02_ * rhs.m22_,
  276. m00_ * rhs.m03_ + m01_ * rhs.m13_ + m02_ * rhs.m23_ + m03_,
  277. m10_ * rhs.m00_ + m11_ * rhs.m10_ + m12_ * rhs.m20_,
  278. m10_ * rhs.m01_ + m11_ * rhs.m11_ + m12_ * rhs.m21_,
  279. m10_ * rhs.m02_ + m11_ * rhs.m12_ + m12_ * rhs.m22_,
  280. m10_ * rhs.m03_ + m11_ * rhs.m13_ + m12_ * rhs.m23_ + m13_,
  281. m20_ * rhs.m00_ + m21_ * rhs.m10_ + m22_ * rhs.m20_,
  282. m20_ * rhs.m01_ + m21_ * rhs.m11_ + m22_ * rhs.m21_,
  283. m20_ * rhs.m02_ + m21_ * rhs.m12_ + m22_ * rhs.m22_,
  284. m20_ * rhs.m03_ + m21_ * rhs.m13_ + m22_ * rhs.m23_ + m23_
  285. );
  286. }
  287. /// Multiply a 4x4 matrix.
  288. Matrix4 operator * (const Matrix4& rhs) const
  289. {
  290. return Matrix4(
  291. m00_ * rhs.m00_ + m01_ * rhs.m10_ + m02_ * rhs.m20_ + m03_ * rhs.m30_,
  292. m00_ * rhs.m01_ + m01_ * rhs.m11_ + m02_ * rhs.m21_ + m03_ * rhs.m31_,
  293. m00_ * rhs.m02_ + m01_ * rhs.m12_ + m02_ * rhs.m22_ + m03_ * rhs.m32_,
  294. m00_ * rhs.m03_ + m01_ * rhs.m13_ + m02_ * rhs.m23_ + m03_ * rhs.m33_,
  295. m10_ * rhs.m00_ + m11_ * rhs.m10_ + m12_ * rhs.m20_ + m13_ * rhs.m30_,
  296. m10_ * rhs.m01_ + m11_ * rhs.m11_ + m12_ * rhs.m21_ + m13_ * rhs.m31_,
  297. m10_ * rhs.m02_ + m11_ * rhs.m12_ + m12_ * rhs.m22_ + m13_ * rhs.m32_,
  298. m10_ * rhs.m03_ + m11_ * rhs.m13_ + m12_ * rhs.m23_ + m13_ * rhs.m33_,
  299. m20_ * rhs.m00_ + m21_ * rhs.m10_ + m22_ * rhs.m20_ + m23_ * rhs.m30_,
  300. m20_ * rhs.m01_ + m21_ * rhs.m11_ + m22_ * rhs.m21_ + m23_ * rhs.m31_,
  301. m20_ * rhs.m02_ + m21_ * rhs.m12_ + m22_ * rhs.m22_ + m23_ * rhs.m32_,
  302. m20_ * rhs.m03_ + m21_ * rhs.m13_ + m22_ * rhs.m23_ + m23_ * rhs.m33_,
  303. rhs.m30_,
  304. rhs.m31_,
  305. rhs.m32_,
  306. rhs.m33_
  307. );
  308. }
  309. /// Set translation elements.
  310. void SetTranslation(const Vector3& translation)
  311. {
  312. m03_ = translation.x_;
  313. m13_ = translation.y_;
  314. m23_ = translation.z_;
  315. }
  316. /// Set rotation elements from a 3x3 matrix.
  317. void SetRotation(const Matrix3& rotation)
  318. {
  319. m00_ = rotation.m00_;
  320. m01_ = rotation.m01_;
  321. m02_ = rotation.m02_;
  322. m10_ = rotation.m10_;
  323. m11_ = rotation.m11_;
  324. m12_ = rotation.m12_;
  325. m20_ = rotation.m20_;
  326. m21_ = rotation.m21_;
  327. m22_ = rotation.m22_;
  328. }
  329. /// Set scaling elements.
  330. void SetScale(const Vector3& scale)
  331. {
  332. m00_ = scale.x_;
  333. m11_ = scale.y_;
  334. m22_ = scale.z_;
  335. }
  336. /// Set uniform scaling elements.
  337. void SetScale(float scale)
  338. {
  339. m00_ = scale;
  340. m11_ = scale;
  341. m22_ = scale;
  342. }
  343. /// Return the combined rotation and scaling matrix.
  344. Matrix3 ToMatrix3() const
  345. {
  346. return Matrix3(
  347. m00_,
  348. m01_,
  349. m02_,
  350. m10_,
  351. m11_,
  352. m12_,
  353. m20_,
  354. m21_,
  355. m22_
  356. );
  357. }
  358. /// Convert to a 4x4 matrix by filling in an identity last row.
  359. Matrix4 ToMatrix4() const
  360. {
  361. return Matrix4(
  362. m00_,
  363. m01_,
  364. m02_,
  365. m03_,
  366. m10_,
  367. m11_,
  368. m12_,
  369. m13_,
  370. m20_,
  371. m21_,
  372. m22_,
  373. m23_,
  374. 0.0f,
  375. 0.0f,
  376. 0.0f,
  377. 1.0f
  378. );
  379. }
  380. /// Return the rotation matrix with scaling removed.
  381. Matrix3 RotationMatrix() const
  382. {
  383. Vector3 invScale(
  384. 1.0f / sqrtf(m00_ * m00_ + m10_ * m10_ + m20_ * m20_),
  385. 1.0f / sqrtf(m01_ * m01_ + m11_ * m11_ + m21_ * m21_),
  386. 1.0f / sqrtf(m02_ * m02_ + m12_ * m12_ + m22_ * m22_)
  387. );
  388. return ToMatrix3().Scaled(invScale);
  389. }
  390. /// Return the translation part.
  391. Vector3 Translation() const
  392. {
  393. return Vector3(
  394. m03_,
  395. m13_,
  396. m23_
  397. );
  398. }
  399. /// Return the rotation part.
  400. Quaternion Rotation() const { return Quaternion(RotationMatrix()); }
  401. /// Return the scaling part.
  402. Vector3 Scale() const
  403. {
  404. return Vector3(
  405. sqrtf(m00_ * m00_ + m10_ * m10_ + m20_ * m20_),
  406. sqrtf(m01_ * m01_ + m11_ * m11_ + m21_ * m21_),
  407. sqrtf(m02_ * m02_ + m12_ * m12_ + m22_ * m22_)
  408. );
  409. }
  410. /// Test for equality with another matrix with epsilon.
  411. bool Equals(const Matrix3x4& rhs) const
  412. {
  413. const float* leftData = Data();
  414. const float* rightData = rhs.Data();
  415. for (unsigned i = 0; i < 12; ++i)
  416. {
  417. if (!Urho3D::Equals(leftData[i], rightData[i]))
  418. return false;
  419. }
  420. return true;
  421. }
  422. /// Return decomposition to translation, rotation and scale.
  423. void Decompose(Vector3& translation, Quaternion& rotation, Vector3& scale) const;
  424. /// Return inverse.
  425. Matrix3x4 Inverse() const;
  426. /// Return float data.
  427. const float* Data() const { return &m00_; }
  428. /// Return as string.
  429. String ToString() const;
  430. float m00_;
  431. float m01_;
  432. float m02_;
  433. float m03_;
  434. float m10_;
  435. float m11_;
  436. float m12_;
  437. float m13_;
  438. float m20_;
  439. float m21_;
  440. float m22_;
  441. float m23_;
  442. /// Zero matrix.
  443. static const Matrix3x4 ZERO;
  444. /// Identity matrix.
  445. static const Matrix3x4 IDENTITY;
  446. };
  447. /// Multiply a 3x4 matrix with a scalar.
  448. inline Matrix3x4 operator * (float lhs, const Matrix3x4& rhs) { return rhs * lhs; }
  449. }