Matrix.hx 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938
  1. package h3d;
  2. import hxd.Math;
  3. typedef ColorAdjust = {
  4. ?saturation : Float,
  5. ?lightness : Float,
  6. ?hue : Float,
  7. ?contrast : Float,
  8. ?gain : { color : Int, alpha : Float },
  9. };
  10. class MatrixImpl {
  11. static var tmp = new Matrix();
  12. public var _11 : Float;
  13. public var _12 : Float;
  14. public var _13 : Float;
  15. public var _14 : Float;
  16. public var _21 : Float;
  17. public var _22 : Float;
  18. public var _23 : Float;
  19. public var _24 : Float;
  20. public var _31 : Float;
  21. public var _32 : Float;
  22. public var _33 : Float;
  23. public var _34 : Float;
  24. public var _41 : Float;
  25. public var _42 : Float;
  26. public var _43 : Float;
  27. public var _44 : Float;
  28. public var tx(get, set) : Float;
  29. public var ty(get, set) : Float;
  30. public var tz(get, set) : Float;
  31. inline public function new() {
  32. }
  33. inline function get_tx() return _41;
  34. inline function get_ty() return _42;
  35. inline function get_tz() return _43;
  36. inline function set_tx(v) return _41 = v;
  37. inline function set_ty(v) return _42 = v;
  38. inline function set_tz(v) return _43 = v;
  39. public function equal( other : Matrix ) {
  40. return _11 == other._11 && _12 == other._12 && _13 == other._13 && _14 == other._14
  41. && _21 == other._21 && _22 == other._22 && _23 == other._23 && _24 == other._24
  42. && _31 == other._31 && _32 == other._32 && _33 == other._33 && _34 == other._34
  43. && _41 == other._41 && _42 == other._42 && _43 == other._43 && _44 == other._44;
  44. }
  45. public function zero() {
  46. _11 = 0.0; _12 = 0.0; _13 = 0.0; _14 = 0.0;
  47. _21 = 0.0; _22 = 0.0; _23 = 0.0; _24 = 0.0;
  48. _31 = 0.0; _32 = 0.0; _33 = 0.0; _34 = 0.0;
  49. _41 = 0.0; _42 = 0.0; _43 = 0.0; _44 = 0.0;
  50. }
  51. public function identity() {
  52. _11 = 1.0; _12 = 0.0; _13 = 0.0; _14 = 0.0;
  53. _21 = 0.0; _22 = 1.0; _23 = 0.0; _24 = 0.0;
  54. _31 = 0.0; _32 = 0.0; _33 = 1.0; _34 = 0.0;
  55. _41 = 0.0; _42 = 0.0; _43 = 0.0; _44 = 1.0;
  56. }
  57. public function isIdentity() {
  58. if( _41 != 0 || _42 != 0 || _43 != 0 )
  59. return false;
  60. if( _11 != 1 || _22 != 1 || _33 != 1 )
  61. return false;
  62. if( _12 != 0 || _13 != 0 || _14 != 0 )
  63. return false;
  64. if( _21 != 0 || _23 != 0 || _24 != 0 )
  65. return false;
  66. if( _31 != 0 || _32 != 0 || _34 != 0 )
  67. return false;
  68. return _44 == 1;
  69. }
  70. public function isIdentityEpsilon( e : Float ) {
  71. if( Math.abs(_41) > e || Math.abs(_42) > e || Math.abs(_43) > e )
  72. return false;
  73. if( Math.abs(_11-1) > e || Math.abs(_22-1) > e || Math.abs(_33-1) > e )
  74. return false;
  75. if( Math.abs(_12) > e || Math.abs(_13) > e || Math.abs(_14) > e )
  76. return false;
  77. if( Math.abs(_21) > e || Math.abs(_23) > e || Math.abs(_24) > e )
  78. return false;
  79. if( Math.abs(_31) > e || Math.abs(_32) > e || Math.abs(_34) > e )
  80. return false;
  81. return Math.abs(_44 - 1) <= e;
  82. }
  83. public function initRotationX( a : Float ) {
  84. var cos = Math.cos(a);
  85. var sin = Math.sin(a);
  86. _11 = 1.0; _12 = 0.0; _13 = 0.0; _14 = 0.0;
  87. _21 = 0.0; _22 = cos; _23 = sin; _24 = 0.0;
  88. _31 = 0.0; _32 = -sin; _33 = cos; _34 = 0.0;
  89. _41 = 0.0; _42 = 0.0; _43 = 0.0; _44 = 1.0;
  90. }
  91. public function initRotationY( a : Float ) {
  92. var cos = Math.cos(a);
  93. var sin = Math.sin(a);
  94. _11 = cos; _12 = 0.0; _13 = -sin; _14 = 0.0;
  95. _21 = 0.0; _22 = 1.0; _23 = 0.0; _24 = 0.0;
  96. _31 = sin; _32 = 0.0; _33 = cos; _34 = 0.0;
  97. _41 = 0.0; _42 = 0.0; _43 = 0.0; _44 = 1.0;
  98. }
  99. public function initRotationZ( a : Float ) {
  100. var cos = Math.cos(a);
  101. var sin = Math.sin(a);
  102. _11 = cos; _12 = sin; _13 = 0.0; _14 = 0.0;
  103. _21 = -sin; _22 = cos; _23 = 0.0; _24 = 0.0;
  104. _31 = 0.0; _32 = 0.0; _33 = 1.0; _34 = 0.0;
  105. _41 = 0.0; _42 = 0.0; _43 = 0.0; _44 = 1.0;
  106. }
  107. public function initTranslation( x = 0., y = 0., z = 0. ) {
  108. _11 = 1.0; _12 = 0.0; _13 = 0.0; _14 = 0.0;
  109. _21 = 0.0; _22 = 1.0; _23 = 0.0; _24 = 0.0;
  110. _31 = 0.0; _32 = 0.0; _33 = 1.0; _34 = 0.0;
  111. _41 = x; _42 = y; _43 = z; _44 = 1.0;
  112. }
  113. public function initScale( x = 1., y = 1., z = 1. ) {
  114. _11 = x; _12 = 0.0; _13 = 0.0; _14 = 0.0;
  115. _21 = 0.0; _22 = y; _23 = 0.0; _24 = 0.0;
  116. _31 = 0.0; _32 = 0.0; _33 = z; _34 = 0.0;
  117. _41 = 0.0; _42 = 0.0; _43 = 0.0; _44 = 1.0;
  118. }
  119. public inline function initRotationAxis( axis : Vector, angle : Float ) {
  120. var cos = Math.cos(angle), sin = Math.sin(angle);
  121. var cos1 = 1 - cos;
  122. var x = -axis.x, y = -axis.y, z = -axis.z;
  123. var xx = x * x, yy = y * y, zz = z * z;
  124. var len = Math.invSqrt(xx + yy + zz);
  125. x *= len;
  126. y *= len;
  127. z *= len;
  128. var xcos1 = x * cos1, zcos1 = z * cos1;
  129. _11 = cos + x * xcos1;
  130. _12 = y * xcos1 - z * sin;
  131. _13 = x * zcos1 + y * sin;
  132. _14 = 0.;
  133. _21 = y * xcos1 + z * sin;
  134. _22 = cos + y * y * cos1;
  135. _23 = y * zcos1 - x * sin;
  136. _24 = 0.;
  137. _31 = x * zcos1 - y * sin;
  138. _32 = y * zcos1 + x * sin;
  139. _33 = cos + z * zcos1;
  140. _34 = 0.;
  141. _41 = 0.; _42 = 0.; _43 = 0.; _44 = 1.;
  142. }
  143. public function initRotation( x : Float, y : Float, z : Float ) {
  144. var cx = Math.cos(x);
  145. var sx = Math.sin(x);
  146. var cy = Math.cos(y);
  147. var sy = Math.sin(y);
  148. var cz = Math.cos(z);
  149. var sz = Math.sin(z);
  150. var cxsy = cx * sy;
  151. var sxsy = sx * sy;
  152. _11 = cy * cz;
  153. _12 = cy * sz;
  154. _13 = -sy;
  155. _14 = 0;
  156. _21 = sxsy * cz - cx * sz;
  157. _22 = sxsy * sz + cx * cz;
  158. _23 = sx * cy;
  159. _24 = 0;
  160. _31 = cxsy * cz + sx * sz;
  161. _32 = cxsy * sz - sx * cz;
  162. _33 = cx * cy;
  163. _34 = 0;
  164. _41 = 0;
  165. _42 = 0;
  166. _43 = 0;
  167. _44 = 1;
  168. }
  169. public function translate( x = 0., y = 0., z = 0. ) {
  170. _11 += x * _14;
  171. _12 += y * _14;
  172. _13 += z * _14;
  173. _21 += x * _24;
  174. _22 += y * _24;
  175. _23 += z * _24;
  176. _31 += x * _34;
  177. _32 += y * _34;
  178. _33 += z * _34;
  179. _41 += x * _44;
  180. _42 += y * _44;
  181. _43 += z * _44;
  182. }
  183. public function scale( x = 1., y = 1., z = 1. ) {
  184. _11 *= x;
  185. _21 *= x;
  186. _31 *= x;
  187. _41 *= x;
  188. _12 *= y;
  189. _22 *= y;
  190. _32 *= y;
  191. _42 *= y;
  192. _13 *= z;
  193. _23 *= z;
  194. _33 *= z;
  195. _43 *= z;
  196. }
  197. public function rotate( x, y, z ) {
  198. var tmp = tmp;
  199. tmp.initRotation(x,y,z);
  200. multiply(this, tmp);
  201. }
  202. public function rotateAxis( axis, angle ) {
  203. var tmp = tmp;
  204. tmp.initRotationAxis(axis, angle);
  205. multiply(this, tmp);
  206. }
  207. public inline function getPosition() {
  208. var v = new Vector();
  209. v.set(_41,_42,_43);
  210. return v;
  211. }
  212. public inline function setPosition( v : Vector ) {
  213. _41 = v.x;
  214. _42 = v.y;
  215. _43 = v.z;
  216. }
  217. public function prependTranslation( x = 0., y = 0., z = 0. ) {
  218. var vx = _11 * x + _21 * y + _31 * z + _41;
  219. var vy = _12 * x + _22 * y + _32 * z + _42;
  220. var vz = _13 * x + _23 * y + _33 * z + _43;
  221. var vw = _14 * x + _24 * y + _34 * z + _44;
  222. _41 = vx;
  223. _42 = vy;
  224. _43 = vz;
  225. _44 = vw;
  226. }
  227. public inline function getScale() {
  228. var v = new Vector();
  229. v.x = Math.sqrt(_11 * _11 + _12 * _12 + _13 * _13);
  230. v.y = Math.sqrt(_21 * _21 + _22 * _22 + _23 * _23);
  231. v.z = Math.sqrt(_31 * _31 + _32 * _32 + _33 * _33);
  232. if( getDeterminant() < 0 ) {
  233. v.x *= -1;
  234. v.y *= -1;
  235. v.z *= -1;
  236. }
  237. return v;
  238. }
  239. public function prependRotation( x, y, z ) {
  240. var tmp = tmp;
  241. tmp.initRotation(x,y,z);
  242. multiply(tmp, this);
  243. }
  244. public function prependRotationAxis( axis, angle ) {
  245. var tmp = tmp;
  246. tmp.initRotationAxis(axis, angle);
  247. multiply(tmp, this);
  248. }
  249. public function prependScale( sx = 1., sy = 1., sz = 1. ) {
  250. var tmp = tmp;
  251. tmp.initScale(sx,sy,sz);
  252. multiply(tmp, this);
  253. }
  254. @:noDebug
  255. public function multiply3x4( a : Matrix, b : Matrix ) {
  256. multiply3x4inline(a, b);
  257. }
  258. public inline function multiply3x4inline( a : Matrix, b : Matrix ) {
  259. var m11 = a._11; var m12 = a._12; var m13 = a._13;
  260. var m21 = a._21; var m22 = a._22; var m23 = a._23;
  261. var a31 = a._31; var a32 = a._32; var a33 = a._33;
  262. var a41 = a._41; var a42 = a._42; var a43 = a._43;
  263. var b11 = b._11; var b12 = b._12; var b13 = b._13;
  264. var b21 = b._21; var b22 = b._22; var b23 = b._23;
  265. var b31 = b._31; var b32 = b._32; var b33 = b._33;
  266. var b41 = b._41; var b42 = b._42; var b43 = b._43;
  267. _11 = m11 * b11 + m12 * b21 + m13 * b31;
  268. _12 = m11 * b12 + m12 * b22 + m13 * b32;
  269. _13 = m11 * b13 + m12 * b23 + m13 * b33;
  270. _14 = 0;
  271. _21 = m21 * b11 + m22 * b21 + m23 * b31;
  272. _22 = m21 * b12 + m22 * b22 + m23 * b32;
  273. _23 = m21 * b13 + m22 * b23 + m23 * b33;
  274. _24 = 0;
  275. _31 = a31 * b11 + a32 * b21 + a33 * b31;
  276. _32 = a31 * b12 + a32 * b22 + a33 * b32;
  277. _33 = a31 * b13 + a32 * b23 + a33 * b33;
  278. _34 = 0;
  279. _41 = a41 * b11 + a42 * b21 + a43 * b31 + b41;
  280. _42 = a41 * b12 + a42 * b22 + a43 * b32 + b42;
  281. _43 = a41 * b13 + a42 * b23 + a43 * b33 + b43;
  282. _44 = 1;
  283. }
  284. public function multiply( a : Matrix, b : Matrix ) {
  285. var a11 = a._11; var a12 = a._12; var a13 = a._13; var a14 = a._14;
  286. var a21 = a._21; var a22 = a._22; var a23 = a._23; var a24 = a._24;
  287. var a31 = a._31; var a32 = a._32; var a33 = a._33; var a34 = a._34;
  288. var a41 = a._41; var a42 = a._42; var a43 = a._43; var a44 = a._44;
  289. var b11 = b._11; var b12 = b._12; var b13 = b._13; var b14 = b._14;
  290. var b21 = b._21; var b22 = b._22; var b23 = b._23; var b24 = b._24;
  291. var b31 = b._31; var b32 = b._32; var b33 = b._33; var b34 = b._34;
  292. var b41 = b._41; var b42 = b._42; var b43 = b._43; var b44 = b._44;
  293. _11 = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
  294. _12 = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
  295. _13 = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
  296. _14 = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
  297. _21 = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
  298. _22 = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
  299. _23 = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
  300. _24 = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
  301. _31 = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
  302. _32 = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
  303. _33 = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
  304. _34 = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
  305. _41 = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
  306. _42 = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
  307. _43 = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
  308. _44 = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
  309. }
  310. public function multiplyValue( v : Float ) {
  311. _11 *= v;
  312. _12 *= v;
  313. _13 *= v;
  314. _14 *= v;
  315. _21 *= v;
  316. _22 *= v;
  317. _23 *= v;
  318. _24 *= v;
  319. _31 *= v;
  320. _32 *= v;
  321. _33 *= v;
  322. _34 *= v;
  323. _41 *= v;
  324. _42 *= v;
  325. _43 *= v;
  326. _44 *= v;
  327. }
  328. public inline function invert() {
  329. initInverse(this);
  330. }
  331. public function getInverse( ?m : h3d.Matrix ) {
  332. if( m == null ) m = new h3d.Matrix();
  333. m.initInverse(this);
  334. return m;
  335. }
  336. public inline function getDeterminant() {
  337. return _11 * (_22*_33 - _23*_32) + _12 * (_23*_31 - _21*_33) + _13 * (_21*_32 - _22*_31);
  338. }
  339. public function inverse3x4( m : Matrix ) {
  340. var m11 = m._11, m12 = m._12, m13 = m._13;
  341. var m21 = m._21, m22 = m._22, m23 = m._23;
  342. var m31 = m._31, m32 = m._32, m33 = m._33;
  343. var m41 = m._41, m42 = m._42, m43 = m._43;
  344. _11 = m22*m33 - m23*m32;
  345. _12 = m13*m32 - m12*m33;
  346. _13 = m12*m23 - m13*m22;
  347. _14 = 0;
  348. _21 = m23*m31 - m21*m33;
  349. _22 = m11*m33 - m13*m31;
  350. _23 = m13*m21 - m11*m23;
  351. _24 = 0;
  352. _31 = m21*m32 - m22*m31;
  353. _32 = m12*m31 - m11*m32;
  354. _33 = m11*m22 - m12*m21;
  355. _34 = 0;
  356. _41 = -m21 * m32 * m43 + m21 * m33 * m42 + m31 * m22 * m43 - m31 * m23 * m42 - m41 * m22 * m33 + m41 * m23 * m32;
  357. _42 = m11 * m32 * m43 - m11 * m33 * m42 - m31 * m12 * m43 + m31 * m13 * m42 + m41 * m12 * m33 - m41 * m13 * m32;
  358. _43 = -m11 * m22 * m43 + m11 * m23 * m42 + m21 * m12 * m43 - m21 * m13 * m42 - m41 * m12 * m23 + m41 * m13 * m22;
  359. _44 = m11 * m22 * m33 - m11 * m23 * m32 - m21 * m12 * m33 + m21 * m13 * m32 + m31 * m12 * m23 - m31 * m13 * m22;
  360. _44 = 1;
  361. var det = m11 * _11 + m12 * _21 + m13 * _31;
  362. if( Math.abs(det) < Math.EPSILON ) {
  363. zero();
  364. return;
  365. }
  366. var invDet = 1.0 / det;
  367. _11 *= invDet; _12 *= invDet; _13 *= invDet;
  368. _21 *= invDet; _22 *= invDet; _23 *= invDet;
  369. _31 *= invDet; _32 *= invDet; _33 *= invDet;
  370. _41 *= invDet; _42 *= invDet; _43 *= invDet;
  371. }
  372. public function initInverse( m : Matrix ) {
  373. var m11 = m._11; var m12 = m._12; var m13 = m._13; var m14 = m._14;
  374. var m21 = m._21; var m22 = m._22; var m23 = m._23; var m24 = m._24;
  375. var m31 = m._31; var m32 = m._32; var m33 = m._33; var m34 = m._34;
  376. var m41 = m._41; var m42 = m._42; var m43 = m._43; var m44 = m._44;
  377. _11 = m22 * m33 * m44 - m22 * m34 * m43 - m32 * m23 * m44 + m32 * m24 * m43 + m42 * m23 * m34 - m42 * m24 * m33;
  378. _12 = -m12 * m33 * m44 + m12 * m34 * m43 + m32 * m13 * m44 - m32 * m14 * m43 - m42 * m13 * m34 + m42 * m14 * m33;
  379. _13 = m12 * m23 * m44 - m12 * m24 * m43 - m22 * m13 * m44 + m22 * m14 * m43 + m42 * m13 * m24 - m42 * m14 * m23;
  380. _14 = -m12 * m23 * m34 + m12 * m24 * m33 + m22 * m13 * m34 - m22 * m14 * m33 - m32 * m13 * m24 + m32 * m14 * m23;
  381. _21 = -m21 * m33 * m44 + m21 * m34 * m43 + m31 * m23 * m44 - m31 * m24 * m43 - m41 * m23 * m34 + m41 * m24 * m33;
  382. _22 = m11 * m33 * m44 - m11 * m34 * m43 - m31 * m13 * m44 + m31 * m14 * m43 + m41 * m13 * m34 - m41 * m14 * m33;
  383. _23 = -m11 * m23 * m44 + m11 * m24 * m43 + m21 * m13 * m44 - m21 * m14 * m43 - m41 * m13 * m24 + m41 * m14 * m23;
  384. _24 = m11 * m23 * m34 - m11 * m24 * m33 - m21 * m13 * m34 + m21 * m14 * m33 + m31 * m13 * m24 - m31 * m14 * m23;
  385. _31 = m21 * m32 * m44 - m21 * m34 * m42 - m31 * m22 * m44 + m31 * m24 * m42 + m41 * m22 * m34 - m41 * m24 * m32;
  386. _32 = -m11 * m32 * m44 + m11 * m34 * m42 + m31 * m12 * m44 - m31 * m14 * m42 - m41 * m12 * m34 + m41 * m14 * m32;
  387. _33 = m11 * m22 * m44 - m11 * m24 * m42 - m21 * m12 * m44 + m21 * m14 * m42 + m41 * m12 * m24 - m41 * m14 * m22;
  388. _34 = -m11 * m22 * m34 + m11 * m24 * m32 + m21 * m12 * m34 - m21 * m14 * m32 - m31 * m12 * m24 + m31 * m14 * m22;
  389. _41 = -m21 * m32 * m43 + m21 * m33 * m42 + m31 * m22 * m43 - m31 * m23 * m42 - m41 * m22 * m33 + m41 * m23 * m32;
  390. _42 = m11 * m32 * m43 - m11 * m33 * m42 - m31 * m12 * m43 + m31 * m13 * m42 + m41 * m12 * m33 - m41 * m13 * m32;
  391. _43 = -m11 * m22 * m43 + m11 * m23 * m42 + m21 * m12 * m43 - m21 * m13 * m42 - m41 * m12 * m23 + m41 * m13 * m22;
  392. _44 = m11 * m22 * m33 - m11 * m23 * m32 - m21 * m12 * m33 + m21 * m13 * m32 + m31 * m12 * m23 - m31 * m13 * m22;
  393. var det = m11 * _11 + m12 * _21 + m13 * _31 + m14 * _41;
  394. if( Math.abs(det) < Math.EPSILON ) {
  395. zero();
  396. return;
  397. }
  398. det = 1.0 / det;
  399. _11 *= det;
  400. _12 *= det;
  401. _13 *= det;
  402. _14 *= det;
  403. _21 *= det;
  404. _22 *= det;
  405. _23 *= det;
  406. _24 *= det;
  407. _31 *= det;
  408. _32 *= det;
  409. _33 *= det;
  410. _34 *= det;
  411. _41 *= det;
  412. _42 *= det;
  413. _43 *= det;
  414. _44 *= det;
  415. }
  416. public function initInverse3x3( m : Matrix ) {
  417. var m11 = m._11; var m12 = m._12; var m13 = m._13;
  418. var m21 = m._21; var m22 = m._22; var m23 = m._23;
  419. var m31 = m._31; var m32 = m._32; var m33 = m._33;
  420. _11 = m22 * m33 - m32 * m23;
  421. _12 = -m12 * m33 + m32 * m13;
  422. _13 = m12 * m23 - m22 * m13;
  423. _21 = -m21 * m33 + m31 * m23;
  424. _22 = m11 * m33 - m31 * m13;
  425. _23 = -m11 * m23 + m21 * m13;
  426. _31 = m21 * m32 - m31 * m22;
  427. _32 = -m11 * m32 + m31 * m12;
  428. _33 = m11 * m22 - m21 * m12;
  429. var det = m11 * _11 + m12 * _21 + m13 * _31;
  430. if( Math.abs(det) < Math.EPSILON ) {
  431. zero();
  432. return;
  433. }
  434. det = 1.0 / det;
  435. _11 *= det;
  436. _12 *= det;
  437. _13 *= det;
  438. _14 = 0;
  439. _21 *= det;
  440. _22 *= det;
  441. _23 *= det;
  442. _24 = 0;
  443. _31 *= det;
  444. _32 *= det;
  445. _33 *= det;
  446. _34 = 0;
  447. _41 = 0;
  448. _42 = 0;
  449. _43 = 0;
  450. _44 = 1;
  451. }
  452. public inline function front() {
  453. var v = new h3d.Vector(_11, _12, _13);
  454. v.normalize();
  455. return v;
  456. }
  457. public inline function right() {
  458. var v = new h3d.Vector(_21, _22, _23);
  459. v.normalize();
  460. return v;
  461. }
  462. public inline function up() {
  463. var v = new h3d.Vector(_31, _32, _33);
  464. v.normalize();
  465. return v;
  466. }
  467. public function transpose() {
  468. var tmp;
  469. tmp = _12; _12 = _21; _21 = tmp;
  470. tmp = _13; _13 = _31; _31 = tmp;
  471. tmp = _14; _14 = _41; _41 = tmp;
  472. tmp = _23; _23 = _32; _32 = tmp;
  473. tmp = _24; _24 = _42; _42 = tmp;
  474. tmp = _34; _34 = _43; _43 = tmp;
  475. }
  476. public function clone() {
  477. var m = new Matrix();
  478. m._11 = _11; m._12 = _12; m._13 = _13; m._14 = _14;
  479. m._21 = _21; m._22 = _22; m._23 = _23; m._24 = _24;
  480. m._31 = _31; m._32 = _32; m._33 = _33; m._34 = _34;
  481. m._41 = _41; m._42 = _42; m._43 = _43; m._44 = _44;
  482. return m;
  483. }
  484. public function load( m : Matrix ) {
  485. _11 = m._11; _12 = m._12; _13 = m._13; _14 = m._14;
  486. _21 = m._21; _22 = m._22; _23 = m._23; _24 = m._24;
  487. _31 = m._31; _32 = m._32; _33 = m._33; _34 = m._34;
  488. _41 = m._41; _42 = m._42; _43 = m._43; _44 = m._44;
  489. }
  490. public function loadValues( a : Array<Float> ) {
  491. _11 = a[0]; _12 = a[1]; _13 = a[2]; _14 = a[3];
  492. _21 = a[4]; _22 = a[5]; _23 = a[6]; _24 = a[7];
  493. _31 = a[8]; _32 = a[9]; _33 = a[10]; _34 = a[11];
  494. _41 = a[12]; _42 = a[13]; _43 = a[14]; _44 = a[15];
  495. }
  496. public function getFloats() {
  497. return [_11, _12, _13, _14, _21, _22, _23, _24, _31, _32, _33, _34, _41, _42, _43, _44];
  498. }
  499. public function getDirection() {
  500. var q = new h3d.Quat();
  501. q.initRotateMatrix(this);
  502. q.normalize();
  503. return q.getDirection();
  504. }
  505. /**
  506. Extracts Euler rotation angles from rotation matrix
  507. **/
  508. public function getEulerAngles() {
  509. var m = this.clone();
  510. var s = this.getScale();
  511. m.prependScale(1.0 / s.x, 1.0 / s.y, 1.0 / s.z);
  512. var cy = hxd.Math.sqrt(m._11 * m._11 + m._12 * m._12);
  513. if(cy > 0.01) {
  514. var v1 = new h3d.Vector(
  515. hxd.Math.atan2(m._23, m._33),
  516. hxd.Math.atan2(-m._13, cy),
  517. hxd.Math.atan2(m._12, m._11));
  518. var v2 = new h3d.Vector(
  519. hxd.Math.atan2(-m._23, -m._33),
  520. hxd.Math.atan2(-m._13, -cy),
  521. hxd.Math.atan2(-m._12, -m._11));
  522. return v1.lengthSq() < v2.lengthSq() ? v1 : v2;
  523. }
  524. else {
  525. return new h3d.Vector(
  526. hxd.Math.atan2(-m._32, m._22),
  527. hxd.Math.atan2(-m._13, cy),
  528. 0.0);
  529. }
  530. }
  531. public function toString() {
  532. return "MAT=[\n" +
  533. " [ " + Math.fmt(_11) + ", " + Math.fmt(_12) + ", " + Math.fmt(_13) + ", " + Math.fmt(_14) + " ]\n" +
  534. " [ " + Math.fmt(_21) + ", " + Math.fmt(_22) + ", " + Math.fmt(_23) + ", " + Math.fmt(_24) + " ]\n" +
  535. " [ " + Math.fmt(_31) + ", " + Math.fmt(_32) + ", " + Math.fmt(_33) + ", " + Math.fmt(_34) + " ]\n" +
  536. " [ " + Math.fmt(_41) + ", " + Math.fmt(_42) + ", " + Math.fmt(_43) + ", " + Math.fmt(_44) + " ]\n" +
  537. "]";
  538. }
  539. // ---- COLOR MATRIX FUNCTIONS -------
  540. static inline var lumR = 0.212671;
  541. static inline var lumG = 0.71516;
  542. static inline var lumB = 0.072169;
  543. static inline var SQ13 = 0.57735026918962576450914878050196; // sqrt(1/3)
  544. public function colorHue( hue : Float ) {
  545. if( hue == 0. )
  546. return;
  547. var cosA = Math.cos(-hue);
  548. var sinA = Math.sin(-hue);
  549. var ch = (1 - cosA) / 3;
  550. var tmp = tmp;
  551. tmp._11 = cosA + ch;
  552. tmp._12 = ch - SQ13 * sinA;
  553. tmp._13 = ch + SQ13 * sinA;
  554. tmp._21 = ch + SQ13 * sinA;
  555. tmp._22 = cosA + ch;
  556. tmp._23 = ch - SQ13 * sinA;
  557. tmp._31 = ch - SQ13 * sinA;
  558. tmp._32 = ch + SQ13 * sinA;
  559. tmp._33 = cosA + ch;
  560. tmp._34 = 0;
  561. tmp._41 = 0;
  562. tmp._42 = 0;
  563. tmp._43 = 0;
  564. multiply3x4(this, tmp);
  565. }
  566. public function colorSaturate( sat : Float ) {
  567. sat += 1;
  568. var ins = 1 - sat;
  569. var r = ins * lumR;
  570. var g = ins * lumG;
  571. var b = ins * lumB;
  572. var tmp = tmp;
  573. tmp._11 = r + sat;
  574. tmp._12 = r;
  575. tmp._13 = r;
  576. tmp._21 = g;
  577. tmp._22 = g + sat;
  578. tmp._23 = g;
  579. tmp._31 = b;
  580. tmp._32 = b;
  581. tmp._33 = b + sat;
  582. tmp._41 = 0;
  583. tmp._42 = 0;
  584. tmp._43 = 0;
  585. multiply3x4(this, tmp);
  586. }
  587. public function colorContrast( contrast : Float ) {
  588. var tmp = tmp;
  589. var v = contrast + 1;
  590. tmp._11 = v;
  591. tmp._12 = 0;
  592. tmp._13 = 0;
  593. tmp._21 = 0;
  594. tmp._22 = v;
  595. tmp._23 = 0;
  596. tmp._31 = 0;
  597. tmp._32 = 0;
  598. tmp._33 = v;
  599. tmp._41 = -contrast*0.5;
  600. tmp._42 = -contrast*0.5;
  601. tmp._43 = -contrast*0.5;
  602. multiply3x4(this, tmp);
  603. }
  604. public function colorLightness( lightness : Float ) {
  605. _41 += lightness;
  606. _42 += lightness;
  607. _43 += lightness;
  608. }
  609. public function colorGain( color : Int, alpha : Float ) {
  610. var tmp = tmp;
  611. tmp._11 = 1 - alpha;
  612. tmp._12 = 0;
  613. tmp._13 = 0;
  614. tmp._21 = 0;
  615. tmp._22 = 1 - alpha;
  616. tmp._23 = 0;
  617. tmp._31 = 0;
  618. tmp._32 = 0;
  619. tmp._33 = 1 - alpha;
  620. tmp._41 = (((color >> 16) & 0xFF) / 255) * alpha;
  621. tmp._42 = (((color >> 8) & 0xFF) / 255) * alpha;
  622. tmp._43 = ((color & 0xFF) / 255) * alpha;
  623. multiply3x4(this, tmp);
  624. }
  625. public function colorBits( bits : Int, blend : Float ) {
  626. var t11 = 0., t12 = 0., t13 = 0.;
  627. var t21 = 0., t22 = 0., t23 = 0.;
  628. var t31 = 0., t32 = 0., t33 = 0.;
  629. var c = bits;
  630. if( c & 1 == 1 ) t11 = 1; c >>= 1;
  631. if( c & 1 == 1 ) t12 = 1; c >>= 1;
  632. if( c & 1 == 1 ) t13 = 1; c >>= 1;
  633. if( c & 1 == 1 ) t21 = 1; c >>= 1;
  634. if( c & 1 == 1 ) t22 = 1; c >>= 1;
  635. if( c & 1 == 1 ) t23 = 1; c >>= 1;
  636. if( c & 1 == 1 ) t31 = 1; c >>= 1;
  637. if( c & 1 == 1 ) t32 = 1; c >>= 1;
  638. if( c & 1 == 1 ) t33 = 1; c >>= 1;
  639. var r = t11 + t21 + t31;
  640. var g = t12 + t22 + t32;
  641. var b = t13 + t23 + t33;
  642. if( r > 1 ) { t11 /= r; t21 /= r; t31 /= r; }
  643. if( g > 1 ) { t12 /= g; t22 /= g; t32 /= g; }
  644. if( b > 1 ) { t13 /= b; t23 /= b; t33 /= b; }
  645. // multiply our 3x3 by current matrix
  646. var b11 = _11 * t11 + _12 * t21 + _13 * t31;
  647. var b12 = _11 * t12 + _12 * t22 + _13 * t32;
  648. var b13 = _11 * t13 + _12 * t23 + _13 * t33;
  649. var b21 = _21 * t11 + _22 * t21 + _23 * t31;
  650. var b22 = _21 * t12 + _22 * t22 + _23 * t32;
  651. var b23 = _21 * t13 + _22 * t23 + _23 * t33;
  652. var b31 = _31 * t11 + _32 * t21 + _33 * t31;
  653. var b32 = _31 * t12 + _32 * t22 + _33 * t32;
  654. var b33 = _31 * t13 + _32 * t23 + _33 * t33;
  655. // blend it
  656. var ik = blend, k = 1 - ik;
  657. _11 = _11 * k + b11 * ik;
  658. _12 = _12 * k + b12 * ik;
  659. _13 = _13 * k + b13 * ik;
  660. _21 = _21 * k + b21 * ik;
  661. _22 = _22 * k + b22 * ik;
  662. _23 = _23 * k + b23 * ik;
  663. _31 = _31 * k + b31 * ik;
  664. _32 = _32 * k + b32 * ik;
  665. _33 = _33 * k + b33 * ik;
  666. }
  667. public inline function colorAdd( c : Int ) {
  668. _41 += ((c >> 16) & 0xFF) / 255;
  669. _42 += ((c >> 8) & 0xFF) / 255;
  670. _43 += (c & 0xFF) / 255;
  671. }
  672. public inline function colorSet( c : Int, alpha = 1. ) {
  673. zero();
  674. _44 = alpha;
  675. colorAdd(c);
  676. }
  677. public function adjustColor( col : ColorAdjust ) {
  678. if( col.hue != null ) colorHue(col.hue);
  679. if( col.saturation != null ) colorSaturate(col.saturation);
  680. if( col.contrast != null ) colorContrast(col.contrast);
  681. if( col.lightness != null ) colorLightness(col.lightness);
  682. if( col.gain != null ) colorGain(col.gain.color, col.gain.alpha);
  683. }
  684. public inline function toMatrix2D( ?m : h2d.col.Matrix ) {
  685. if( m == null ) m = new h2d.col.Matrix();
  686. m.a = _11;
  687. m.b = _12;
  688. m.c = _21;
  689. m.d = _22;
  690. m.x = tx;
  691. m.y = ty;
  692. return m;
  693. }
  694. // ----- h3d.anim Helpers ------
  695. /**
  696. Extract the rotation from `inMatrix` and stores it as a quaternion inside the [m12,m13,m21,m23] component
  697. instead of the rotation being mixed with the scale.
  698. **/
  699. public function decomposeMatrix(inMatrix: h3d.Matrix) {
  700. this.load(inMatrix);
  701. var scale = inline this.getScale();
  702. this.prependScale(1.0/scale.x, 1.0/scale.y, 1.0/scale.z);
  703. var quat = inline new h3d.Quat();
  704. inline quat.initRotateMatrix(this);
  705. this._11 = scale.x;
  706. this._12 = quat.x;
  707. this._13 = quat.y;
  708. this._14 = 0.0;
  709. this._21 = quat.z;
  710. this._22 = scale.y;
  711. this._23 = quat.w;
  712. this._24 = 0.0;
  713. this._31 = 0.0;
  714. this._32 = 0.0;
  715. this._33 = scale.z;
  716. this._34 = 0.0;
  717. this.tx = inMatrix.tx;
  718. this.ty = inMatrix.ty;
  719. this.tz = inMatrix.tz;
  720. this._44 = 1.0;
  721. }
  722. /**
  723. Inverts the operation of `decomposeMatrix`, giving back a normal transformation matrix from a decomposed one
  724. **/
  725. public function recomposeMatrix(inMatrix: h3d.Matrix) {
  726. var copy = inline new h3d.Matrix(); // copy to avoid aliasing this and inMatrix
  727. inline copy.load(inMatrix);
  728. var quat = inline new h3d.Quat(inMatrix._12, inMatrix._13, inMatrix._21, inMatrix._23);
  729. inline quat.toMatrix(this);
  730. this._11 *= copy._11;
  731. this._12 *= copy._11;
  732. this._13 *= copy._11;
  733. this._21 *= copy._22;
  734. this._22 *= copy._22;
  735. this._23 *= copy._22;
  736. this._31 *= copy._33;
  737. this._32 *= copy._33;
  738. this._33 *= copy._33;
  739. this._41 = copy._41;
  740. this._42 = copy._42;
  741. this._43 = copy._43;
  742. this._14 = copy._14;
  743. this._24 = copy._24;
  744. this._34 = copy._34;
  745. }
  746. }
  747. @:forward abstract Matrix(MatrixImpl) from MatrixImpl to MatrixImpl {
  748. public inline function new() {
  749. this = new MatrixImpl();
  750. }
  751. @:op(a * b) public inline function multiplied( m : Matrix ) {
  752. var mout = new Matrix();
  753. mout.multiply(this, m);
  754. return mout;
  755. }
  756. // STATICS
  757. public static function I() {
  758. var m = new Matrix();
  759. m.identity();
  760. return m;
  761. }
  762. public static function L( a : Array<Float> ) {
  763. var m = new Matrix();
  764. m.loadValues(a);
  765. return m;
  766. }
  767. public static function T( x = 0., y = 0., z = 0. ) {
  768. var m = new Matrix();
  769. m.initTranslation(x, y, z);
  770. return m;
  771. }
  772. public static function R(x,y,z) {
  773. var m = new Matrix();
  774. m.initRotation(x,y,z);
  775. return m;
  776. }
  777. public static function S( x = 1., y = 1., z = 1.0 ) {
  778. var m = new Matrix();
  779. m.initScale(x, y, z);
  780. return m;
  781. }
  782. /**
  783. Build a rotation Matrix so the X axis will look at the given direction, and the Z axis will be the Up vector ([0,0,1] by default)
  784. **/
  785. public static inline function lookAtXInline( dir : Vector, up : Vector, m : Matrix ) {
  786. var ax = dir.normalized();
  787. var ay = up.cross(ax).normalized();
  788. if( ay.lengthSq() < Math.EPSILON2 ) {
  789. ay.x = ax.y;
  790. ay.y = ax.z;
  791. ay.z = ax.x;
  792. }
  793. var az = ax.cross(ay);
  794. m._11 = ax.x;
  795. m._12 = ax.y;
  796. m._13 = ax.z;
  797. m._14 = 0;
  798. m._21 = ay.x;
  799. m._22 = ay.y;
  800. m._23 = ay.z;
  801. m._24 = 0;
  802. m._31 = az.x;
  803. m._32 = az.y;
  804. m._33 = az.z;
  805. m._34 = 0;
  806. m._41 = 0;
  807. m._42 = 0;
  808. m._43 = 0;
  809. m._44 = 1;
  810. return m;
  811. }
  812. public static function lookAtX( dir : Vector, ?up : Vector, ?m : Matrix ) {
  813. if( up == null ) up = new Vector(0, 0, 1);
  814. if( m == null ) m = new Matrix();
  815. return lookAtXInline(dir, up, m);
  816. }
  817. public static final IDENTITY_DECOMPOSED = h3d.Matrix.L([
  818. 1, 0, 0, 0,
  819. 0, 1, 1, 0,
  820. 0, 0, 1, 0,
  821. 0, 0, 0, 1,
  822. ]);
  823. }