matrix.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907
  1. #include "pch.h"
  2. //////////////////////////////////////////////////////////////////////////////
  3. //
  4. // The Identity Matrix
  5. //
  6. //////////////////////////////////////////////////////////////////////////////
  7. Matrix g_matIdentity;
  8. class InitializeTransform {
  9. public:
  10. InitializeTransform()
  11. {
  12. g_matIdentity.SetIdentity();
  13. }
  14. } initialize;
  15. const Matrix& Matrix::GetIdentity()
  16. {
  17. return g_matIdentity;
  18. }
  19. //////////////////////////////////////////////////////////////////////////////
  20. //
  21. // Constructor
  22. //
  23. //////////////////////////////////////////////////////////////////////////////
  24. Matrix::Matrix(const Matrix2& mat2) :
  25. m_type(TransformUnknown)
  26. {
  27. m_m[0][0] = mat2[0][0]; m_m[0][1] = mat2[0][1]; m_m[0][2] = 0; m_m[0][3] = mat2[0][2];
  28. m_m[1][0] = mat2[1][0]; m_m[1][1] = mat2[1][1]; m_m[1][2] = 0; m_m[1][3] = mat2[1][2];
  29. m_m[2][0] = 0; m_m[2][1] = 0; m_m[2][2] = 1; m_m[2][3] = 0;
  30. m_m[3][0] = mat2[2][0]; m_m[3][1] = mat2[2][1]; m_m[3][2] = 0; m_m[3][3] = mat2[2][2];
  31. }
  32. Matrix::Matrix(
  33. float v00, float v01, float v02, float v03,
  34. float v10, float v11, float v12, float v13,
  35. float v20, float v21, float v22, float v23,
  36. float v30, float v31, float v32, float v33
  37. ) :
  38. m_type(TransformUnknown)
  39. {
  40. m_m[0][0] = v00; m_m[0][1] = v01; m_m[0][2] = v02; m_m[0][3] = v03;
  41. m_m[1][0] = v10; m_m[1][1] = v11; m_m[1][2] = v12; m_m[1][3] = v13;
  42. m_m[2][0] = v20; m_m[2][1] = v21; m_m[2][2] = v22; m_m[2][3] = v23;
  43. m_m[3][0] = v30; m_m[3][1] = v31; m_m[3][2] = v32; m_m[3][3] = v33;
  44. }
  45. Matrix::Matrix(
  46. const Orientation& o,
  47. const Vector& p,
  48. float s
  49. ) :
  50. m_type(TransformUnknown)
  51. {
  52. //
  53. // note that orientations are transposed
  54. //
  55. m_m[0][0] = o.m_r[0][0] * s; m_m[0][1] = o.m_r[1][0] * s; m_m[0][2] = o.m_r[2][0] * s; m_m[0][3] = p.x;
  56. m_m[1][0] = o.m_r[0][1] * s; m_m[1][1] = o.m_r[1][1] * s; m_m[1][2] = o.m_r[2][1] * s; m_m[1][3] = p.y;
  57. m_m[2][0] = o.m_r[0][2] * s; m_m[2][1] = o.m_r[1][2] * s; m_m[2][2] = o.m_r[2][2] * s; m_m[2][3] = p.z;
  58. m_m[3][0] = 0.0; m_m[3][1] = 0.0; m_m[3][2] = 0.0; m_m[3][3] = 1.0f;
  59. }
  60. //////////////////////////////////////////////////////////////////////////////
  61. //
  62. // Matrix Accessors
  63. //
  64. //////////////////////////////////////////////////////////////////////////////
  65. float Matrix::GetScale() const
  66. {
  67. return Vector(m_m[0][0], m_m[1][0], m_m[2][0]).Length();
  68. }
  69. Vector Matrix::GetTranslate() const
  70. {
  71. return Vector(m_m[0][3], m_m[1][3], m_m[2][3]);
  72. }
  73. //////////////////////////////////////////////////////////////////////////////
  74. //
  75. // Determinants
  76. //
  77. //////////////////////////////////////////////////////////////////////////////
  78. float Determinant( // 40 mul 23 add
  79. float m00, float m01, float m02, float m03,
  80. float m10, float m11, float m12, float m13,
  81. float m20, float m21, float m22, float m23,
  82. float m30, float m31, float m32, float m33
  83. ) {
  84. return
  85. m00 * Determinant3(
  86. m11, m12, m13,
  87. m21, m22, m23,
  88. m31, m32, m33
  89. )
  90. + m10 * Determinant3(
  91. m21, m22, m23,
  92. m31, m32, m33,
  93. m01, m02, m03
  94. )
  95. + m20 * Determinant3(
  96. m31, m32, m33,
  97. m01, m02, m03,
  98. m11, m12, m13
  99. )
  100. + m30 * Determinant3(
  101. m01, m02, m03,
  102. m11, m12, m13,
  103. m21, m22, m23
  104. );
  105. }
  106. //
  107. // alternate Determinate implementation
  108. //
  109. float Determinant(const float m[4][4], int startRow, int startCol, int size);
  110. float Determinant(const float m[4][4], int size)
  111. {
  112. if (size == 2) {
  113. return m[0][0] * m[1][1] - m[0][1] * m[1][0];
  114. } else {
  115. float sum = 0;
  116. for(int index = 0; index < size; index++) {
  117. int nextIndex = index == size ? 0 : index + 1;
  118. sum += m[index][0] * Determinant(m, nextIndex, 1, size);
  119. }
  120. return sum;
  121. }
  122. }
  123. float Determinant(const float m[4][4], int startRow, int startCol, int size)
  124. {
  125. float mm[4][4];
  126. for (int row = 0; row < size - 1; row++) {
  127. for (int col = 0; col < size - 1; col++) {
  128. int fromRow = startRow + row; if (fromRow >= size) fromRow -= size;
  129. int fromCol = startCol + col; if (fromCol >= size) fromCol -= size;
  130. mm[row][col] = m[fromRow][fromCol];
  131. }
  132. }
  133. return Determinant(mm, size - 1);
  134. }
  135. //////////////////////////////////////////////////////////////////////////////
  136. //
  137. // Matrix
  138. //
  139. //////////////////////////////////////////////////////////////////////////////
  140. TransformType Matrix::GetType() const
  141. {
  142. if (m_type == TransformUnknown) {
  143. ((Matrix*)this)->CalcType();
  144. }
  145. return m_type;
  146. }
  147. void Matrix::InvalidateType()
  148. {
  149. m_type = TransformUnknown;
  150. }
  151. void Matrix::CalcType()
  152. {
  153. m_type = TransformIdentity;
  154. if (m_m[3][0] != 0 || m_m[3][1] != 0 || m_m[3][2] != 0 || m_m[3][3] != 1) {
  155. m_type |= TransformPerspective;
  156. }
  157. if (
  158. m_m[0][1] != 0 || m_m[0][2] != 0 ||
  159. m_m[1][0] != 0 || m_m[1][2] != 0 ||
  160. m_m[2][0] != 0 || m_m[2][1] != 0
  161. ) {
  162. m_type |= TransformRotate;
  163. }
  164. if (m_m[0][0] != 1 || m_m[1][1] != 1 || m_m[2][2] != 1) {
  165. m_type |= TransformScale;
  166. }
  167. if (m_m[0][3] != 0 || m_m[1][3] != 0 || m_m[2][3] != 0) {
  168. m_type |= TransformTranslate;
  169. }
  170. }
  171. Matrix& Matrix::SetIdentity()
  172. {
  173. m_m[0][0] = 1; m_m[0][1] = 0; m_m[0][2] = 0; m_m[0][3] = 0;
  174. m_m[1][0] = 0; m_m[1][1] = 1; m_m[1][2] = 0; m_m[1][3] = 0;
  175. m_m[2][0] = 0; m_m[2][1] = 0; m_m[2][2] = 1; m_m[2][3] = 0;
  176. m_m[3][0] = 0; m_m[3][1] = 0; m_m[3][2] = 0; m_m[3][3] = 1;
  177. m_type = TransformIdentity;
  178. return *this;
  179. }
  180. void Matrix::Set(int row, int col, float value)
  181. {
  182. ZAssert(row >= 0 && row <= 3 && col >= 0 && col <= 3);
  183. m_m[row][col] = value;
  184. m_type = TransformUnknown;
  185. }
  186. //////////////////////////////////////////////////////////////////////////////
  187. //
  188. // Scales
  189. //
  190. //////////////////////////////////////////////////////////////////////////////
  191. Matrix& Matrix::SetScale(float scale)
  192. {
  193. SetIdentity();
  194. m_m[0][0] = scale;
  195. m_m[1][1] = scale;
  196. m_m[2][2] = scale;
  197. m_type = TransformScale;
  198. return *this;
  199. }
  200. Matrix& Matrix::Scale(float scale)
  201. {
  202. m_m[0][0] *= scale; m_m[0][1] *= scale; m_m[0][2] *= scale; m_m[0][3] *= scale;
  203. m_m[1][0] *= scale; m_m[1][1] *= scale; m_m[1][2] *= scale; m_m[1][3] *= scale;
  204. m_m[2][0] *= scale; m_m[2][1] *= scale; m_m[2][2] *= scale; m_m[2][3] *= scale;
  205. m_type |= TransformScale;
  206. return *this;
  207. }
  208. Matrix& Matrix::PreScale(float scale)
  209. {
  210. m_m[0][0] *= scale; m_m[0][1] *= scale; m_m[0][2] *= scale;
  211. m_m[1][0] *= scale; m_m[1][1] *= scale; m_m[1][2] *= scale;
  212. m_m[2][0] *= scale; m_m[2][1] *= scale; m_m[2][2] *= scale;
  213. m_m[3][0] *= scale; m_m[3][1] *= scale; m_m[3][2] *= scale;
  214. m_type |= TransformScale;
  215. return *this;
  216. }
  217. Matrix& Matrix::SetScale(const Vector& vec)
  218. {
  219. SetIdentity();
  220. m_m[0][0] = vec.X();
  221. m_m[1][1] = vec.Y();
  222. m_m[2][2] = vec.Z();
  223. m_type = TransformScale;
  224. return *this;
  225. }
  226. Matrix& Matrix::Scale(const Vector& vec)
  227. {
  228. m_m[0][0] *= vec.X(); m_m[0][1] *= vec.X(); m_m[0][2] *= vec.X(); m_m[0][3] *= vec.X();
  229. m_m[1][0] *= vec.Y(); m_m[1][1] *= vec.Y(); m_m[1][2] *= vec.Y(); m_m[1][3] *= vec.Y();
  230. m_m[2][0] *= vec.Z(); m_m[2][1] *= vec.Z(); m_m[2][2] *= vec.Z(); m_m[2][3] *= vec.Z();
  231. m_type |= TransformScale;
  232. return *this;
  233. }
  234. Matrix& Matrix::PreScale(const Vector& vec)
  235. {
  236. m_m[0][0] *= vec.X(); m_m[0][1] *= vec.Y(); m_m[0][2] *= vec.Z();
  237. m_m[1][0] *= vec.X(); m_m[1][1] *= vec.Y(); m_m[1][2] *= vec.Z();
  238. m_m[2][0] *= vec.X(); m_m[2][1] *= vec.Y(); m_m[2][2] *= vec.Z();
  239. m_m[3][0] *= vec.X(); m_m[3][1] *= vec.Y(); m_m[3][2] *= vec.Z();
  240. m_type |= TransformScale;
  241. return *this;
  242. }
  243. //////////////////////////////////////////////////////////////////////////////
  244. //
  245. // Translations
  246. //
  247. //////////////////////////////////////////////////////////////////////////////
  248. Matrix& Matrix::SetTranslate(const Vector& vec)
  249. {
  250. SetIdentity();
  251. m_m[0][3] = vec.X();
  252. m_m[1][3] = vec.Y();
  253. m_m[2][3] = vec.Z();
  254. m_type = TransformTranslate;
  255. return *this;
  256. }
  257. Matrix& Matrix::Translate(const Vector& vec)
  258. {
  259. float x = vec.X();
  260. float y = vec.Y();
  261. float z = vec.Z();
  262. m_m[0][0] = m_m[0][0] + x * m_m[3][0];
  263. m_m[0][1] = m_m[0][1] + x * m_m[3][1];
  264. m_m[0][2] = m_m[0][2] + x * m_m[3][2];
  265. m_m[0][3] = m_m[0][3] + x * m_m[3][3];
  266. m_m[1][0] = m_m[1][0] + y * m_m[3][0];
  267. m_m[1][1] = m_m[1][1] + y * m_m[3][1];
  268. m_m[1][2] = m_m[1][2] + y * m_m[3][2];
  269. m_m[1][3] = m_m[1][3] + y * m_m[3][3];
  270. m_m[2][0] = m_m[2][0] + z * m_m[3][0];
  271. m_m[2][1] = m_m[2][1] + z * m_m[3][1];
  272. m_m[2][2] = m_m[2][2] + z * m_m[3][2];
  273. m_m[2][3] = m_m[2][3] + z * m_m[3][3];
  274. m_type |= TransformTranslate;
  275. return *this;
  276. }
  277. Matrix& Matrix::PreTranslate(const Vector& vec)
  278. {
  279. m_m[0][3] += m_m[0][0] * vec.X() + m_m[0][1] * vec.Y() + m_m[0][2] * vec.Z();
  280. m_m[1][3] += m_m[1][0] * vec.X() + m_m[1][1] * vec.Y() + m_m[1][2] * vec.Z();
  281. m_m[2][3] += m_m[2][0] * vec.X() + m_m[2][1] * vec.Y() + m_m[2][2] * vec.Z();
  282. m_m[3][3] += m_m[3][0] * vec.X() + m_m[3][1] * vec.Y() + m_m[3][2] * vec.Z();
  283. m_type |= TransformTranslate;
  284. return *this;
  285. }
  286. //////////////////////////////////////////////////////////////////////////////
  287. //
  288. // Rotations
  289. //
  290. //////////////////////////////////////////////////////////////////////////////
  291. Matrix& Matrix::SetRotateX(float angle)
  292. {
  293. SetIdentity();
  294. float c = cos(angle);
  295. float s = sin(angle);
  296. m_m[1][1] = c; m_m[1][2] = -s;
  297. m_m[2][1] = s; m_m[2][2] = c;
  298. m_type = TransformRotate;
  299. return *this;
  300. }
  301. Matrix& Matrix::SetRotateY(float angle)
  302. {
  303. SetIdentity();
  304. float c = cos(angle);
  305. float s = sin(angle);
  306. m_m[2][2] = c; m_m[2][0] = -s;
  307. m_m[0][2] = s; m_m[0][0] = c;
  308. m_type = TransformRotate;
  309. return *this;
  310. }
  311. Matrix& Matrix::SetRotateZ(float angle)
  312. {
  313. SetIdentity();
  314. float c = cos(angle);
  315. float s = sin(angle);
  316. m_m[0][0] = c; m_m[0][1] = -s;
  317. m_m[1][0] = s; m_m[1][1] = c;
  318. m_type = TransformRotate;
  319. return *this;
  320. }
  321. Matrix& Matrix::SetRotate(const Vector& vec, float angle)
  322. {
  323. if (vec.Y() == 0 && vec.Z() == 0) {
  324. return SetRotateX(angle * sign(vec.X()));
  325. } else if (vec.X() == 0 && vec.Z() == 0) {
  326. return SetRotateY(angle * sign(vec.Y()));
  327. } else if (vec.X() == 0 && vec.Y() == 0) {
  328. return SetRotateZ(angle * sign(vec.Z()));
  329. } else {
  330. Vector vecUnit = vec.Normalize();
  331. float x = vecUnit.X();
  332. float y = vecUnit.Y();
  333. float z = vecUnit.Z();
  334. float c = cos(angle);
  335. float s = sin(angle);
  336. float x2 = x * x;
  337. float y2 = y * y;
  338. float z2 = z * z;
  339. float xy = x * y * (1 - c);
  340. float yz = y * z * (1 - c);
  341. float zx = z * x * (1 - c);
  342. m_m[0][0] = x2 + c * (1 - x2); m_m[0][1] = xy - z * s; m_m[0][2] = zx + y * s; m_m[0][3] = 0;
  343. m_m[1][0] = xy + z * s; m_m[1][1] = y2 + c * (1 - y2); m_m[1][2] = yz - x * s; m_m[1][3] = 0;
  344. m_m[2][0] = zx - y * s; m_m[2][1] = yz + x * s; m_m[2][2] = z2 + c * (1 - z2); m_m[2][3] = 0;
  345. m_m[3][0] = 0; m_m[3][1] = 0; m_m[3][2] = 0; m_m[3][3] = 1;
  346. }
  347. m_type = TransformRotate;
  348. return *this;
  349. }
  350. Matrix& Matrix::Rotate(const Vector& vec, float angle)
  351. {
  352. Matrix m;
  353. m.SetRotate(vec, angle);
  354. Multiply(m);
  355. return *this;
  356. }
  357. Matrix& Matrix::PreRotate(const Vector& vec, float angle)
  358. {
  359. Matrix m;
  360. m.SetRotate(vec, angle);
  361. PreMultiply(m);
  362. return *this;
  363. }
  364. //////////////////////////////////////////////////////////////////////////////
  365. //
  366. // Look at from
  367. //
  368. //////////////////////////////////////////////////////////////////////////////
  369. Matrix& Matrix::SetLookAtFrom(const Vector& vecAt, const Vector& vecFrom, const Vector& vecUp)
  370. {
  371. Vector vecZAxis = (vecFrom - vecAt).Normalize();
  372. if (vecZAxis == vecUp) {
  373. SetIdentity();
  374. m_m[0][3] = vecFrom.X();
  375. m_m[1][3] = vecFrom.Y();
  376. m_m[2][3] = vecFrom.Z();
  377. } else {
  378. Vector vecXAxis = CrossProduct(vecUp, vecZAxis).Normalize();
  379. Vector vecYAxis = CrossProduct(vecZAxis, vecXAxis);
  380. m_m[0][0] = vecXAxis.X();
  381. m_m[0][1] = vecYAxis.X();
  382. m_m[0][2] = vecZAxis.X();
  383. m_m[0][3] = vecFrom.X();
  384. m_m[1][0] = vecXAxis.Y();
  385. m_m[1][1] = vecYAxis.Y();
  386. m_m[1][2] = vecZAxis.Y();
  387. m_m[1][3] = vecFrom.Y();
  388. m_m[2][0] = vecXAxis.Z();
  389. m_m[2][1] = vecYAxis.Z();
  390. m_m[2][2] = vecZAxis.Z();
  391. m_m[2][3] = vecFrom.Z();
  392. m_m[3][0] = 0;
  393. m_m[3][1] = 0;
  394. m_m[3][2] = 0;
  395. m_m[3][3] = 1;
  396. m_type = TransformRotate | TransformTranslate;
  397. }
  398. return *this;
  399. }
  400. Matrix& Matrix::LookAtFrom(const Vector& vecAt, const Vector& vecFrom, const Vector& vecUp)
  401. {
  402. Matrix m;
  403. m.SetLookAtFrom(vecAt, vecFrom, vecUp);
  404. Multiply(m);
  405. return *this;
  406. }
  407. Matrix& Matrix::PreLookAtFrom(const Vector& vecAt, const Vector& vecFrom, const Vector& vecUp)
  408. {
  409. Matrix m;
  410. m.SetLookAtFrom(vecAt, vecFrom, vecUp);
  411. PreMultiply(m);
  412. return *this;
  413. }
  414. //////////////////////////////////////////////////////////////////////////////
  415. //
  416. // Multiply (64 mul 48 add)
  417. //
  418. //////////////////////////////////////////////////////////////////////////////
  419. Matrix& Matrix::SetMultiply(const Matrix& m1, const Matrix& m2)
  420. {
  421. for (int row = 0; row < 4; row++) {
  422. for (int col = 0; col < 4; col++) {
  423. m_m[row][col] =
  424. m1.m_m[0][col] * m2.m_m[row][0]
  425. + m1.m_m[1][col] * m2.m_m[row][1]
  426. + m1.m_m[2][col] * m2.m_m[row][2]
  427. + m1.m_m[3][col] * m2.m_m[row][3];
  428. }
  429. }
  430. m_type = m1.GetType() | m2.GetType();
  431. return *this;
  432. }
  433. Matrix& Matrix::Multiply(const Matrix& m2)
  434. {
  435. Matrix m1(*this);
  436. SetMultiply(m1, m2);
  437. return *this;
  438. }
  439. Matrix& Matrix::PreMultiply(const Matrix& m1)
  440. {
  441. Matrix m2(*this);
  442. SetMultiply(m1, m2);
  443. return *this;
  444. }
  445. //////////////////////////////////////////////////////////////////////////////
  446. //
  447. // Inverse
  448. //
  449. //////////////////////////////////////////////////////////////////////////////
  450. Matrix& Matrix::SetInverse(const Matrix& mStart)
  451. {
  452. const int size = 4;
  453. bool bSwap = false;
  454. Matrix m(mStart);
  455. SetIdentity();
  456. for (int row = 0; row < size; row++) {
  457. //
  458. // pick the largest row in the rowth column
  459. //
  460. float max = abs(m.m_m[row][row]);
  461. int rowMax = row;
  462. for (int rowIndex = row + 1; rowIndex < size; rowIndex++) {
  463. if (abs(m.m_m[rowIndex][row]) > max) {
  464. max = abs(m.m_m[rowIndex][row]);
  465. rowMax = rowIndex;
  466. }
  467. }
  468. //
  469. // swap this row with the largest row
  470. //
  471. if (rowMax != row) {
  472. //
  473. // swap rows
  474. //
  475. bSwap = true;
  476. for (int col = 0; col < size; col++) {
  477. swap(m.m_m[row][col], m.m_m[rowMax][col]);
  478. swap( m_m[row][col], m_m[rowMax][col]);
  479. }
  480. }
  481. //
  482. // scale to get a one in the diagonal
  483. //
  484. float scale = m.m_m[row][row];
  485. if (scale != 1.0f) {
  486. float rscale = 1.0f / scale;
  487. int col;
  488. m.m_m[row][row] = 1;
  489. for (col = row + 1; col < size; col++) {
  490. m.m_m[row][col] *= rscale;
  491. }
  492. if (bSwap) {
  493. for (col = 0; col < size; col++) {
  494. m_m[row][col] *= rscale;
  495. }
  496. } else {
  497. m_m[row][row] = rscale;
  498. for (col = 0; col < row; col++) {
  499. m_m[row][col] *= rscale;
  500. }
  501. }
  502. }
  503. //
  504. // get zeros in the rowth column of each row
  505. // by subtracting a multiple of row from row2
  506. //
  507. for (int row2 = 0; row2 < size; row2++) {
  508. if (row2 != row) {
  509. float scale = m.m_m[row2][row];
  510. if (scale != 0) {
  511. int col;
  512. m.m_m[row2][row] = 0;
  513. for (col = row + 1; col < size; col++) {
  514. m.m_m[row2][col] -= scale * m.m_m[row][col];
  515. }
  516. if (bSwap) {
  517. for (col = 0; col < size; col++) {
  518. m_m[row2][col] -= scale * m_m[row][col];
  519. }
  520. } else {
  521. for (col = 0; col <= row; col++) {
  522. m_m[row2][col] -= scale * m_m[row][col];
  523. }
  524. }
  525. }
  526. }
  527. }
  528. }
  529. m_type = TransformUnknown;
  530. return *this;
  531. }
  532. Matrix& Matrix::Inverse()
  533. {
  534. Matrix mat(*this);
  535. SetInverse(mat);
  536. return *this;
  537. }
  538. //////////////////////////////////////////////////////////////////////////////
  539. //
  540. // Transpose
  541. //
  542. //////////////////////////////////////////////////////////////////////////////
  543. Matrix& Matrix::SetTranspose(const Matrix& m)
  544. {
  545. for (int row = 0; row < 4; row++) {
  546. for (int col = 0; col < 4; col++) {
  547. m_m[row][col] = m.m_m[col][row];
  548. }
  549. }
  550. return *this;
  551. }
  552. Matrix& Matrix::Transpose()
  553. {
  554. for (int row = 0; row < 3; row++) {
  555. for (int col = row + 1; col < 4; col++) {
  556. float value = m_m[row][col];
  557. m_m[row][col] = m_m[col][row];
  558. m_m[col][row] = value;
  559. }
  560. }
  561. return *this;
  562. }
  563. //////////////////////////////////////////////////////////////////////////////
  564. //
  565. // Transforms
  566. //
  567. //////////////////////////////////////////////////////////////////////////////
  568. bool operator==(const Matrix& m1, const Matrix& m2)
  569. {
  570. for (int row = 0; row < 3; row++) {
  571. for (int col = row + 1; col < 4; col++) {
  572. if (m1.m_m[row][col] != m2.m_m[row][col]) {
  573. return false;
  574. }
  575. }
  576. }
  577. return true;
  578. }
  579. bool operator!=(const Matrix& m1, const Matrix& m2)
  580. {
  581. for (int row = 0; row < 3; row++) {
  582. for (int col = row + 1; col < 4; col++) {
  583. if (m1.m_m[row][col] == m2.m_m[row][col]) {
  584. return false;
  585. }
  586. }
  587. }
  588. return true;
  589. }
  590. Matrix operator*(const Matrix& m1, const Matrix& m2)
  591. {
  592. Matrix m(m1);
  593. m.Multiply(m2);
  594. return m;
  595. }
  596. //////////////////////////////////////////////////////////////////////////////
  597. //
  598. // Transforms
  599. //
  600. //////////////////////////////////////////////////////////////////////////////
  601. Point Matrix::Transform(const Point& point) const
  602. {
  603. float x = ((m_m[0][0] * point.X()) + (m_m[0][1] * point.Y()) + m_m[0][3]);
  604. float y = ((m_m[1][0] * point.X()) + (m_m[1][1] * point.Y()) + m_m[1][3]);
  605. Point p(x, y);
  606. return p;
  607. }
  608. HVector Matrix::Transform(const HVector& vec) const
  609. {
  610. float x = vec.X();
  611. float y = vec.Y();
  612. float z = vec.Z();
  613. float w = vec.W();
  614. return
  615. HVector(
  616. m_m[0][0] * x + m_m[0][1] * y + m_m[0][2] * z + m_m[0][3] * w,
  617. m_m[1][0] * x + m_m[1][1] * y + m_m[1][2] * z + m_m[1][3] * w,
  618. m_m[2][0] * x + m_m[2][1] * y + m_m[2][2] * z + m_m[2][3] * w,
  619. m_m[3][0] * x + m_m[3][1] * y + m_m[3][2] * z + m_m[3][3] * w
  620. );
  621. }
  622. Vector Matrix::Transform(const Vector& vec) const
  623. {
  624. //#ifndef FLOATASM
  625. float x = vec.X();
  626. float y = vec.Y();
  627. float z = vec.Z();
  628. return
  629. Vector(
  630. m_m[0][0] * x + m_m[0][1] * y + m_m[0][2] * z + m_m[0][3],
  631. m_m[1][0] * x + m_m[1][1] * y + m_m[1][2] * z + m_m[1][3],
  632. m_m[2][0] * x + m_m[2][1] * y + m_m[2][2] * z + m_m[2][3]
  633. );
  634. /*
  635. #else
  636. float* pm = m_m;
  637. Vector result;
  638. __asm {
  639. mov esi, vec
  640. lea edi, result
  641. mov eax, pm
  642. fld [esi].x \\ x
  643. fld [esi].y \\ y x
  644. fld [esi].z \\ z y x
  645. fld [eax] \\ m00 z y x
  646. fmul st(3) \\ m00*x z y x
  647. fld [eax + 4] \\ m01 m00*x z y x
  648. fmul st(3) \\ m01*y m00*x z y x
  649. fld [eax + 8] \\ m02 m01*y m00*x z y x
  650. fmul st(3) \\ m02*z mo1*y m00*x z y x
  651. fld [eax + 12] \\ m03 m02*z mo1*y m00*x z y x
  652. faddp st(3), st(0) \\ m02*z mo1*y m00*x+m03 z y x
  653. faddp st(1), st(0) \\ m02*z+mo1*y m00*x+m03 z y x
  654. fld [eax + 16 + 0] \\ m10 m02*z+mo1*y m00*x+m03 z y x
  655. fmul st(5) \\ m10*x m02*z+mo1*y m00*x+m03 z y x
  656. fxch st(1) \\ m02*z+mo1*y m10*x m00*x+m03 z y x
  657. faddp st(2), st(0) \\ m10*x m02*z+mo1*y+m00*x+m03 z y x
  658. fld [eax + 16 + 4] \\ m11 m10*x m02*z+mo1*y+m00*x+m03 z y x
  659. fmul st(4) \\ m11*y m10*x m02*z+mo1*y+m00*x+m03 z y x
  660. fld [eax + 16] \\ m12 m11*4 m10*x m02*z+mo1*y+m00*x+m03 z y x
  661. fmul st(4) \\ m12*z m11*4 m10*x m02*z+mo1*y+m00*x+m03 z y x
  662. fxch st(3) \\ m02*z+mo1*y+m00*x+m03 m11*4 m10*x m12*z z y x
  663. fstp [edi].x \\ m11*4 m10*x m12*z z y x
  664. fadd
  665. }
  666. #endif
  667. */
  668. }
  669. Vector Matrix::TransformDirection(const Vector& vec) const
  670. {
  671. float x = vec.X();
  672. float y = vec.Y();
  673. float z = vec.Z();
  674. return
  675. Vector(
  676. m_m[0][0] * x + m_m[0][1] * y + m_m[0][2] * z,
  677. m_m[1][0] * x + m_m[1][1] * y + m_m[1][2] * z,
  678. m_m[2][0] * x + m_m[2][1] * y + m_m[2][2] * z
  679. );
  680. }
  681. void Matrix::Transform(const TVector<Point>& vSource, TVector<Point>& vDest) const
  682. {
  683. int count = vSource.GetCount();
  684. vDest.SetCount(count);
  685. for (int index = 0; index < count; index++) {
  686. float x = vSource[index].X();
  687. float y = vSource[index].Y();
  688. vDest.Set(
  689. index,
  690. Point(
  691. m_m[0][0] * x + m_m[0][1] * y + m_m[0][3],
  692. m_m[1][0] * x + m_m[1][1] * y + m_m[1][3]
  693. )
  694. );
  695. }
  696. }
  697. void Matrix::Transform(const TVector<HVector>& vSource, TVector<HVector>& vDest) const
  698. {
  699. int count = vSource.GetCount();
  700. vDest.SetCount(count);
  701. for (int index = 0; index < count; index++) {
  702. float x = vSource[index].X();
  703. float y = vSource[index].Y();
  704. float z = vSource[index].Z();
  705. vDest.Set(
  706. index,
  707. HVector(
  708. m_m[0][0] * x + m_m[0][1] * y + m_m[0][2] * z + m_m[0][3],
  709. m_m[1][0] * x + m_m[1][1] * y + m_m[1][2] * z + m_m[1][3],
  710. m_m[2][0] * x + m_m[2][1] * y + m_m[2][2] * z + m_m[2][3]
  711. )
  712. );
  713. }
  714. }
  715. void Matrix::Transform(const TVector<Vector>& vSource, TVector<Vector>& vDest) const
  716. {
  717. int count = vSource.GetCount();
  718. vDest.SetCount(count);
  719. for (int index = 0; index < count; index++) {
  720. float x = vSource[index].X();
  721. float y = vSource[index].Y();
  722. float z = vSource[index].Z();
  723. vDest.Set(
  724. index,
  725. Vector(
  726. m_m[0][0] * x + m_m[0][1] * y + m_m[0][2] * z + m_m[0][3],
  727. m_m[1][0] * x + m_m[1][1] * y + m_m[1][2] * z + m_m[1][3],
  728. m_m[2][0] * x + m_m[2][1] * y + m_m[2][2] * z + m_m[2][3]
  729. )
  730. );
  731. }
  732. }