One thing that is mathematically sound isI am trying to grabtransform the mesh data in a gltf modelfile and apply some arbitrary linear transformation to it, like a rotation or a translationthen modify the skin and animation data accordingly.
Let's say we want to transform the transformation is encoded asdata using a 4x4 homogeneous matrix.
I think it needs to be applied to For simplification let us say the meshes, nodes, ibms intransformation is just swapping the skins,y and animationsz axes.
Starting simple, I want to applyDoing it to only the meshes.mesh data is simple enough:
i.e. somethingSomething like this:
for mesh in &self&gltf.meshes
{
for primitive in &mesh.primitives
{
for position in selfgltf
.data_from_accessor::<Vec3>(primitive.attributes.position)
.unwrap()
{
*position = transform_vec3(&position, &transform, true);
}
for normal in selfgltf
.data_from_accessor::<Vec3>(primitive.attributes.normal)
.unwrap()
{
*normal = transform_vec3(&normal, &transform, false);
}
}
}
ThisNow the issue is ok, after doing this, what must we do to the skin data and yieldsanimation data to correctly change it so that now the y and z axes are swapped.
We know that before our transformation, the animations are effectively computed as:
$$(\sum \lambda_i A_i \cdot M_i) \cdot v$$
where $\lambda_i, A_i, M_i$ are the weights, animation matrices and inverse bind matrices.
Now, after modifying the vertices of the mesh data we have:
$$(\sum \lambda_i A_i \cdot M_i) \cdot T v$$
So we need to modify our matrices such that the transformation $T$ is applied only once after all other transformations are applied, so:
$$T(\sum \lambda_i A_i \cdot M_i)T^{-1} T v$$
$$(\sum \lambda_i TA_i \cdot M_iT^{-1}) T v$$
Ok now I wantThe above formula suggests that the correct approach is to apply the transformation to all animation data and its inverse to the nodes, so I attempt thisibms.
Something like:
for node in &mut self.nodes
{
let mut mat : Mat4 = compose_homogeneous(&node.scale, &node.rotation, &node.translation);
mat = transform * mat;
let (new_scale, new_rot, new_trans) = decompose_homogeneous(&mat);
node.rotation = new_rot;
node.translation = new_trans;
node.scale = new_scale;
}
- for each ibm matrix ibm -> ibm * $T^{-1}$
- for each node in the skin node -> $T$ * node
- for each animation output in the skin, output -> $T$ * output
Now gltf viewers showThis fails miserably in all real life data I try and I don't understand why. For example this is the result on a model:
If I have tested things and both compose_homogeneous
and decompose_homogeneous
are correct. Why amremove the skins from the model I gettingget this degenerate:
Which is the expected output, the mesh data has flipped the z and the y.
So what must be done to convert the animation data to match the transform to the mesh?