• entries
33
64
• views
46251

# Inverse Kinematics to the rescue.

2490 views

I'm currently trying things to make the game easier on the new player, without sacrificing the original vision.
Besides modifying the first levels, I have added a few control related improvements.

Inverse kinematics:

I slowed it down on purpose to give the user more control.

This is something that several people asked me to add. So now you can control the whole arm through IK, or control each individual part as before if you want more control.

IK is usually not an easy subject, but for my case I was able to approach it in the simplest way, using Cyclic Coordinate Descent. Using this awesome article by Ryan Juckett (includes explanation, drawing, math and code!) it took me very few adjustments to make it work.

The only thing I had to add was restrictions to the joints, since the wrist of my character is not supposed to do a 360 rotation.

To make it work, I modified Juckets' Bone_2D_CCD struct to:struct Bone_2D_CCD{ double x; double y; double angle; bool hasLimits; // new double minAngle; // new double maxAngle; // new};
And fed this new information to the algorithm.

Inside the IK function, after these rotAng variable is computed (these lines)...double rotAng = acos( max(-1.0, min(1.0,cosRotAng) ) );if( sinRotAng < 0.0 ) rotAng = -rotAng;
...I added code to truncate the rotAng variable:if (bones[boneIdx].hasLimits){ bool limitExceeded = false; if (rotAng > 0 && bones[boneIdx].angle + rotAng > bones[boneIdx].maxAngle) // truncate to maxAngle { rotAng = bones[boneIdx].maxAngle - bones[boneIdx].angle; limitExceeded = true; } else if (rotAng < 0 && bones[boneIdx].angle + rotAng < bones[boneIdx].minAngle) // truncate to minAngle { rotAng = bones[boneIdx].minAngle - bones[boneIdx].angle; limitExceeded = true; } if (limitExceeded) // Recompute the newly truncated angle. { cosRotAng = cos(rotAng); sinRotAng = sin(rotAng); }}
And although I'm not super proud to bring trigonometric functions to an "all linear algebra" solution, I don't know enough math to do it properly, and this was a case of not needing to optimize things that do not slow down your game (this code follows the action of the much-slower user).

looks rally good, and quite fluid, excellent work!

Looks great. CCD not easy to implement so nice work.

CCD not easy to implement so nice work.

Thanks! but to be honest Ryan has already done all the heavy lifting in his article. Using his code was very easy.

## Create an account

Register a new account