I posted once a status update about Inverse Kinematics and described the maths on Discord (I had also a doubt if it should be posted in a new topic, but lastly decided to not to do it). The problem is, math is only a part of the system. There's also need to code the UI for that, I was posting the example also on the Discord.
UI
Each keyframe for the bendable object would have a bool: whether to use IK or not. If not, it's all like now. If IK is used, there's a second position tab instead of a rotation tab, to manage the IK controller (I think there should be light blue arrows and light blue sphere for that.) If the transition is between two keyframes that have IK on, the IK controller will move instead of transitioning the rotations and bending directly. If between IK and FK or between two FK, the rotations would transist directly (like now). Also, when toggling between IK and FK mode, the position of IK controller/rotations+bend of the object would be calculated automatically so the limb wouldn't move (that might be helpful in certain situations).
Math (you might not understand nothing below, don't complain to me if so )
To make IK working, there should be equations for calculating the limb positions though. The main things we need to calculate first are the distance between the object root point (rotation point) and IK controller and the angle between these points.
You can use this pseudocode for reference:
#pseudocode
// Expectations:
// Because of Mine-imator limitations, only two-bone implementation will be demonstrated here.
// Object position will be (0, 0, 0), because it's easier and we have a reference points (all points declared below are relative to object root position).
// BELOW THERE ARE VARIABLES THAT SHOULD BE COPIED/USED FROM EXISTING MINE-IMATOR CODE.
var cPos = {x = 0, y = -6, z = 0} // IK controller position
var bones = {3, 3} // two bones, because we have one bending point, therefore we can have support for multiple bendings in various positions in the future
// BELOW THERE ARE FUNCTIONS THAT ARE JUST HELPING DOING MATHS AND DOES NOT AFFECT DIRECTLY INTO INVERSE KINEMATICS SIMULATION.
func diagonal(x, y) {
// Simple Pythagorean theorem...
return(((x ^ 2) + (y ^ 2)) !^ 2)
}
func angleToPoint(x, y) {
// An angle between the point (0, 0) and the point (x, y) in degrees.
[...]
}
func add(array) {
// Example: if array = {0, 5, -3, 666}, the output will be 0 + 5 + -3 + 666 = 668.
localvar total = 0
for i = 0, bones.length {
total += bones[i]
}
return(total)
}
// BELOW THERE IS CODE THAT IS NECESSARY TO CALCULATE BENDINGS/ROTATIONS IN MINE-IMATOR.
// THAT CODE SHOULD BE EXECUTED EVERY FRAME TO WORK PROPERLY.
var limbLength = add(bones) // It's basically addition of all numbers in "bones" variable.
var desiredLen = diagonal(diagonal(cPos[0], cPos[1]), cPos[2]) // Length between the object position and the controller position.
var desiredRot = {x = angleToPoint(cPos[1], cPos[2]), y = angleToPoint(cPos[0], cPos[2]), z = angleToPoint(cPos[0], cPos[1])} // Rotations in each axis between the object position and the controller position.
var stretching = desiredLen > limbLength // If it's true, the bone will be stretched. Because I think it looks fancy, I think stretching wouldn't be necessary there.
// Now that's there the magic happens.
// We can imagine a triangle where we have its three sides, and we need to calculate the angles between each side.
/*
R
|\
|x\ b
a | \
| y/
|z/ c
|/
C
where:
a = distance between the root and IK controller (given)
b, c = bone lengths (given)
x = the object rotation (we should calculate this)
y = the bending angle (we should calculate this)
z = calculating the 3rd angle isn't necessary
R = the object root position (here: (0, 0, 0))
C = the IK controller position (given)
*/
//
if !stretching {
}
To Be Edited soon, again.