rs_matrix.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. #include "rs_core.rsh"
  2. #include "rs_structs.h"
  3. /* Function declarations from libRS */
  4. extern float4 __attribute__((overloadable)) convert_float4(uchar4 c);
  5. /* Implementation of Core Runtime */
  6. /////////////////////////////////////////////////////
  7. // Matrix ops
  8. /////////////////////////////////////////////////////
  9. extern void __attribute__((overloadable))
  10. rsMatrixLoadIdentity(rs_matrix4x4 *m) {
  11. m->m[0] = 1.f;
  12. m->m[1] = 0.f;
  13. m->m[2] = 0.f;
  14. m->m[3] = 0.f;
  15. m->m[4] = 0.f;
  16. m->m[5] = 1.f;
  17. m->m[6] = 0.f;
  18. m->m[7] = 0.f;
  19. m->m[8] = 0.f;
  20. m->m[9] = 0.f;
  21. m->m[10] = 1.f;
  22. m->m[11] = 0.f;
  23. m->m[12] = 0.f;
  24. m->m[13] = 0.f;
  25. m->m[14] = 0.f;
  26. m->m[15] = 1.f;
  27. }
  28. extern void __attribute__((overloadable))
  29. rsMatrixLoadIdentity(rs_matrix3x3 *m) {
  30. m->m[0] = 1.f;
  31. m->m[1] = 0.f;
  32. m->m[2] = 0.f;
  33. m->m[3] = 0.f;
  34. m->m[4] = 1.f;
  35. m->m[5] = 0.f;
  36. m->m[6] = 0.f;
  37. m->m[7] = 0.f;
  38. m->m[8] = 1.f;
  39. }
  40. extern void __attribute__((overloadable))
  41. rsMatrixLoadIdentity(rs_matrix2x2 *m) {
  42. m->m[0] = 1.f;
  43. m->m[1] = 0.f;
  44. m->m[2] = 0.f;
  45. m->m[3] = 1.f;
  46. }
  47. extern void __attribute__((overloadable))
  48. rsMatrixLoad(rs_matrix4x4 *m, const float *f) {
  49. m->m[0] = f[0];
  50. m->m[1] = f[1];
  51. m->m[2] = f[2];
  52. m->m[3] = f[3];
  53. m->m[4] = f[4];
  54. m->m[5] = f[5];
  55. m->m[6] = f[6];
  56. m->m[7] = f[7];
  57. m->m[8] = f[8];
  58. m->m[9] = f[9];
  59. m->m[10] = f[10];
  60. m->m[11] = f[11];
  61. m->m[12] = f[12];
  62. m->m[13] = f[13];
  63. m->m[14] = f[14];
  64. m->m[15] = f[15];
  65. }
  66. extern void __attribute__((overloadable))
  67. rsMatrixLoad(rs_matrix3x3 *m, const float *f) {
  68. m->m[0] = f[0];
  69. m->m[1] = f[1];
  70. m->m[2] = f[2];
  71. m->m[3] = f[3];
  72. m->m[4] = f[4];
  73. m->m[5] = f[5];
  74. m->m[6] = f[6];
  75. m->m[7] = f[7];
  76. m->m[8] = f[8];
  77. }
  78. extern void __attribute__((overloadable))
  79. rsMatrixLoad(rs_matrix2x2 *m, const float *f) {
  80. m->m[0] = f[0];
  81. m->m[1] = f[1];
  82. m->m[2] = f[2];
  83. m->m[3] = f[3];
  84. }
  85. extern void __attribute__((overloadable))
  86. rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix4x4 *s) {
  87. m->m[0] = s->m[0];
  88. m->m[1] = s->m[1];
  89. m->m[2] = s->m[2];
  90. m->m[3] = s->m[3];
  91. m->m[4] = s->m[4];
  92. m->m[5] = s->m[5];
  93. m->m[6] = s->m[6];
  94. m->m[7] = s->m[7];
  95. m->m[8] = s->m[8];
  96. m->m[9] = s->m[9];
  97. m->m[10] = s->m[10];
  98. m->m[11] = s->m[11];
  99. m->m[12] = s->m[12];
  100. m->m[13] = s->m[13];
  101. m->m[14] = s->m[14];
  102. m->m[15] = s->m[15];
  103. }
  104. extern void __attribute__((overloadable))
  105. rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix3x3 *v) {
  106. m->m[0] = v->m[0];
  107. m->m[1] = v->m[1];
  108. m->m[2] = v->m[2];
  109. m->m[3] = 0.f;
  110. m->m[4] = v->m[3];
  111. m->m[5] = v->m[4];
  112. m->m[6] = v->m[5];
  113. m->m[7] = 0.f;
  114. m->m[8] = v->m[6];
  115. m->m[9] = v->m[7];
  116. m->m[10] = v->m[8];
  117. m->m[11] = 0.f;
  118. m->m[12] = 0.f;
  119. m->m[13] = 0.f;
  120. m->m[14] = 0.f;
  121. m->m[15] = 1.f;
  122. }
  123. extern void __attribute__((overloadable))
  124. rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix2x2 *v) {
  125. m->m[0] = v->m[0];
  126. m->m[1] = v->m[1];
  127. m->m[2] = 0.f;
  128. m->m[3] = 0.f;
  129. m->m[4] = v->m[2];
  130. m->m[5] = v->m[3];
  131. m->m[6] = 0.f;
  132. m->m[7] = 0.f;
  133. m->m[8] = 0.f;
  134. m->m[9] = 0.f;
  135. m->m[10] = 1.f;
  136. m->m[11] = 0.f;
  137. m->m[12] = 0.f;
  138. m->m[13] = 0.f;
  139. m->m[14] = 0.f;
  140. m->m[15] = 1.f;
  141. }
  142. extern void __attribute__((overloadable))
  143. rsMatrixLoad(rs_matrix3x3 *m, const rs_matrix3x3 *s) {
  144. m->m[0] = s->m[0];
  145. m->m[1] = s->m[1];
  146. m->m[2] = s->m[2];
  147. m->m[3] = s->m[3];
  148. m->m[4] = s->m[4];
  149. m->m[5] = s->m[5];
  150. m->m[6] = s->m[6];
  151. m->m[7] = s->m[7];
  152. m->m[8] = s->m[8];
  153. }
  154. extern void __attribute__((overloadable))
  155. rsMatrixLoad(rs_matrix2x2 *m, const rs_matrix2x2 *s) {
  156. m->m[0] = s->m[0];
  157. m->m[1] = s->m[1];
  158. m->m[2] = s->m[2];
  159. m->m[3] = s->m[3];
  160. }
  161. extern void __attribute__((overloadable))
  162. rsMatrixSet(rs_matrix4x4 *m, uint32_t col, uint32_t row, float v) {
  163. m->m[col * 4 + row] = v;
  164. }
  165. extern float __attribute__((overloadable))
  166. rsMatrixGet(const rs_matrix4x4 *m, uint32_t col, uint32_t row) {
  167. return m->m[col * 4 + row];
  168. }
  169. extern void __attribute__((overloadable))
  170. rsMatrixSet(rs_matrix3x3 *m, uint32_t col, uint32_t row, float v) {
  171. m->m[col * 3 + row] = v;
  172. }
  173. extern float __attribute__((overloadable))
  174. rsMatrixGet(const rs_matrix3x3 *m, uint32_t col, uint32_t row) {
  175. return m->m[col * 3 + row];
  176. }
  177. extern void __attribute__((overloadable))
  178. rsMatrixSet(rs_matrix2x2 *m, uint32_t col, uint32_t row, float v) {
  179. m->m[col * 2 + row] = v;
  180. }
  181. extern float __attribute__((overloadable))
  182. rsMatrixGet(const rs_matrix2x2 *m, uint32_t col, uint32_t row) {
  183. return m->m[col * 2 + row];
  184. }
  185. extern float2 __attribute__((overloadable))
  186. rsMatrixMultiply(const rs_matrix2x2 *m, float2 in) {
  187. float2 ret;
  188. ret.x = (m->m[0] * in.x) + (m->m[2] * in.y);
  189. ret.y = (m->m[1] * in.x) + (m->m[3] * in.y);
  190. return ret;
  191. }
  192. extern float2 __attribute__((overloadable))
  193. rsMatrixMultiply(rs_matrix2x2 *m, float2 in) {
  194. return rsMatrixMultiply((const rs_matrix2x2 *)m, in);
  195. }
  196. extern float4 __attribute__((overloadable))
  197. rsMatrixMultiply(rs_matrix4x4 *m, float4 in) {
  198. return rsMatrixMultiply((const rs_matrix4x4 *)m, in);
  199. }
  200. extern float4 __attribute__((overloadable))
  201. rsMatrixMultiply(rs_matrix4x4 *m, float3 in) {
  202. return rsMatrixMultiply((const rs_matrix4x4 *)m, in);
  203. }
  204. extern float4 __attribute__((overloadable))
  205. rsMatrixMultiply(rs_matrix4x4 *m, float2 in) {
  206. return rsMatrixMultiply((const rs_matrix4x4 *)m, in);
  207. }
  208. extern float3 __attribute__((overloadable))
  209. rsMatrixMultiply(rs_matrix3x3 *m, float3 in) {
  210. return rsMatrixMultiply((const rs_matrix3x3 *)m, in);
  211. }
  212. extern float3 __attribute__((overloadable))
  213. rsMatrixMultiply(rs_matrix3x3 *m, float2 in) {
  214. return rsMatrixMultiply((const rs_matrix3x3 *)m, in);
  215. }
  216. extern void __attribute__((overloadable))
  217. rsMatrixLoadMultiply(rs_matrix4x4 *ret, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) {
  218. // Use a temporary variable to support the case where one of the inputs
  219. // is also the destination, e.g. rsMatrixLoadMultiply(&left, &left, &right);
  220. rs_matrix4x4 result;
  221. for (int i=0 ; i<4 ; i++) {
  222. float ri0 = 0;
  223. float ri1 = 0;
  224. float ri2 = 0;
  225. float ri3 = 0;
  226. for (int j=0 ; j<4 ; j++) {
  227. const float rhs_ij = rsMatrixGet(rhs, i, j);
  228. ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij;
  229. ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij;
  230. ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij;
  231. ri3 += rsMatrixGet(lhs, j, 3) * rhs_ij;
  232. }
  233. rsMatrixSet(&result, i, 0, ri0);
  234. rsMatrixSet(&result, i, 1, ri1);
  235. rsMatrixSet(&result, i, 2, ri2);
  236. rsMatrixSet(&result, i, 3, ri3);
  237. }
  238. rsMatrixLoad(ret, &result);
  239. }
  240. extern void __attribute__((overloadable))
  241. rsMatrixMultiply(rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) {
  242. rsMatrixLoadMultiply(lhs, lhs, rhs);
  243. }
  244. extern void __attribute__((overloadable))
  245. rsMatrixLoadMultiply(rs_matrix3x3 *ret, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) {
  246. // Use a temporary variable to support the case where one of the inputs
  247. // is also the destination, e.g. rsMatrixLoadMultiply(&left, &left, &right);
  248. rs_matrix3x3 result;
  249. for (int i=0 ; i<3 ; i++) {
  250. float ri0 = 0;
  251. float ri1 = 0;
  252. float ri2 = 0;
  253. for (int j=0 ; j<3 ; j++) {
  254. const float rhs_ij = rsMatrixGet(rhs, i, j);
  255. ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij;
  256. ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij;
  257. ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij;
  258. }
  259. rsMatrixSet(&result, i, 0, ri0);
  260. rsMatrixSet(&result, i, 1, ri1);
  261. rsMatrixSet(&result, i, 2, ri2);
  262. }
  263. rsMatrixLoad(ret, &result);
  264. }
  265. extern void __attribute__((overloadable))
  266. rsMatrixMultiply(rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) {
  267. rsMatrixLoadMultiply(lhs, lhs, rhs);
  268. }
  269. extern void __attribute__((overloadable))
  270. rsMatrixLoadMultiply(rs_matrix2x2 *ret, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) {
  271. // Use a temporary variable to support the case where one of the inputs
  272. // is also the destination, e.g. rsMatrixLoadMultiply(&left, &left, &right);
  273. rs_matrix2x2 result;
  274. for (int i=0 ; i<2 ; i++) {
  275. float ri0 = 0;
  276. float ri1 = 0;
  277. for (int j=0 ; j<2 ; j++) {
  278. const float rhs_ij = rsMatrixGet(rhs, i, j);
  279. ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij;
  280. ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij;
  281. }
  282. rsMatrixSet(&result, i, 0, ri0);
  283. rsMatrixSet(&result, i, 1, ri1);
  284. }
  285. rsMatrixLoad(ret, &result);
  286. }
  287. extern void __attribute__((overloadable))
  288. rsMatrixMultiply(rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) {
  289. rsMatrixLoadMultiply(lhs, lhs, rhs);
  290. }
  291. extern void __attribute__((overloadable))
  292. rsExtractFrustumPlanes(const rs_matrix4x4* viewProj, float4* left, float4* right, float4* top,
  293. float4* bottom, float4* near, float4* far) {
  294. // x y z w = a b c d in the plane equation
  295. left->x = viewProj->m[3] + viewProj->m[0];
  296. left->y = viewProj->m[7] + viewProj->m[4];
  297. left->z = viewProj->m[11] + viewProj->m[8];
  298. left->w = viewProj->m[15] + viewProj->m[12];
  299. right->x = viewProj->m[3] - viewProj->m[0];
  300. right->y = viewProj->m[7] - viewProj->m[4];
  301. right->z = viewProj->m[11] - viewProj->m[8];
  302. right->w = viewProj->m[15] - viewProj->m[12];
  303. top->x = viewProj->m[3] - viewProj->m[1];
  304. top->y = viewProj->m[7] - viewProj->m[5];
  305. top->z = viewProj->m[11] - viewProj->m[9];
  306. top->w = viewProj->m[15] - viewProj->m[13];
  307. bottom->x = viewProj->m[3] + viewProj->m[1];
  308. bottom->y = viewProj->m[7] + viewProj->m[5];
  309. bottom->z = viewProj->m[11] + viewProj->m[9];
  310. bottom->w = viewProj->m[15] + viewProj->m[13];
  311. near->x = viewProj->m[3] + viewProj->m[2];
  312. near->y = viewProj->m[7] + viewProj->m[6];
  313. near->z = viewProj->m[11] + viewProj->m[10];
  314. near->w = viewProj->m[15] + viewProj->m[14];
  315. far->x = viewProj->m[3] - viewProj->m[2];
  316. far->y = viewProj->m[7] - viewProj->m[6];
  317. far->z = viewProj->m[11] - viewProj->m[10];
  318. far->w = viewProj->m[15] - viewProj->m[14];
  319. float len = length(left->xyz);
  320. *left /= len;
  321. len = length(right->xyz);
  322. *right /= len;
  323. len = length(top->xyz);
  324. *top /= len;
  325. len = length(bottom->xyz);
  326. *bottom /= len;
  327. len = length(near->xyz);
  328. *near /= len;
  329. len = length(far->xyz);
  330. *far /= len;
  331. }
  332. extern bool __attribute__((overloadable))
  333. rsIsSphereInFrustum(float4* sphere, float4* left, float4* right, float4* top, float4* bottom,
  334. float4* near, float4* far) {
  335. float distToCenter = dot(left->xyz, sphere->xyz) + left->w;
  336. if (distToCenter < -sphere->w) {
  337. return false;
  338. }
  339. distToCenter = dot(right->xyz, sphere->xyz) + right->w;
  340. if (distToCenter < -sphere->w) {
  341. return false;
  342. }
  343. distToCenter = dot(top->xyz, sphere->xyz) + top->w;
  344. if (distToCenter < -sphere->w) {
  345. return false;
  346. }
  347. distToCenter = dot(bottom->xyz, sphere->xyz) + bottom->w;
  348. if (distToCenter < -sphere->w) {
  349. return false;
  350. }
  351. distToCenter = dot(near->xyz, sphere->xyz) + near->w;
  352. if (distToCenter < -sphere->w) {
  353. return false;
  354. }
  355. distToCenter = dot(far->xyz, sphere->xyz) + far->w;
  356. if (distToCenter < -sphere->w) {
  357. return false;
  358. }
  359. return true;
  360. }