limited IK calculation

This commit is contained in:
devZoGok
2021-10-19 19:06:41 +03:00
parent de8a6fb1aa
commit 9eb87999cf
4 changed files with 71 additions and 17 deletions
+7 -1
View File
@@ -99,9 +99,15 @@ namespace vb01{
break;
}
}
/*
swap(currentPos.y, currentPos.z);
currentPos.z = -currentPos.z;
swap(currentRot.y, currentRot.z);
currentRot.z = -currentRot.z;
*/
channelBone->setPosePos(currentPos);
//channelBone->setPoseRot(currentRot);
channelBone->setPoseRot(currentRot);
//channelBone->setPoseScale(currentScale);
}
}
+2 -2
View File
@@ -36,8 +36,8 @@ namespace vb01{
inline Quaternion fromAngle(float angle, Vector3 axis){
return Quaternion(cos(angle/2),axis.x*sin(angle/2),axis.y*sin(angle/2),axis.z*sin(angle/2));
}
inline float getAngle(){return 2*acos(w);}
inline Vector3 getAxis(){return getAngle()==0?Vector3(1,0,0):Vector3(x,y,z).norm();}
inline float getAngle(){return w > 1 ? 0 : 2*acos(w);}
inline Vector3 getAxis(){return x == 0 && y == 0 && z == 0? Vector3(1,0,0) : Vector3(x,y,z).norm();}
inline Quaternion operator+(Quaternion q){return Quaternion(w+q.w,x+q.x,y+q.y,z+q.z);}
inline Quaternion operator-(Quaternion q){return Quaternion(w-q.w,x-q.x,y-q.y,z-q.z);}
template<typename T> inline Quaternion operator*(T s){return Quaternion(w*s,x*s,y*s,z*s);}
+58 -14
View File
@@ -29,7 +29,7 @@ namespace vb01{
Bone *boneChain[chainLength];
Bone *ikBoneAncestor = ikBone;
Vector3 boneIkPos[chainLength];
Vector3 targetPos = ikTarget->getModelSpacePos() + model->globalToLocalPosition(ikTarget->localToGlobalPosition(ikTarget->getPosePos()));
Vector3 targetPos = ikTarget->getPosition();
float sumLengths = 0;
@@ -42,40 +42,84 @@ namespace vb01{
Vector3 startPos = boneChain[chainLength - 1]->getModelSpacePos();
if(startPos.getDistanceFrom(targetPos) < sumLengths){
int numIterations = 500;
int numIterations = 2;
for(int i = 0 ; i < numIterations; i++){
bool backward = (i % 2 == 0);
for(int j = 0; j < chainLength; j++){
int boneId = (backward ? j : chainLength - 1 - j);
Vector3 ikPos = (j == 0 ? (backward ? targetPos : startPos) : boneIkPos[boneId]);
Vector3 bonePos = boneChain[boneId]->getModelSpacePos();
Vector3 fromBoneToIkPos = (ikPos - bonePos).norm();
boneIkPos[boneId] = ikPos - fromBoneToIkPos * boneChain[boneId]->getLength();
int boneId;
float length;
Vector3 ikPos, bonePos, fromBoneToIkPos;
if(backward){
boneId = j;
length = boneChain[boneId]->getLength();
ikPos = (j == 0 ? targetPos : boneIkPos[boneId - 1]);
bonePos = boneIkPos[boneId];
fromBoneToIkPos = (ikPos - bonePos).norm();
boneIkPos[boneId] = ikPos - fromBoneToIkPos * length;
}
else{
boneId = chainLength - 1 - j;
if(j == 0){
ikPos = startPos;
length = 0;
}
else{
ikPos = boneIkPos[boneId + 1];
length = boneChain[boneId + 0]->getLength();
}
bonePos = boneIkPos[boneId];
fromBoneToIkPos = (ikPos - bonePos).norm();
boneIkPos[boneId] = ikPos - fromBoneToIkPos * length;
}
}
}
}
/*
else{
Vector3 fromStartToTarget = targetPos - startPos;
for(int i = 0; i < chainLength; i++){
Vector3 startToEndVec = (targetPos - startPos).norm();
for(int i = chainLength - 1; i >= 0; i--){
float length;
Vector3 bonePos;
if(i == chainLength - 1){
length = 0;
bonePos = boneIkPos[i];
}
else{
length = boneChain[i]->getLength();
bonePos = boneIkPos[i + 1];
}
boneIkPos[i] = bonePos + startToEndVec * length;
}
}
*/
float boneAngles[chainLength];
Vector3 axis[chainLength];
for(int i = chainLength - 1; i >= 0; i--){
Vector3 dir = ((i == 0 ? targetPos : boneIkPos[i - 1]) - boneChain[i]->getModelSpacePos()).norm() * -1;
Vector3 dir = ((i == 0 ? targetPos : boneIkPos[i - 1]) - boneIkPos[i]).norm();
Vector3 boneAxis = boneChain[i]->getInitAxis(1);
Vector3 rotAxis = dir.cross(boneAxis).norm();
//rotAxis = (model->localToGlobalPosition(boneChain[i]->globalToLocalPosition(rotAxis))).norm();
float angle = boneAxis.getAngleBetween(dir);
if(rotAxis == Vector3::VEC_ZERO){
angle = 0;
rotAxis = Vector3::VEC_I;
}
boneAngles[i] = angle;
axis[i] = rotAxis;
}
for(int i = 0; i < chainLength; i++){
for(int j = i + 1; j < chainLength; j++){
boneAngles[i] -= boneAngles[j];
if(boneAngles[i] <= 0){
boneAngles[i] = 0;
break;
}
}
float angle = boneAngles[i];
Vector3 rotAxis = axis[i];
boneChain[i]->setPoseRot(Quaternion(angle, rotAxis));
//((Node*)boneChain[i])->lookAt(dir, model);
}
}
+4
View File
@@ -121,6 +121,10 @@ namespace vb01{
yAxis.z = -yAxis.z;
swap(zAxis.y, zAxis.z);
zAxis.z = -zAxis.z;
swap(pos.y, pos.z);
pos.z = -pos.z;
/*
*/
}
else
pos = pos + Vector3(0, ((Bone*)parent)->getLength(), 0);