in what space should animation frames be?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By majidarif

I wrote a custom importer for my custom animation file and tested it by animating a mesh using bones.

On bind/rest pose the mesh with skeleton looks right but when I start animating the mesh gets deformed beyond recognition.

My animation data is in localspace. I’m trying to figure out why it doesn’t work, so my question is does the animation in Godot require the frames be in different space other than local to hierarchy? modelspace? or am I doing this wrong?

My code for generating the animations:

var anim = Animation.new()

var numBones = file.get_16()
var numFrames = file.get_16()

for x in range(numBones):
	var trackId = anim.add_track(Animation.TYPE_TRANSFORM)
	var boneName  = ".:bone_%d" % x
	anim.track_set_path(trackId, boneName)
	anim.track_set_imported(trackId, true)
	anim.length = float(numFrames)/30

	for y in range(numFrames):
		var loc = Vector3(file.get_float(), file.get_float(), file.get_float())
		var rot = Quat(file.get_float(), file.get_float(), file.get_float(), file.get_float())
		var scale = Vector3(file.get_float(), file.get_float(), file.get_float())
		
		anim.transform_track_insert_key(trackId, float(y)/30, loc, rot, scale)

file.close()

return ResourceSaver.save("%s.%s" % [save_path, get_save_extension()], anim)

My code for creating the skeleton with bones:

var numBones = file.get_16()
for _x in range(numBones):
	var boneIndex  = file.get_16()
	var bonePIndex = file.get_16()

	var boneName  = "bone_%d" % boneIndex
	var bonePName = "bone_%d" % bonePIndex if bonePIndex >= 0 else ""
	
	var xAxis = Vector3(file.get_float(), file.get_float(), file.get_float())
	var yAxis = Vector3(file.get_float(), file.get_float(), file.get_float())
	var zAxis = Vector3(file.get_float(), file.get_float(), file.get_float())
	var origin = Vector3(file.get_float(), file.get_float(), file.get_float())
	
	add_bone(boneName)
	var boneId = find_bone(boneName)
	if bonePName != "":
		var bonePId = find_bone(bonePName)
		set_bone_parent(boneId, bonePId)
	set_bone_rest(boneId, Transform(xAxis, yAxis, zAxis, origin))
:bust_in_silhouette: Reply From: doggod

Transform xform;
xform.basis.set_quat_scale(rot, scale);
xform.origin = pos;

Skeleton3D skeleton = state.skeletons[node->skeleton].godot_skeleton;
int bone_idx = skeleton->find_bone(node->name);
xform = skeleton->get_bone_rest(bone_idx).affine_inverse() * xform;

rot = xform.basis.get_rotation_quat();
rot.normalize();
scale = xform.basis.get_scale();
pos = xform.origin;

animation->transform_track_insert_key(track_idx, time, pos, rot, scale);