FK/IK and Skinning Editor
Forward/Inverse kinematics and skinning editor with Unity Foot-IK plugin
Overview
This is an FK/IK and skinning project written in C++ and OpenGL for my Computer Animation class: forward kinematics, a limb-based IK solver, a CCD IK solver, and automatic skin binding with linear blend skinning. I also compiled the same core into a native Unity plugin that does terrain-adaptive foot IK on a walking character.
Forward Kinematics
The skeleton is a tree of joints. Each joint stores only its transform relative to its parent, and FK walks the tree from the root, multiplying each joint’s local transform with the parent’s world transform to get the global position and orientation. Both IK solvers, the skinning, and the Unity plugin read these world transforms, so editing one local rotation anywhere moves the whole subtree below it.
Limb-Based IK
Hands and feet use the analytic two-bone solver. The base joint, the middle joint, and the target form a triangle, so the elbow/knee angle comes straight out of the law of cosines. The base-to-target distance is clamped to the total length of the chain: an unreachable target straightens the limb instead of producing NaNs. A second axis-angle rotation at the base joint then swings the whole limb so the end effector lands on the target.
CCD IK
Cyclic Coordinate Descent handles chains of any length, up to the full path from end effector to root. One pass walks the chain from the tip back toward the root:
- Compute the axis and angle that rotate the current end effector position toward the target, in global space.
- Convert the axis into the joint’s local frame.
- Apply it as a quaternion delta and move on to the parent.
Passes repeat until the end effector is within tolerance of the target. There is no closed-form guarantee like the limb solver, but it can bend a spine or a tail, and because the sweep starts at the tip the motion spreads along the chain instead of all happening at the base.
Skin Binding
The binding step assigns joint weights to every vertex automatically. Each joint gets a binding radius from the distance to its nearest vertex, times a user-set multiplier. For every vertex:
- Find the nearest joint.
- Project the vertex onto the bone from that joint toward its parent. This decides which side of the joint the vertex sits on.
- Inside the radius, blend the weight linearly between joint and parent by the normalized distance. Outside it, snap fully to one or the other.
Without the falloff, the two bones’ influence switches at a hard edge and elbows and knees crease.
Linear Blend Skinning
At bind time each joint’s inverse global transform is stored as its bind matrix, which takes a vertex from model space into that joint’s local space. Per frame, every vertex sums its influences:
newPosition = sum( weight_i * (jointGlobal_i * bindMatrix_i) * restPosition )
Each term moves the vertex from the bind pose into the joint’s space and back out through the joint’s current pose. The weights decide how much of each bone’s motion the vertex picks up. Normals go through the same sum with the rotation-only part of each matrix, so lighting stays correct as the mesh deforms.
Unity Foot-IK Plugin
The C++ core is compiled as a native Unity plugin and drives a walking character over uneven terrain. A guide joint projected onto the ground plane steers the character toward its target, rotating the walk direction with a shortest-arc quaternion. Every frame:
- Sample the terrain height under each foot.
- Lower the root by the lower of the two heights, so the support leg never has to reach further than it can.
- Run the limb IK solver on each leg to pull the foot to its own contact point.
- Optionally rotate each foot to match the terrain normal at the contact point.
Tools Used
C++, OpenGL, Eigen, ImGui, Unity, CMake