Hello, maybe I found the bug of the FABRIK algorithm or your code, so I want to discuss this bug with you and get your advice if you want.
Based on Demo 7, I built a chain as shown below. The start and end positions of each bone are: [0, 0, 0] [0, 0, 40]; [0, 0, 40], [0, 0, 80]; [0, 0, 80], [0, 0, 120]. The target that I want to solve is [0, 0, 100]. I have tried to change the joint limit many times, but all the results were all problematic. This chain is always along the z-axis, and the end of the last bone is not placed at the target position. The ideal configuration of this chain should be like this:
------1-----End point (target)
------1-------
------1-------
------1-----third joint (local hinge)
--------1-----
----------1---
------------1- second joint (local hinge)
----------1---
--------1-----
-------1------
------1---base joint (ball)
Did I make a mistake? Looking forward to your reply!
Code:
public class LocalHingesWithReferenceAxisConstraints extends CalikoDemoStructure3D {
@Override
public void setup() {
this.structure = new FabrikStructure3D("Demo 7 - Local Hinges with Reference Axis Constraints");
int numChains = 1; // 3
Vec3f hingeRotationAxis = new Vec3f();
Vec3f hingeReferenceAxis = new Vec3f();
Vec3f baseBoneConstraintAxis = new Vec3f();
float baseBoneConstraintAngleDegs = 90.0f;
baseBoneConstraintAxis = X_AXIS;
float rotStep = 360.0f / (float)numChains;
for (int loop = 0; loop < numChains; loop++)
{
// Set colour and axes
Colour4f chainColour = new Colour4f();
switch (loop % 3)
{
case 0:
chainColour = Utils.RED;
hingeRotationAxis = new Vec3f(X_AXIS);
hingeReferenceAxis = new Vec3f(Y_AXIS);
break;
case 1:
chainColour = Utils.GREEN;
hingeRotationAxis = new Vec3f(Y_AXIS);
hingeReferenceAxis = new Vec3f(X_AXIS);
break;
case 2:
chainColour = Utils.BLUE;
hingeRotationAxis = new Vec3f(Z_AXIS);
hingeReferenceAxis = new Vec3f(Y_AXIS);
break;
}
FabrikChain3D chain = new FabrikChain3D();
Vec3f startLoc = new Vec3f(0.0f, 0.0f, 0.0f);
startLoc = Vec3f.rotateYDegs(startLoc, rotStep * (float)loop);
Vec3f endLoc = startLoc.plus( defaultBoneDirection.times(base_BoneLength) ); // base_BoneLength = 40
FabrikBone3D basebone = new FabrikBone3D(startLoc, endLoc);
basebone.setColour(chainColour);
chain.addBone(basebone);
chain.setRotorBaseboneConstraint(FabrikChain3D.BaseboneConstraintType3D.GLOBAL_ROTOR, baseBoneConstraintAxis, baseBoneConstraintAngleDegs);
float constraintAngleDegs_1 = 120.0f;
chain.addConsecutiveHingedBone(defaultBoneDirection, (float) 40, JointType.LOCAL_HINGE, hingeRotationAxis, constraintAngleDegs_1, constraintAngleDegs_1, hingeReferenceAxis, Utils.GREY);
chain.addConsecutiveHingedBone(defaultBoneDirection, (float) 40, JointType.LOCAL_HINGE, hingeRotationAxis, constraintAngleDegs_1, constraintAngleDegs_1, hingeReferenceAxis, Utils.GREY);
this.structure.addChain(chain);
}
}
Hello, maybe I found the bug of the FABRIK algorithm or your code, so I want to discuss this bug with you and get your advice if you want.
Based on Demo 7, I built a chain as shown below. The start and end positions of each bone are: [0, 0, 0] [0, 0, 40]; [0, 0, 40], [0, 0, 80]; [0, 0, 80], [0, 0, 120]. The target that I want to solve is [0, 0, 100]. I have tried to change the joint limit many times, but all the results were all problematic. This chain is always along the z-axis, and the end of the last bone is not placed at the target position. The ideal configuration of this chain should be like this:
------1-----End point (target)
------1-------
------1-------
------1-----third joint (local hinge)
--------1-----
----------1---
------------1- second joint (local hinge)
----------1---
--------1-----
-------1------
------1---base joint (ball)
Did I make a mistake? Looking forward to your reply!
Code: