I’m working with 3D in SceneKit, iOS.
For my scene I take a glb
model from my provider and animation for it in dae
format from mixamo.com.
Problem: when I try to apply the animation on my model, it stretches each node of my model far away from each other, deforming the model. I realized this when trying to apply the animation only to one node
Looking at js code on my provider’s web sdk, I see that they descale all of the position values on the animation.
function normaliseFbxAnimation(fbx: Group, index: number = 0) {
const { tracks } = fbx.animations[index];
for (let i = 0; i < tracks.length; i += 1) {
const hasMixamoPrefix = tracks[i].name.includes(MIXAMO_PREFIX);
if (hasMixamoPrefix) {
tracks[i].name = tracks[i].name.replace(MIXAMO_PREFIX, '');
}
if (tracks[i].name.includes(POSITION_SUFFIX)) {
for (let j = 0; j < tracks[i].values.length; j += 1) {
// Scale the bound size down to match the size of the model
// eslint-disable-next-line operator-assignment
tracks[i].values[j] = tracks[i].values[j] * MIXAMO_SCALE;
}
}
}
return fbx.animations[index];
}
I don’t know the way to do the same in iOS, so I wrote a Python script with bpy
, that is supposed to do the same.
def scale_fcurve_values(fcurve, scale_factor):
for keyframe in fcurve.keyframe_points:
keyframe.co[1] *= scale_factor
keyframe.handle_left[1] *= scale_factor
keyframe.handle_right[1] *= scale_factor
def normalise_fbx_animation():
if len(bpy.data.actions) == 0:
print("No animations found in the FBX file.")
return
for obj in bpy.context.scene.objects:
print("BOOB")
print(obj.name)
if obj.animation_data and obj.animation_data.action:
action = obj.animation_data.action
for fcurve in action.fcurves:
print(f"Processing fcurve with data_path: {fcurve.data_path}")
if "location" in fcurve.data_path:
print(f"Scaling fcurve values for data_path: {fcurve.data_path}")
scale_fcurve_values(fcurve, 0.1)
However, once applied, I don’t see any change on the model itself and on the matrices of my keyframe animation.
I’m only able to see some effect when scaling scale
fcurves, but that just makes my model move chaotically all over the scene.
What am I doing wrong in my Python script? Am I accessing the wrong keyframe values?