Linear Blend Skinning - cmu462/Scotty3D GitHub Wiki

Now that we have a skeleton set up, we need to link the skeleton to the mesh in order to get the mesh to follow the movements of the skeleton. We will implement linear blend skinning in Mesh::linearBlendSkinning().

Task 3a Naive Linear Blend Skinning

The easiest way to do this is to update each of mesh vertices' positions in relation to the bones (Joints) in the skeleton. Your implementation should have the following basic steps for each vertex:

  • Compute the vertex's position with respect to each joint j in the skeleton in j's coordinate frame when no transformations have been applied to the skeleton (bind pose, vertex bind position).
  • Find where this vertex would end up (in world coordinates) if it were transformed along with bone j.
  • Find the closest point on joint j's bone segment (axis) and compute the distance to this closest point.
  • Store the transformed location and distance for each j in an LBSInfo structure, which has been defined for you in dynamic_scene/mesh.h.
  • Compute the resulting position of the vertex by doing a weighted average of the positions from each bone, as stored in the LBSInfo structures. The weights for the weighted average should be the inverse distance to the joint, so closer bones have a stronger influence.

Below we have an equation representation. ![height=16px](https://raw.githubusercontent.com/wiki/cmu462/Scotty3Dmedia/task4_dev_eq_images/0080.png|height=12px]] is the new vertex position. media/task4_dev_eq_images/0081.png is the weight metric computed as the inverse of distance between vertex media/task4_dev_eq_images/0082.png and closest point on joint media/task4_dev_eq_images/0083.png. media/task4_dev_eq_images/0084.png is the vertex's position with respect to joint [[media/task4_dev_eq_images/0085.png) after joint's transformations has been applied.

height=37px

height=51px

In Scotty3D, the linearBlendSkinning() function gets called on every frame draw iteration, recomputing all skinning related quantities. In this function, you should read vertex bind positions from Vertex::bindPosition, and write the resulting skinned positions to Vertex::position. Be careful about mutating any other quantities in linearBlendSkinning(), or else the repeated calls to this function my lead to strange behavior.

Task 3b Linear Blend Skinning with Threshold

After you implemented the method in Task 3a, you probably noticed that parts of the mesh that is very far away moves when you move a joint. In part 3b, we will implement a threshold to limit the volume that each joint affects. You should change your code such that when parameter useCapsuleRadius is true, you check the distance between the vertex and the closest point on the joint, and if it is more than the joint's capsuleRadius, you do not let that joint affect this vertex. In your code, don't forget to properly handle the case where a vertex is not affected by any bones!

media/animation_3_demo_nothreshold.gif

Naive linear blend skinning affects other parts of the mesh, not just the arm. Also, the arm does not follow the joint exactly because other joints hold it back.

media/animation_3_demo.gif

Linear blend skinning with threshold allows us to better pose our characters.