util_mesh.ts 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. let util_mesh_unwrappers: map_t<string, any> = map_create(); // JSValue * -> ((a: raw_mesh_t)=>void)
  2. function util_mesh_merge(paint_objects: mesh_object_t[] = null) {
  3. if (paint_objects == null) {
  4. ///if is_forge
  5. paint_objects = util_mesh_ext_get_unique();
  6. ///else
  7. paint_objects = project_paint_objects;
  8. ///end
  9. }
  10. if (paint_objects.length == 0) {
  11. return;
  12. }
  13. context_raw.merged_object_is_atlas = paint_objects.length < project_paint_objects.length;
  14. let vlen: i32 = 0;
  15. let ilen: i32 = 0;
  16. let max_scale: f32 = 0.0;
  17. for (let i: i32 = 0; i < paint_objects.length; ++i) {
  18. vlen += paint_objects[i].data.vertex_arrays[0].values.length;
  19. ilen += paint_objects[i].data.index_arrays[0].values.length;
  20. if (paint_objects[i].data.scale_pos > max_scale) {
  21. max_scale = paint_objects[i].data.scale_pos;
  22. }
  23. }
  24. vlen = math_floor(vlen / 4);
  25. let va0: i16_array_t = i16_array_create(vlen * 4);
  26. let va1: i16_array_t = i16_array_create(vlen * 2);
  27. let va2: i16_array_t = i16_array_create(vlen * 2);
  28. let va3: i16_array_t = paint_objects[0].data.vertex_arrays.length > 3 ? i16_array_create(vlen * 4) : null;
  29. let ia: u32_array_t = u32_array_create(ilen);
  30. let voff: i32 = 0;
  31. let ioff: i32 = 0;
  32. for (let i: i32 = 0; i < paint_objects.length; ++i) {
  33. let vas: vertex_array_t[] = paint_objects[i].data.vertex_arrays;
  34. let ias: index_array_t[] = paint_objects[i].data.index_arrays;
  35. let scale: f32 = paint_objects[i].data.scale_pos;
  36. // Pos
  37. for (let j: i32 = 0; j < vas[0].values.length; ++j) {
  38. va0[j + voff * 4] = vas[0].values[j];
  39. }
  40. // Translate
  41. // for (let j: i32 = 0; j < math_floor(va0.length / 4); ++j) {
  42. // va0[j * 4 + voff * 4] += math_floor(transform_world_x(paint_objects[i].base.transform) * 32767);
  43. // va0[j * 4 + 1 + voff * 4] += math_floor(transform_world_y(paint_objects[i].base.transform) * 32767);
  44. // va0[j * 4 + 2 + voff * 4] += math_floor(transform_world_z(paint_objects[i].base.transform) * 32767);
  45. // }
  46. // Re-scale
  47. for (let j: i32 = voff; j < math_floor(va0.length / 4); ++j) {
  48. va0[j * 4 ] = math_floor((va0[j * 4 ] * scale) / max_scale);
  49. va0[j * 4 + 1] = math_floor((va0[j * 4 + 1] * scale) / max_scale);
  50. va0[j * 4 + 2] = math_floor((va0[j * 4 + 2] * scale) / max_scale);
  51. }
  52. // Nor
  53. for (let j: i32 = 0; j < vas[1].values.length; ++j) {
  54. va1[j + voff * 2] = vas[1].values[j];
  55. }
  56. // Tex
  57. for (let j: i32 = 0; j < vas[2].values.length; ++j) {
  58. va2[j + voff * 2] = vas[2].values[j];
  59. }
  60. // Col
  61. if (va3 != null) {
  62. for (let j: i32 = 0; j < vas[3].values.length; ++j) {
  63. va3[j + voff * 4] = vas[3].values[j];
  64. }
  65. }
  66. // Indices
  67. for (let j: i32 = 0; j < ias[0].values.length; ++j) {
  68. ia[j + ioff] = ias[0].values[j] + voff;
  69. }
  70. voff += math_floor(vas[0].values.length / 4);
  71. ioff += math_floor(ias[0].values.length);
  72. }
  73. let raw: mesh_data_t = {
  74. name: context_raw.paint_object.base.name,
  75. vertex_arrays: [
  76. {
  77. values: va0,
  78. attrib: "pos",
  79. data: "short4norm"
  80. },
  81. {
  82. values: va1,
  83. attrib: "nor",
  84. data: "short2norm"
  85. },
  86. {
  87. values: va2,
  88. attrib: "tex",
  89. data: "short2norm"
  90. }
  91. ],
  92. index_arrays: [
  93. {
  94. values: ia,
  95. material: 0
  96. }
  97. ],
  98. scale_pos: max_scale,
  99. scale_tex: 1.0
  100. };
  101. if (va3 != null) {
  102. let col: vertex_array_t = {
  103. values: va3,
  104. attrib: "col",
  105. data: "short4norm"
  106. };
  107. array_push(raw.vertex_arrays, col);
  108. }
  109. util_mesh_remove_merged();
  110. let md: mesh_data_t = mesh_data_create(raw);
  111. context_raw.merged_object = mesh_object_create(md, context_raw.paint_object.materials);
  112. context_raw.merged_object.base.name = context_raw.paint_object.base.name + "_merged";
  113. context_raw.merged_object.force_context = "paint";
  114. object_set_parent(context_raw.merged_object.base, context_main_object().base);
  115. render_path_raytrace_ready = false;
  116. }
  117. function util_mesh_remove_merged() {
  118. if (context_raw.merged_object != null) {
  119. mesh_data_delete(context_raw.merged_object.data);
  120. mesh_object_remove(context_raw.merged_object);
  121. context_raw.merged_object = null;
  122. }
  123. }
  124. function util_mesh_swap_axis(a: i32, b: i32) {
  125. let objects: mesh_object_t[] = project_paint_objects;
  126. for (let i: i32 = 0; i < objects.length; ++i) {
  127. let o: mesh_object_t = objects[i];
  128. // Remapping vertices, buckle up
  129. // 0 - x, 1 - y, 2 - z
  130. let vas: vertex_array_t[] = o.data.vertex_arrays;
  131. let pa: i16_array_t = vas[0].values;
  132. let na0: i16_array_t = a == 2 ? vas[0].values : vas[1].values;
  133. let na1: i16_array_t = b == 2 ? vas[0].values : vas[1].values;
  134. let c: i32 = a == 2 ? 3 : a;
  135. let d: i32 = b == 2 ? 3 : b;
  136. let e: i32 = a == 2 ? 4 : 2;
  137. let f: i32 = b == 2 ? 4 : 2;
  138. for (let i: i32 = 0; i < math_floor(pa.length / 4); ++i) {
  139. let t: i32 = pa[i * 4 + a];
  140. pa[i * 4 + a] = pa[i * 4 + b];
  141. pa[i * 4 + b] = -t;
  142. t = na0[i * e + c];
  143. na0[i * e + c] = na1[i * f + d];
  144. na1[i * f + d] = -t;
  145. }
  146. let g: mesh_data_t = o.data;
  147. let l: i32 = gpu_vertex_struct_size(g._.structure) / 2;
  148. let vertices: buffer_t = gpu_lock_vertex_buffer(g._.vertex_buffer); // posnortex
  149. for (let i: i32 = 0; i < math_floor((vertices.length) / 2 / l); ++i) {
  150. buffer_set_i16(vertices, (i * l ) * 2, vas[0].values[i * 4 ]);
  151. buffer_set_i16(vertices, (i * l + 1) * 2, vas[0].values[i * 4 + 1]);
  152. buffer_set_i16(vertices, (i * l + 2) * 2, vas[0].values[i * 4 + 2]);
  153. buffer_set_i16(vertices, (i * l + 3) * 2, vas[0].values[i * 4 + 3]);
  154. buffer_set_i16(vertices, (i * l + 4) * 2, vas[1].values[i * 2 ]);
  155. buffer_set_i16(vertices, (i * l + 5) * 2, vas[1].values[i * 2 + 1]);
  156. }
  157. gpu_vertex_buffer_unlock(g._.vertex_buffer);
  158. }
  159. util_mesh_remove_merged();
  160. util_mesh_merge();
  161. }
  162. function util_mesh_flip_normals() {
  163. let objects: mesh_object_t[] = project_paint_objects;
  164. for (let i: i32 = 0; i < objects.length; ++i) {
  165. let o: mesh_object_t = objects[i];
  166. let vas: vertex_array_t[] = o.data.vertex_arrays;
  167. let va0: i16_array_t = vas[0].values;
  168. let va1: i16_array_t = vas[1].values;
  169. let g: mesh_data_t = o.data;
  170. let l: i32 = gpu_vertex_struct_size(g._.structure) / 2;
  171. let vertices: buffer_t = gpu_lock_vertex_buffer(g._.vertex_buffer); // posnortex
  172. for (let i: i32 = 0; i < math_floor((vertices.length) / 2 / l); ++i) {
  173. va0[i * 4 + 3] = -va0[i * 4 + 3];
  174. va1[i * 2] = -va1[i * 2];
  175. va1[i * 2 + 1] = -va1[i * 2 + 1];
  176. buffer_set_i16(vertices, (i * l + 3) * 2, -buffer_get_i16(vertices, (i * l + 3) * 2));
  177. buffer_set_i16(vertices, (i * l + 4) * 2, -buffer_get_i16(vertices, (i * l + 4) * 2));
  178. buffer_set_i16(vertices, (i * l + 5) * 2, -buffer_get_i16(vertices, (i * l + 5) * 2));
  179. }
  180. gpu_vertex_buffer_unlock(g._.vertex_buffer);
  181. }
  182. render_path_raytrace_ready = false;
  183. }
  184. function util_mesh_calc_normals(smooth: bool = false) {
  185. let va: vec4_t = vec4_create();
  186. let vb: vec4_t = vec4_create();
  187. let vc: vec4_t = vec4_create();
  188. let cb: vec4_t = vec4_create();
  189. let ab: vec4_t = vec4_create();
  190. let objects: mesh_object_t[] = project_paint_objects;
  191. for (let i: i32 = 0; i < objects.length; ++i) {
  192. let o: mesh_object_t = objects[i];
  193. let g: mesh_data_t = o.data;
  194. let l: i32 = gpu_vertex_struct_size(g._.structure) / 2;
  195. let inda: u32_array_t = g._.indices[0];
  196. let vertices: buffer_t = gpu_lock_vertex_buffer(g._.vertex_buffer); // posnortex
  197. for (let i: i32 = 0; i < math_floor(inda.length / 3); ++i) {
  198. let i1: i32 = inda[i * 3 ];
  199. let i2: i32 = inda[i * 3 + 1];
  200. let i3: i32 = inda[i * 3 + 2];
  201. va = vec4_create(buffer_get_i16(vertices, (i1 * l) * 2), buffer_get_i16(vertices, (i1 * l + 1) * 2), buffer_get_i16(vertices, (i1 * l + 2) * 2));
  202. vb = vec4_create(buffer_get_i16(vertices, (i2 * l) * 2), buffer_get_i16(vertices, (i2 * l + 1) * 2), buffer_get_i16(vertices, (i2 * l + 2) * 2));
  203. vc = vec4_create(buffer_get_i16(vertices, (i3 * l) * 2), buffer_get_i16(vertices, (i3 * l + 1) * 2), buffer_get_i16(vertices, (i3 * l + 2) * 2));
  204. cb = vec4_sub(vc, vb);
  205. ab = vec4_sub(va, vb);
  206. cb = vec4_cross(cb, ab);
  207. cb = vec4_norm(cb);
  208. buffer_set_i16(vertices, (i1 * l + 4) * 2, math_floor(cb.x * 32767));
  209. buffer_set_i16(vertices, (i1 * l + 5) * 2, math_floor(cb.y * 32767));
  210. buffer_set_i16(vertices, (i1 * l + 3) * 2, math_floor(cb.z * 32767));
  211. buffer_set_i16(vertices, (i2 * l + 4) * 2, math_floor(cb.x * 32767));
  212. buffer_set_i16(vertices, (i2 * l + 5) * 2, math_floor(cb.y * 32767));
  213. buffer_set_i16(vertices, (i2 * l + 3) * 2, math_floor(cb.z * 32767));
  214. buffer_set_i16(vertices, (i3 * l + 4) * 2, math_floor(cb.x * 32767));
  215. buffer_set_i16(vertices, (i3 * l + 5) * 2, math_floor(cb.y * 32767));
  216. buffer_set_i16(vertices, (i3 * l + 3) * 2, math_floor(cb.z * 32767));
  217. }
  218. if (smooth) {
  219. let shared: u32_array_t = u32_array_create(1024);
  220. let shared_len: i32 = 0;
  221. let found: i32[] = [];
  222. for (let i: i32 = 0; i < (inda.length - 1); ++i) {
  223. if (array_index_of(found, i) >= 0) {
  224. continue;
  225. }
  226. let i1: i32 = inda[i];
  227. shared_len = 0;
  228. shared[shared_len++] = i1;
  229. for (let j: i32 = (i + 1); j < inda.length; ++j) {
  230. let i2: i32 = inda[j];
  231. let i1l: i32 = i1 * l;
  232. let i2l: i32 = i2 * l;
  233. if (buffer_get_i16(vertices, (i1l ) * 2) == buffer_get_i16(vertices, (i2l ) * 2) &&
  234. buffer_get_i16(vertices, (i1l + 1) * 2) == buffer_get_i16(vertices, (i2l + 1) * 2) &&
  235. buffer_get_i16(vertices, (i1l + 2) * 2) == buffer_get_i16(vertices, (i2l + 2) * 2)) {
  236. // if (n1.dot(n2) > 0)
  237. shared[shared_len++] = i2;
  238. array_push(found, j);
  239. if (shared_len >= 1024) {
  240. break;
  241. }
  242. }
  243. }
  244. if (shared_len > 1) {
  245. va = vec4_create(0, 0, 0);
  246. for (let j: i32 = 0; j < shared_len; ++j) {
  247. let i1: i32 = shared[j];
  248. let i1l: i32 = i1 * l;
  249. va = vec4_fadd(va,
  250. buffer_get_i16(vertices, (i1l + 4) * 2),
  251. buffer_get_i16(vertices, (i1l + 5) * 2),
  252. buffer_get_i16(vertices, (i1l + 3) * 2));
  253. }
  254. va = vec4_mult(va, 1 / shared_len);
  255. va = vec4_norm(va);
  256. let vax: i32 = math_floor(va.x * 32767);
  257. let vay: i32 = math_floor(va.y * 32767);
  258. let vaz: i32 = math_floor(va.z * 32767);
  259. for (let j: i32 = 0; j < shared_len; ++j) {
  260. let i1: i32 = shared[j];
  261. let i1l: i32 = i1 * l;
  262. buffer_set_i16(vertices, (i1l + 4) * 2, vax);
  263. buffer_set_i16(vertices, (i1l + 5) * 2, vay);
  264. buffer_set_i16(vertices, (i1l + 3) * 2, vaz);
  265. }
  266. }
  267. }
  268. }
  269. gpu_vertex_buffer_unlock(g._.vertex_buffer);
  270. let va0: i16_array_t = o.data.vertex_arrays[0].values;
  271. let va1: i16_array_t = o.data.vertex_arrays[1].values;
  272. for (let i: i32 = 0; i < math_floor((vertices.length) / 4 / l); ++i) {
  273. va1[i * 2 ] = buffer_get_i16(vertices, (i * l + 4) * 2);
  274. va1[i * 2 + 1] = buffer_get_i16(vertices, (i * l + 5) * 2);
  275. va0[i * 4 + 3] = buffer_get_i16(vertices, (i * l + 3) * 2);
  276. }
  277. }
  278. util_mesh_merge();
  279. render_path_raytrace_ready = false;
  280. }
  281. function util_mesh_to_origin() {
  282. let dx: f32 = 0.0;
  283. let dy: f32 = 0.0;
  284. let dz: f32 = 0.0;
  285. for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
  286. let o: mesh_object_t = project_paint_objects[i];
  287. let l: i32 = 4;
  288. let sc: f32 = o.data.scale_pos / 32767;
  289. let va: i16_array_t = o.data.vertex_arrays[0].values;
  290. let minx: f32 = va[0];
  291. let maxx: f32 = va[0];
  292. let miny: f32 = va[1];
  293. let maxy: f32 = va[1];
  294. let minz: f32 = va[2];
  295. let maxz: f32 = va[2];
  296. for (let i: i32 = 1; i < math_floor(va.length / l); ++i) {
  297. if (va[i * l] < minx) {
  298. minx = va[i * l];
  299. }
  300. else if (va[i * l] > maxx) {
  301. maxx = va[i * l];
  302. }
  303. if (va[i * l + 1] < miny) {
  304. miny = va[i * l + 1];
  305. }
  306. else if (va[i * l + 1] > maxy) {
  307. maxy = va[i * l + 1];
  308. }
  309. if (va[i * l + 2] < minz) {
  310. minz = va[i * l + 2];
  311. }
  312. else if (va[i * l + 2] > maxz) {
  313. maxz = va[i * l + 2];
  314. }
  315. }
  316. dx += (minx + maxx) / 2 * sc;
  317. dy += (miny + maxy) / 2 * sc;
  318. dz += (minz + maxz) / 2 * sc;
  319. }
  320. dx /= project_paint_objects.length;
  321. dy /= project_paint_objects.length;
  322. dz /= project_paint_objects.length;
  323. for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
  324. let o: mesh_object_t = project_paint_objects[i];
  325. let g: mesh_data_t = o.data;
  326. let sc: f32 = o.data.scale_pos / 32767;
  327. let va: i16_array_t = o.data.vertex_arrays[0].values;
  328. let max_scale: f32 = 0.0;
  329. for (let i: i32 = 0; i < math_floor(va.length / 4); ++i) {
  330. if (math_abs(va[i * 4 ] * sc - dx) > max_scale) {
  331. max_scale = math_abs(va[i * 4 ] * sc - dx);
  332. }
  333. if (math_abs(va[i * 4 + 1] * sc - dy) > max_scale) {
  334. max_scale = math_abs(va[i * 4 + 1] * sc - dy);
  335. }
  336. if (math_abs(va[i * 4 + 2] * sc - dz) > max_scale) {
  337. max_scale = math_abs(va[i * 4 + 2] * sc - dz);
  338. }
  339. }
  340. o.base.transform.scale_world = o.data.scale_pos = o.data.scale_pos = max_scale;
  341. transform_build_matrix(o.base.transform);
  342. for (let i: i32 = 0; i < math_floor(va.length / 4); ++i) {
  343. va[i * 4 ] = math_floor((va[i * 4 ] * sc - dx) / max_scale * 32767);
  344. va[i * 4 + 1] = math_floor((va[i * 4 + 1] * sc - dy) / max_scale * 32767);
  345. va[i * 4 + 2] = math_floor((va[i * 4 + 2] * sc - dz) / max_scale * 32767);
  346. }
  347. let l: i32 = gpu_vertex_struct_size(g._.structure) / 2;
  348. let vertices: buffer_t = gpu_lock_vertex_buffer(g._.vertex_buffer); // posnortex
  349. for (let i: i32 = 0; i < math_floor((vertices.length) / 2 / l); ++i) {
  350. buffer_set_i16(vertices, (i * l ) * 2, va[i * 4 ]);
  351. buffer_set_i16(vertices, (i * l + 1) * 2, va[i * 4 + 1]);
  352. buffer_set_i16(vertices, (i * l + 2) * 2, va[i * 4 + 2]);
  353. }
  354. gpu_vertex_buffer_unlock(g._.vertex_buffer);
  355. }
  356. util_mesh_merge();
  357. }
  358. function util_mesh_apply_displacement(texpaint_pack: gpu_texture_t, strength: f32 = 0.1, uv_scale: f32 = 1.0) {
  359. let height: buffer_t = gpu_get_texture_pixels(texpaint_pack);
  360. let res: i32 = texpaint_pack.width;
  361. let o: mesh_object_t = project_paint_objects[0];
  362. let g: mesh_data_t = o.data;
  363. let l: i32 = gpu_vertex_struct_size(g._.structure) / 2;
  364. let vertices: buffer_t = gpu_lock_vertex_buffer(g._.vertex_buffer); // posnortex
  365. for (let i: i32 = 0; i < math_floor((vertices.length) / 2 / l); ++i) {
  366. let x: i32 = math_floor(buffer_get_i16(vertices, (i * l + 6) * 2) / 32767 * res);
  367. let y: i32 = math_floor(buffer_get_i16(vertices, (i * l + 7) * 2) / 32767 * res);
  368. let ix: i32 = math_floor(x * uv_scale);
  369. let iy: i32 = math_floor(y * uv_scale);
  370. let xx: i32 = ix % res;
  371. let yy: i32 = iy % res;
  372. let h: f32 = (1.0 - buffer_get_u8(height, (yy * res + xx) * 4 + 3) / 255) * strength;
  373. buffer_set_i16(vertices, (i * l ) * 2, buffer_get_i16(vertices, (i * l ) * 2) - math_floor(buffer_get_i16(vertices, (i * l + 4) * 2) * h));
  374. buffer_set_i16(vertices, (i * l + 1) * 2, buffer_get_i16(vertices, (i * l + 1) * 2) - math_floor(buffer_get_i16(vertices, (i * l + 5) * 2) * h));
  375. buffer_set_i16(vertices, (i * l + 2) * 2, buffer_get_i16(vertices, (i * l + 2) * 2) - math_floor(buffer_get_i16(vertices, (i * l + 3) * 2) * h));
  376. }
  377. gpu_vertex_buffer_unlock(g._.vertex_buffer);
  378. let va0: i16_array_t = o.data.vertex_arrays[0].values;
  379. for (let i: i32 = 0; i < math_floor((vertices.length) / 4 / l); ++i) {
  380. va0[i * 4 ] = buffer_get_i16(vertices, (i * l ) * 2);
  381. va0[i * 4 + 1] = buffer_get_i16(vertices, (i * l + 1) * 2);
  382. va0[i * 4 + 2] = buffer_get_i16(vertices, (i * l + 2) * 2);
  383. }
  384. }
  385. function util_mesh_equirect_unwrap(mesh: raw_mesh_t) {
  386. let verts: i32 = math_floor(mesh.posa.length / 4);
  387. mesh.texa = i16_array_create(verts * 2);
  388. let n: vec4_t = vec4_create();
  389. for (let i: i32 = 0; i < verts; ++i) {
  390. n = vec4_create(mesh.posa[i * 4] / 32767, mesh.posa[i * 4 + 1] / 32767, mesh.posa[i * 4 + 2] / 32767);
  391. n = vec4_norm(n);
  392. // Sphere projection
  393. // mesh.texa[i * 2 ] = math_atan2(n.x, n.y) / (math_pi() * 2) + 0.5;
  394. // mesh.texa[i * 2 + 1] = n.z * 0.5 + 0.5;
  395. // Equirect
  396. mesh.texa[i * 2 ] = math_floor(((math_atan2(-n.z, n.x) + math_pi()) / (math_pi() * 2)) * 32767);
  397. mesh.texa[i * 2 + 1] = math_floor((math_acos(n.y) / math_pi()) * 32767);
  398. }
  399. }
  400. function util_mesh_pnpoly(v0x: f32, v0y: f32, v1x: f32, v1y: f32, v2x: f32, v2y: f32, px: f32, py: f32): bool {
  401. // https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html
  402. let c: bool = false;
  403. if (((v0y > py) != (v2y > py)) && (px < (v2x - v0x) * (py - v0y) / (v2y - v0y) + v0x)) {
  404. c = !c;
  405. }
  406. if (((v1y > py) != (v0y > py)) && (px < (v0x - v1x) * (py - v1y) / (v0y - v1y) + v1x)) {
  407. c = !c;
  408. }
  409. if (((v2y > py) != (v1y > py)) && (px < (v1x - v2x) * (py - v2y) / (v1y - v2y) + v2x)) {
  410. c = !c;
  411. }
  412. return c;
  413. }
  414. function util_mesh_calc_normal(p0: vec4_t, p1: vec4_t, p2: vec4_t): vec4_t {
  415. let cb: vec4_t = vec4_sub(p2, p1);
  416. let ab: vec4_t = vec4_sub(p0, p1);
  417. cb = vec4_cross(cb, ab);
  418. cb = vec4_norm(cb);
  419. return cb;
  420. }
  421. function util_mesh_decimate() {
  422. let o: mesh_object_t = project_paint_objects[0];
  423. let vas: vertex_array_t[] = o.data.vertex_arrays;
  424. let posa: i16_array_t = vas[0].values;
  425. let nora: i16_array_t = vas[1].values;
  426. let texa: i16_array_t = vas[2].values;
  427. let inda: u32_array_t = o.data.index_arrays[0].values;
  428. let mesh: raw_mesh_t = {
  429. posa: posa,
  430. nora: nora,
  431. texa: texa,
  432. cola: null,
  433. inda: inda,
  434. vertex_count: posa.length / 4,
  435. index_count: inda.length,
  436. scale_pos: o.data.scale_pos,
  437. scale_tex: 1.0,
  438. name: "Decimated",
  439. };
  440. // decimate_mesh(mesh);
  441. import_mesh_add_mesh(mesh);
  442. }