Implementing multiple animation channels support (as seen in the Fox model). The get_skin_timelines() method now returns a dictionary of all animation channels with Timeline as their value.

We merged two PRs, #689 (colors from Material) and #643 (simple animations).

Added ability to load morphing information and create timelines from it. Here's a preview of the AnimatedMorphCube and AnimatedMorphSphere models:

This week I fixed all the issues with skeletal animations, and we got to see our first render of skeletal animation :).

Implemented a hierarchical timeline system (i.e., one timeline for each bone, and the timeline will contain its parent timeline in a hierarchy).

- I figured out that we don't need to apply the parent transform as we're applying it to the vertex data while forming the actor. So the skin matrix becomes SkinMatrix = InverseBindPose * BoneDeform where BoneDeform = CurrentBoneTransform * ParentBonetransform.

Week 12 - Adding skeleton as actors and fix global transformation

xtanion
Published: 09/20/2022

What did you do this week?

I started this week by fixing the segmentation fault for the skinning test. I could not fix this as of now.

I imported the RiggedFigure model into the Blender and I was quite impressed with how it visualizes each bone. So, I created a function that creates an arrow actor in place of a bone, and by applying the correct transformation, we get the bones of a model in place. Here's a quick preview of bones in Blender vs bones in FURY:

After having the bones actor, I noticed that some bones are not aligned correctly. It was happening due to multiplication of the same transformation matrix twice.

I also created a function that calculates the total transformation of a node, it eliminates the need to use timeline.get_value in get_skin_timeline function.

What is coming up next week?

It seems like I fixed everything, but we are not getting the correct model at timestamp 0. We need to find the cause and fix it!

Cleaning the Simple Animation PR #643, and merging it.

Did you get stuck anywhere?

While applying the timeline, we were getting the identity matrix for timestamp 0.0s, it was set to a new value before. We figured this in our meeting that it's happening due to some model's animation not starting from 0.0s.

Week 11 - Multiple transformations support and adding tests

xtanion
Published: 09/20/2022

What did you do this week?

As decided last week, I added support for multiple animations at the same timestamp. But this didn't solve the animation problems of RiggedSimple model.

I figured out that I was not applying the global transform of joints in the skinning matrix causing the joints to move to a new position. I referred to this answer by irradicator.

We had to invert the multiplication order (ie, np.dot(skin_mat, vertex) instead of np.dot(vertex, skin_mat)) for this model. We still need to figure out from where we get the multiplication order of the two.

I also tried to create a custom Interpolator that does all calculations required for vertex skinning. However, we couldn't get this working. I got a few suggestions from Mohamed in our meeting, I'll try to implement those.

As we figured out that the SimpleSkin model is not animated as intended. This week I started working with that model; I figured out that we need to apply the InverseBindMatrix to each timer callback. I had a hard time figuring out what inverse bind matrix actually does. Here's a good blog that answers that.

In short: The InverseBindMatrix "undoes" any transformation that has already been applied to your model in its bind pose. Note: Inverse bind matrix shouldn't be applied with weights.

I got the SimpleSkin model to work perfectly. Here's a preview:

Support for multiple transformations is still missing. However RiggedSimple is also working fine, except that It doesn't interpolate translation and scaling matrices.

What is coming up next week?

Adding tests and adding support for combining transformation matrices for the same timestamp.

Write an Interpolator that applies skinning to the mesh internally.