I wanted to make a character's feet align to the ground when standing on a slope or on stairs. This was very easy to get a basic version set up.
The code here only handles the feet, so the legs currently will get stretched out. Each model may require a little bit different final rotation.
The next step is to adjust the knee bones. The hip, knee, and foot form a triangle. One of the constructors for the Plane class accepts three points in space, so those three bones can be used to find a plane. Then you transform their positions to a matrix facing in the direction of the plane normal, solve the triangle, transform back, and that's how IK works.
void MyComponent::UpdateFeet()
{
auto entity = GetEntity();
auto world = entity->GetWorld();
if (not world) return;
for (int n = 0; n < footbones.size(); ++n)
{
if (not footbones[n]) continue;
auto pos = footbones[n]->GetPosition(true);
pos.y = 0;
pos = TransformPoint(pos, entity, NULL);
auto pickmode = entity->GetPickMode();
entity->SetPickMode(PICK_NONE);
auto pickinfo = world->Pick(pos + Vec3(0, footradius + 0.75, 0), pos - Vec3(0, footreach, 0), footradius, true);
entity->SetPickMode(pickmode);
if (pickinfo.entity)
{
pos = TransformPoint(pickinfo.position, NULL, entity);
footbones[n]->SetPosition(pos, true);
Vec3 normal = TransformNormal(pickinfo.normal, NULL, entity);
footbones[n]->AlignToVector(-normal, 1);
footbones[n]->Turn(0, 180, 0);
}
}
}