From 3b3269f033b3831b749b9076b8b1187878dd0824 Mon Sep 17 00:00:00 2001 From: luboslenco Date: Mon, 11 Aug 2025 23:08:58 +0200 Subject: [PATCH] Cleanup --- base/assets/Scene.arm | Bin 177864 -> 177724 bytes base/project.js | 1 - base/sources/ts/iron/anim.ts | 21 +- base/sources/ts/iron/anim_bone.ts | 720 ------------------- base/sources/ts/iron/anim_object.ts | 7 +- base/sources/ts/iron/armature.ts | 103 --- base/sources/ts/iron/mesh_data.ts | 103 --- base/sources/ts/iron/mesh_object.ts | 14 - base/sources/ts/iron/object.ts | 24 - base/sources/ts/iron/scene.ts | 71 +- base/sources/ts/iron/transform.ts | 12 - base/sources/ts/iron/uniforms.ts | 9 +- base/sources/ts/strings.ts | 24 - base/sources/ts/util_clone.ts | 5 - base/sources/ts/util_encode.ts | 2 - base/tools/io_export_arm.py | 303 +------- paint/assets/meshes/box.arm | Bin 1334 -> 1324 bytes paint/assets/meshes/box_bevel.arm | Bin 9206 -> 9196 bytes paint/assets/meshes/box_bevel_shared_uvs.arm | Bin 19766 -> 19756 bytes paint/assets/meshes/box_shared_uvs.arm | Bin 1334 -> 1324 bytes paint/assets/meshes/cone.arm | Bin 6417 -> 6407 bytes paint/assets/meshes/cylinder.arm | Bin 9989 -> 9979 bytes paint/assets/meshes/torus.arm | Bin 27212 -> 27202 bytes paint/sources/make_mesh_preview.ts | 26 - 24 files changed, 9 insertions(+), 1436 deletions(-) delete mode 100644 base/sources/ts/iron/anim_bone.ts delete mode 100644 base/sources/ts/iron/armature.ts diff --git a/base/assets/Scene.arm b/base/assets/Scene.arm index f7f5643f26faf7e7a5629ccc5325d43351e3f083..ae908d7248bd24e73c5945c2e46d46a40b0efc31 100644 GIT binary patch delta 309 zcmX@{mTS)&t__U>jI0y2r6$i2P@B%g&nUF{o`7B&BkN=bMv2L)E~q_ogr2i%fdyZr|*}CDfCc4 z5{9`Te7meNMA%Q2(GKj-?JHCn_cJoGPR~$hv;~WRe7T)bgVD_yDC&{TXb%@{f1J&@ K{c$$aQ!fA!w^0}X delta 421 zcmdn&zt__U>jBFFNr6$i2P~&7_U|=ZD&dfWo`JjMf8YA0e2S$m>(&b1JlMf06 zZ=PIkHw7q}$1E}Z6*r>>Lfdvh9>xwPu$0vFEqshf8mBK5WQ^Kw%+II?k(ZcWC5WOG zC=b#){i7J8_;g1RWVz`;V z=IsY%AeI7!rKhLLqw9;>{!AWXFj#?s61swj?dz2w20u_?v_lvS3?||22C9tv8G%0f mpvGv6A{D&7UY*g+8RA*t={K_&bx`Ho!?PK;hi5ZA^#TCm9&;%G diff --git a/base/project.js b/base/project.js index b1801ee2..41a163fd 100644 --- a/base/project.js +++ b/base/project.js @@ -83,7 +83,6 @@ if (!flags.lite) { project.add_define("arm_physics"); } - // project.add_define("arm_skin"); // project.add_define("arm_audio"); if (platform === "android") { diff --git a/base/sources/ts/iron/anim.ts b/base/sources/ts/iron/anim.ts index 1abf0b23..89ebf41e 100644 --- a/base/sources/ts/iron/anim.ts +++ b/base/sources/ts/iron/anim.ts @@ -2,13 +2,9 @@ ///if arm_anim type anim_raw_t = { - ext?: any; // anim_bone_t | anim_object_t + ext?: any; // anim_object_t ext_type?: string; - is_skinned?: bool; action?: string; - ///if arm_skin - armature?: armature_t; // Bone - ///end time?: f32; speed?: f32; loop?: bool; @@ -77,11 +73,6 @@ function anim_play(raw: anim_raw_t, action: string = "", on_complete: ()=>void = if (raw.ext_type == "anim_object_t") { anim_object_play(raw.ext, action, on_complete, blend_time, speed, loop); } - ///if arm_skin - else if (raw.ext_type == "anim_bone_t") { - anim_bone_play(raw.ext, action, on_complete, blend_time, speed, loop); - } - ///end else { anim_play_super(raw, action, on_complete, blend_time, speed, loop); } @@ -94,11 +85,6 @@ function anim_blend_super(raw: anim_raw_t, action1: string, action2: string, fac function anim_blend(raw: anim_raw_t, action1: string, action2: string, factor: f32) { if (raw.ext != null) { - ///if arm_skin - if (raw.ext_type == "anim_bone_t") { - anim_bone_blend(raw.ext, action1, action2, factor); - } - ///end } else { anim_blend_super(raw, action1, action2, factor); @@ -135,11 +121,6 @@ function anim_update(raw: anim_raw_t, delta: f32) { if (raw.ext_type == "anim_object_t") { anim_object_update(raw.ext, delta); } - ///if arm_skin - else if (raw.ext_type == "anim_bone_t") { - anim_bone_update(raw.ext, delta); - } - ///end else { anim_update_super(raw, delta); } diff --git a/base/sources/ts/iron/anim_bone.ts b/base/sources/ts/iron/anim_bone.ts deleted file mode 100644 index 71913fed..00000000 --- a/base/sources/ts/iron/anim_bone.ts +++ /dev/null @@ -1,720 +0,0 @@ - -///if arm_skin - -type anim_bone_t = { - base?: anim_raw_t; - object?: mesh_object_t; - data?: mesh_data_t; - skin_buffer?: f32_array_t; - skeleton_bones?: obj_t[]; - skeleton_mats?: mat4_t[]; - skeleton_bones_blend?: obj_t[]; - skeleton_mats_blend?: mat4_t[]; - abs_mats?: mat4_t[]; - apply_parent?: bool[]; - mats_fast?: mat4_t[]; - mats_fast_sort?: i32[]; - mats_fast_blend?: mat4_t[]; - mats_fast_blend_sort?: i32[]; - bone_children?: map_t; // Parented to bone - // Do inverse kinematics here - on_updates?: (()=>void)[]; -}; - -let _anim_bone_skin_max_bones: i32 = 128; -let _anim_bone_m: mat4_t = mat4_identity(); // Skinning matrix -let _anim_bone_m1: mat4_t = mat4_identity(); -let _anim_bone_m2: mat4_t = mat4_identity(); -let _anim_bone_bm: mat4_t = mat4_identity(); // Absolute bone matrix -let _anim_bone_wm: mat4_t = mat4_identity(); -let _anim_bone_vpos: vec4_t = vec4_create(); -let _anim_bone_vscale: vec4_t = vec4_create(); -let _anim_bone_q1: quat_t = quat_create(); -let _anim_bone_q2: quat_t = quat_create(); -let _anim_bone_q3: quat_t = quat_create(); -let _anim_bone_vpos2: vec4_t = vec4_create(); -let _anim_bone_vscale2: vec4_t = vec4_create(); -let _anim_bone_v1: vec4_t = vec4_create(); -let _anim_bone_v2: vec4_t = vec4_create(); - -function anim_bone_create(armature_name: string = ""): anim_bone_t { - let raw: anim_bone_t = {}; - raw.mats_fast = []; - raw.mats_fast_sort = []; - raw.mats_fast_blend = []; - raw.mats_fast_blend_sort = []; - raw.base = anim_create(); - raw.base.ext = raw; - raw.base.ext_type = "anim_bone_t"; - - for (let i: i32 = 0; i < scene_armatures.length; ++i) { - let a: armature_t = scene_armatures[i]; - if (a.name == armature_name) { - raw.base.armature = a; - break; - } - } - return raw; -} - -function anim_bone_set_skin(raw: anim_bone_t, mo: mesh_object_t) { - raw.object = mo; - raw.data = mo != null ? mo.data : null; - raw.base.is_skinned = raw.data != null ? raw.data.skin != null : false; - if (raw.base.is_skinned) { - let bone_size: i32 = 8; // Dual-quat skinning - raw.skin_buffer = f32_array_create(_anim_bone_skin_max_bones * bone_size); - for (let i: i32 = 0; i < raw.skin_buffer.length; ++i) { - raw.skin_buffer[i] = 0; - } - // Rotation is already applied to skin at export - raw.object.base.transform.rot = quat_create(0, 0, 0, 1); - transform_build_matrix(raw.object.base.transform); - - let refs: string[] = mo.base.parent.raw.anim.bone_actions; - if (refs != null && refs.length > 0) { - let action: scene_t = data_get_scene_raw(refs[0]); - anim_bone_play(raw, action.name); - } - } -} - -function anim_bone_add_bone_child(raw: anim_bone_t, bone: string, o: object_t) { - if (raw.bone_children == null) { - raw.bone_children = map_create(); - } - let ar: object_t[] = map_get(raw.bone_children, bone); - if (ar == null) { - ar = []; - map_set(raw.bone_children, bone, ar); - } - array_push(ar, o); -} - -function anim_bone_remove_bone_child(raw: anim_bone_t, bone: string, o: object_t) { - if (raw.bone_children != null) { - let ar: object_t[] = map_get(raw.bone_children, bone); - if (ar != null) { - array_remove(ar, o); - } - } -} - -function anim_bone_update_bone_children(raw: anim_bone_t, bone: obj_t, bm: mat4_t) { - let ar: object_t[] = map_get(raw.bone_children, bone.name); - if (ar == null) { - return; - } - for (let i: i32 = 0; i < ar.length; ++i) { - let o: object_t = ar[i]; - let t: transform_t = o.transform; - if (t.bone_parent == null) { - t.bone_parent = mat4_identity(); - } - if (o.raw.anim.parent_bone_tail != null) { - if (o.raw.anim.parent_bone_connected || raw.base.is_skinned) { - let v: f32_array_t = o.raw.anim.parent_bone_tail; - t.bone_parent = mat4_init_translate(v[0], v[1], v[2]); - t.bone_parent = mat4_mult_mat(t.bone_parent, bm); - } - else { - let v: f32_array_t = o.raw.anim.parent_bone_tail_pose; - t.bone_parent = mat4_clone(bm); - t.bone_parent = mat4_translate(t.bone_parent, v[0], v[1], v[2]); - } - } - else { - t.bone_parent = mat4_clone(bm); - } - transform_build_matrix(t); - } -} - -function anim_bone_num_parents(b: obj_t): i32 { - let i: i32 = 0; - let p: obj_t = b.parent; - while (p != null) { - i++; - p = p.parent; - } - return i; -} - -let _anim_bone_sort_data: any; - -function anim_bone_sort(pa: any_ptr, pb: any_ptr) { - let a: i32 = DEREFERENCE(pa); - let b: i32 = DEREFERENCE(pb); - let i: i32 = anim_bone_num_parents(_anim_bone_sort_data[a]); - let j: i32 = anim_bone_num_parents(_anim_bone_sort_data[b]); - return i < j ? -1 : i > j ? 1 : 0; -} - -function anim_bone_set_mats(raw: anim_bone_t) { - while (raw.mats_fast.length < raw.skeleton_bones.length) { - array_push(raw.mats_fast, mat4_identity()); - array_push(raw.mats_fast_sort, raw.mats_fast_sort.length); - } - // Calc bones with 0 parents first - _anim_bone_sort_data = raw.skeleton_bones; - array_sort(raw.mats_fast_sort, anim_bone_sort); - - if (raw.skeleton_bones_blend != null) { - while (raw.mats_fast_blend.length < raw.skeleton_bones_blend.length) { - array_push(raw.mats_fast_blend, mat4_identity()); - array_push(raw.mats_fast_blend_sort, raw.mats_fast_blend_sort.length); - } - _anim_bone_sort_data = raw.skeleton_bones_blend; - array_sort(raw.mats_fast_blend_sort, anim_bone_sort); - } -} - -function anim_bone_set_action(raw: anim_bone_t, action: string) { - if (raw.base.is_skinned) { - raw.skeleton_bones = map_get(raw.data._actions, action); - raw.skeleton_mats = map_get(raw.data._mats, action); - raw.skeleton_bones_blend = null; - raw.skeleton_mats_blend = null; - } - else { - armature_init_mats(raw.base.armature); - let a = armature_get_action(raw.base.armature, action); - raw.skeleton_bones = a.bones; - raw.skeleton_mats = a.mats; - } - anim_bone_set_mats(raw); -} - -function anim_bone_set_action_blend(raw: anim_bone_t, action: string) { - if (raw.base.is_skinned) { - raw.skeleton_bones_blend = raw.skeleton_bones; - raw.skeleton_mats_blend = raw.skeleton_mats; - raw.skeleton_bones = map_get(raw.data._actions, action); - raw.skeleton_mats = map_get(raw.data._mats, action); - } - else { - armature_init_mats(raw.base.armature); - let a: armature_action_t = armature_get_action(raw.base.armature, action); - raw.skeleton_bones = a.bones; - raw.skeleton_mats = a.mats; - } - anim_bone_set_mats(raw); -} - -function anim_bone_mult_parent(raw: anim_bone_t, i: i32, fasts: mat4_t[], bones: obj_t[], mats: mat4_t[]) { - let f: mat4_t = fasts[i]; - if (raw.apply_parent != null && !raw.apply_parent[i]) { - f = mat4_clone(mats[i]); - return; - } - let p = bones[i].parent; - let bi = anim_bone_get_bone_index(raw, p, bones); - if (p == null || bi == -1) { - f = mat4_clone(mats[i]); - } - else { - f = mat4_mult_mat(mats[i], fasts[bi]); - } -} - -function anim_bone_mult_parents(raw: anim_bone_t, m: mat4_t, i: i32, bones: obj_t[], mats: mat4_t[]) { - let bone: obj_t = bones[i]; - let p: obj_t = bone.parent; - while (p != null) { - let i: i32 = anim_bone_get_bone_index(raw, p, bones); - if (i == -1) { - continue; - } - m = mat4_mult_mat(m, mats[i]); - p = p.parent; - } -} - -function anim_bone_notify_on_update(raw: anim_bone_t, f: ()=>void) { - if (raw.on_updates == null) { - raw.on_updates = []; - } - array_push(raw.on_updates, f); -} - -function anim_bone_remove_update(raw: anim_bone_t, f: ()=>void) { - array_remove(raw.on_updates, f); -} - -function anim_bone_update_bones_only(raw: anim_bone_t) { - if (raw.bone_children != null) { - for (let i: i32 = 0; i < raw.skeleton_bones.length; ++i) { - let b = raw.skeleton_bones[i]; // TODO: blend_time > 0 - _anim_bone_m = mat4_clone(raw.mats_fast[i]); - anim_bone_update_bone_children(raw, b, _anim_bone_m); - } - } -} - -function anim_bone_update_skin_gpu(raw: anim_bone_t) { - let bones: obj_t[] = raw.skeleton_bones; - - let s: f32 = raw.base.blend_current / raw.base.blend_time; - s = s * s * (3.0 - 2.0 * s); // Smoothstep - if (raw.base.blend_factor != 0.0) { - s = 1.0 - raw.base.blend_factor; - } - - // Update skin buffer - for (let i: i32 = 0; i < bones.length; ++i) { - _anim_bone_m = mat4_clone(raw.mats_fast[i]); - - if (raw.base.blend_time > 0 && raw.skeleton_bones_blend != null) { - // Decompose - _anim_bone_m1 = mat4_clone(raw.mats_fast_blend[i]); - mat4_decompose(_anim_bone_m1, _anim_bone_vpos, _anim_bone_q1, _anim_bone_vscale); - mat4_decompose(_anim_bone_m, _anim_bone_vpos2, _anim_bone_q2, _anim_bone_vscale2); - - // Lerp - _anim_bone_v1 = vec4_lerp(_anim_bone_vpos, _anim_bone_vpos2, s); - _anim_bone_v2 = vec4_lerp(_anim_bone_vscale, _anim_bone_vscale2, s); - _anim_bone_q3 = quat_lerp(_anim_bone_q1, _anim_bone_q2, s); - - // Compose - _anim_bone_m = mat4_from_quat(_anim_bone_q3); - _anim_bone_m = mat4_scale(_anim_bone_m, _anim_bone_v2); - _anim_bone_m.m30 = _anim_bone_v1.x; - _anim_bone_m.m31 = _anim_bone_v1.y; - _anim_bone_m.m32 = _anim_bone_v1.z; - } - - if (raw.abs_mats != null && i < raw.abs_mats.length) { - raw.abs_mats[i] = mat4_clone(_anim_bone_m); - } - if (raw.bone_children != null) { - anim_bone_update_bone_children(raw, bones[i], _anim_bone_m); - } - - _anim_bone_m = mat4_mult_mat(raw.data._skeleton_transforms_inv[i], _anim_bone_m); - anim_bone_update_skin_buffer(raw, _anim_bone_m, i); - } -} - -function anim_bone_update_skin_buffer(raw: anim_bone_t, m: mat4_t, i: i32) { - // Dual quat skinning - mat4_decompose(m, _anim_bone_vpos, _anim_bone_q1, _anim_bone_vscale); - _anim_bone_q1 = quat_norm(_anim_bone_q1); - _anim_bone_q2 = quat_create(_anim_bone_vpos.x, _anim_bone_vpos.y, _anim_bone_vpos.z, 0.0); - _anim_bone_q2 = quat_mult(_anim_bone_q2, _anim_bone_q1); - raw.skin_buffer[i * 8] = _anim_bone_q1.x; // Real - raw.skin_buffer[i * 8 + 1] = _anim_bone_q1.y; - raw.skin_buffer[i * 8 + 2] = _anim_bone_q1.z; - raw.skin_buffer[i * 8 + 3] = _anim_bone_q1.w; - raw.skin_buffer[i * 8 + 4] = _anim_bone_q2.x * 0.5; // Dual - raw.skin_buffer[i * 8 + 5] = _anim_bone_q2.y * 0.5; - raw.skin_buffer[i * 8 + 6] = _anim_bone_q2.z * 0.5; - raw.skin_buffer[i * 8 + 7] = _anim_bone_q2.w * 0.5; -} - -function anim_bone_get_bone(raw: anim_bone_t, name: string): obj_t { - if (raw.skeleton_bones == null) { - return null; - } - for (let i: i32 = 0; i < raw.skeleton_bones.length; ++i) { - let b: obj_t = raw.skeleton_bones[i]; - if (b.name == name) { - return b; - } - } - return null; -} - -function anim_bone_get_bone_index(raw: anim_bone_t, bone: obj_t, bones: obj_t[] = null): i32 { - if (bones == null) { - bones = raw.skeleton_bones; - } - if (bones != null) { - for (let i: i32 = 0; i < bones.length; ++i) { - if (bones[i] == bone) { - return i; - } - } - } - return -1; -} - -function anim_bone_get_bone_mat(raw: anim_bone_t, bone: obj_t): mat4_t { - return raw.skeleton_mats != null ? raw.skeleton_mats[anim_bone_get_bone_index(raw, bone)] : null; -} - -function anim_bone_get_bone_mat_blend(raw: anim_bone_t, bone: obj_t): mat4_t { - return raw.skeleton_mats_blend != null ? raw.skeleton_mats_blend[anim_bone_get_bone_index(raw, bone)] : null; -} - -function anim_bone_get_abs_mat(raw: anim_bone_t, bone: obj_t): mat4_t { - // With applied blending - if (raw.skeleton_mats == null) { - return null; - } - if (raw.abs_mats == null) { - raw.abs_mats = []; - while (raw.abs_mats.length < raw.skeleton_mats.length) { - array_push(raw.abs_mats, mat4_identity()); - } - } - return raw.abs_mats[anim_bone_get_bone_index(raw, bone)]; -} - -function anim_bone_get_world_mat(raw: anim_bone_t, bone: obj_t): mat4_t { - if (raw.skeleton_mats == null) { - return null; - } - if (raw.apply_parent == null) { - raw.apply_parent = []; - for (let i: i32 = 0; i < raw.skeleton_mats.length; ++i) { - array_push(raw.apply_parent, true); - } - } - let i: i32 = anim_bone_get_bone_index(raw, bone); - _anim_bone_wm = mat4_clone(raw.skeleton_mats[i]); - anim_bone_mult_parents(raw, _anim_bone_wm, i, raw.skeleton_bones, raw.skeleton_mats); - // anim_bone_wm = mat4_clone(raw.mats_fast[i]); // TODO - return _anim_bone_wm; -} - -function anim_bone_get_bone_len(raw: anim_bone_t, bone: obj_t): f32 { - let refs: string[] = raw.data.skin.bone_ref_array; - let lens: f32_array_t = raw.data.skin.bone_len_array; - for (let i: i32 = 0; i < refs.length; ++i) { - if (refs[i] == bone.name) { - return lens[i]; - } - } - return 0.0; -} - -// Returns bone length with scale applied -function anim_bone_get_bone_abs_len(raw: anim_bone_t, bone: obj_t): f32 { - let refs: string[] = raw.data.skin.bone_ref_array; - let lens: f32_array_t = raw.data.skin.bone_len_array; - let scale: f32 = mat4_get_scale(raw.object.base.parent.transform.world).z; - for (let i: i32 = 0; i < refs.length; ++i) { - if (refs[i] == bone.name) { - return lens[i] * scale; - } - } - return 0.0; -} - -// Returns bone matrix in world space -function anim_bone_get_abs_world_mat(raw: anim_bone_t, bone: obj_t): mat4_t { - let wm = anim_bone_get_world_mat(raw, bone); - wm = mat4_mult_mat(wm, raw.object.base.parent.transform.world); - return wm; -} - -function anim_bone_solve_ik(raw: anim_bone_t, effector: obj_t, goal: vec4_t, precision: f32 = 0.01, max_iters: i32 = 100, chain_lenght: i32 = 100, roll_angle: f32 = 0.0) { - // Array of bones to solve IK for, effector at 0 - let bones: obj_t[] = []; - - // Array of bones lengths, effector length at 0 - let lengths: f32[] = []; - - // Array of bones matrices in world coordinates, effector at 0 - let bone_world_mats: mat4_t[]; - - let temp_loc: vec4_t = vec4_create(); - let temp_rot: quat_t = quat_create(); - let temp_rot2: quat_t = quat_create(); - let temp_scale: vec4_t = vec4_create(); - let roll: quat_t = quat_from_euler(0, roll_angle, 0); - - // Store all bones and lengths in array - let tip: obj_t = effector; - array_push(bones, tip); - array_push(lengths, anim_bone_get_bone_abs_len(raw, tip)); - let root: obj_t = tip; - - while (root.parent != null) { - if (bones.length > chain_lenght - 1) { - break; - } - array_push(bones, root.parent); - array_push(lengths, anim_bone_get_bone_abs_len(raw, root.parent)); - root = root.parent; - } - - // Root bone - root = bones[bones.length - 1]; - - // World matrix of root bone - let root_world_mat: mat4_t = mat4_clone(anim_bone_get_world_mat(raw, root)); - // World matrix of armature - let armature_mat: mat4_t = mat4_clone(raw.object.base.parent.transform.world); - // Apply armature transform to world matrix - root_world_mat = mat4_mult_mat(root_world_mat, armature_mat); - // Distance from root to goal - let dist: f32 = vec4_dist(goal, mat4_get_loc(root_world_mat)); - - // Total bones length - let total_length: f32 = 0.0; - for (let i: i32 = 0; i < lengths.length; ++i) { - let l: f32 = lengths[i]; - total_length += l; - } - - // Unreachable distance - if (dist > total_length) { - // Calculate unit vector from root to goal - let new_look: vec4_t = vec4_clone(goal); - new_look = vec4_sub(new_look, mat4_get_loc(root_world_mat)); - new_look = vec4_norm(new_look); - - // Rotate root bone to point at goal - mat4_decompose(root_world_mat, temp_loc, temp_rot, temp_scale); - temp_rot2 = quat_from_to(vec4_norm(mat4_look(root_world_mat)), new_look); - temp_rot2 = quat_mult(temp_rot2, temp_rot); - temp_rot2 = quat_mult(temp_rot2, roll); - root_world_mat = mat4_compose(temp_loc, temp_rot2, temp_scale); - - // Set bone matrix in local space from world space - anim_bone_set_bone_mat_from_world_mat(raw, root_world_mat, root); - - // Set child bone rotations to zero - for (let i: i32 = 0; i < bones.length - 1; ++i) { - mat4_decompose(anim_bone_get_bone_mat(raw, bones[i]), temp_loc, temp_rot, temp_scale); - mat4_compose(anim_bone_get_bone_mat(raw, bones[i]), temp_loc, roll, temp_scale); - } - return; - } - - // Get all bone mats in world space - bone_world_mats = anim_bone_get_world_mats_fast(raw, effector, bones.length); - - // Array of bone locations in world space, root location at [0] - let bone_world_locs: vec4_t[] = []; - for (let i: i32 = 0; i < bone_world_mats.length; ++i) { - let b: mat4_t = bone_world_mats[i]; - array_push(bone_world_locs, mat4_get_loc(b)); - } - - // Solve FABRIK - let vec: vec4_t = vec4_create(); - let start_loc: vec4_t = vec4_clone(bone_world_locs[0]); - let l: i32 = bone_world_locs.length; - - for (let iter: i32 = 0; iter < max_iters; ++iter) { - // Backward - vec = vec4_clone(goal); - vec = vec4_sub(vec, bone_world_locs[l - 1]); - vec = vec4_norm(vec); - vec = vec4_mult(vec, lengths[0]); - bone_world_locs[l - 1] = vec4_clone(goal); - bone_world_locs[l - 1] = vec4_sub(bone_world_locs[l - 1], vec); - - for (let j: i32 = 1; j < l; ++j) { - vec = vec4_clone(bone_world_locs[l - 1 - j]); - vec = vec4_sub(vec, bone_world_locs[l - j]); - vec = vec4_norm(vec); - vec = vec4_mult(vec, lengths[j]); - bone_world_locs[l - 1 - j] = vec4_clone(bone_world_locs[l - j]); - bone_world_locs[l - 1 - j] = vec4_add(bone_world_locs[l - 1 - j], vec); - } - - // Forward - bone_world_locs[0] = vec4_clone(start_loc); - for (let j: i32 = 1; j < l; ++j) { - vec = vec4_clone(bone_world_locs[j]); - vec = vec4_sub(vec, bone_world_locs[j - 1]); - vec = vec4_norm(vec); - vec = vec4_mult(vec, lengths[l - j]); - bone_world_locs[j] = vec4_clone(bone_world_locs[j - 1]); - bone_world_locs[j] = vec4_add(bone_world_locs[j], vec); - } - - if (vec4_dist(bone_world_locs[l - 1], goal) - lengths[0] <= precision) { - break; - } - } - - // Correct rotations - // Applying locations and rotations - let temp_look: vec4_t = vec4_create(); - let temp_loc2: vec4_t = vec4_create(); - - for (let i: i32 = 0; i < l - 1; ++i) { - // Decompose matrix - mat4_decompose(bone_world_mats[i], temp_loc, temp_rot, temp_scale); - - // Rotate to point to parent bone - temp_loc2 = vec4_clone(bone_world_locs[i + 1]); - temp_loc2 = vec4_sub(temp_loc2, bone_world_locs[i]); - temp_loc2 = vec4_norm(temp_loc2); - temp_look = vec4_clone(mat4_look(bone_world_mats[i])); - temp_look = vec4_norm(temp_look); - temp_rot2 = quat_from_to(temp_look, temp_loc2); - temp_rot2 = quat_mult(temp_rot2, temp_rot); - temp_rot2 = quat_mult(temp_rot2, roll); - - // Compose matrix with new rotation and location - bone_world_mats[i] = mat4_compose(bone_world_locs[i], temp_rot2, temp_scale); - - // Set bone matrix in local space from world space - anim_bone_set_bone_mat_from_world_mat(raw, bone_world_mats[i], bones[bones.length - 1 - i]); - } - - // Decompose matrix - mat4_decompose(bone_world_mats[l - 1], temp_loc, temp_rot, temp_scale); - - // Rotate to point to goal - temp_loc2 = vec4_clone(goal); - temp_loc2 = vec4_sub(temp_loc2, temp_loc); - temp_loc2 = vec4_norm(temp_loc2); - temp_look = vec4_clone(mat4_look(bone_world_mats[l - 1])); - temp_look = vec4_norm(temp_look); - temp_rot2 = quat_from_to(temp_look, temp_loc2); - temp_rot2 = quat_mult(temp_rot2, temp_rot); - temp_rot2 = quat_mult(temp_rot2, roll); - - // Compose matrix with new rotation and location - bone_world_mats[l - 1] = mat4_compose(bone_world_locs[l - 1], temp_rot2, temp_scale); - - // Set bone matrix in local space from world space - anim_bone_set_bone_mat_from_world_mat(raw, bone_world_mats[l - 1], bones[0]); -} - -// Returns an array of bone matrices in world space -function anim_bone_get_world_mats_fast(raw: anim_bone_t, tip: obj_t, chain_len: i32): mat4_t[] { - let wm_array: mat4_t[] = []; - let root: obj_t = tip; - let num_p: i32 = chain_len; - for (let i: i32 = 0; i < chain_len; ++i) { - let wm: mat4_t = anim_bone_get_abs_world_mat(raw, root); - wm_array[chain_len - 1 - i] = mat4_clone(wm); - root = root.parent; - num_p--; - } - - // Root bone at [0] - return wm_array; -} - -// Set bone transforms in world space -function anim_bone_set_bone_mat_from_world_mat(raw: anim_bone_t, wm: mat4_t, bone: obj_t) { - let inv_mat: mat4_t = mat4_identity(); - let temp_mat: mat4_t = mat4_clone(wm); - inv_mat = mat4_inv(raw.object.base.parent.transform.world); - temp_mat = mat4_mult_mat(temp_mat, inv_mat); - let bones: obj_t[] = []; - let p_bone: obj_t = bone; - while (p_bone.parent != null) { - array_push(bones, p_bone.parent); - p_bone = p_bone.parent; - } - - for (let i: i32 = 0; i < bones.length; ++i) { - let x: i32 = bones.length - 1; - inv_mat = mat4_inv(anim_bone_get_bone_mat(raw, bones[x - i])); - temp_mat = mat4_mult_mat(temp_mat, inv_mat); - } - - mat4_set_from(anim_bone_get_bone_mat(raw, bone), temp_mat); -} - -function anim_bone_play(raw: anim_bone_t, action: string = "", on_complete: ()=>void = null, blend_time: f32 = 0.2, speed: f32 = 1.0, loop: bool = true) { - if (action != "") { - blend_time > 0 ? anim_bone_set_action_blend(raw, action) : anim_bone_set_action(raw, action); - } - raw.base.blend_factor = 0.0; -} - -function anim_bone_blend(raw: anim_bone_t, action1: string, action2: string, factor: f32) { - if (factor == 0.0) { - anim_bone_set_action(raw, action1); - return; - } - anim_bone_set_action(raw, action2); - anim_bone_set_action_blend(raw, action1); - - anim_blend_super(raw.base, action1, action2, factor); -} - -function anim_bone_update(raw: anim_bone_t, delta: f32) { - if (!raw.base.is_skinned && raw.skeleton_bones == null) { - anim_bone_set_action(raw, raw.base.armature.actions[0].name); - } - if (raw.object != null && (!raw.object.base.visible || raw.object.base.culled)) { - return; - } - if (raw.skeleton_bones == null || raw.skeleton_bones.length == 0) { - return; - } - - anim_update_super(raw.base, delta); - - if (raw.base.paused || raw.base.speed == 0.0) { - return; - } - - let last_bones: obj_t[] = raw.skeleton_bones; - for (let i: i32 = 0; i < raw.skeleton_bones.length; ++i) { - let b: obj_t = raw.skeleton_bones[i]; - if (b.anim != null) { - anim_update_track(raw.base, b.anim); - break; - } - } - // Action has been changed by on_complete - if (last_bones != raw.skeleton_bones) { - return; - } - - for (let i: i32 = 0; i < raw.skeleton_bones.length; ++i) { - anim_update_anim_sampled(raw.base, raw.skeleton_bones[i].anim, raw.skeleton_mats[i]); - } - if (raw.base.blend_time > 0 && raw.skeleton_bones_blend != null) { - for (let i: i32 = 0; i < raw.skeleton_bones_blend.length; ++i) { - let b: obj_t = raw.skeleton_bones_blend[i]; - if (b.anim != null) { - anim_update_track(raw.base, b.anim); - break; - } - } - for (let i: i32 = 0; i < raw.skeleton_bones_blend.length; ++i) { - anim_update_anim_sampled(raw.base, raw.skeleton_bones_blend[i].anim, raw.skeleton_mats_blend[i]); - } - } - - // Do forward kinematics and inverse kinematics here - if (raw.on_updates != null) { - let i: i32 = 0; - let l: i32 = raw.on_updates.length; - while (i < l) { - raw.on_updates[i](); - l <= raw.on_updates.length ? i++ : l = raw.on_updates.length; - } - } - - // Calc absolute bones - for (let i: i32 = 0; i < raw.skeleton_bones.length; ++i) { - // Take bones with 0 parents first - anim_bone_mult_parent(raw, raw.mats_fast_sort[i], raw.mats_fast, raw.skeleton_bones, raw.skeleton_mats); - } - if (raw.skeleton_bones_blend != null) { - for (let i: i32 = 0; i < raw.skeleton_bones_blend.length; ++i) { - anim_bone_mult_parent(raw, raw.mats_fast_blend_sort[i], raw.mats_fast_blend, raw.skeleton_bones_blend, raw.skeleton_mats_blend); - } - } - - if (raw.base.is_skinned) { - anim_bone_update_skin_gpu(raw); - } - else { - anim_bone_update_bones_only(raw); - } -} - -function anim_bone_total_frames(raw: anim_bone_t): i32 { - if (raw.skeleton_bones == null) { - return 0; - } - let track: track_t = raw.skeleton_bones[0].anim.tracks[0]; - return math_floor(track.frames[track.frames.length - 1] - track.frames[0]); -} - -///end diff --git a/base/sources/ts/iron/anim_object.ts b/base/sources/ts/iron/anim_object.ts index f257014c..cd3133ce 100644 --- a/base/sources/ts/iron/anim_object.ts +++ b/base/sources/ts/iron/anim_object.ts @@ -12,10 +12,9 @@ function anim_object_create(object: object_t, oactions: scene_t[]): anim_object_ let raw: anim_object_t = {}; raw.base = anim_create(); raw.base.ext = raw; - raw.base.ext_type = "anim_bone_t"; + raw.base.ext_type = "anim_object_t"; raw.object = object; raw.oactions = oactions; - raw.base.is_skinned = false; anim_object_play(raw); return raw; } @@ -209,9 +208,7 @@ function anim_object_update(raw: anim_object_t, delta: f32) { if (raw.base.paused) { return; } - if (!raw.base.is_skinned) { - anim_object_update_object_anim(raw); - } + anim_object_update_object_anim(raw); } function anim_object_is_track_end(raw: anim_object_t, track: track_t): bool { diff --git a/base/sources/ts/iron/armature.ts b/base/sources/ts/iron/armature.ts deleted file mode 100644 index c9fdcd47..00000000 --- a/base/sources/ts/iron/armature.ts +++ /dev/null @@ -1,103 +0,0 @@ - -///if arm_skin - -type armature_t = { - uid?: i32; - name?: string; - actions?: armature_action_t[]; - mats_ready?: bool; -}; - -type armature_action_t = { - name?: string; - bones?: obj_t[]; - mats?: mat4_t[]; -}; - -let _armature_traverse_bones_data: any; - -function armature_traverse_bones_done(object: obj_t) { - array_push(_armature_traverse_bones_data, object); -} - -function armature_create(uid: i32, name: string, actions: scene_t[]): armature_t { - let raw: armature_t = {}; - raw.actions = []; - raw.mats_ready = false; - raw.uid = uid; - raw.name = name; - - for (let i: i32 = 0; i < actions.length; ++i) { - let a: scene_t = actions[i]; - for (let i: i32 = 0; i < a.objects.length; ++i) { - let o: obj_t = a.objects[i]; - armature_set_parents(o); - } - let bones: obj_t[] = []; - _armature_traverse_bones_data = bones; - armature_traverse_bones(a.objects, armature_traverse_bones_done); - array_push(raw.actions, { name: a.name, bones: bones, mats: null }); - } - return raw; -} - -function armature_init_mats(raw: armature_t) { - if (raw.mats_ready) { - return; - } - raw.mats_ready = true; - - for (let i: i32 = 0; i < raw.actions.length; ++i) { - let a: armature_action_t = raw.actions[i]; - if (a.mats != null) { - continue; - } - a.mats = []; - for (let i: i32 = 0; i < a.bones.length; ++i) { - let b: obj_t = a.bones[i]; - array_push(a.mats, mat4_from_f32_array(b.transform)); - } - } -} - -function armature_get_action(raw: armature_t, name: string): armature_action_t { - for (let i: i32 = 0; i < raw.actions.length; ++i) { - let a: armature_action_t = raw.actions[i]; - if (a.name == name) { - return a; - } - } - return null; -} - -function armature_set_parents(object: obj_t) { - if (object.children == null) { - return; - } - - for (let i: i32 = 0; i < object.children.length; ++i) { - let o: obj_t = object.children[i]; - o.parent = object; - armature_set_parents(o); - } -} - -function armature_traverse_bones(objects: obj_t[], callback: (o: obj_t)=>void) { - for (let i: i32 = 0; i < objects.length; ++i) { - armature_traverse_bones_step(objects[i], callback); - } -} - -function armature_traverse_bones_step(object: obj_t, callback: (o: obj_t)=>void) { - if (object.type == "bone_object") { - callback(object); - } - if (object.children == null) { - return; - } - for (let i: i32 = 0; i < object.children.length; ++i) { - armature_traverse_bones_step(object.children[i], callback); - } -} - -///end diff --git a/base/sources/ts/iron/mesh_data.ts b/base/sources/ts/iron/mesh_data.ts index 05fbf205..5e95bd2c 100644 --- a/base/sources/ts/iron/mesh_data.ts +++ b/base/sources/ts/iron/mesh_data.ts @@ -8,11 +8,6 @@ function mesh_data_parse(name: string, id: string): mesh_data_t { } let data: mesh_data_t = mesh_data_create(raw); - ///if arm_skin - if (raw.skin != null) { - mesh_data_init_skeleton_transforms(data, raw.skin.transforms_inv); - } - ///end return data; } @@ -41,53 +36,6 @@ function mesh_data_create(raw: mesh_data_t): mesh_data_t { raw._.refcount = 0; raw._.vertex_buffer_map = map_create(); raw._.ready = false; - - ///if arm_skin - // Prepare vertex array for skinning and fill size data - let vertex_arrays: vertex_array_t[] = raw.vertex_arrays; - if (raw.skin != null) { - let va_bone: vertex_array_t = {}; - va_bone.attrib = "bone"; - va_bone.values = null; - va_bone.data = "short4norm"; - let va_weight: vertex_array_t = {}; - va_weight.attrib = "weight"; - va_weight.values = null; - va_weight.data = "short4norm"; - array_push(vertex_arrays, va_bone); - array_push(vertex_arrays, va_weight); - } - - if (raw.skin != null) { - let size: i32 = mesh_data_get_vertex_size(vertex_arrays[0].data); - let vertex_length: i32 = math_floor(vertex_arrays[0].values.length / size); - let l: i32 = vertex_length * 4; - let bonea: i16_array_t = i16_array_create(l); - let weighta: i16_array_t = i16_array_create(l); - - let index: i32 = 0; - let ai: i32 = 0; - for (let i: i32 = 0; i < vertex_length; ++i) { - let bone_count: i32 = raw.skin.bone_count_array[i]; - for (let j: i32 = index; j < index + bone_count; ++j) { - bonea[ai] = raw.skin.bone_index_array[j]; - weighta[ai] = raw.skin.bone_weight_array[j]; - ai++; - } - // Fill unused weights - for (let j: i32 = bone_count; j < 4; ++j) { - bonea[ai] = 0; - weighta[ai] = 0; - ai++; - } - index += bone_count; - } - vertex_arrays[vertex_arrays.length - 2].values = bonea; - vertex_arrays[vertex_arrays.length - 1].values = weighta; - } - ///end - - // Make vertex buffers raw._.structure = mesh_data_get_vertex_struct(raw.vertex_arrays); return raw; @@ -237,57 +185,6 @@ function mesh_data_build(raw: mesh_data_t) { raw._.ready = true; } -///if arm_skin -function mesh_data_add_armature(raw: mesh_data_t, armature: armature_t) { - for (let i: i32 = 0; i < armature.actions.length; ++i) { - let a: armature_action_t = armature.actions[i]; - mesh_data_add_action(raw, a.bones, a.name); - } -} - -function mesh_data_add_action(raw: mesh_data_t, bones: obj_t[], name: string) { - if (bones == null) { - return; - } - if (raw._.actions == null) { - raw._.actions = map_create(); - raw._.mats = map_create(); - } - if (map_get(raw._.actions, name) != null) { - return; - } - let action_bones: obj_t[] = []; - - // Set bone references - for (let i: i32 = 0; i < raw.skin.bone_ref_array.length; ++i) { - let s: string = raw.skin.bone_ref_array[i]; - for (let j: i32 = 0; j < bones.length; ++j) { - let b: obj_t = bones[j]; - if (b.name == s) { - array_push(action_bones, b); - } - } - } - map_set(raw._.actions, name, action_bones); - - let action_mats: mat4_t[] = []; - for (let i: i32 = 0; i < action_bones.length; ++i) { - let b: obj_t = action_bones[i]; - array_push(action_mats, mat4_from_f32_array(b.transform)); - } - map_set(raw._.mats, name, action_mats); -} - -function mesh_data_init_skeleton_transforms(raw: mesh_data_t, transforms_inv: f32_array_t[]) { - raw._.skeleton_transforms_inv = []; - for (let i: i32 = 0; i < transforms_inv.length; ++i) { - let t: f32_array_t = transforms_inv[i]; - let mi = mat4_from_f32_array(t); - array_push(raw._.skeleton_transforms_inv, mi); - } -} -///end - function mesh_data_calculate_aabb(raw: mesh_data_t): vec4_t { let aabb_min: vec4_t = vec4_create(-0.01, -0.01, -0.01); let aabb_max: vec4_t = vec4_create(0.01, 0.01, 0.01); diff --git a/base/sources/ts/iron/mesh_object.ts b/base/sources/ts/iron/mesh_object.ts index d0cc5b07..fa23c2c1 100644 --- a/base/sources/ts/iron/mesh_object.ts +++ b/base/sources/ts/iron/mesh_object.ts @@ -45,20 +45,6 @@ function mesh_object_remove(raw: mesh_object_t) { } function mesh_object_setup_animation(raw: mesh_object_t, oactions: scene_t[] = null) { - ///if arm_skin - let has_action: bool = raw.base.parent != null && raw.base.parent.raw != null && raw.base.parent.raw.anim != null && raw.base.parent.raw.anim.bone_actions != null; - if (has_action) { - let armature_name: string = raw.base.parent.name; - raw.base.animation = object_get_parent_armature(raw.base, armature_name).base; - if (raw.base.animation == null) { - raw.base.animation = anim_bone_create(armature_name).base; - } - if (raw.data.skin != null) { - anim_bone_set_skin(raw.base.animation.ext, raw); - } - } - ///end - ///if arm_anim object_setup_animation_super(raw.base, oactions); ///end diff --git a/base/sources/ts/iron/object.ts b/base/sources/ts/iron/object.ts index aaf12ec7..65017285 100644 --- a/base/sources/ts/iron/object.ts +++ b/base/sources/ts/iron/object.ts @@ -125,12 +125,6 @@ function object_get_children(raw: object_t, recursive: bool = false): object_t[] ///if arm_anim function object_setup_animation_super(raw: object_t, oactions: scene_t[] = null) { - // Parented to bone - ///if arm_skin - if (raw.raw.anim != null && raw.raw.anim.parent_bone != null) { - sys_notify_on_init(_object_setup_animation_on_init, raw); - } - ///end // object_t actions if (oactions == null) { return; @@ -138,24 +132,6 @@ function object_setup_animation_super(raw: object_t, oactions: scene_t[] = null) raw.animation = anim_object_create(raw, oactions).base; } -///if arm_skin -function _object_setup_animation_on_init(raw: object_t) { - let banim: anim_bone_t = object_get_parent_armature(raw, raw.parent.name); - if (banim != null) { - anim_bone_add_bone_child(banim, raw.raw.anim.parent_bone, raw); - } -} -function object_get_parent_armature(raw: object_t, name: string): anim_bone_t { - for (let i: i32 = 0; i < scene_animations.length; ++i) { - let a: anim_raw_t = scene_animations[i]; - if (a.armature != null && a.armature.name == name) { - return a.ext; - } - } - return null; -} -///end - function object_setup_animation(raw: object_t, oactions: scene_t[] = null) { if (raw.ext_type == "mesh_object_t") { mesh_object_setup_animation(raw.ext, oactions); diff --git a/base/sources/ts/iron/scene.ts b/base/sources/ts/iron/scene.ts index b7e15a92..1f6c0209 100644 --- a/base/sources/ts/iron/scene.ts +++ b/base/sources/ts/iron/scene.ts @@ -10,9 +10,6 @@ let scene_empties: object_t[]; ///if arm_anim let scene_animations: anim_raw_t[]; ///end -///if arm_skin -let scene_armatures: armature_t[]; -///end let scene_embedded: map_t; let _scene_ready: bool; @@ -35,9 +32,6 @@ function scene_create(format: scene_t): object_t { ///if arm_anim scene_animations = []; ///end - ///if arm_skin - scene_armatures = []; - ///end scene_embedded = map_create(); _scene_root = object_create(); _scene_root.name = "Root"; @@ -328,43 +322,6 @@ function scene_create_mesh_object(o: obj_t, format: scene_t, parent: object_t, p data_ref = o.data_ref; } - // Bone objects are stored in armature parent - ///if arm_skin - if (parent_object != null && parent_object.anim != null && parent_object.anim.bone_actions != null) { - let bactions: scene_t[] = []; - for (let i: i32 = 0; i < parent_object.anim.bone_actions.length; ++i) { - let ref: string = parent_object.anim.bone_actions[i]; - let action: scene_t = data_get_scene_raw(ref); - array_push(bactions, action); - } - let armature: armature_t = null; - // Check if armature exists - for (let j: i32 = 0; j < scene_armatures.length; ++j) { - let a: armature_t = scene_armatures[j]; - if (a.uid == parent.uid) { - armature = a; - break; - } - } - // Create new one - if (armature == null) { - // Unique name if armature was already instantiated for different object - for (let j: i32 = 0; j < scene_armatures.length; ++j) { - let a: armature_t = scene_armatures[j]; - let aname: string = a.name; - if (aname == parent.name) { - parent.name += "." + parent.uid; - break; - } - } - armature = armature_create(parent.uid, parent.name, bactions); - array_push(scene_armatures, armature); - } - return scene_return_mesh_object( - object_file, data_ref, scene_name, armature, materials, parent, parent_object, o); - } - ///end - return scene_return_mesh_object(object_file, data_ref, scene_name, null, materials, parent, parent_object, o); } @@ -372,11 +329,6 @@ function scene_return_mesh_object(object_file: string, data_ref: string, scene_n materials: material_data_t[], parent: object_t, parent_object: obj_t, o: obj_t): object_t { let mesh: mesh_data_t = data_get_mesh(object_file, data_ref); - ///if arm_skin - if (mesh.skin != null) { - armature != null ? mesh_data_add_armature(mesh, armature) : mesh_data_add_action(mesh, _scene_raw.objects, "none"); - } - ///end let object: mesh_object_t = scene_add_mesh_object(mesh, materials, parent); return scene_return_object(object.base, o); @@ -466,7 +418,6 @@ type mesh_data_t = { name?: string; scale_pos?: f32; // Unpack pos from (-1,1) coords scale_tex?: f32; // Unpack tex from (-1,1) coords - skin?: skin_t; vertex_arrays?: vertex_array_t[]; index_arrays?: index_array_t[]; _?: mesh_data_runtime_t; @@ -480,21 +431,6 @@ type mesh_data_runtime_t = { index_buffers?: gpu_buffer_t[]; ready?: bool; structure?: gpu_vertex_structure_t; - ///if arm_skin - skeleton_transforms_inv?: mat4_t[]; - actions?: map_t; - mats?: map_t; - ///end -}; - -type skin_t = { - transform?: f32_array_t; - bone_ref_array?: string[]; - bone_len_array?: f32_array_t; - transforms_inv?: f32_array_t[]; // per-bone, size = 16, with skin.transform, pre-inverted - bone_count_array?: i16_array_t; - bone_index_array?: i16_array_t; - bone_weight_array?: i16_array_t; }; type vertex_array_t = { @@ -652,7 +588,7 @@ type obj_t = { dimensions?: f32_array_t; // Geometry objects visible?: bool; spawn?: bool; // Auto add object when creating scene - anim?: anim_t; // Bone/object animation + anim?: anim_t; // Object animation material_refs?: string[]; children?: obj_t[]; _?: obj_runtime_t; @@ -664,11 +600,6 @@ type obj_runtime_t = { type anim_t = { object_actions?: string[]; - bone_actions?: string[]; - parent_bone?: string; - parent_bone_tail?: f32_array_t; // Translate from head to tail - parent_bone_tail_pose?: f32_array_t; - parent_bone_connected?: bool; tracks?: track_t[]; begin?: i32; // Frames, for non-sampled end?: i32; diff --git a/base/sources/ts/iron/transform.ts b/base/sources/ts/iron/transform.ts index 5d701619..d21dbfe5 100644 --- a/base/sources/ts/iron/transform.ts +++ b/base/sources/ts/iron/transform.ts @@ -12,17 +12,11 @@ type transform_t = { object?: object_t; dim?: vec4_t; radius?: f32; - - ///if arm_skin - bone_parent?: mat4_t; - ///end - ///if arm_anim // Wrong order returned from get_euler(), store last state for animation _euler_x?: f32; _euler_y?: f32; _euler_z?: f32; - // Animated delta transform dloc?: vec4_t; drot?: quat_t; @@ -79,12 +73,6 @@ function transform_build_matrix(raw: transform_t) { // transform_compose_delta(raw); // } - ///if arm_skin - if (raw.bone_parent != null) { - raw.local = mat4_mult_mat(raw.local, raw.bone_parent); - } - ///end - if (raw.object.parent != null && !raw.local_only) { raw.world = mat4_mult_mat3x4(raw.local, raw.object.parent.transform.world); } diff --git a/base/sources/ts/iron/uniforms.ts b/base/sources/ts/iron/uniforms.ts index 662d7666..da9ba399 100644 --- a/base/sources/ts/iron/uniforms.ts +++ b/base/sources/ts/iron/uniforms.ts @@ -514,14 +514,7 @@ function uniforms_set_obj_const(obj: object_t, loc: i32, c: shader_const_t) { else if (c.type == "floats") { let fa: f32_array_t = null; - if (c.link == "_skin_bones") { - ///if arm_skin - if (obj.animation != null) { - fa = obj.animation.ext.skin_buffer; - } - ///end - } - else if (uniforms_f32_array_links != null) { + if (uniforms_f32_array_links != null) { fa = uniforms_f32_array_links(obj, current_material(obj), c.link); } diff --git a/base/sources/ts/strings.ts b/base/sources/ts/strings.ts index 2a5e32df..341d92f4 100644 --- a/base/sources/ts/strings.ts +++ b/base/sources/ts/strings.ts @@ -303,30 +303,6 @@ fun pack_f32_i16(f: float, i: uint): float { \ // } \ // "; -///if arm_skin -let str_get_skinning_dual_quat: string = "\ -fun get_skinning_dual_quat(bone: int4, weight: float4, out A: float4, inout B: float4) { \ - var bonei: int4 = bone * 2; \ - var mat_a: float4x4 = float4x4( \ - skin_bones[bonei.x], \ - skin_bones[bonei.y], \ - skin_bones[bonei.z], \ - skin_bones[bonei.w]); \ - var mat_b: float4x4 = float4x4( \ - skin_bones[bonei.x + 1], \ - skin_bones[bonei.y + 1], \ - skin_bones[bonei.z + 1], \ - skin_bones[bonei.w + 1]); \ - weight.xyz *= sign(mat_a[3] * mat_a).xyz; \ - A = mat_a * weight; \ - B = mat_b * weight; \ - var inv_norm_a: float = 1.0 / length(A); \ - A *= inv_norm_a; \ - B *= inv_norm_a; \ -} \ -"; -///end - let str_create_basis: string = "\ fun create_basis(normal: float3, out tangent: float3, out binormal: float3) { \ tangent = normalize(camera_right - normal * dot(camera_right, normal)); \ diff --git a/base/sources/ts/util_clone.ts b/base/sources/ts/util_clone.ts index fdd9fcd9..467f462f 100644 --- a/base/sources/ts/util_clone.ts +++ b/base/sources/ts/util_clone.ts @@ -305,11 +305,6 @@ function util_clone_anim(a: anim_t): anim_t { } let r: anim_t = {}; r.object_actions = util_clone_string_array(a.object_actions); - r.bone_actions = util_clone_string_array(a.bone_actions); - r.parent_bone = a.parent_bone; - r.parent_bone_tail = util_clone_f32_array(a.parent_bone_tail); - r.parent_bone_tail_pose = util_clone_f32_array(a.parent_bone_tail_pose); - r.parent_bone_connected = a.parent_bone_connected; r.tracks = util_clone_tracks(a.tracks); r.begin = a.begin; r.end = a.end; diff --git a/base/sources/ts/util_encode.ts b/base/sources/ts/util_encode.ts index e06e4828..6c6e0f8a 100644 --- a/base/sources/ts/util_encode.ts +++ b/base/sources/ts/util_encode.ts @@ -92,8 +92,6 @@ function util_encode_mesh_datas(datas: mesh_data_t[]) { armpack_encode_f32(datas[i].scale_pos); armpack_encode_string("scale_tex"); armpack_encode_f32(datas[i].scale_tex); - armpack_encode_string("skin"); - armpack_encode_null(); // skin_t armpack_encode_string("vertex_arrays"); armpack_encode_array(datas[i].vertex_arrays.length); for (let j: i32 = 0; j < datas[i].vertex_arrays.length; ++j) { diff --git a/base/tools/io_export_arm.py b/base/tools/io_export_arm.py index 34bbcbe8..e95f9dda 100644 --- a/base/tools/io_export_arm.py +++ b/base/tools/io_export_arm.py @@ -24,15 +24,14 @@ bl_info = { "location": "File -> Export", "description": "Armory mesh data", "author": "Armory3D.org", - "version": (2025, 2, 0), + "version": (2025, 8, 0), "blender": (4, 3, 1), "doc_url": "", "tracker_url": "", } -NodeTypeBone = 1 -NodeTypeMesh = 2 -structIdentifier = ["object", "bone_object", "mesh_object"] +NodeTypeMesh = 1 +structIdentifier = ["object", "mesh_object"] class ArmoryExporter(bpy.types.Operator, ExportHelper): """Export to Armory format""" @@ -48,10 +47,7 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): self.scene = context.scene self.output = {} self.bobjectArray = {} - self.bobjectBoneArray = {} self.meshArray = {} - self.boneParentArray = {} - self.bone_tracks = [] self.depsgraph = context.evaluated_depsgraph_get() scene_objects = self.scene.collection.all_objects @@ -59,8 +55,6 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): if not bobject.parent: self.process_bobject(bobject) - self.process_skinned_meshes() - self.output["name"] = self.scene.name self.output["objects"] = [] for bo in scene_objects: @@ -84,7 +78,6 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): self.scene.frame_set(current_frame, subframe=current_subframe) print(f"Scene exported in {str(time.time() - profile_time)}") - return {"FINISHED"} def write_arm(self, filepath, output): @@ -111,121 +104,16 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): matrix[3][3], ] - def find_bone(self, name): - return next( - ( - bobject_ref - for bobject_ref in self.bobjectBoneArray.items() - if bobject_ref[0].name == name - ), - None, - ) - - def collect_bone_animation(self, armature, name): - path = 'pose.bones["' + name + '"].' - curve_array = [] - if armature.animation_data: - if action := armature.animation_data.action: - curve_array.extend( - fcurve - for fcurve in action.fcurves - if fcurve.data_path.startswith(path) - ) - return curve_array - - def export_bone(self, armature, bone, scene, o, action): - if bobjectRef := self.bobjectBoneArray.get(bone): - o["name"] = bobjectRef["structName"] - o["type"] = structIdentifier[bobjectRef["objectType"]] - self.export_bone_transform(armature, bone, o, action) - o["children"] = [] - for subbobject in bone.children: - so = {} - self.export_bone(armature, subbobject, scene, so, action) - o["children"].append(so) - - def export_pose_markers(self, oanim, action): - if action.pose_markers is None or len(action.pose_markers) == 0: - return - oanim["marker_frames"] = [] - oanim["marker_names"] = [] - for m in action.pose_markers: - oanim["marker_frames"].append(int(m.frame)) - oanim["marker_names"].append(m.name) - - def process_bone(self, bone): - self.bobjectBoneArray[bone] = { - "objectType": NodeTypeBone, - "structName": bone.name, - } - for subbobject in bone.children: - self.process_bone(subbobject) - def process_bobject(self, bobject): - if bobject.type not in ["MESH", "ARMATURE"]: + if bobject.type not in ["MESH"]: return btype = NodeTypeMesh if bobject.type == "MESH" else 0 self.bobjectArray[bobject] = {"objectType": btype, "structName": bobject.name} - if bobject.type == "ARMATURE": - if skeleton := bobject.data: - for bone in skeleton.bones: - if not bone.parent: - self.process_bone(bone) - for subbobject in bobject.children: self.process_bobject(subbobject) - def process_skinned_meshes(self): - for bobjectRef in self.bobjectArray.items(): - if bobjectRef[1]["objectType"] == NodeTypeMesh: - if armature := bobjectRef[0].find_armature(): - for bone in armature.data.bones: - boneRef = self.find_bone(bone.name) - if boneRef: - boneRef[1]["objectType"] = NodeTypeBone - - def export_bone_transform(self, armature, bone, o, action): - pose_bone = armature.pose.bones.get(bone.name) - transform = bone.matrix_local.copy() - if bone.parent is not None: - transform = bone.parent.matrix_local.inverted_safe() @ transform - - o["transform"] = {} - o["transform"]["values"] = self.write_matrix(transform) - - curve_array = self.collect_bone_animation(armature, bone.name) - animation = len(curve_array) != 0 - - if animation and pose_bone: - begin_frame = int(action.frame_range[0]) - end_frame = int(action.frame_range[1]) - tracko = {} - o["anim"] = {} - o["anim"]["tracks"] = [tracko] - tracko["target"] = "transform" - tracko["frames"] = [ - i - begin_frame for i in range(begin_frame, end_frame + 1) - ] - tracko["values"] = [] - self.bone_tracks.append((tracko["values"], pose_bone)) - - def write_bone_matrices(self, scene, action): - if len(self.bone_tracks) > 0: - begin_frame = int(action.frame_range[0]) - end_frame = int(action.frame_range[1]) - for i in range(begin_frame, end_frame + 1): - scene.frame_set(i) - for track in self.bone_tracks: - values, pose_bone = track[0], track[1] - if parent := pose_bone.parent: - values += self.write_matrix( - (parent.matrix.inverted_safe() @ pose_bone.matrix) - ) - else: - values += self.write_matrix(pose_bone.matrix) - def export_object(self, bobject, scene, parento=None): if bobjectRef := self.bobjectArray.get(bobject): o = {} @@ -240,9 +128,6 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): o["material_refs"] = None o["children"] = None - if bobject.parent_type == "BONE": - o["anim"]["parent_bone"] = bobject.parent_bone - if bobjectRef["objectType"] == NodeTypeMesh: objref = bobject.data if objref not in self.meshArray: @@ -256,90 +141,6 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): o["data_ref"] = oid o["dimensions"] = self.calc_aabb(bobject) - # If the object is parented to a bone and is not relative, undo the - # bone's transform - if bobject.parent_type == "BONE": - armature = bobject.parent.data - bone = armature.bones[bobject.parent_bone] - o["anim"]["parent_bone_connected"] = bone.use_connect - if bone.use_connect: - bone_translation = Vector((0, bone.length, 0)) + bone.head - o["anim"]["parent_bone_tail"] = [ - bone_translation[0], - bone_translation[1], - bone_translation[2], - ] - else: - bone_translation = bone.tail - bone.head - o["anim"]["parent_bone_tail"] = [ - bone_translation[0], - bone_translation[1], - bone_translation[2], - ] - pose_bone = bobject.parent.pose.bones[bobject.parent_bone] - bone_translation_pose = pose_bone.tail - pose_bone.head - o["anim"]["parent_bone_tail_pose"] = [ - bone_translation_pose[0], - bone_translation_pose[1], - bone_translation_pose[2], - ] - - if bobject.type == "ARMATURE" and bobject.data is not None: - bdata = bobject.data - action = None - adata = bobject.animation_data - - # Active action - if adata is not None: - action = adata.action - if action is None: - bobject.animation_data_create() - actions = bpy.data.actions - action = actions.get("armory_pose") - if action is None: - action = actions.new(name="armory_pose") - - # Collect export actions - export_actions = [action] - if hasattr(adata, "nla_tracks") and adata.nla_tracks is not None: - for track in adata.nla_tracks: - if track.strips is None: - continue - for strip in track.strips: - if strip.action is None: - continue - if strip.action.name == action.name: - continue - export_actions.append(strip.action) - - basename = os.path.basename(self.filepath)[:-4] - o["anim"]["bone_actions"] = [] - for action in export_actions: - o["anim"]["bone_actions"].append(basename + "_" + action.name) - - orig_action = bobject.animation_data.action - for action in export_actions: - bobject.animation_data.action = action - bones = [] - self.bone_tracks = [] - for bone in bdata.bones: - if not bone.parent: - boneo = {} - self.export_bone(bobject, bone, scene, boneo, action) - bones.append(boneo) - self.write_bone_matrices(scene, action) - if len(bones) > 0 and "anim" in bones[0]: - self.export_pose_markers(bones[0]["anim"], action) - # Save action separately - action_obj = {} - action_obj["name"] = action.name - action_obj["objects"] = bones - self.write_arm( - self.filepath[:-4] + "_" + action.name + ".arm", action_obj - ) - - bobject.animation_data.action = orig_action - if parento is None: self.output["objects"].append(o) else: @@ -351,96 +152,6 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper): for subbobject in bobject.children: self.export_object(subbobject, scene, o) - def export_skin(self, bobject, armature, exportMesh, o): - # This function exports all skinning data, which includes the skeleton - # and per-vertex bone influence data - oskin = {} - o["skin"] = oskin - - # Write the skin bind pose transform - otrans = {} - oskin["transform"] = otrans - otrans["values"] = self.write_matrix(bobject.matrix_world) - - bone_array = armature.data.bones - bone_count = len(bone_array) - max_bones = 128 - bone_count = min(bone_count, max_bones) - - # Write the bone object reference array - oskin["bone_ref_array"] = np.empty(bone_count, dtype=object) - oskin["bone_len_array"] = np.empty(bone_count, dtype="= 0: # and bone_weight != 0.0: - bone_values.append((bone_weight, bone_index)) - total_weight += bone_weight - bone_count += 1 - - if bone_count > 4: - bone_count = 4 - bone_values.sort(reverse=True) - bone_values = bone_values[:4] - - bone_count_array[index] = bone_count - for bv in bone_values: - bone_weight_array[count] = bv[0] - bone_index_array[count] = bv[1] - count += 1 - - if total_weight not in (0.0, 1.0): - normalizer = 1.0 / total_weight - for i in range(bone_count): - bone_weight_array[count - i - 1] *= normalizer - - bone_index_array = bone_index_array[:count] - bone_weight_array = bone_weight_array[:count] - bone_weight_array *= 32767 - bone_weight_array = np.array(bone_weight_array, dtype="FWS6(b|-WNSw2%?*rYN&rOF1~>o! delta 28 jcmaFk{>^=Z6(b|tWNSuiP8J3RhT`nZyaSs{8OxObgslj% diff --git a/paint/assets/meshes/box_bevel_shared_uvs.arm b/paint/assets/meshes/box_bevel_shared_uvs.arm index 9e2fb9db881b182dfe95b2a16d13bae8e20e8c5d..a1ca30389c4efd3531efa2b06400db2303c830f7 100644 GIT binary patch delta 20 ccmdlsi*d~?#tl}CjI5Kb8Lc-rFmCe(083{E$p8QV delta 30 mcmZ28i*eg5#tl}CjBJyw8Lc^47#J9evorG!Y%XQo?hOEp#R)N$g^`hMqPEoJct$l&76t}};_S@41DjhI%T)oH(g|Gv diff --git a/paint/assets/meshes/torus.arm b/paint/assets/meshes/torus.arm index f2d3573aab1019aa7c6f366bc5bef60e8fbd2c2d..f507125048acad7c24862d63ef1157abe18fb9c2 100644 GIT binary patch delta 20 ccmX?eh4Ii8#tn9ijI5LG8ErSWF&@hR09QB%rT_o{ delta 30 mcmX?fh4IW4#tn9ijBJzb8ErXP7#J9evorG!Y_4WJo&f-#Itm{E diff --git a/paint/sources/make_mesh_preview.ts b/paint/sources/make_mesh_preview.ts index 9b410c46..64d780b5 100644 --- a/paint/sources/make_mesh_preview.ts +++ b/paint/sources/make_mesh_preview.ts @@ -31,26 +31,6 @@ function make_mesh_preview_run(data: material_t, matcon: material_context_t): no let pos: string = "input.pos"; - ///if arm_skin - let skin: bool = mesh_data_get_vertex_array(context_raw.paint_object.data, "bone") != null; - if (skin) { - pos = "spos"; - node_shader_context_add_elem(con_mesh, "bone", "short4norm"); - node_shader_context_add_elem(con_mesh, "weight", "short4norm"); - node_shader_add_function(kong, str_get_skinning_dual_quat); - node_shader_add_constant(kong, "skin_bones float4[128 * 2]", "_skin_bones"); - node_shader_add_constant(kong, "pos_unpack: float", "_pos_unpack"); - node_shader_write_attrib_vert(kong, "var skin_a: float4;"); - node_shader_write_attrib_vert(kong, "var skin_b: float4;"); - node_shader_write_attrib_vert(kong, "get_skinning_dual_quat(int4(bone * 32767), weight, skin_a, skin_b);"); - node_shader_write_attrib_vert(kong, "var spos: float3 = input.pos.xyz;"); - node_shader_write_attrib_vert(kong, "spos.xyz *= constants.pos_unpack;"); - node_shader_write_attrib_vert(kong, "spos.xyz += 2.0 * cross(skin_a.xyz, cross(skin_a.xyz, spos.xyz) + skin_a.w * spos.xyz);"); - node_shader_write_attrib_vert(kong, "spos.xyz += 2.0 * (skin_a.w * skin_b.xyz - skin_b.w * skin_a.xyz + cross(skin_a.xyz, skin_b.xyz));"); - node_shader_write_attrib_vert(kong, "spos.xyz /= constants.pos_unpack;"); - } - ///end - node_shader_add_constant(kong, "WVP: float4x4", "_world_view_proj_matrix"); node_shader_write_attrib_vert(kong, "output.pos = constants.WVP * float4(" + pos + ".xyz, 1.0);"); @@ -142,12 +122,6 @@ function make_mesh_preview_run(data: material_t, matcon: material_context_t): no parser_material_finalize(con_mesh); - ///if arm_skin - if (skin) { - node_shader_write_vert(kong, "wnormal = normalize(constants.N * float3(input.nor.xy, input.pos.w) + 2.0 * cross(skin_a.xyz, cross(skin_a.xyz, float3(input.nor.xy, input.pos.w)) + skin_a.w * float3(input.nor.xy, input.pos.w)));"); - } - ///end - con_mesh.data.shader_from_source = true; gpu_create_shaders_from_kong(node_shader_get(kong), ADDRESS(con_mesh.data.vertex_shader), ADDRESS(con_mesh.data.fragment_shader), ADDRESS(con_mesh.data._.vertex_shader_size), ADDRESS(con_mesh.data._.fragment_shader_size));