luboslenco 1 month ago
parent
commit
3b3269f033

BIN
base/assets/Scene.arm


+ 0 - 1
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") {

+ 1 - 20
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);
 	}

+ 0 - 720
base/sources/ts/iron/anim_bone.ts

@@ -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<string, object_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

+ 2 - 5
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 {

+ 0 - 103
base/sources/ts/iron/armature.ts

@@ -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

+ 0 - 103
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);

+ 0 - 14
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

+ 0 - 24
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);

+ 1 - 70
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<string, gpu_texture_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<string, obj_t[]>;
-	mats?: map_t<string, mat4_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;

+ 0 - 12
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);
 	}

+ 1 - 8
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);
 		}
 

+ 0 - 24
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)); \

+ 0 - 5
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;

+ 0 - 2
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) {

+ 4 - 299
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="<f4")
-
-        for i in range(bone_count):
-            if boneRef := self.find_bone(bone_array[i].name):
-                oskin["bone_ref_array"][i] = boneRef[1]["structName"]
-                oskin["bone_len_array"][i] = bone_array[i].length
-            else:
-                oskin["bone_ref_array"][i] = ""
-                oskin["bone_len_array"][i] = 0.0
-
-        # Write the bind pose transform array
-        oskin["transforms_inv"] = []
-        for i in range(bone_count):
-            skeleton_inv = (
-                armature.matrix_world @ bone_array[i].matrix_local
-            ).inverted_safe()
-            skeleton_inv = skeleton_inv @ bobject.matrix_world
-            oskin["transforms_inv"].append(self.write_matrix(skeleton_inv))
-
-        # Export the per-vertex bone influence data
-        group_remap = []
-        for group in bobject.vertex_groups:
-            for i in range(bone_count):
-                if bone_array[i].name == group.name:
-                    group_remap.append(i)
-                    break
-            else:
-                group_remap.append(-1)
-
-        bone_count_array = np.empty(len(exportMesh.loops), dtype="<i2")
-        bone_index_array = np.empty(len(exportMesh.loops) * 4, dtype="<i2")
-        bone_weight_array = np.empty(len(exportMesh.loops) * 4, dtype="<f4")
-
-        vertices = bobject.data.vertices
-        count = 0
-        for index, l in enumerate(exportMesh.loops):
-            bone_count = 0
-            total_weight = 0.0
-            bone_values = []
-            for g in vertices[l.vertex_index].groups:
-                bone_index = group_remap[g.group]
-                bone_weight = g.weight
-                if bone_index >= 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="<i2")
-
-        oskin["bone_count_array"] = bone_count_array
-        oskin["bone_index_array"] = bone_index_array
-        oskin["bone_weight_array"] = bone_weight_array
-
     def calc_aabb(self, bobject):
         aabb_center = 0.125 * sum((Vector(b) for b in bobject.bound_box), Vector())
         return [
@@ -480,8 +191,6 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
             o["scale_pos"] = maxdim / 2
         else:
             o["scale_pos"] = 1.0
-        if has_armature:  # Allow up to 2x bigger bounds for skinned mesh
-            o["scale_pos"] *= 2.0
 
         pdata = np.empty(num_verts * 4, dtype="<f4")  # p.xyz, n.z
         ndata = np.empty(num_verts * 2, dtype="<f4")  # n.xy
@@ -524,8 +233,6 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
         if has_col:
             cdata = np.empty(num_verts * 4, dtype="<f4")
 
-        o["skin"] = None
-
         scale_pos = o["scale_pos"]
         invscale_pos = (1 / scale_pos) * 32767
 
@@ -678,8 +385,6 @@ class ArmoryExporter(bpy.types.Operator, ExportHelper):
         exportMesh = bobject_eval.to_mesh()
 
         self.export_mesh_data(exportMesh, bobject, o, has_armature=armature is not None)
-        if armature:
-            self.export_skin(bobject, armature, exportMesh, o)
 
         self.output["mesh_datas"].append(o)
         bobject_eval.to_mesh_clear()

BIN
paint/assets/meshes/box.arm


BIN
paint/assets/meshes/box_bevel.arm


BIN
paint/assets/meshes/box_bevel_shared_uvs.arm


BIN
paint/assets/meshes/box_shared_uvs.arm


BIN
paint/assets/meshes/cone.arm


BIN
paint/assets/meshes/cylinder.arm


BIN
paint/assets/meshes/torus.arm


+ 0 - 26
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));