improved quaternion conversion

This commit is contained in:
devZoGok
2025-07-06 12:09:11 +03:00
parent fd1f54697c
commit c50ce3aba6
2 changed files with 28 additions and 28 deletions
+27 -27
View File
@@ -393,51 +393,51 @@ namespace vb01{
return Vector3(local.x, local.y, local.z); return Vector3(local.x, local.y, local.z);
} }
Quaternion Node::adjustRot(vector<Node*> ancestors, Quaternion adjustableRot, bool localToGlobal){ Quaternion Node::adjustRot(Quaternion adjustableRot, bool localToGlobal){
Quaternion rOrigin = adjustableRot; vector<Node*> ancestors = getAncestors();
Quaternion rOrigin = (localToGlobal ? Quaternion::QUAT_W : adjustableRot);
while(!ancestors.empty()){ while(!ancestors.empty()){
int id = localToGlobal ? 0 : ancestors.size() - 1; int id = (localToGlobal ? ancestors.size() - 1 : 0);
Node *node = ancestors[id], *nodePar = node->getParent();
float angle = ancestors[id]->getOrientation().getAngle(); Vector3 parAxis[]{
Vector3 axis = ancestors[id]->getOrientation().getAxis(); nodePar ? nodePar->getGlobalAxis(0) : Vector3::VEC_I,
nodePar ? nodePar->getGlobalAxis(1) : Vector3::VEC_J,
nodePar ? nodePar->getGlobalAxis(2) : Vector3::VEC_K
};
Vector3 axis = node->getOrientation().getAxis();
axis = (parAxis[0] * axis.x + parAxis[1] * axis.y + parAxis[2] * axis.z).norm();
float angle = node->getOrientation().getAngle();
Quaternion o;
if(localToGlobal){ if(localToGlobal){
Node *par = ancestors[id]->getParent(); rOrigin = Quaternion(angle, axis) * rOrigin;
Vector3 parAxis[]{ ancestors.pop_back();
par ? par->getGlobalAxis(0) : Vector3::VEC_I,
par ? par->getGlobalAxis(1) : Vector3::VEC_J,
par ? par->getGlobalAxis(2) : Vector3::VEC_K
};
axis = (parAxis[0] * axis.x + parAxis[1] * axis.y + parAxis[2] * axis.z).norm(); if(ancestors.empty()){
Vector3 ax = adjustableRot.getAxis();
o = Quaternion(angle, axis); ax = (globalAxis[0] * ax.x + globalAxis[1] * ax.y + globalAxis[2] * ax.z).norm();
rOrigin = rOrigin * o; return Quaternion(adjustableRot.getAngle(), ax) * rOrigin;
ancestors.erase(ancestors.begin()); }
} }
else{ else{
o = Quaternion(angle, axis).conj(); rOrigin = rOrigin * Quaternion(angle, axis).conj();
rOrigin = rOrigin * o;
ancestors.pop_back(); ancestors.pop_back();
if(ancestors.empty())
return rOrigin;
} }
} }
return rOrigin;
} }
Quaternion Node::localToGlobalOrientation(Quaternion localRot){ Quaternion Node::localToGlobalOrientation(Quaternion localRot){
vector<Node*> ancestors = getAncestors(); return adjustRot(localRot, true);
Quaternion origin = adjustRot(ancestors, Quaternion::QUAT_W, true);
return localRot * origin;
} }
Quaternion Node::globalToLocalOrientation(Quaternion globalRot){ Quaternion Node::globalToLocalOrientation(Quaternion globalRot){
vector<Node*> ancestors = getAncestors(); return adjustRot(globalRot, false);
Quaternion origin = adjustRot(ancestors, globalRot, false);
return origin;
} }
Node* Node::findDescendant(string name, bool allDescendants){ Node* Node::findDescendant(string name, bool allDescendants){
+1 -1
View File
@@ -81,7 +81,7 @@ namespace vb01{
void adjustDir(Vector3); void adjustDir(Vector3);
void updateShaders(); void updateShaders();
Quaternion adjustRot(std::vector<Node*>, Quaternion, bool); Quaternion adjustRot(Quaternion, bool);
std::vector<Driver*> drivers; std::vector<Driver*> drivers;
protected: protected:
virtual void animate(float, KeyframeChannel); virtual void animate(float, KeyframeChannel);