Files
armorpaint/base/sources/import_blend_mesh.ts
T
2024-07-22 00:14:37 +02:00

501 lines
19 KiB
TypeScript

let import_blend_mesh_eps: f32 = 1.0 / 32767;
function import_blend_mesh_run(path: string, replace_existing: bool = true) {
// let b: buffer_t = data_get_blob(path);
// let bl: blend_t = parser_blend_init(b);
// if (bl.dna == null) {
// console_error(strings_error3());
// return;
// }
// let obs: bl_handle_t[] = parser_blend_get(bl, "Object");
// if (obs == null || obs.length == 0) {
// import_mesh_make_mesh(null, path);
// return;
// }
// let first: bool = true;
// for (let i: i32 = 0; i < obs.length; ++i) {
// let ob: bl_handle_t = obs[i];
// if (bl_handle_get(ob, "type") != 1) {
// continue;
// }
// let name: string = bl_handle_get(bl_handle_get(ob, "id"), "name");
// name = substring(name, 2, name.length);
// let m: any = bl_handle_get(ob, "data", 0, "Mesh");
// if (m == null) {
// continue;
// }
// let totpoly: i32 = bl_handle_get(m, "totpoly");
// if (totpoly == 0) {
// continue;
// }
// let numtri: i32 = 0;
// for (let i: i32 = 0; i < totpoly; ++i) {
// let poly: any = bl_handle_get(m, "mpoly", i);
// let totloop: i32 = bl_handle_get(poly, "totloop");
// numtri += totloop - 2;
// }
// let inda: u32_array_t = u32_array_create(numtri * 3);
// for (let i: i32 = 0; i < inda.length; ++i) {
// inda[i] = i;
// }
// let posa32: f32_array_t = f32_array_create(numtri * 3 * 4);
// let posa: i16_array_t = i16_array_create(numtri * 3 * 4);
// let nora: i16_array_t = i16_array_create(numtri * 3 * 2);
// // pdata, 25 == CD_MPOLY
// // let vdata: any = get(m, "vdata");
// // let codata: any = null;
// // let codata_pos: i32 = 0;
// // for (let i: i32 = 0; i < get(vdata, "totlayer"); ++i) {
// // let l: any = get(vdata, "layers", i);
// // if (get(l, "type") == 0) { // CD_MVERT
// // let ptr: any = get(l, "data");
// // codata_pos = bl.get(map, ptr).pos;
// // codata = l;
// // }
// // }
// let ldata: any = bl_handle_get(m, "ldata");
// let uvdata: any = null;
// let uvdata_pos: i32 = 0;
// let coldata: any = null;
// let coldata_pos: i32 = 0;
// for (let i: i32 = 0; i < bl_handle_get(ldata, "totlayer"); ++i) {
// let l: any = bl_handle_get(ldata, "layers", i);
// if (bl_handle_get(l, "type") == 16) { // CD_MLOOPUV
// let ptr: any = bl_handle_get(l, "data");
// uvdata_pos = map_get(bl.map, ptr).pos;
// uvdata = l;
// }
// else if (bl_handle_get(l, "type") == 17) { // CD_PROP_BYTE_COLOR
// let ptr: any = bl_handle_get(l, "data");
// coldata_pos = map_get(bl.map, ptr).pos;
// coldata = l;
// }
// // CD_MLOOP == 26
// }
// let hasuv: bool = uvdata != null;
// let texa: i16_array_t = hasuv ? i16_array_create(numtri * 3 * 2) : null;
// let hascol: bool = context_raw.parse_vcols && coldata != null;
// let cola: i16_array_t = hascol ? i16_array_create(numtri * 3 * 4) : null;
// let tri: i32 = 0;
// let vec0: vec4_t = vec4_create();
// let vec1: vec4_t = vec4_create();
// let vec2: vec4_t = vec4_create();
// for (let i: i32 = 0; i < totpoly; ++i) {
// let poly: any = bl_handle_get(m, "mpoly", i);
// // let smooth: bool = get(poly, "flag") & 1 == 1; // ME_SMOOTH
// let smooth: bool = false; // TODO: fetch smooth normals
// let loopstart: i32 = bl_handle_get(poly, "loopstart");
// let totloop: i32 = bl_handle_get(poly, "totloop");
// if (totloop <= 4) { // Convex, fan triangulation
// let v0: bl_handle_t = import_blend_mesh_get_mvert_v(m, loopstart + totloop - 1);
// let v1: bl_handle_t = import_blend_mesh_get_mvert_v(m, loopstart);
// let co0: any = bl_handle_get(v0, "co");
// let co1: any = bl_handle_get(v1, "co");
// let no0: any = bl_handle_get(v0, "no");
// let no1: any = bl_handle_get(v1, "no");
// if (smooth) {
// vec4_normalize(vec4_set(vec0, no0[0] / 32767, no0[1] / 32767, no0[2] / 32767)); // shortmax
// vec4_normalize(vec4_set(vec1, no1[0] / 32767, no1[1] / 32767, no1[2] / 32767));
// }
// let uv0: f32_array_t = null;
// let uv1: f32_array_t = null;
// let uv2: f32_array_t = null;
// if (hasuv) {
// bl.pos = uvdata_pos + (loopstart + totloop - 1) * 4 * 3; // * 3 = x, y, flag
// uv0 = parser_blend_read_f32array(bl, 2);
// if (uv0[0] > 1.0 + import_blend_mesh_eps) {
// uv0[0] = uv0[0] - math_floor(uv0[0]);
// }
// if (uv0[1] > 1.0 + import_blend_mesh_eps) {
// uv0[1] = uv0[1] - math_floor(uv0[1]);
// }
// bl.pos = uvdata_pos + (loopstart) * 4 * 3;
// uv1 = parser_blend_read_f32array(bl, 2);
// if (uv1[0] > 1.0 + import_blend_mesh_eps) {
// uv1[0] = uv1[0] - math_floor(uv1[0]);
// }
// if (uv1[1] > 1.0 + import_blend_mesh_eps) {
// uv1[1] = uv1[1] - math_floor(uv1[1]);
// }
// }
// let col0r: i32 = 0;
// let col0g: i32 = 0;
// let col0b: i32 = 0;
// let col1r: i32 = 0;
// let col1g: i32 = 0;
// let col1b: i32 = 0;
// let col2r: i32 = 0;
// let col2g: i32 = 0;
// let col2b: i32 = 0;
// if (hascol) {
// bl.pos = coldata_pos + (loopstart + totloop - 1) * 1 * 4; // * 4 = r, g, b, a
// col0r = parser_blend_read_i8(bl);
// col0g = parser_blend_read_i8(bl);
// col0b = parser_blend_read_i8(bl);
// bl.pos = coldata_pos + (loopstart) * 1 * 4;
// col1r = parser_blend_read_i8(bl);
// col1g = parser_blend_read_i8(bl);
// col1b = parser_blend_read_i8(bl);
// }
// for (let j: i32 = 0; j < totloop - 2; ++j) {
// let v2: bl_handle_t = import_blend_mesh_get_mvert_v(m, loopstart + j + 1);
// let co2: any = bl_handle_get(v2, "co");
// let no2: any = bl_handle_get(v2, "no");
// if (smooth) {
// vec4_normalize(vec4_set(vec2, no2[0] / 32767, no2[1] / 32767, no2[2] / 32767));
// }
// else {
// vec4_set(vec2, co2[0], co2[1], co2[2]);
// vec4_set(vec1, co1[0], co1[1], co1[2]);
// vec4_sub_vecs(vec0, vec2, vec1);
// vec4_set(vec2, co0[0], co0[1], co0[2]);
// vec4_sub_vecs(vec1, vec2, vec1);
// vec4_cross(vec0, vec1);
// vec4_normalize(vec0);
// }
// posa32[tri * 9 ] = co0[0];
// posa32[tri * 9 + 1] = co0[1];
// posa32[tri * 9 + 2] = co0[2];
// posa32[tri * 9 + 3] = co1[0];
// posa32[tri * 9 + 4] = co1[1];
// posa32[tri * 9 + 5] = co1[2];
// posa32[tri * 9 + 6] = co2[0];
// posa32[tri * 9 + 7] = co2[1];
// posa32[tri * 9 + 8] = co2[2];
// posa[tri * 12 + 3] = math_floor(vec0.z * 32767);
// posa[tri * 12 + 7] = math_floor((smooth ? vec1.z : vec0.z) * 32767);
// posa[tri * 12 + 11] = math_floor((smooth ? vec2.z : vec0.z) * 32767);
// nora[tri * 6 ] = math_floor(vec0.x * 32767);
// nora[tri * 6 + 1] = math_floor(vec0.y * 32767);
// nora[tri * 6 + 2] = math_floor((smooth ? vec1.x : vec0.x) * 32767);
// nora[tri * 6 + 3] = math_floor((smooth ? vec1.y : vec0.y) * 32767);
// nora[tri * 6 + 4] = math_floor((smooth ? vec2.x : vec0.x) * 32767);
// nora[tri * 6 + 5] = math_floor((smooth ? vec2.y : vec0.y) * 32767);
// co1 = co2;
// no1 = no2;
// vec4_set_from(vec1, vec2);
// if (hasuv) {
// bl.pos = uvdata_pos + (loopstart + j + 1) * 4 * 3;
// uv2 = parser_blend_read_f32array(bl, 2);
// if (uv2[0] > 1.0 + import_blend_mesh_eps) {
// uv2[0] = uv2[0] - math_floor(uv2[0]);
// }
// if (uv2[1] > 1.0 + import_blend_mesh_eps) {
// uv2[1] = uv2[1] - math_floor(uv2[1]);
// }
// texa[tri * 6 ] = math_floor(uv0[0] * 32767);
// texa[tri * 6 + 1] = math_floor((1.0 - uv0[1]) * 32767);
// texa[tri * 6 + 2] = math_floor(uv1[0] * 32767);
// texa[tri * 6 + 3] = math_floor((1.0 - uv1[1]) * 32767);
// texa[tri * 6 + 4] = math_floor(uv2[0] * 32767);
// texa[tri * 6 + 5] = math_floor((1.0 - uv2[1]) * 32767);
// uv1 = uv2;
// }
// if (hascol) {
// bl.pos = coldata_pos + (loopstart + j + 1) * 1 * 4;
// col2r = parser_blend_read_i8(bl);
// col2g = parser_blend_read_i8(bl);
// col2b = parser_blend_read_i8(bl);
// cola[tri * 12 ] = col0r * 128;
// cola[tri * 12 + 1] = col0g * 128;
// cola[tri * 12 + 2] = col0b * 128;
// cola[tri * 12 + 3] = col1r * 128;
// cola[tri * 12 + 4] = col1g * 128;
// cola[tri * 12 + 5] = col1b * 128;
// cola[tri * 12 + 6] = col2r * 128;
// cola[tri * 12 + 7] = col2g * 128;
// cola[tri * 12 + 8] = col2b * 128;
// col1r = col2r;
// col1g = col2g;
// col1b = col2b;
// }
// tri++;
// }
// }
// else { // Convex or concave, ear clipping
// let va: i32[] = [];
// for (let i: i32 = 0; i < totloop; ++i) {
// array_push(va, loopstart + i);
// }
// let v0: bl_handle_t = import_blend_mesh_get_mvert_v(m, loopstart);
// let v1: bl_handle_t = import_blend_mesh_get_mvert_v(m, loopstart + 1);
// let v2: bl_handle_t = import_blend_mesh_get_mvert_v(m, loopstart + 2);
// let co0: any = bl_handle_get(v0, "co");
// let co1: any = bl_handle_get(v1, "co");
// let co2: any = bl_handle_get(v2, "co");
// vec4_set(vec2, co2[0], co2[1], co2[2]);
// vec4_set(vec1, co1[0], co1[1], co1[2]);
// vec4_sub_vecs(vec0, vec2, vec1);
// vec4_set(vec2, co0[0], co0[1], co0[2]);
// vec4_sub_vecs(vec1, vec2, vec1);
// vec4_cross(vec0, vec1);
// vec4_normalize(vec0, );
// let nx: f32 = vec0.x;
// let ny: f32 = vec0.y;
// let nz: f32 = vec0.z;
// let nxabs: f32 = math_abs(nx);
// let nyabs: f32 = math_abs(ny);
// let nzabs: f32 = math_abs(nz);
// let flip: bool = nx + ny + nz > 0;
// let axis: i32 = nxabs > nyabs && nxabs > nzabs ? 0 : nyabs > nxabs && nyabs > nzabs ? 1 : 2;
// let axis0: i32 = axis == 0 ? (flip ? 2 : 1) : axis == 1 ? (flip ? 0 : 2) : (flip ? 1 : 0);
// let axis1: i32 = axis == 0 ? (flip ? 1 : 2) : axis == 1 ? (flip ? 2 : 0) : (flip ? 0 : 1);
// let winding: f32 = 0.0;
// for (let i: i32 = 0; i < totloop; ++i) {
// let v0: bl_handle_t = import_blend_mesh_get_mvert_v(m, loopstart + i);
// let v1: bl_handle_t = import_blend_mesh_get_mvert_v(m, loopstart + ((i + 1) % totloop));
// let co0: any = bl_handle_get(v0, "co");
// let co1: any = bl_handle_get(v1, "co");
// winding += (co1[axis0] - co0[axis0]) * (co1[axis1] + co0[axis1]);
// }
// flip = winding > 0 ? nx + ny + nz > 0 : nx + ny + nz < 0;
// axis0 = axis == 0 ? (flip ? 2 : 1) : axis == 1 ? (flip ? 0 : 2) : (flip ? 1 : 0);
// axis1 = axis == 0 ? (flip ? 1 : 2) : axis == 1 ? (flip ? 2 : 0) : (flip ? 0 : 1);
// let vi: i32 = totloop;
// let loops: i32 = 0;
// let i: i32 = -1;
// while (vi > 2 && loops++ < vi) {
// i = (i + 1) % vi;
// let i1: i32 = (i + 1) % vi;
// let i2: i32 = (i + 2) % vi;
// let v0: bl_handle_t = import_blend_mesh_get_mvert_v(m, va[i ]);
// let v1: bl_handle_t = import_blend_mesh_get_mvert_v(m, va[i1]);
// let v2: bl_handle_t = import_blend_mesh_get_mvert_v(m, va[i2]);
// let co0: any = bl_handle_get(v0, "co");
// let co1: any = bl_handle_get(v1, "co");
// let co2: any = bl_handle_get(v2, "co");
// let v0x: f32 = co0[axis0];
// let v0y: f32 = co0[axis1];
// let v1x: f32 = co1[axis0];
// let v1y: f32 = co1[axis1];
// let v2x: f32 = co2[axis0];
// let v2y: f32 = co2[axis1];
// let e0x: f32 = v0x - v1x; // Not an interior vertex
// let e0y: f32 = v0y - v1y;
// let e1x: f32 = v2x - v1x;
// let e1y: f32 = v2y - v1y;
// let cross: f32 = e0x * e1y - e0y * e1x;
// if (cross <= 0) {
// continue;
// }
// let overlap: bool = false; // Other vertex found inside this triangle
// for (let j: i32 = 0; j < vi - 3; ++j) {
// let j0: i32 = (i + 3 + j) % vi;
// let v: bl_handle_t = import_blend_mesh_get_mvert_v(m, va[j0]);
// let co: any = bl_handle_get(v, "co");
// let px: f32 = co[axis0];
// let py: f32 = co[axis1];
// if (util_mesh_pnpoly(v0x, v0y, v1x, v1y, v2x, v2y, px, py)) {
// overlap = true;
// break;
// }
// }
// if (overlap) {
// continue;
// }
// // Found ear
// {
// let no0: any = bl_handle_get(v0, "no");
// let no1: any = bl_handle_get(v1, "no");
// let no2: any = bl_handle_get(v2, "no");
// if (smooth) {
// vec4_normalize(vec4_set(vec0, no0[0] / 32767, no0[1] / 32767, no0[2] / 32767)); // shortmax
// vec4_normalize(vec4_set(vec1, no1[0] / 32767, no1[1] / 32767, no1[2] / 32767));
// vec4_normalize(vec4_set(vec2, no2[0] / 32767, no2[1] / 32767, no2[2] / 32767));
// }
// else {
// vec4_set(vec2, co2[0], co2[1], co2[2]);
// vec4_set(vec1, co1[0], co1[1], co1[2]);
// vec4_sub_vecs(vec0, vec2, vec1);
// vec4_set(vec2, co0[0], co0[1], co0[2]);
// vec4_sub_vecs(vec1, vec2, vec1);
// vec4_cross(vec0, vec1);
// vec4_normalize(vec0, );
// }
// let uv0: f32_array_t = null;
// let uv1: f32_array_t = null;
// let uv2: f32_array_t = null;
// if (hasuv) {
// bl.pos = uvdata_pos + (va[i ]) * 4 * 3;
// uv0 = parser_blend_read_f32array(bl, 2);
// if (uv0[0] > 1.0 + import_blend_mesh_eps) {
// uv0[0] = uv0[0] - math_floor(uv0[0]);
// }
// if (uv0[1] > 1.0 + import_blend_mesh_eps) {
// uv0[1] = uv0[1] - math_floor(uv0[1]);
// }
// bl.pos = uvdata_pos + (va[i1]) * 4 * 3;
// uv1 = parser_blend_read_f32array(bl, 2);
// if (uv1[0] > 1.0 + import_blend_mesh_eps) {
// uv1[0] = uv1[0] - math_floor(uv1[0]);
// }
// if (uv1[1] > 1.0 + import_blend_mesh_eps) {
// uv1[1] = uv1[1] - math_floor(uv1[1]);
// }
// bl.pos = uvdata_pos + (va[i2]) * 4 * 3;
// uv2 = parser_blend_read_f32array(bl, 2);
// if (uv2[0] > 1.0 + import_blend_mesh_eps) {
// uv2[0] = uv2[0] - math_floor(uv2[0]);
// }
// if (uv2[1] > 1.0 + import_blend_mesh_eps) {
// uv2[1] = uv2[1] - math_floor(uv2[1]);
// }
// }
// let col0r: i32 = 0;
// let col0g: i32 = 0;
// let col0b: i32 = 0;
// let col1r: i32 = 0;
// let col1g: i32 = 0;
// let col1b: i32 = 0;
// let col2r: i32 = 0;
// let col2g: i32 = 0;
// let col2b: i32 = 0;
// if (hascol) {
// bl.pos = coldata_pos + (va[i ]) * 1 * 4;
// col0r = parser_blend_read_i8(bl);
// col0g = parser_blend_read_i8(bl);
// col0b = parser_blend_read_i8(bl);
// bl.pos = coldata_pos + (va[i1]) * 1 * 4;
// col1r = parser_blend_read_i8(bl);
// col1g = parser_blend_read_i8(bl);
// col1b = parser_blend_read_i8(bl);
// bl.pos = coldata_pos + (va[i2]) * 1 * 4;
// col2r = parser_blend_read_i8(bl);
// col2g = parser_blend_read_i8(bl);
// col2b = parser_blend_read_i8(bl);
// }
// posa32[tri * 9 ] = co0[0];
// posa32[tri * 9 + 1] = co0[1];
// posa32[tri * 9 + 2] = co0[2];
// posa32[tri * 9 + 3] = co1[0];
// posa32[tri * 9 + 4] = co1[1];
// posa32[tri * 9 + 5] = co1[2];
// posa32[tri * 9 + 6] = co2[0];
// posa32[tri * 9 + 7] = co2[1];
// posa32[tri * 9 + 8] = co2[2];
// posa[tri * 12 + 3] = math_floor(vec0.z * 32767);
// posa[tri * 12 + 7] = math_floor((smooth ? vec1.z : vec0.z) * 32767);
// posa[tri * 12 + 11] = math_floor((smooth ? vec2.z : vec0.z) * 32767);
// nora[tri * 6 ] = math_floor(vec0.x * 32767);
// nora[tri * 6 + 1] = math_floor(vec0.y * 32767);
// nora[tri * 6 + 2] = math_floor((smooth ? vec1.x : vec0.x) * 32767);
// nora[tri * 6 + 3] = math_floor((smooth ? vec1.y : vec0.y) * 32767);
// nora[tri * 6 + 4] = math_floor((smooth ? vec2.x : vec0.x) * 32767);
// nora[tri * 6 + 5] = math_floor((smooth ? vec2.y : vec0.y) * 32767);
// if (hasuv) {
// texa[tri * 6 ] = math_floor(uv0[0] * 32767);
// texa[tri * 6 + 1] = math_floor((1.0 - uv0[1]) * 32767);
// texa[tri * 6 + 2] = math_floor(uv1[0] * 32767);
// texa[tri * 6 + 3] = math_floor((1.0 - uv1[1]) * 32767);
// texa[tri * 6 + 4] = math_floor(uv2[0] * 32767);
// texa[tri * 6 + 5] = math_floor((1.0 - uv2[1]) * 32767);
// }
// if (hascol) {
// cola[tri * 12 ] = col0r * 128;
// cola[tri * 12 + 1] = col0g * 128;
// cola[tri * 12 + 2] = col0b * 128;
// cola[tri * 12 + 3] = col1r * 128;
// cola[tri * 12 + 4] = col1g * 128;
// cola[tri * 12 + 5] = col1b * 128;
// cola[tri * 12 + 6] = col2r * 128;
// cola[tri * 12 + 7] = col2g * 128;
// cola[tri * 12 + 8] = col2b * 128;
// }
// tri++;
// }
// for (let j: i32 = ((i + 1) % vi); j < vi - 1; ++j) { // Consume vertex
// va[j] = va[j + 1];
// }
// vi--;
// i--;
// loops = 0;
// }
// }
// }
// // Apply world matrix
// let obmat: any = bl_handle_get(ob, "obmat", 0, "float", 16);
// let mat: mat4_t = mat4_transpose(mat4_from_f32_array(obmat));
// let v: vec4_t = vec4_create();
// for (let i: i32 = 0; i < math_floor(posa32.length / 3); ++i) {
// vec4_set(v, posa32[i * 3], posa32[i * 3 + 1], posa32[i * 3 + 2]);
// vec4_apply_mat4(v, mat);
// posa32[i * 3 ] = v.x;
// posa32[i * 3 + 1] = v.y;
// posa32[i * 3 + 2] = v.z;
// }
// mat4_get_inv(mat, mat);
// mat4_transpose3x3(mat);
// mat.m[12] = mat.m[13] = mat.m[14] = mat.m[15] = 0;
// for (let i: i32 = 0; i < math_floor(nora.length / 2); ++i) {
// vec4_set(v, nora[i * 2] / 32767, nora[i * 2 + 1] / 32767, posa[i * 4 + 3] / 32767);
// vec4_apply_mat(v, mat);
// vec4_normalize(v);
// nora[i * 2 ] = math_floor(v.x * 32767);
// nora[i * 2 + 1] = math_floor(v.y * 32767);
// posa[i * 4 + 3] = math_floor(v.z * 32767);
// }
// // Pack positions to (-1, 1) range
// let scale_pos: f32 = 0.0;
// for (let i: i32 = 0; i < posa32.length; ++i) {
// let f: f32 = math_abs(posa32[i]);
// if (scale_pos < f) {
// scale_pos = f;
// }
// }
// let inv: f32 = 1 / scale_pos;
// for (let i: i32 = 0; i < math_floor(posa32.length / 3); ++i) {
// posa[i * 4 ] = math_floor(posa32[i * 3 ] * 32767 * inv);
// posa[i * 4 + 1] = math_floor(posa32[i * 3 + 1] * 32767 * inv);
// posa[i * 4 + 2] = math_floor(posa32[i * 3 + 2] * 32767 * inv);
// }
// let obj: any = {
// posa: posa,
// nora: nora,
// texa: texa,
// cola: cola,
// inda: inda,
// name: name,
// scale_pos: scale_pos,
// scale_tex: 1.0
// };
// if (first && replace_existing) {
// import_mesh_make_mesh(obj, path);
// }
// else {
// import_mesh_add_mesh(obj);
// }
// first = false;
// }
// data_delete_blob(path);
}
// function import_blend_mesh_get_mvert_v(m: bl_handle_t, loopstart: i32) {
// return bl_handle_get(m, "mvert", bl_handle_get(bl_handle_get(m, "mloop", loopstart), "v"));
// }