vmath.c 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423
  1. #include "pocketpy/vmath.h"
  2. #include "pocketpy/pocketpy.h"
  3. #include "pocketpy/common/sstream.h"
  4. #include "pocketpy/common/utils.h"
  5. #include "pocketpy/common/dmath.h"
  6. #include "pocketpy/interpreter/vm.h"
  7. static bool isclose(float a, float b) { return dmath_fabs(a - b) < 1e-4; }
  8. py_i64 cpy312__int_floordiv(py_i64 a, py_i64 b);
  9. py_i64 cpy312__int_mod(py_i64 a, py_i64 b);
  10. #define DEFINE_VEC_FIELD(name, T, Tc, field) \
  11. static bool name##__##field(int argc, py_Ref argv) { \
  12. PY_CHECK_ARGC(1); \
  13. py_new##T(py_retval(), py_to##name(argv).field); \
  14. return true; \
  15. } \
  16. static bool name##__with_##field(int argc, py_Ref argv) { \
  17. PY_CHECK_ARGC(2); \
  18. Tc val; \
  19. if(!py_cast##T(&argv[1], &val)) return false; \
  20. c11_##name v = py_to##name(argv); \
  21. v.field = val; \
  22. py_new##name(py_retval(), v); \
  23. return true; \
  24. }
  25. #define DEFINE_BOOL_NE(name, f_eq) \
  26. static bool name##__ne__(int argc, py_Ref argv) { \
  27. f_eq(argc, argv); \
  28. py_Ref ret = py_retval(); \
  29. if(ret->type == tp_NotImplementedType) return true; \
  30. ret->_bool = !ret->_bool; \
  31. return true; \
  32. }
  33. void py_newvec2(py_OutRef out, c11_vec2 v) {
  34. out->type = tp_vec2;
  35. out->is_ptr = false;
  36. out->_vec2 = v;
  37. }
  38. c11_vec2 py_tovec2(py_Ref self) {
  39. assert(self->type == tp_vec2);
  40. return self->_vec2;
  41. }
  42. void py_newvec2i(py_OutRef out, c11_vec2i v) {
  43. out->type = tp_vec2i;
  44. out->is_ptr = false;
  45. out->_vec2i = v;
  46. }
  47. c11_vec2i py_tovec2i(py_Ref self) {
  48. assert(self->type == tp_vec2i);
  49. return self->_vec2i;
  50. }
  51. void py_newvec3(py_OutRef out, c11_vec3 v) {
  52. out->type = tp_vec3;
  53. out->is_ptr = false;
  54. out->_vec3 = v;
  55. }
  56. c11_vec3 py_tovec3(py_Ref self) {
  57. assert(self->type == tp_vec3);
  58. return self->_vec3;
  59. }
  60. void py_newvec3i(py_OutRef out, c11_vec3i v) {
  61. out->type = tp_vec3i;
  62. out->is_ptr = false;
  63. out->_vec3i = v;
  64. }
  65. c11_vec3i py_tovec3i(py_Ref self) {
  66. assert(self->type == tp_vec3i);
  67. return self->_vec3i;
  68. }
  69. void py_newvec4i(py_OutRef out, c11_vec4i v) {
  70. out->type = tp_vec4i;
  71. out->is_ptr = false;
  72. out->_vec4i = v;
  73. }
  74. c11_vec4i py_tovec4i(py_Ref self) {
  75. assert(self->type == tp_vec4i);
  76. return self->_vec4i;
  77. }
  78. c11_mat3x3* py_newmat3x3(py_OutRef out) {
  79. return py_newobject(out, tp_mat3x3, 0, sizeof(c11_mat3x3));
  80. }
  81. c11_mat3x3* py_tomat3x3(py_Ref self) {
  82. assert(self->type == tp_mat3x3);
  83. return py_touserdata(self);
  84. }
  85. static py_Ref _const(py_Type type, const char* name) {
  86. return py_emplacedict(py_tpobject(type), py_name(name));
  87. }
  88. #define DEF_VECTOR_ELEMENT_WISE(D, T, name, op) \
  89. static bool T##name(int argc, py_Ref argv) { \
  90. PY_CHECK_ARGC(2); \
  91. if(argv[1].type != tp_##T) { \
  92. py_newnotimplemented(py_retval()); \
  93. return true; \
  94. } \
  95. c11_##T a = py_to##T(&argv[0]); \
  96. c11_##T b = py_to##T(&argv[1]); \
  97. c11_##T res; \
  98. for(int i = 0; i < D; i++) \
  99. res.data[i] = a.data[i] op b.data[i]; \
  100. py_new##T(py_retval(), res); \
  101. return true; \
  102. }
  103. #define DEF_VECTOR_OPS(D) \
  104. static bool vec##D##__new__(int argc, py_Ref argv) { \
  105. c11_vec##D res; \
  106. if(argc == 2) { \
  107. PY_CHECK_ARG_TYPE(1, tp_vec##D##i); \
  108. c11_vec##D##i v = py_tovec##D##i(&argv[1]); \
  109. for(int i = 0; i < D; i++) \
  110. res.data[i] = v.data[i]; \
  111. } else { \
  112. PY_CHECK_ARGC(D + 1); \
  113. for(int i = 0; i < D; i++) { \
  114. if(!py_castfloat32(&argv[i + 1], &res.data[i])) return false; \
  115. } \
  116. } \
  117. py_newvec##D(py_retval(), res); \
  118. return true; \
  119. } \
  120. DEF_VECTOR_ELEMENT_WISE(D, vec##D, __add__, +) \
  121. DEF_VECTOR_ELEMENT_WISE(D, vec##D, __sub__, -) \
  122. static bool vec##D##__mul__(int argc, py_Ref argv) { \
  123. PY_CHECK_ARGC(2); \
  124. c11_vec##D res; \
  125. switch(argv[1].type) { \
  126. case tp_vec##D: { \
  127. c11_vec##D a = py_tovec##D(&argv[0]); \
  128. c11_vec##D b = py_tovec##D(&argv[1]); \
  129. for(int i = 0; i < D; i++) \
  130. res.data[i] = a.data[i] * b.data[i]; \
  131. py_newvec##D(py_retval(), res); \
  132. return true; \
  133. } \
  134. case tp_int: { \
  135. c11_vec##D a = py_tovec##D(&argv[0]); \
  136. py_i64 b = argv[1]._i64; \
  137. for(int i = 0; i < D; i++) \
  138. res.data[i] = a.data[i] * b; \
  139. py_newvec##D(py_retval(), res); \
  140. return true; \
  141. } \
  142. case tp_float: { \
  143. c11_vec##D a = py_tovec##D(&argv[0]); \
  144. py_f64 b = argv[1]._f64; \
  145. for(int i = 0; i < D; i++) \
  146. res.data[i] = a.data[i] * b; \
  147. py_newvec##D(py_retval(), res); \
  148. return true; \
  149. } \
  150. default: py_newnotimplemented(py_retval()); return true; \
  151. } \
  152. } \
  153. static bool vec##D##__truediv__(int argc, py_Ref argv) { \
  154. PY_CHECK_ARGC(2); \
  155. float divisor; \
  156. if(!py_castfloat32(&argv[1], &divisor)) { \
  157. py_clearexc(NULL); \
  158. py_newnotimplemented(py_retval()); \
  159. return true; \
  160. } \
  161. c11_vec##D res; \
  162. c11_vec##D a = py_tovec##D(&argv[0]); \
  163. for(int i = 0; i < D; i++) \
  164. res.data[i] = a.data[i] / divisor; \
  165. py_newvec##D(py_retval(), res); \
  166. return true; \
  167. } \
  168. static bool vec##D##__eq__(int argc, py_Ref argv) { \
  169. PY_CHECK_ARGC(2); \
  170. if(argv[1].type != tp_vec##D) { \
  171. py_newnotimplemented(py_retval()); \
  172. return true; \
  173. } \
  174. c11_vec##D lhs = py_tovec##D(&argv[0]); \
  175. c11_vec##D rhs = py_tovec##D(&argv[1]); \
  176. bool ok = true; \
  177. for(int i = 0; i < D; i++) { \
  178. if(!isclose(lhs.data[i], rhs.data[i])) ok = false; \
  179. } \
  180. py_newbool(py_retval(), ok); \
  181. return true; \
  182. } \
  183. DEFINE_BOOL_NE(vec##D, vec##D##__eq__) \
  184. static bool vec##D##_length(int argc, py_Ref argv) { \
  185. PY_CHECK_ARGC(1); \
  186. c11_vec##D v = py_tovec##D(argv); \
  187. float sum = 0; \
  188. for(int i = 0; i < D; i++) \
  189. sum += v.data[i] * v.data[i]; \
  190. py_newfloat(py_retval(), dmath_sqrt(sum)); \
  191. return true; \
  192. } \
  193. static bool vec##D##_length_squared(int argc, py_Ref argv) { \
  194. PY_CHECK_ARGC(1); \
  195. c11_vec##D v = py_tovec##D(argv); \
  196. float sum = 0; \
  197. for(int i = 0; i < D; i++) \
  198. sum += v.data[i] * v.data[i]; \
  199. py_newfloat(py_retval(), sum); \
  200. return true; \
  201. } \
  202. static bool vec##D##_dot(int argc, py_Ref argv) { \
  203. PY_CHECK_ARGC(2); \
  204. PY_CHECK_ARG_TYPE(1, tp_vec##D); \
  205. c11_vec##D a = py_tovec##D(&argv[0]); \
  206. c11_vec##D b = py_tovec##D(&argv[1]); \
  207. float sum = 0; \
  208. for(int i = 0; i < D; i++) \
  209. sum += a.data[i] * b.data[i]; \
  210. py_newfloat(py_retval(), sum); \
  211. return true; \
  212. } \
  213. static bool vec##D##_normalize(int argc, py_Ref argv) { \
  214. PY_CHECK_ARGC(1); \
  215. c11_vec##D self = py_tovec##D(argv); \
  216. float len = 0; \
  217. for(int i = 0; i < D; i++) \
  218. len += self.data[i] * self.data[i]; \
  219. if(isclose(len, 0)) return ZeroDivisionError("cannot normalize zero vector"); \
  220. len = dmath_sqrt(len); \
  221. c11_vec##D res; \
  222. for(int i = 0; i < D; i++) \
  223. res.data[i] = self.data[i] / len; \
  224. py_newvec##D(py_retval(), res); \
  225. return true; \
  226. }
  227. DEF_VECTOR_OPS(2)
  228. DEF_VECTOR_OPS(3)
  229. #define DEF_VECTOR_INT_OPS(D) \
  230. static bool vec##D##i__new__(int argc, py_Ref argv) { \
  231. PY_CHECK_ARGC(D + 1); \
  232. c11_vec##D##i res; \
  233. for(int i = 0; i < D; i++) { \
  234. if(!py_checkint(&argv[i + 1])) return false; \
  235. res.data[i] = py_toint(&argv[i + 1]); \
  236. } \
  237. py_newvec##D##i(py_retval(), res); \
  238. return true; \
  239. } \
  240. DEF_VECTOR_ELEMENT_WISE(D, vec##D##i, __add__, +) \
  241. DEF_VECTOR_ELEMENT_WISE(D, vec##D##i, __sub__, -) \
  242. static bool vec##D##i__mul__(int argc, py_Ref argv) { \
  243. PY_CHECK_ARGC(2); \
  244. c11_vec##D##i res; \
  245. switch(argv[1].type) { \
  246. case tp_vec##D##i: { \
  247. c11_vec##D##i a = py_tovec##D##i(&argv[0]); \
  248. c11_vec##D##i b = py_tovec##D##i(&argv[1]); \
  249. for(int i = 0; i < D; i++) \
  250. res.data[i] = a.data[i] * b.data[i]; \
  251. py_newvec##D##i(py_retval(), res); \
  252. return true; \
  253. } \
  254. case tp_int: { \
  255. c11_vec##D##i a = py_tovec##D##i(&argv[0]); \
  256. py_i64 b = argv[1]._i64; \
  257. for(int i = 0; i < D; i++) \
  258. res.data[i] = a.data[i] * b; \
  259. py_newvec##D##i(py_retval(), res); \
  260. return true; \
  261. } \
  262. default: py_newnotimplemented(py_retval()); return true; \
  263. } \
  264. } \
  265. static bool vec##D##i__eq__(int argc, py_Ref argv) { \
  266. PY_CHECK_ARGC(2); \
  267. if(argv[1].type != tp_vec##D##i) { \
  268. py_newnotimplemented(py_retval()); \
  269. return true; \
  270. } \
  271. c11_vec##D##i lhs = py_tovec##D##i(&argv[0]); \
  272. c11_vec##D##i rhs = py_tovec##D##i(&argv[1]); \
  273. bool ok = true; \
  274. for(int i = 0; i < D; i++) { \
  275. if(lhs.data[i] != rhs.data[i]) ok = false; \
  276. } \
  277. py_newbool(py_retval(), ok); \
  278. return true; \
  279. } \
  280. DEFINE_BOOL_NE(vec##D##i, vec##D##i__eq__) \
  281. static bool vec##D##i##_dot(int argc, py_Ref argv) { \
  282. PY_CHECK_ARGC(2); \
  283. PY_CHECK_ARG_TYPE(1, tp_vec##D##i); \
  284. c11_vec##D##i a = py_tovec##D##i(&argv[0]); \
  285. c11_vec##D##i b = py_tovec##D##i(&argv[1]); \
  286. py_i64 sum = 0; \
  287. for(int i = 0; i < D; i++) \
  288. sum += a.data[i] * b.data[i]; \
  289. py_newint(py_retval(), sum); \
  290. return true; \
  291. } \
  292. static bool vec##D##i##__floordiv__(int argc, py_Ref argv) { \
  293. PY_CHECK_ARGC(2); \
  294. PY_CHECK_ARG_TYPE(1, tp_int); \
  295. c11_vec##D##i a = py_tovec##D##i(&argv[0]); \
  296. py_i64 b = py_toint(&argv[1]); \
  297. for(int i = 0; i < D; i++) \
  298. a.data[i] = cpy312__int_floordiv(a.data[i], b); \
  299. py_newvec##D##i(py_retval(), a); \
  300. return true; \
  301. } \
  302. static bool vec##D##i##__mod__(int argc, py_Ref argv) { \
  303. PY_CHECK_ARGC(2); \
  304. PY_CHECK_ARG_TYPE(1, tp_int); \
  305. c11_vec##D##i a = py_tovec##D##i(&argv[0]); \
  306. py_i64 b = py_toint(&argv[1]); \
  307. for(int i = 0; i < D; i++) \
  308. a.data[i] = cpy312__int_mod(a.data[i], b); \
  309. py_newvec##D##i(py_retval(), a); \
  310. return true; \
  311. }
  312. DEF_VECTOR_INT_OPS(2)
  313. DEF_VECTOR_INT_OPS(3)
  314. DEF_VECTOR_INT_OPS(4)
  315. // vec2i l1_norm, l2_norm, max_norm
  316. static bool vec2i_l1_norm(int argc, py_Ref argv) {
  317. PY_CHECK_ARGC(1);
  318. c11_vec2i v = py_tovec2i(argv);
  319. int norm = abs(v.x) + abs(v.y);
  320. py_newint(py_retval(), norm);
  321. return true;
  322. }
  323. static bool vec2i_l2_norm(int argc, py_Ref argv) {
  324. PY_CHECK_ARGC(1);
  325. c11_vec2i v = py_tovec2i(argv);
  326. double norm = dmath_sqrt(v.x * v.x + v.y * v.y);
  327. py_newfloat(py_retval(), norm);
  328. return true;
  329. }
  330. static bool vec2i_max_norm(int argc, py_Ref argv) {
  331. PY_CHECK_ARGC(1);
  332. c11_vec2i v = py_tovec2i(argv);
  333. int norm = c11__max(abs(v.x), abs(v.y));
  334. py_newint(py_retval(), norm);
  335. return true;
  336. }
  337. static bool vec2i__hash__(int argc, py_Ref argv) {
  338. PY_CHECK_ARGC(1);
  339. c11_vec2i v = py_tovec2i(argv);
  340. uint64_t x_part = (uint32_t)v.x & 0xFFFFFFFF;
  341. uint64_t y_part = (uint32_t)v.y & 0xFFFFFFFF;
  342. uint64_t hash = (x_part << 32) | y_part;
  343. py_newint(py_retval(), (py_i64)hash);
  344. return true;
  345. }
  346. static bool vec3i__hash__(int argc, py_Ref argv) {
  347. PY_CHECK_ARGC(1);
  348. c11_vec3i v = py_tovec3i(argv);
  349. uint64_t x_part = (uint32_t)v.x & 0xFFFFFF;
  350. uint64_t y_part = (uint32_t)v.y & 0xFFFFFF;
  351. uint64_t z_part = (uint32_t)v.z & 0xFFFF;
  352. uint64_t hash = (x_part << 40) | (y_part << 16) | z_part;
  353. py_newint(py_retval(), (py_i64)hash);
  354. return true;
  355. }
  356. static bool vec4i__hash__(int argc, py_Ref argv) {
  357. PY_CHECK_ARGC(1);
  358. c11_vec4i v = py_tovec4i(argv);
  359. uint64_t x_part = (uint32_t)v.x & 0xFFFF;
  360. uint64_t y_part = (uint32_t)v.y & 0xFFFF;
  361. uint64_t z_part = (uint32_t)v.z & 0xFFFF;
  362. uint64_t w_part = (uint32_t)v.w & 0xFFFF;
  363. uint64_t hash = (x_part << 48) | (y_part << 32) | (z_part << 16) | w_part;
  364. py_newint(py_retval(), (py_i64)hash);
  365. return true;
  366. }
  367. static bool vec2__repr__(int argc, py_Ref argv) {
  368. PY_CHECK_ARGC(1);
  369. char buf[64];
  370. int size = snprintf(buf, 64, "vec2(%.4f, %.4f)", argv[0]._vec2.x, argv[0]._vec2.y);
  371. py_newstrv(py_retval(), (c11_sv){buf, size});
  372. return true;
  373. }
  374. static bool vec2_rotate(int argc, py_Ref argv) {
  375. PY_CHECK_ARGC(2);
  376. py_f64 radians;
  377. if(!py_castfloat(&argv[1], &radians)) return false;
  378. double sr, cr;
  379. dmath_sincos(radians, &sr, &cr);
  380. c11_vec2 res;
  381. res.x = argv[0]._vec2.x * cr - argv[0]._vec2.y * sr;
  382. res.y = argv[0]._vec2.x * sr + argv[0]._vec2.y * cr;
  383. py_newvec2(py_retval(), res);
  384. return true;
  385. }
  386. static bool vec2_angle_STATIC(int argc, py_Ref argv) {
  387. PY_CHECK_ARGC(2);
  388. PY_CHECK_ARG_TYPE(0, tp_vec2);
  389. PY_CHECK_ARG_TYPE(1, tp_vec2);
  390. float val = dmath_atan2(argv[1]._vec2.y, argv[1]._vec2.x) -
  391. dmath_atan2(argv[0]._vec2.y, argv[0]._vec2.x);
  392. if(val > DMATH_PI) val -= 2 * (float)DMATH_PI;
  393. if(val < -DMATH_PI) val += 2 * (float)DMATH_PI;
  394. py_newfloat(py_retval(), val);
  395. return true;
  396. }
  397. static bool vec2_smoothdamp_STATIC(int argc, py_Ref argv) {
  398. PY_CHECK_ARGC(6);
  399. PY_CHECK_ARG_TYPE(0, tp_vec2); // current: vec2
  400. PY_CHECK_ARG_TYPE(1, tp_vec2); // target: vec2
  401. PY_CHECK_ARG_TYPE(2, tp_vec2); // current_velocity: vec2
  402. float smoothTime;
  403. if(!py_castfloat32(&argv[3], &smoothTime)) return false;
  404. float maxSpeed;
  405. if(!py_castfloat32(&argv[4], &maxSpeed)) return false;
  406. float deltaTime;
  407. if(!py_castfloat32(&argv[5], &deltaTime)) return false;
  408. c11_vec2 current = argv[0]._vec2;
  409. c11_vec2 target = argv[1]._vec2;
  410. c11_vec2 currentVelocity = argv[2]._vec2;
  411. // https://github.com/Unity-Technologies/UnityCsReference/blob/master/Runtime/Export/Math/Vector2.cs#L289
  412. // Based on Game Programming Gems 4 Chapter 1.10
  413. smoothTime = c11__max(0.0001F, smoothTime);
  414. float omega = 2.0F / smoothTime;
  415. float x = omega * deltaTime;
  416. float exp = 1.0F / (1.0F + x + 0.48F * x * x + 0.235F * x * x * x);
  417. float change_x = current.x - target.x;
  418. float change_y = current.y - target.y;
  419. c11_vec2 originalTo = target;
  420. // Clamp maximum speed
  421. float maxChange = maxSpeed * smoothTime;
  422. float maxChangeSq = maxChange * maxChange;
  423. float sqDist = change_x * change_x + change_y * change_y;
  424. if(sqDist > maxChangeSq) {
  425. float mag = dmath_sqrt(sqDist);
  426. change_x = change_x / mag * maxChange;
  427. change_y = change_y / mag * maxChange;
  428. }
  429. target.x = current.x - change_x;
  430. target.y = current.y - change_y;
  431. float temp_x = (currentVelocity.x + omega * change_x) * deltaTime;
  432. float temp_y = (currentVelocity.y + omega * change_y) * deltaTime;
  433. currentVelocity.x = (currentVelocity.x - omega * temp_x) * exp;
  434. currentVelocity.y = (currentVelocity.y - omega * temp_y) * exp;
  435. float output_x = target.x + (change_x + temp_x) * exp;
  436. float output_y = target.y + (change_y + temp_y) * exp;
  437. // Prevent overshooting
  438. float origMinusCurrent_x = originalTo.x - current.x;
  439. float origMinusCurrent_y = originalTo.y - current.y;
  440. float outMinusOrig_x = output_x - originalTo.x;
  441. float outMinusOrig_y = output_y - originalTo.y;
  442. if(origMinusCurrent_x * outMinusOrig_x + origMinusCurrent_y * outMinusOrig_y > 0) {
  443. output_x = originalTo.x;
  444. output_y = originalTo.y;
  445. currentVelocity.x = (output_x - originalTo.x) / deltaTime;
  446. currentVelocity.y = (output_y - originalTo.y) / deltaTime;
  447. }
  448. py_Ref ret = py_retval();
  449. py_Ref p = py_newtuple(ret, 2);
  450. py_newvec2(&p[0],
  451. (c11_vec2){
  452. {output_x, output_y}
  453. });
  454. py_newvec2(&p[1], currentVelocity);
  455. return true;
  456. }
  457. DEFINE_VEC_FIELD(vec2, float, py_f64, x)
  458. DEFINE_VEC_FIELD(vec2, float, py_f64, y)
  459. static bool vec2__with_z(int argc, py_Ref argv) {
  460. PY_CHECK_ARGC(2);
  461. float z;
  462. if(!py_castfloat32(&argv[1], &z)) return false;
  463. c11_vec3 v = {
  464. {argv->_vec2.x, argv->_vec2.y, z}
  465. };
  466. py_newvec3(py_retval(), v);
  467. return true;
  468. }
  469. /* mat3x3 */
  470. static bool mat3x3__new__(int argc, py_Ref argv) {
  471. PY_CHECK_ARGC(10);
  472. c11_mat3x3* m = py_newmat3x3(py_retval());
  473. for(int i = 0; i < 9; i++) {
  474. py_f64 val;
  475. if(!py_castfloat(&argv[i + 1], &val)) return false;
  476. m->data[i] = val;
  477. }
  478. return true;
  479. }
  480. static bool mat3x3__repr__(int argc, py_Ref argv) {
  481. PY_CHECK_ARGC(1);
  482. c11_mat3x3* m = py_tomat3x3(argv);
  483. char buf[256];
  484. const char* fmt =
  485. "mat3x3(%.4f, %.4f, %.4f,\n %.4f, %.4f, %.4f,\n "
  486. " %.4f, %.4f, %.4f)";
  487. int size = snprintf(buf,
  488. 256,
  489. fmt,
  490. m->data[0],
  491. m->data[1],
  492. m->data[2],
  493. m->data[3],
  494. m->data[4],
  495. m->data[5],
  496. m->data[6],
  497. m->data[7],
  498. m->data[8]);
  499. py_newstrv(py_retval(), (c11_sv){buf, size});
  500. return true;
  501. }
  502. static bool mat3x3__getitem__(int argc, py_Ref argv) {
  503. PY_CHECK_ARGC(2);
  504. PY_CHECK_ARG_TYPE(1, tp_tuple);
  505. c11_mat3x3* ud = py_tomat3x3(argv);
  506. if(py_tuple_len(&argv[1]) != 2) return IndexError("expected a tuple of length 2");
  507. py_Ref i = py_tuple_getitem(&argv[1], 0);
  508. py_Ref j = py_tuple_getitem(&argv[1], 1);
  509. if(!py_checktype(i, tp_int) || !py_checktype(j, tp_int)) return false;
  510. if(i->_i64 < 0 || i->_i64 >= 3 || j->_i64 < 0 || j->_i64 >= 3) {
  511. return IndexError("index out of range");
  512. }
  513. py_newfloat(py_retval(), ud->m[i->_i64][j->_i64]);
  514. return true;
  515. }
  516. static bool mat3x3__setitem__(int argc, py_Ref argv) {
  517. PY_CHECK_ARGC(3);
  518. PY_CHECK_ARG_TYPE(1, tp_tuple);
  519. c11_mat3x3* ud = py_tomat3x3(argv);
  520. if(py_tuple_len(&argv[1]) != 2) return IndexError("expected a tuple of length 2");
  521. py_Ref i = py_tuple_getitem(&argv[1], 0);
  522. py_Ref j = py_tuple_getitem(&argv[1], 1);
  523. if(!py_checktype(i, tp_int) || !py_checktype(j, tp_int)) return false;
  524. py_f64 val;
  525. if(!py_castfloat(&argv[2], &val)) return false;
  526. if(i->_i64 < 0 || i->_i64 >= 3 || j->_i64 < 0 || j->_i64 >= 3) {
  527. return IndexError("index out of range");
  528. }
  529. ud->m[i->_i64][j->_i64] = val;
  530. py_newnone(py_retval());
  531. return true;
  532. }
  533. static bool mat3x3__eq__(int argc, py_Ref argv) {
  534. PY_CHECK_ARGC(2);
  535. if(argv[1].type != tp_mat3x3) {
  536. py_newnotimplemented(py_retval());
  537. return true;
  538. }
  539. c11_mat3x3* lhs = py_tomat3x3(argv);
  540. c11_mat3x3* rhs = py_tomat3x3(&argv[1]);
  541. for(int i = 0; i < 9; i++) {
  542. if(!isclose(lhs->data[i], rhs->data[i])) {
  543. py_newbool(py_retval(), false);
  544. return true;
  545. }
  546. }
  547. py_newbool(py_retval(), true);
  548. return true;
  549. }
  550. DEFINE_BOOL_NE(mat3x3, mat3x3__eq__)
  551. static void matmul(const c11_mat3x3* lhs, const c11_mat3x3* rhs, c11_mat3x3* restrict out) {
  552. out->_11 = lhs->_11 * rhs->_11 + lhs->_12 * rhs->_21 + lhs->_13 * rhs->_31;
  553. out->_12 = lhs->_11 * rhs->_12 + lhs->_12 * rhs->_22 + lhs->_13 * rhs->_32;
  554. out->_13 = lhs->_11 * rhs->_13 + lhs->_12 * rhs->_23 + lhs->_13 * rhs->_33;
  555. out->_21 = lhs->_21 * rhs->_11 + lhs->_22 * rhs->_21 + lhs->_23 * rhs->_31;
  556. out->_22 = lhs->_21 * rhs->_12 + lhs->_22 * rhs->_22 + lhs->_23 * rhs->_32;
  557. out->_23 = lhs->_21 * rhs->_13 + lhs->_22 * rhs->_23 + lhs->_23 * rhs->_33;
  558. out->_31 = lhs->_31 * rhs->_11 + lhs->_32 * rhs->_21 + lhs->_33 * rhs->_31;
  559. out->_32 = lhs->_31 * rhs->_12 + lhs->_32 * rhs->_22 + lhs->_33 * rhs->_32;
  560. out->_33 = lhs->_31 * rhs->_13 + lhs->_32 * rhs->_23 + lhs->_33 * rhs->_33;
  561. }
  562. static float determinant(const c11_mat3x3* m) {
  563. return m->_11 * (m->_22 * m->_33 - m->_23 * m->_32) -
  564. m->_12 * (m->_21 * m->_33 - m->_23 * m->_31) +
  565. m->_13 * (m->_21 * m->_32 - m->_22 * m->_31);
  566. }
  567. static bool inverse(const c11_mat3x3* m, c11_mat3x3* restrict out) {
  568. float det = determinant(m);
  569. if(isclose(det, 0)) return false;
  570. float invdet = 1.0f / det;
  571. out->_11 = (m->_22 * m->_33 - m->_23 * m->_32) * invdet;
  572. out->_12 = (m->_13 * m->_32 - m->_12 * m->_33) * invdet;
  573. out->_13 = (m->_12 * m->_23 - m->_13 * m->_22) * invdet;
  574. out->_21 = (m->_23 * m->_31 - m->_21 * m->_33) * invdet;
  575. out->_22 = (m->_11 * m->_33 - m->_13 * m->_31) * invdet;
  576. out->_23 = (m->_13 * m->_21 - m->_11 * m->_23) * invdet;
  577. out->_31 = (m->_21 * m->_32 - m->_22 * m->_31) * invdet;
  578. out->_32 = (m->_12 * m->_31 - m->_11 * m->_32) * invdet;
  579. out->_33 = (m->_11 * m->_22 - m->_12 * m->_21) * invdet;
  580. return true;
  581. }
  582. static void trs(c11_vec2 t, float r, c11_vec2 s, c11_mat3x3* restrict out) {
  583. double sr, cr;
  584. dmath_sincos(r, &sr, &cr);
  585. // clang-format off
  586. *out = (c11_mat3x3){
  587. ._11 = s.x * cr, ._12 = -s.y * sr, ._13 = t.x,
  588. ._21 = s.x * sr, ._22 = s.y * cr, ._23 = t.y,
  589. ._31 = 0, ._32 = 0, ._33 = 1,
  590. };
  591. // clang-format on
  592. }
  593. static bool mat3x3__matmul__(int argc, py_Ref argv) {
  594. PY_CHECK_ARGC(2);
  595. c11_mat3x3* lhs = py_tomat3x3(argv);
  596. if(argv[1].type == tp_mat3x3) {
  597. c11_mat3x3* rhs = py_tomat3x3(&argv[1]);
  598. c11_mat3x3* out = py_newmat3x3(py_retval());
  599. matmul(lhs, rhs, out);
  600. } else if(argv[1].type == tp_vec3) {
  601. c11_vec3 rhs = py_tovec3(&argv[1]);
  602. c11_vec3 res;
  603. res.x = lhs->_11 * rhs.x + lhs->_12 * rhs.y + lhs->_13 * rhs.z;
  604. res.y = lhs->_21 * rhs.x + lhs->_22 * rhs.y + lhs->_23 * rhs.z;
  605. res.z = lhs->_31 * rhs.x + lhs->_32 * rhs.y + lhs->_33 * rhs.z;
  606. py_newvec3(py_retval(), res);
  607. } else {
  608. py_newnotimplemented(py_retval());
  609. }
  610. return true;
  611. }
  612. static bool mat3x3__invert__(int argc, py_Ref argv) {
  613. PY_CHECK_ARGC(1);
  614. c11_mat3x3* ud = py_tomat3x3(argv);
  615. c11_mat3x3* out = py_newmat3x3(py_retval());
  616. if(inverse(ud, out)) return true;
  617. return ZeroDivisionError("matrix is not invertible");
  618. }
  619. static bool mat3x3_matmul(int argc, py_Ref argv) {
  620. PY_CHECK_ARGC(3);
  621. PY_CHECK_ARG_TYPE(0, tp_mat3x3);
  622. PY_CHECK_ARG_TYPE(1, tp_mat3x3);
  623. PY_CHECK_ARG_TYPE(2, tp_mat3x3);
  624. c11_mat3x3* lhs = py_tomat3x3(&argv[0]);
  625. c11_mat3x3* rhs = py_tomat3x3(&argv[1]);
  626. c11_mat3x3* out = py_tomat3x3(&argv[2]);
  627. matmul(lhs, rhs, out);
  628. py_newnone(py_retval());
  629. return true;
  630. }
  631. static bool mat3x3_determinant(int argc, py_Ref argv) {
  632. PY_CHECK_ARGC(1);
  633. c11_mat3x3* ud = py_tomat3x3(argv);
  634. py_newfloat(py_retval(), determinant(ud));
  635. return true;
  636. }
  637. static bool mat3x3_copy(int argc, py_Ref argv) {
  638. PY_CHECK_ARGC(1);
  639. c11_mat3x3* ud = py_tomat3x3(argv);
  640. c11_mat3x3* out = py_newmat3x3(py_retval());
  641. *out = *ud;
  642. return true;
  643. }
  644. static bool mat3x3_inverse(int argc, py_Ref argv) {
  645. PY_CHECK_ARGC(1);
  646. c11_mat3x3* ud = py_tomat3x3(argv);
  647. c11_mat3x3* out = py_newmat3x3(py_retval());
  648. if(inverse(ud, out)) return true;
  649. return ZeroDivisionError("matrix is not invertible");
  650. }
  651. static bool mat3x3_copy_(int argc, py_Ref argv) {
  652. PY_CHECK_ARGC(2);
  653. PY_CHECK_ARG_TYPE(1, tp_mat3x3);
  654. c11_mat3x3* self = py_tomat3x3(argv);
  655. c11_mat3x3* other = py_tomat3x3(&argv[1]);
  656. *self = *other;
  657. py_newnone(py_retval());
  658. return true;
  659. }
  660. static bool mat3x3_inverse_(int argc, py_Ref argv) {
  661. PY_CHECK_ARGC(1);
  662. c11_mat3x3* ud = py_tomat3x3(argv);
  663. c11_mat3x3 res;
  664. if(inverse(ud, &res)) {
  665. *ud = res;
  666. py_newnone(py_retval());
  667. return true;
  668. }
  669. return ZeroDivisionError("matrix is not invertible");
  670. }
  671. static bool mat3x3_zeros_STATIC(int argc, py_Ref argv) {
  672. PY_CHECK_ARGC(0);
  673. c11_mat3x3* out = py_newmat3x3(py_retval());
  674. memset(out, 0, sizeof(c11_mat3x3));
  675. return true;
  676. }
  677. static bool mat3x3_identity_STATIC(int argc, py_Ref argv) {
  678. PY_CHECK_ARGC(0);
  679. c11_mat3x3* out = py_newmat3x3(py_retval());
  680. // clang-format off
  681. *out = (c11_mat3x3){
  682. ._11 = 1, ._12 = 0, ._13 = 0,
  683. ._21 = 0, ._22 = 1, ._23 = 0,
  684. ._31 = 0, ._32 = 0, ._33 = 1,
  685. };
  686. // clang-format on
  687. return true;
  688. }
  689. static bool mat3x3_trs_STATIC(int argc, py_Ref argv) {
  690. PY_CHECK_ARGC(3);
  691. py_f64 r;
  692. if(!py_checktype(&argv[0], tp_vec2)) return false;
  693. if(!py_castfloat(&argv[1], &r)) return false;
  694. if(!py_checktype(&argv[2], tp_vec2)) return false;
  695. c11_vec2 t = py_tovec2(&argv[0]);
  696. c11_vec2 s = py_tovec2(&argv[2]);
  697. c11_mat3x3* out = py_newmat3x3(py_retval());
  698. trs(t, r, s, out);
  699. return true;
  700. }
  701. static bool mat3x3_copy_trs_(int argc, py_Ref argv) {
  702. PY_CHECK_ARGC(4);
  703. c11_mat3x3* ud = py_tomat3x3(&argv[0]);
  704. py_f64 r;
  705. if(!py_checktype(&argv[1], tp_vec2)) return false;
  706. if(!py_castfloat(&argv[2], &r)) return false;
  707. if(!py_checktype(&argv[3], tp_vec2)) return false;
  708. c11_vec2 t = py_tovec2(&argv[1]);
  709. c11_vec2 s = py_tovec2(&argv[3]);
  710. trs(t, r, s, ud);
  711. py_newnone(py_retval());
  712. return true;
  713. }
  714. static bool mat3x3_t(int argc, py_Ref argv) {
  715. PY_CHECK_ARGC(1);
  716. c11_mat3x3* ud = py_tomat3x3(argv);
  717. c11_vec2 res;
  718. res.x = ud->_13;
  719. res.y = ud->_23;
  720. py_newvec2(py_retval(), res);
  721. return true;
  722. }
  723. static bool mat3x3_r(int argc, py_Ref argv) {
  724. PY_CHECK_ARGC(1);
  725. c11_mat3x3* ud = py_tomat3x3(argv);
  726. float r = dmath_atan2(ud->_21, ud->_11);
  727. py_newfloat(py_retval(), r);
  728. return true;
  729. }
  730. static bool mat3x3_s(int argc, py_Ref argv) {
  731. PY_CHECK_ARGC(1);
  732. c11_mat3x3* ud = py_tomat3x3(argv);
  733. c11_vec2 res;
  734. res.x = dmath_sqrt(ud->_11 * ud->_11 + ud->_21 * ud->_21);
  735. res.y = dmath_sqrt(ud->_12 * ud->_12 + ud->_22 * ud->_22);
  736. py_newvec2(py_retval(), res);
  737. return true;
  738. }
  739. static bool mat3x3_transform_point(int argc, py_Ref argv) {
  740. PY_CHECK_ARGC(2);
  741. PY_CHECK_ARG_TYPE(1, tp_vec2);
  742. c11_mat3x3* ud = py_tomat3x3(&argv[0]);
  743. c11_vec2 p = py_tovec2(&argv[1]);
  744. c11_vec2 res;
  745. res.x = ud->_11 * p.x + ud->_12 * p.y + ud->_13;
  746. res.y = ud->_21 * p.x + ud->_22 * p.y + ud->_23;
  747. py_newvec2(py_retval(), res);
  748. return true;
  749. }
  750. static bool mat3x3_transform_vector(int argc, py_Ref argv) {
  751. PY_CHECK_ARGC(2);
  752. PY_CHECK_ARG_TYPE(1, tp_vec2);
  753. c11_mat3x3* ud = py_tomat3x3(&argv[0]);
  754. c11_vec2 p = py_tovec2(&argv[1]);
  755. c11_vec2 res;
  756. res.x = ud->_11 * p.x + ud->_12 * p.y;
  757. res.y = ud->_21 * p.x + ud->_22 * p.y;
  758. py_newvec2(py_retval(), res);
  759. return true;
  760. }
  761. /* vec2i */
  762. DEFINE_VEC_FIELD(vec2i, int, py_i64, x)
  763. DEFINE_VEC_FIELD(vec2i, int, py_i64, y)
  764. static bool vec2i__repr__(int argc, py_Ref argv) {
  765. PY_CHECK_ARGC(1);
  766. c11_vec2i data = py_tovec2i(argv);
  767. char buf[64];
  768. int size = snprintf(buf, 64, "vec2i(%d, %d)", data.x, data.y);
  769. py_newstrv(py_retval(), (c11_sv){buf, size});
  770. return true;
  771. }
  772. /* vec3i */
  773. static bool vec3i__repr__(int argc, py_Ref argv) {
  774. PY_CHECK_ARGC(1);
  775. c11_vec3i data = py_tovec3i(argv);
  776. char buf[64];
  777. int size = snprintf(buf, 64, "vec3i(%d, %d, %d)", data.x, data.y, data.z);
  778. py_newstrv(py_retval(), (c11_sv){buf, size});
  779. return true;
  780. }
  781. DEFINE_VEC_FIELD(vec3i, int, py_i64, x)
  782. DEFINE_VEC_FIELD(vec3i, int, py_i64, y)
  783. DEFINE_VEC_FIELD(vec3i, int, py_i64, z)
  784. /* vec4i */
  785. static bool vec4i__repr__(int argc, py_Ref argv) {
  786. PY_CHECK_ARGC(1);
  787. c11_vec4i data = py_tovec4i(argv);
  788. char buf[64];
  789. int size = snprintf(buf, 64, "vec4i(%d, %d, %d, %d)", data.x, data.y, data.z, data.w);
  790. py_newstrv(py_retval(), (c11_sv){buf, size});
  791. return true;
  792. }
  793. DEFINE_VEC_FIELD(vec4i, int, py_i64, x)
  794. DEFINE_VEC_FIELD(vec4i, int, py_i64, y)
  795. DEFINE_VEC_FIELD(vec4i, int, py_i64, z)
  796. DEFINE_VEC_FIELD(vec4i, int, py_i64, w)
  797. /* vec3 */
  798. static bool vec3__repr__(int argc, py_Ref argv) {
  799. PY_CHECK_ARGC(1);
  800. c11_vec3 data = py_tovec3(argv);
  801. char buf[64];
  802. int size = snprintf(buf, 64, "vec3(%.4f, %.4f, %.4f)", data.x, data.y, data.z);
  803. py_newstrv(py_retval(), (c11_sv){buf, size});
  804. return true;
  805. }
  806. DEFINE_VEC_FIELD(vec3, float, py_f64, x)
  807. DEFINE_VEC_FIELD(vec3, float, py_f64, y)
  808. DEFINE_VEC_FIELD(vec3, float, py_f64, z)
  809. static bool vec3__xy(int argc, py_Ref argv) {
  810. PY_CHECK_ARGC(1);
  811. c11_vec3 data = py_tovec3(argv);
  812. c11_vec2 res = {
  813. {data.x, data.y}
  814. };
  815. py_newvec2(py_retval(), res);
  816. return true;
  817. }
  818. static bool vec3__with_xy(int argc, py_Ref argv) {
  819. PY_CHECK_ARGC(2);
  820. PY_CHECK_ARG_TYPE(1, tp_vec2);
  821. c11_vec2 xy = py_tovec2(&argv[1]);
  822. c11_vec3 res = {
  823. {xy.x, xy.y, py_tovec3(argv).z}
  824. };
  825. py_newvec3(py_retval(), res);
  826. return true;
  827. }
  828. /* Color32 */
  829. void py_newcolor32(py_OutRef out, c11_color32 color) {
  830. out->type = tp_color32;
  831. out->is_ptr = false;
  832. out->_color32 = color;
  833. }
  834. c11_color32 py_tocolor32(py_Ref obj) {
  835. assert(obj->type == tp_color32);
  836. return obj->_color32;
  837. }
  838. static bool color32__new__(int argc, py_Ref argv) {
  839. PY_CHECK_ARGC(5);
  840. c11_color32 color;
  841. for(int i = 1; i < 5; i++) {
  842. PY_CHECK_ARG_TYPE(i, tp_int);
  843. py_i64 val = py_toint(&argv[i]);
  844. if(val < 0 || val > 255) return ValueError("color32 values must be between 0 and 255");
  845. color.data[i - 1] = (unsigned char)val;
  846. }
  847. py_newcolor32(py_retval(), color);
  848. return true;
  849. }
  850. #define DEFINE_COLOR32_FIELD(name) \
  851. static bool color32__##name(int argc, py_Ref argv) { \
  852. PY_CHECK_ARGC(1); \
  853. c11_color32 color = py_tocolor32(argv); \
  854. py_newint(py_retval(), color.name); \
  855. return true; \
  856. } \
  857. static bool color32_with_##name(int argc, py_Ref argv) { \
  858. PY_CHECK_ARGC(2); \
  859. c11_color32 color = py_tocolor32(argv); \
  860. PY_CHECK_ARG_TYPE(1, tp_int); \
  861. py_i64 val = py_toint(&argv[1]); \
  862. if(val < 0 || val > 255) { \
  863. return ValueError("color32 values must be between 0 and 255"); \
  864. } \
  865. color.name = (unsigned char)val; \
  866. py_newcolor32(py_retval(), color); \
  867. return true; \
  868. }
  869. DEFINE_COLOR32_FIELD(r)
  870. DEFINE_COLOR32_FIELD(g)
  871. DEFINE_COLOR32_FIELD(b)
  872. DEFINE_COLOR32_FIELD(a)
  873. #undef DEFINE_COLOR32_FIELD
  874. static bool color32_from_hex_STATIC(int argc, py_Ref argv) {
  875. PY_CHECK_ARGC(1);
  876. PY_CHECK_ARG_TYPE(0, tp_str);
  877. c11_sv hex = py_tosv(argv);
  878. c11_color32 color;
  879. int res;
  880. if(hex.size == 7) {
  881. res = sscanf(hex.data, "#%2hhx%2hhx%2hhx", &color.r, &color.g, &color.b);
  882. if(res != 3) return ValueError("invalid hex color format");
  883. color.a = 255;
  884. } else {
  885. res = sscanf(hex.data, "#%2hhx%2hhx%2hhx%2hhx", &color.r, &color.g, &color.b, &color.a);
  886. if(res != 4) return ValueError("invalid hex color format");
  887. }
  888. py_newcolor32(py_retval(), color);
  889. return true;
  890. }
  891. static bool color32_from_vec3_STATIC(int argc, py_Ref argv) {
  892. PY_CHECK_ARGC(1);
  893. PY_CHECK_ARG_TYPE(0, tp_vec3);
  894. c11_vec3 v = py_tovec3(argv);
  895. c11_color32 color;
  896. color.r = (unsigned char)(v.x * 255);
  897. color.g = (unsigned char)(v.y * 255);
  898. color.b = (unsigned char)(v.z * 255);
  899. color.a = 255;
  900. py_newcolor32(py_retval(), color);
  901. return true;
  902. }
  903. static bool color32_from_vec3i_STATIC(int argc, py_Ref argv) {
  904. PY_CHECK_ARGC(1);
  905. PY_CHECK_ARG_TYPE(0, tp_vec3i);
  906. c11_vec3i v = py_tovec3i(argv);
  907. c11_color32 color;
  908. color.r = (unsigned char)v.x;
  909. color.g = (unsigned char)v.y;
  910. color.b = (unsigned char)v.z;
  911. color.a = 255;
  912. py_newcolor32(py_retval(), color);
  913. return true;
  914. }
  915. static bool color32_to_hex(int argc, py_Ref argv) {
  916. PY_CHECK_ARGC(1);
  917. c11_color32 color = py_tocolor32(argv);
  918. char buf[16];
  919. int size;
  920. if(color.a == 255) {
  921. size = snprintf(buf, sizeof(buf), "#%02x%02x%02x", color.r, color.g, color.b);
  922. } else {
  923. size = snprintf(buf, sizeof(buf), "#%02x%02x%02x%02x", color.r, color.g, color.b, color.a);
  924. }
  925. py_newstrv(py_retval(), (c11_sv){buf, size});
  926. return true;
  927. }
  928. void c11_color32_premult(c11_color32* color) {
  929. if(color->a == 255) return;
  930. float alpha = color->a / 255.0f;
  931. color->r = (unsigned char)(color->r * alpha);
  932. color->g = (unsigned char)(color->g * alpha);
  933. color->b = (unsigned char)(color->b * alpha);
  934. }
  935. static bool color32_to_vec3(int argc, py_Ref argv) {
  936. PY_CHECK_ARGC(1);
  937. c11_color32 color = py_tocolor32(argv);
  938. c11_color32_premult(&color);
  939. c11_vec3 v;
  940. v.x = (float)color.r / 255;
  941. v.y = (float)color.g / 255;
  942. v.z = (float)color.b / 255;
  943. py_newvec3(py_retval(), v);
  944. return true;
  945. }
  946. static bool color32_to_vec3i(int argc, py_Ref argv) {
  947. PY_CHECK_ARGC(1);
  948. c11_color32 color = py_tocolor32(argv);
  949. c11_color32_premult(&color);
  950. c11_vec3i v;
  951. v.x = (int)color.r;
  952. v.y = (int)color.g;
  953. v.z = (int)color.b;
  954. py_newvec3i(py_retval(), v);
  955. return true;
  956. }
  957. static bool color32_to_rgb565(int argc, py_Ref argv) {
  958. PY_CHECK_ARGC(1);
  959. c11_color32 color = py_tocolor32(argv);
  960. c11_color32_premult(&color);
  961. uint16_t r = (color.r >> 3) & 0x1F;
  962. uint16_t g = (color.g >> 2) & 0x3F;
  963. uint16_t b = (color.b >> 3) & 0x1F;
  964. uint16_t rgb565 = (r << 11) | (g << 5) | b;
  965. py_newint(py_retval(), rgb565);
  966. return true;
  967. }
  968. static bool color32__eq__(int argc, py_Ref argv) {
  969. PY_CHECK_ARGC(2);
  970. if(argv[1].type != tp_color32) {
  971. py_newnotimplemented(py_retval());
  972. return true;
  973. }
  974. c11_color32 lhs = py_tocolor32(&argv[0]);
  975. c11_color32 rhs = py_tocolor32(&argv[1]);
  976. bool eq = memcmp(&lhs, &rhs, sizeof(c11_color32)) == 0;
  977. py_newbool(py_retval(), eq);
  978. return true;
  979. }
  980. static bool color32__ne__(int argc, py_Ref argv) {
  981. PY_CHECK_ARGC(2);
  982. if(argv[1].type != tp_color32) {
  983. py_newnotimplemented(py_retval());
  984. return true;
  985. }
  986. c11_color32 lhs = py_tocolor32(&argv[0]);
  987. c11_color32 rhs = py_tocolor32(&argv[1]);
  988. bool eq = memcmp(&lhs, &rhs, sizeof(c11_color32)) != 0;
  989. py_newbool(py_retval(), eq);
  990. return true;
  991. }
  992. static bool color32__repr__(int argc, py_Ref argv) {
  993. PY_CHECK_ARGC(1);
  994. c11_color32 color = py_tocolor32(argv);
  995. char buf[64];
  996. int size = snprintf(buf, 64, "color32(%d, %d, %d, %d)", color.r, color.g, color.b, color.a);
  997. py_newstrv(py_retval(), (c11_sv){buf, size});
  998. return true;
  999. }
  1000. static bool color32__hash__(int argc, py_Ref argv) {
  1001. PY_CHECK_ARGC(1);
  1002. c11_color32 color = py_tocolor32(argv);
  1003. uint32_t* color_int = (uint32_t*)&color;
  1004. py_newint(py_retval(), *color_int);
  1005. return true;
  1006. }
  1007. static bool color32_ansi_fg(int argc, py_Ref argv) {
  1008. PY_CHECK_ARGC(2);
  1009. c11_color32 color = py_tocolor32(argv);
  1010. c11_color32_premult(&color);
  1011. PY_CHECK_ARG_TYPE(1, tp_str);
  1012. c11_sv text = py_tosv(&argv[1]);
  1013. c11_sbuf buf;
  1014. c11_sbuf__ctor(&buf);
  1015. pk_sprintf(&buf, "\x1b[38;2;%d;%d;%dm%v\x1b[0m", color.r, color.g, color.b, text);
  1016. c11_sbuf__py_submit(&buf, py_retval());
  1017. return true;
  1018. }
  1019. static bool color32_ansi_bg(int argc, py_Ref argv) {
  1020. PY_CHECK_ARGC(2);
  1021. c11_color32 color = py_tocolor32(argv);
  1022. c11_color32_premult(&color);
  1023. PY_CHECK_ARG_TYPE(1, tp_str);
  1024. c11_sv text = py_tosv(&argv[1]);
  1025. c11_sbuf buf;
  1026. c11_sbuf__ctor(&buf);
  1027. pk_sprintf(&buf, "\x1b[48;2;%d;%d;%dm%v\x1b[0m", color.r, color.g, color.b, text);
  1028. c11_sbuf__py_submit(&buf, py_retval());
  1029. return true;
  1030. }
  1031. static bool vmath_rgb(int argc, py_Ref argv) {
  1032. PY_CHECK_ARGC(3);
  1033. PY_CHECK_ARG_TYPE(0, tp_int);
  1034. PY_CHECK_ARG_TYPE(1, tp_int);
  1035. PY_CHECK_ARG_TYPE(2, tp_int);
  1036. c11_color32 color;
  1037. color.r = (unsigned char)py_toint(&argv[0]);
  1038. color.g = (unsigned char)py_toint(&argv[1]);
  1039. color.b = (unsigned char)py_toint(&argv[2]);
  1040. color.a = 255;
  1041. py_newcolor32(py_retval(), color);
  1042. return true;
  1043. }
  1044. static bool vmath_rgba(int argc, py_Ref argv) {
  1045. PY_CHECK_ARGC(4);
  1046. PY_CHECK_ARG_TYPE(0, tp_int);
  1047. PY_CHECK_ARG_TYPE(1, tp_int);
  1048. PY_CHECK_ARG_TYPE(2, tp_int);
  1049. PY_CHECK_ARG_TYPE(3, tp_float);
  1050. c11_color32 color;
  1051. color.r = (unsigned char)py_toint(&argv[0]);
  1052. color.g = (unsigned char)py_toint(&argv[1]);
  1053. color.b = (unsigned char)py_toint(&argv[2]);
  1054. color.a = (unsigned char)(py_tofloat(&argv[3]) * 255);
  1055. py_newcolor32(py_retval(), color);
  1056. return true;
  1057. }
  1058. static bool color32_alpha_blend_STATIC(int argc, py_Ref argv) {
  1059. PY_CHECK_ARGC(2);
  1060. if(!py_checktype(&argv[0], tp_color32)) return false;
  1061. if(py_isnone(&argv[1])) {
  1062. py_assign(py_retval(), &argv[0]);
  1063. return true;
  1064. }
  1065. if(!py_checktype(&argv[1], tp_color32)) return false;
  1066. c11_color32 src = py_tocolor32(&argv[0]);
  1067. c11_color32 dst = py_tocolor32(&argv[1]);
  1068. float alpha = src.a / 255.0f;
  1069. c11_color32 res;
  1070. res.r = (unsigned char)(src.r * alpha + dst.r * (1 - alpha));
  1071. res.g = (unsigned char)(src.g * alpha + dst.g * (1 - alpha));
  1072. res.b = (unsigned char)(src.b * alpha + dst.b * (1 - alpha));
  1073. res.a = (unsigned char)(src.a + dst.a * (1 - alpha));
  1074. py_newcolor32(py_retval(), res);
  1075. return true;
  1076. }
  1077. void pk__add_module_vmath() {
  1078. py_Ref mod = py_newmodule("vmath");
  1079. py_Type vec2 = pk_newtype("vec2", tp_object, mod, NULL, false, true);
  1080. py_Type vec3 = pk_newtype("vec3", tp_object, mod, NULL, false, true);
  1081. py_Type vec2i = pk_newtype("vec2i", tp_object, mod, NULL, false, true);
  1082. py_Type vec3i = pk_newtype("vec3i", tp_object, mod, NULL, false, true);
  1083. py_Type vec4i = pk_newtype("vec4i", tp_object, mod, NULL, false, true);
  1084. py_Type mat3x3 = pk_newtype("mat3x3", tp_object, mod, NULL, false, true);
  1085. py_Type color32 = pk_newtype("color32", tp_object, mod, NULL, false, true);
  1086. py_setdict(mod, py_name("vec2"), py_tpobject(vec2));
  1087. py_setdict(mod, py_name("vec3"), py_tpobject(vec3));
  1088. py_setdict(mod, py_name("vec2i"), py_tpobject(vec2i));
  1089. py_setdict(mod, py_name("vec3i"), py_tpobject(vec3i));
  1090. py_setdict(mod, py_name("vec4i"), py_tpobject(vec4i));
  1091. py_setdict(mod, py_name("mat3x3"), py_tpobject(mat3x3));
  1092. py_setdict(mod, py_name("color32"), py_tpobject(color32));
  1093. c11__rtassert(vec2 == tp_vec2);
  1094. c11__rtassert(vec3 == tp_vec3);
  1095. c11__rtassert(vec2i == tp_vec2i);
  1096. c11__rtassert(vec3i == tp_vec3i);
  1097. c11__rtassert(vec4i == tp_vec4i);
  1098. c11__rtassert(mat3x3 == tp_mat3x3);
  1099. c11__rtassert(color32 == tp_color32);
  1100. /* vec2 */
  1101. py_bindmagic(vec2, __new__, vec2__new__);
  1102. py_bindmagic(vec2, __add__, vec2__add__);
  1103. py_bindmagic(vec2, __sub__, vec2__sub__);
  1104. py_bindmagic(vec2, __mul__, vec2__mul__);
  1105. py_bindmagic(vec2, __truediv__, vec2__truediv__);
  1106. py_bindmagic(vec2, __repr__, vec2__repr__);
  1107. py_bindmagic(vec2, __eq__, vec2__eq__);
  1108. py_bindmagic(vec2, __ne__, vec2__ne__);
  1109. py_bindmethod(vec2, "dot", vec2_dot);
  1110. py_bindmethod(vec2, "length", vec2_length);
  1111. py_bindmethod(vec2, "length_squared", vec2_length_squared);
  1112. py_bindmethod(vec2, "normalize", vec2_normalize);
  1113. py_bindmethod(vec2, "rotate", vec2_rotate);
  1114. // clang-format off
  1115. py_newvec2(_const(vec2, "ZERO"), (c11_vec2){{0, 0}});
  1116. py_newvec2(_const(vec2, "ONE"), (c11_vec2){{1, 1}});
  1117. py_newvec2(_const(vec2, "LEFT"), (c11_vec2){{-1, 0}});
  1118. py_newvec2(_const(vec2, "RIGHT"), (c11_vec2){{1, 0}});
  1119. py_newvec2(_const(vec2, "UP"), (c11_vec2){{0, -1}});
  1120. py_newvec2(_const(vec2, "DOWN"), (c11_vec2){{0, 1}});
  1121. // clang-format on
  1122. py_bindstaticmethod(vec2, "angle", vec2_angle_STATIC);
  1123. py_bindstaticmethod(vec2, "smooth_damp", vec2_smoothdamp_STATIC);
  1124. py_bindproperty(vec2, "x", vec2__x, NULL);
  1125. py_bindproperty(vec2, "y", vec2__y, NULL);
  1126. py_bindmethod(vec2, "with_x", vec2__with_x);
  1127. py_bindmethod(vec2, "with_y", vec2__with_y);
  1128. py_bindmethod(vec2, "with_z", vec2__with_z);
  1129. /* mat3x3 */
  1130. py_bindmagic(mat3x3, __new__, mat3x3__new__);
  1131. py_bindmagic(mat3x3, __repr__, mat3x3__repr__);
  1132. py_bindmagic(mat3x3, __getitem__, mat3x3__getitem__);
  1133. py_bindmagic(mat3x3, __setitem__, mat3x3__setitem__);
  1134. py_bindmagic(mat3x3, __matmul__, mat3x3__matmul__);
  1135. py_bindmagic(mat3x3, __invert__, mat3x3__invert__);
  1136. py_bindmagic(mat3x3, __eq__, mat3x3__eq__);
  1137. py_bindmagic(mat3x3, __ne__, mat3x3__ne__);
  1138. py_bindmethod(mat3x3, "matmul", mat3x3_matmul);
  1139. py_bindmethod(mat3x3, "determinant", mat3x3_determinant);
  1140. py_bindmethod(mat3x3, "copy", mat3x3_copy);
  1141. py_bindmethod(mat3x3, "inverse", mat3x3_inverse);
  1142. py_bindmethod(mat3x3, "copy_", mat3x3_copy_);
  1143. py_bindmethod(mat3x3, "inverse_", mat3x3_inverse_);
  1144. py_bindstaticmethod(mat3x3, "zeros", mat3x3_zeros_STATIC);
  1145. py_bindstaticmethod(mat3x3, "identity", mat3x3_identity_STATIC);
  1146. py_bindstaticmethod(mat3x3, "trs", mat3x3_trs_STATIC);
  1147. py_bindmethod(mat3x3, "copy_trs_", mat3x3_copy_trs_);
  1148. py_bindmethod(mat3x3, "t", mat3x3_t);
  1149. py_bindmethod(mat3x3, "r", mat3x3_r);
  1150. py_bindmethod(mat3x3, "s", mat3x3_s);
  1151. py_bindmethod(mat3x3, "transform_point", mat3x3_transform_point);
  1152. py_bindmethod(mat3x3, "transform_vector", mat3x3_transform_vector);
  1153. /* vec2i */
  1154. py_bindmagic(vec2i, __new__, vec2i__new__);
  1155. py_bindmagic(vec2i, __repr__, vec2i__repr__);
  1156. py_bindmagic(vec2i, __add__, vec2i__add__);
  1157. py_bindmagic(vec2i, __sub__, vec2i__sub__);
  1158. py_bindmagic(vec2i, __mul__, vec2i__mul__);
  1159. py_bindmagic(vec2i, __floordiv__, vec2i__floordiv__);
  1160. py_bindmagic(vec2i, __mod__, vec2i__mod__);
  1161. py_bindmagic(vec2i, __eq__, vec2i__eq__);
  1162. py_bindmagic(vec2i, __ne__, vec2i__ne__);
  1163. py_bindmagic(vec2i, __hash__, vec2i__hash__);
  1164. py_bindproperty(vec2i, "x", vec2i__x, NULL);
  1165. py_bindproperty(vec2i, "y", vec2i__y, NULL);
  1166. py_bindmethod(vec2i, "with_x", vec2i__with_x);
  1167. py_bindmethod(vec2i, "with_y", vec2i__with_y);
  1168. py_bindmethod(vec2i, "dot", vec2i_dot);
  1169. py_bindmethod(vec2i, "l1_norm", vec2i_l1_norm);
  1170. py_bindmethod(vec2i, "l2_norm", vec2i_l2_norm);
  1171. py_bindmethod(vec2i, "max_norm", vec2i_max_norm);
  1172. py_bindmethod(vec2i, "length", vec2i_l2_norm);
  1173. // clang-format off
  1174. py_newvec2i(_const(vec2i, "ZERO"), (c11_vec2i){{0, 0}});
  1175. py_newvec2i(_const(vec2i, "ONE"), (c11_vec2i){{1, 1}});
  1176. py_newvec2i(_const(vec2i, "LEFT"), (c11_vec2i){{-1, 0}});
  1177. py_newvec2i(_const(vec2i, "RIGHT"), (c11_vec2i){{1, 0}});
  1178. py_newvec2i(_const(vec2i, "UP"), (c11_vec2i){{0, -1}});
  1179. py_newvec2i(_const(vec2i, "DOWN"), (c11_vec2i){{0, 1}});
  1180. // clang-format on
  1181. /* vec3i */
  1182. py_bindmagic(vec3i, __new__, vec3i__new__);
  1183. py_bindmagic(vec3i, __repr__, vec3i__repr__);
  1184. py_bindmagic(vec3i, __add__, vec3i__add__);
  1185. py_bindmagic(vec3i, __sub__, vec3i__sub__);
  1186. py_bindmagic(vec3i, __mul__, vec3i__mul__);
  1187. py_bindmagic(vec3i, __floordiv__, vec3i__floordiv__);
  1188. py_bindmagic(vec3i, __mod__, vec3i__mod__);
  1189. py_bindmagic(vec3i, __eq__, vec3i__eq__);
  1190. py_bindmagic(vec3i, __ne__, vec3i__ne__);
  1191. py_bindmagic(vec3i, __hash__, vec3i__hash__);
  1192. py_bindproperty(vec3i, "x", vec3i__x, NULL);
  1193. py_bindproperty(vec3i, "y", vec3i__y, NULL);
  1194. py_bindproperty(vec3i, "z", vec3i__z, NULL);
  1195. py_bindmethod(vec3i, "with_x", vec3i__with_x);
  1196. py_bindmethod(vec3i, "with_y", vec3i__with_y);
  1197. py_bindmethod(vec3i, "with_z", vec3i__with_z);
  1198. py_bindmethod(vec3i, "dot", vec3i_dot);
  1199. py_newvec3i(_const(vec3i, "ZERO"),
  1200. (c11_vec3i){
  1201. {0, 0, 0}
  1202. });
  1203. py_newvec3i(_const(vec3i, "ONE"),
  1204. (c11_vec3i){
  1205. {1, 1, 1}
  1206. });
  1207. /* vec4i */
  1208. py_bindmagic(vec4i, __new__, vec4i__new__);
  1209. py_bindmagic(vec4i, __repr__, vec4i__repr__);
  1210. py_bindmagic(vec4i, __add__, vec4i__add__);
  1211. py_bindmagic(vec4i, __sub__, vec4i__sub__);
  1212. py_bindmagic(vec4i, __mul__, vec4i__mul__);
  1213. py_bindmagic(vec4i, __floordiv__, vec4i__floordiv__);
  1214. py_bindmagic(vec4i, __mod__, vec4i__mod__);
  1215. py_bindmagic(vec4i, __eq__, vec4i__eq__);
  1216. py_bindmagic(vec4i, __ne__, vec4i__ne__);
  1217. py_bindmagic(vec4i, __hash__, vec4i__hash__);
  1218. py_bindproperty(vec4i, "x", vec4i__x, NULL);
  1219. py_bindproperty(vec4i, "y", vec4i__y, NULL);
  1220. py_bindproperty(vec4i, "z", vec4i__z, NULL);
  1221. py_bindproperty(vec4i, "w", vec4i__w, NULL);
  1222. py_bindmethod(vec4i, "with_x", vec4i__with_x);
  1223. py_bindmethod(vec4i, "with_y", vec4i__with_y);
  1224. py_bindmethod(vec4i, "with_z", vec4i__with_z);
  1225. py_bindmethod(vec4i, "with_w", vec4i__with_w);
  1226. py_bindmethod(vec4i, "dot", vec4i_dot);
  1227. py_newvec4i(_const(vec4i, "ZERO"),
  1228. (c11_vec4i){
  1229. {0, 0, 0, 0}
  1230. });
  1231. py_newvec4i(_const(vec4i, "ONE"),
  1232. (c11_vec4i){
  1233. {1, 1, 1, 1}
  1234. });
  1235. /* vec3 */
  1236. py_bindmagic(vec3, __new__, vec3__new__);
  1237. py_bindmagic(vec3, __add__, vec3__add__);
  1238. py_bindmagic(vec3, __sub__, vec3__sub__);
  1239. py_bindmagic(vec3, __mul__, vec3__mul__);
  1240. py_bindmagic(vec3, __truediv__, vec3__truediv__);
  1241. py_bindmagic(vec3, __repr__, vec3__repr__);
  1242. py_bindmagic(vec3, __eq__, vec3__eq__);
  1243. py_bindmagic(vec3, __ne__, vec3__ne__);
  1244. py_bindmethod(vec3, "dot", vec3_dot);
  1245. py_bindmethod(vec3, "length", vec3_length);
  1246. py_bindmethod(vec3, "length_squared", vec3_length_squared);
  1247. py_bindmethod(vec3, "normalize", vec3_normalize);
  1248. py_bindproperty(vec3, "x", vec3__x, NULL);
  1249. py_bindproperty(vec3, "y", vec3__y, NULL);
  1250. py_bindproperty(vec3, "z", vec3__z, NULL);
  1251. py_bindproperty(vec3, "xy", vec3__xy, NULL);
  1252. py_bindmethod(vec3, "with_x", vec3__with_x);
  1253. py_bindmethod(vec3, "with_y", vec3__with_y);
  1254. py_bindmethod(vec3, "with_z", vec3__with_z);
  1255. py_bindmethod(vec3, "with_xy", vec3__with_xy);
  1256. py_newvec3(_const(vec3, "ZERO"),
  1257. (c11_vec3){
  1258. {0, 0, 0}
  1259. });
  1260. py_newvec3(_const(vec3, "ONE"),
  1261. (c11_vec3){
  1262. {1, 1, 1}
  1263. });
  1264. /* color32 */
  1265. py_bindmagic(color32, __new__, color32__new__);
  1266. py_bindmagic(color32, __repr__, color32__repr__);
  1267. py_bindmagic(color32, __eq__, color32__eq__);
  1268. py_bindmagic(color32, __ne__, color32__ne__);
  1269. py_bindmagic(color32, __hash__, color32__hash__);
  1270. py_bindproperty(color32, "r", color32__r, NULL);
  1271. py_bindproperty(color32, "g", color32__g, NULL);
  1272. py_bindproperty(color32, "b", color32__b, NULL);
  1273. py_bindproperty(color32, "a", color32__a, NULL);
  1274. py_bindmethod(color32, "with_r", color32_with_r);
  1275. py_bindmethod(color32, "with_g", color32_with_g);
  1276. py_bindmethod(color32, "with_b", color32_with_b);
  1277. py_bindmethod(color32, "with_a", color32_with_a);
  1278. py_bindstaticmethod(color32, "from_hex", color32_from_hex_STATIC);
  1279. py_bindstaticmethod(color32, "from_vec3", color32_from_vec3_STATIC);
  1280. py_bindstaticmethod(color32, "from_vec3i", color32_from_vec3i_STATIC);
  1281. py_bindmethod(color32, "to_hex", color32_to_hex);
  1282. py_bindmethod(color32, "to_vec3", color32_to_vec3);
  1283. py_bindmethod(color32, "to_vec3i", color32_to_vec3i);
  1284. py_bindmethod(color32, "to_rgb565", color32_to_rgb565);
  1285. py_bindmethod(color32, "ansi_fg", color32_ansi_fg);
  1286. py_bindmethod(color32, "ansi_bg", color32_ansi_bg);
  1287. py_bindfunc(mod, "rgb", vmath_rgb);
  1288. py_bindfunc(mod, "rgba", vmath_rgba);
  1289. py_bindstaticmethod(color32, "alpha_blend", color32_alpha_blend_STATIC);
  1290. }
  1291. #undef DEFINE_VEC_FIELD
  1292. #undef DEFINE_BOOL_NE
  1293. #undef DEF_VECTOR_ELEMENT_WISE
  1294. #undef DEF_VECTOR_OPS
  1295. #undef DEF_VECTOR_INT_OPS