From 66f3adfb4e6316fc8f9ef230a02dbbaa336125eb Mon Sep 17 00:00:00 2001 From: devZoGok Date: Thu, 7 Jan 2021 20:04:01 +0200 Subject: [PATCH] revamped Y axis orientation method assignment of animated model bone axis pose orientaion axis retrieved from bone axis --- bone.cpp | 13 +------------ bone.h | 3 +-- mesh.cpp | 4 +++- node.cpp | 39 +++++++++++++++++++++++++-------------- nodeTest.cpp | 3 +++ vbModelReader.cpp | 24 ++++++++++++++++++++---- 6 files changed, 53 insertions(+), 33 deletions(-) diff --git a/bone.cpp b/bone.cpp index 5b7d999..55e1912 100644 --- a/bone.cpp +++ b/bone.cpp @@ -9,7 +9,7 @@ namespace vb01{ this->length = length; } - void Bone::lookAt(Vector3 newDir, Vector3 newUp, Node *par){ + void Bone::lookAt(Vector3 newDir, Vector3 newUp){ Node::lookAt(newDir, newUp); for(int i = 0; i < 3; i++) this->initAxis[i] = globalAxis[i]; @@ -18,17 +18,6 @@ namespace vb01{ restScale = scale; } - /* - void Bone::lookAt(Vector3 newDir, Node *par){ - Node::lookAt(newDir, par); - for(int i = 0; i < 3; i++) - this->initAxis[i] = globalAxis[i]; - restPos = pos; - restRot = orientation; - restScale = scale; - } - */ - Vector3 Bone::getModelSpacePos(){ Vector3 modelSpacePos = Vector3::VEC_ZERO; Bone *rootBone = skeleton->getRootBone(); diff --git a/bone.h b/bone.h index 75d0b56..70cd9c4 100644 --- a/bone.h +++ b/bone.h @@ -13,8 +13,7 @@ namespace vb01{ void setPosePos(Vector3 p); void setPoseRot(Quaternion r); void setPoseScale(Vector3 s); - void lookAt(Vector3, Vector3, Node*); - //void lookAt(Vector3, Node*); + void lookAt(Vector3, Vector3); Vector3 getModelSpacePos(); inline Bone* getIkTarget(){return ikTarget;} inline void setIkTarget(Bone *target){this->ikTarget = target;} diff --git a/mesh.cpp b/mesh.cpp index 24adf70..efedc3c 100755 --- a/mesh.cpp +++ b/mesh.cpp @@ -169,6 +169,8 @@ namespace vb01{ }; Vector3 posePos = bone->getPosePos(); Quaternion poseRot = bone->getPoseRot(); + Vector3 rotAxis = poseRot.getAxis(); + rotAxis = boneAxis[0] * rotAxis.x + boneAxis[1] * rotAxis.y + boneAxis[2] * rotAxis.z; Vector3 trans = boneAxis[0] * posePos.x + boneAxis[1] * posePos.y + boneAxis[2] * posePos.z; Vector3 scale = bone->getPoseScale(); Vector3 bonePos = bone->getModelSpacePos(); @@ -185,7 +187,7 @@ namespace vb01{ shader->setVec3(bonePos, "bones[" + to_string(i) + "].pos"); shader->setVec3(trans, "bones[" + to_string(i) + "].trans"); - shader->setVec3(poseRot.getAxis(), "bones[" + to_string(i) + "].rotAxis"); + shader->setVec3(rotAxis, "bones[" + to_string(i) + "].rotAxis"); shader->setFloat(poseRot.getAngle(), "bones[" + to_string(i) + "].angle"); shader->setVec3(scale, "bones[" + to_string(i) + "].scale"); shader->setInt(vertGroupId, "bones[" + to_string(i) + "].vertGroup"); diff --git a/node.cpp b/node.cpp index 0f13424..fb55c98 100755 --- a/node.cpp +++ b/node.cpp @@ -120,23 +120,34 @@ namespace vb01{ } void Node::adjustUp(Vector3 newUp){ + Vector3 xDir = + parent->globalToLocalPosition(localToGlobalPosition(Vector3::VEC_I)) - + parent->globalToLocalPosition(localToGlobalPosition(Vector3::VEC_ZERO)); + + Vector3 yDir = + parent->globalToLocalPosition(localToGlobalPosition(Vector3::VEC_J)) - + parent->globalToLocalPosition(localToGlobalPosition(Vector3::VEC_ZERO)); + + Vector3 zDir = xDir.cross(yDir).norm(); + mat3 mat; - mat[0][0] = 1; - mat[1][0] = 0; - mat[2][0] = 0; - mat[0][1] = 0; - mat[1][1] = 1; - mat[2][1] = 0; - mat[0][2] = 0; - mat[1][2] = 0; - mat[2][2] = 1; - mat = inverse(mat); + mat[0][0] = xDir.x; + mat[1][0] = xDir.y; + mat[2][0] = xDir.z; + mat[0][1] = yDir.x; + mat[1][1] = yDir.y; + mat[2][1] = yDir.z; + mat[0][2] = zDir.x; + mat[1][2] = zDir.y; + mat[2][2] = zDir.z; - vec3 nu = vec3(newUp.x, newUp.y, newUp.z) * mat; - newUp = (Vector3(1, 0, 0) * nu.x + Vector3(0, 1, 0) * nu.y).norm(); - float angle = Vector3(0, 1, 0).getAngleBetween(newUp); + vec3 nu = vec3(newUp.x, newUp.y, newUp.z) * inverse(mat); + newUp = (xDir * nu.x + yDir * nu.y).norm(); + if(newUp != Vector3::VEC_ZERO){ + float angle = yDir.getAngleBetween(newUp); - setOrientation(Quaternion(angle * (nu.x < 0 ? 1 : -1), Vector3::VEC_K)); + setOrientation(Quaternion(angle * (nu.x < 0 ? 1 : -1), zDir) * orientation); + } } void Node::getDescendants(vector &descendants){ diff --git a/nodeTest.cpp b/nodeTest.cpp index 2b55c55..83ffef1 100644 --- a/nodeTest.cpp +++ b/nodeTest.cpp @@ -256,6 +256,9 @@ namespace vb01{ Vector3 upClamped = Vector3(up[i].x, up[i].y, 0).norm(); CPPUNIT_ASSERT(lookNode->getGlobalAxis(1).getAngleBetween(upClamped) < maxAngle); } + lookNode->setOrientation(Quaternion::QUAT_W); + lookNode->lookAt(Vector3::VEC_K, Vector3::VEC_K); + CPPUNIT_ASSERT(lookNode->getGlobalAxis(1) == Vector3::VEC_J); Quaternion rotQuat = Quaternion(.707, Vector3(1, 0 ,0)); lookNodeParent->setOrientation(rotQuat); diff --git a/vbModelReader.cpp b/vbModelReader.cpp index 21cd93a..51aea26 100644 --- a/vbModelReader.cpp +++ b/vbModelReader.cpp @@ -9,6 +9,7 @@ #include"animationController.h" #include +#include #include using namespace std; @@ -117,11 +118,26 @@ namespace vb01{ float length = atof(data[1].c_str()); Vector3 head = Vector3(atof(data[2].c_str()), atof(data[3].c_str()), atof(data[4].c_str())); - Vector3 xAxis = Vector3(atof(data[5].c_str()), atof(data[6].c_str()), atof(data[7].c_str())); - Vector3 yAxis = Vector3(atof(data[8].c_str()), atof(data[9].c_str()), atof(data[10].c_str())); + Vector3 xAxis = Vector3(atof(data[5].c_str()), atof(data[6].c_str()), atof(data[7].c_str())).norm(); + Vector3 yAxis = Vector3(atof(data[8].c_str()), atof(data[9].c_str()), atof(data[10].c_str())).norm(); + + float eps = pow(10, -2); + if(fabs(xAxis.x) < eps) + xAxis.x = 0; + if(fabs(xAxis.y) < eps) + xAxis.y = 0; + if(fabs(xAxis.z) < eps) + xAxis.z = 0; + if(fabs(yAxis.x) < eps) + yAxis.x = 0; + if(fabs(yAxis.y) < eps) + yAxis.y = 0; + if(fabs(yAxis.z) < eps) + yAxis.z = 0; + string ikTarget = data[11].c_str(); int ikChainLength = atoi(data[12].c_str()); - Vector3 zAxis = xAxis.cross(yAxis); + Vector3 zAxis = xAxis.cross(yAxis).norm(); Vector3 pos = head; string parName = string(data[0].c_str()); @@ -143,7 +159,7 @@ namespace vb01{ Bone *bone = new Bone(preColon, length, pos); bone->setIkChainLength(ikChainLength); skeleton->addBone(bone, (Bone*)parent); - bone->lookAt(zAxis, yAxis, parent); + bone->lookAt(zAxis, yAxis); if(ikTarget != "-") ikRelationships.emplace(preColon, ikTarget); }