Matrix3x4.h 13 KB

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