mirror of
https://github.com/ApfelTeeSaft/vb01.git
synced 2026-08-26 19:33:45 +00:00
local - global orientation and ancestor retrieval tests
This commit is contained in:
@@ -10,7 +10,7 @@ namespace vb01{
|
||||
}
|
||||
|
||||
void Bone::lookAt(Vector3 newDir, Vector3 newUp, Node *par){
|
||||
Node::lookAt(newDir, newUp, par);
|
||||
Node::lookAt(newDir, newUp);
|
||||
for(int i = 0; i < 3; i++)
|
||||
this->initAxis[i] = globalAxis[i];
|
||||
restPos = pos;
|
||||
|
||||
@@ -101,60 +101,42 @@ namespace vb01{
|
||||
text->setNode(this);
|
||||
}
|
||||
|
||||
void Node::lookAt(Vector3 newDir, Vector3 newUp, Node *node){
|
||||
adjustDir(newDir, node);
|
||||
adjustUp(newUp, node);
|
||||
void Node::lookAt(Vector3 newDir, Vector3 newUp){
|
||||
adjustDir(newDir);
|
||||
adjustUp(newUp);
|
||||
}
|
||||
|
||||
void Node::lookAt(Vector3 newDir, Node *node){
|
||||
adjustDir(newDir, node);
|
||||
void Node::lookAt(Vector3 newDir){
|
||||
adjustDir(newDir);
|
||||
}
|
||||
|
||||
void Node::adjustDir(Vector3 newDir, Node *node){
|
||||
Vector3 parAxis[]{
|
||||
node->getGlobalAxis(0),
|
||||
node->getGlobalAxis(1),
|
||||
node->getGlobalAxis(2)
|
||||
};
|
||||
newDir = (parAxis[0] * newDir.x + parAxis[1] * newDir.y + parAxis[2] * newDir.z).norm();
|
||||
|
||||
float angle = globalAxis[2].getAngleBetween(newDir);
|
||||
Vector3 rotAxis = globalAxis[2].cross(newDir).norm();
|
||||
void Node::adjustDir(Vector3 newDir){
|
||||
float angle = Vector3(0, 0, 1).getAngleBetween(newDir);
|
||||
Vector3 rotAxis = Vector3(0, 0, 1).cross(newDir).norm();
|
||||
if(rotAxis == Vector3::VEC_ZERO)
|
||||
rotAxis = globalAxis[1];
|
||||
rotAxis = Vector3::VEC_I;
|
||||
|
||||
Quaternion oldRot = node->localToGlobalOrientation(orientation);
|
||||
Quaternion newRot = node->globalToLocalOrientation(Quaternion(angle,rotAxis));
|
||||
setOrientation(newRot * oldRot);
|
||||
setOrientation(Quaternion(angle, rotAxis));
|
||||
}
|
||||
|
||||
void Node::adjustUp(Vector3 newUp, Node *node){
|
||||
Vector3 parAxis[]{
|
||||
node->getGlobalAxis(0),
|
||||
node->getGlobalAxis(1),
|
||||
node->getGlobalAxis(2)
|
||||
};
|
||||
newUp = (parAxis[0] * newUp.x + parAxis[1] * newUp.y + parAxis[2] * newUp.z).norm();
|
||||
|
||||
void Node::adjustUp(Vector3 newUp){
|
||||
mat3 mat;
|
||||
mat[0][0] = globalAxis[0].x;
|
||||
mat[1][0] = globalAxis[0].y;
|
||||
mat[2][0] = globalAxis[0].z;
|
||||
mat[0][1] = globalAxis[1].x;
|
||||
mat[1][1] = globalAxis[1].y;
|
||||
mat[2][1] = globalAxis[1].z;
|
||||
mat[0][2] = globalAxis[2].x;
|
||||
mat[1][2] = globalAxis[2].y;
|
||||
mat[2][2] = globalAxis[2].z;
|
||||
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);
|
||||
|
||||
vec3 nu = vec3(newUp.x, newUp.y, newUp.z) * mat;
|
||||
newUp = (globalAxis[0] * nu.x + globalAxis[1] * nu.y).norm();
|
||||
float angle = globalAxis[1].getAngleBetween(newUp);
|
||||
newUp = (Vector3(1, 0, 0) * nu.x + Vector3(0, 1, 0) * nu.y).norm();
|
||||
float angle = Vector3(0, 1, 0).getAngleBetween(newUp);
|
||||
|
||||
Quaternion oldRot = node->localToGlobalOrientation(orientation);
|
||||
Quaternion newRot = node->globalToLocalOrientation(Quaternion(angle * (nu.x < 0 ? 1 : -1), globalAxis[2]));
|
||||
setOrientation(newRot * oldRot);
|
||||
setOrientation(Quaternion(angle * (nu.x < 0 ? 1 : -1), Vector3::VEC_K));
|
||||
}
|
||||
|
||||
void Node::getDescendants(vector<Node*> &descendants){
|
||||
|
||||
@@ -31,8 +31,8 @@ namespace vb01{
|
||||
void addLight(Light*);
|
||||
void removeLight(int);
|
||||
void addText(Text*);
|
||||
virtual void lookAt(Vector3, Vector3, Node*);
|
||||
virtual void lookAt(Vector3, Node*);
|
||||
virtual void lookAt(Vector3, Vector3);
|
||||
virtual void lookAt(Vector3);
|
||||
void updateAxis();
|
||||
void setOrientation(Quaternion);
|
||||
void getDescendants(std::vector<Node*>&);
|
||||
@@ -64,8 +64,8 @@ namespace vb01{
|
||||
inline std::string getName(){return name;}
|
||||
inline void setVisible(bool v){this->visible = v;}
|
||||
private:
|
||||
void adjustUp(Vector3, Node*);
|
||||
void adjustDir(Vector3, Node*);
|
||||
void adjustUp(Vector3);
|
||||
void adjustDir(Vector3);
|
||||
Quaternion adjustRot(std::vector<Node*>, Quaternion, bool);
|
||||
protected:
|
||||
void updateShaders();
|
||||
|
||||
+131
-48
@@ -12,10 +12,11 @@ namespace vb01{
|
||||
|
||||
void NodeTest::setUp(){
|
||||
rootNode = Root::getSingleton()->getRootNode();
|
||||
nodeA = new Node();
|
||||
nodeB = new Node();
|
||||
nodeC = new Node();
|
||||
nodeD = new Node();
|
||||
|
||||
lookNodeParent = new Node();
|
||||
rootNode->attachChild(lookNodeParent);
|
||||
lookNode = new Node();
|
||||
lookNodeParent->attachChild(lookNode);
|
||||
|
||||
firstChainNode = new Node();
|
||||
rootNode->attachChild(firstChainNode);
|
||||
@@ -23,16 +24,27 @@ namespace vb01{
|
||||
firstChainNode->attachChild(secondChainNode);
|
||||
thirdChainNode = new Node();
|
||||
secondChainNode->attachChild(thirdChainNode);
|
||||
|
||||
ancestorA = new Node();
|
||||
ancestorB = new Node();
|
||||
ancestorC = new Node();
|
||||
ancestorD = new Node();
|
||||
|
||||
rootNode->attachChild(ancestorA);
|
||||
ancestorA->attachChild(ancestorB);
|
||||
ancestorB->attachChild(ancestorC);
|
||||
ancestorC->attachChild(ancestorD);
|
||||
}
|
||||
|
||||
void NodeTest::tearDown(){
|
||||
/*
|
||||
delete nodeD;
|
||||
delete nodeC;
|
||||
delete nodeB;
|
||||
nodeA->dettachChild(nodeB);
|
||||
delete nodeA;
|
||||
*/
|
||||
}
|
||||
|
||||
void NodeTest::testGetAncestors(){
|
||||
vector<Node*> ancestors = ancestorD->getAncestors();
|
||||
CPPUNIT_ASSERT(ancestors[ancestors.size() - 1] == rootNode);
|
||||
|
||||
ancestors = ancestorD->getAncestors(ancestorB);
|
||||
CPPUNIT_ASSERT(ancestors[ancestors.size() - 1] == ancestorB);
|
||||
}
|
||||
|
||||
void NodeTest::testLocalToGlobalPosition(){
|
||||
@@ -105,9 +117,6 @@ namespace vb01{
|
||||
CPPUNIT_ASSERT(thirdChainNode->globalToLocalPosition(Vector3::VEC_ZERO) == -pos3);
|
||||
}
|
||||
|
||||
void NodeTest::testGlobalToLocalOrientation(){
|
||||
}
|
||||
|
||||
void NodeTest::testLocalToGlobalOrientation(){
|
||||
firstChainNode->setOrientation(Quaternion::QUAT_W);
|
||||
secondChainNode->setOrientation(Quaternion::QUAT_W);
|
||||
@@ -117,13 +126,88 @@ namespace vb01{
|
||||
CPPUNIT_ASSERT(secondChainNode->localToGlobalOrientation(Quaternion::QUAT_W) == Quaternion::QUAT_W);
|
||||
CPPUNIT_ASSERT(thirdChainNode->localToGlobalOrientation(Quaternion::QUAT_W) == Quaternion::QUAT_W);
|
||||
|
||||
Quaternion q0 = Quaternion(.2, Vector3(0, 1, 0));
|
||||
thirdChainNode->setOrientation(q0);
|
||||
CPPUNIT_ASSERT(thirdChainNode->localToGlobalOrientation(Quaternion::QUAT_W) == q0);
|
||||
float eps = .001;
|
||||
|
||||
float an = .2;
|
||||
Vector3 ax = Vector3(0, 1, 0).norm();
|
||||
|
||||
Quaternion q0 = Quaternion(an, ax);
|
||||
secondChainNode->setOrientation(q0);
|
||||
thirdChainNode->setOrientation(Quaternion::QUAT_W);
|
||||
Quaternion ltg0 = secondChainNode->localToGlobalOrientation(Quaternion::QUAT_W);
|
||||
Quaternion ltg01 = thirdChainNode->localToGlobalOrientation(Quaternion::QUAT_W);
|
||||
CPPUNIT_ASSERT(ax.getAngleBetween(ltg0.getAxis()) < eps && fabs(an - ltg0.getAngle()) < eps);
|
||||
CPPUNIT_ASSERT(ax.getAngleBetween(ltg01.getAxis()) < eps && fabs(an - ltg01.getAngle()) < eps);
|
||||
|
||||
Quaternion q1 = Quaternion(an, ax);
|
||||
secondChainNode->setOrientation(Quaternion::QUAT_W);
|
||||
thirdChainNode->setOrientation(q1);
|
||||
Quaternion ltg1 = secondChainNode->localToGlobalOrientation(Quaternion::QUAT_W);
|
||||
Quaternion ltg11 = thirdChainNode->localToGlobalOrientation(Quaternion::QUAT_W);
|
||||
CPPUNIT_ASSERT(ltg1 == Quaternion::QUAT_W);
|
||||
CPPUNIT_ASSERT(ax.getAngleBetween(ltg11.getAxis()) < eps && fabs(an - ltg11.getAngle()) < eps);
|
||||
|
||||
an = .3;
|
||||
ax = Vector3(1, 0, 1).norm();
|
||||
Quaternion q2 = Quaternion(an, ax);
|
||||
Quaternion q21 = Quaternion(an, ax);
|
||||
secondChainNode->setOrientation(q2);
|
||||
thirdChainNode->setOrientation(q21);
|
||||
Quaternion ltg2 = secondChainNode->localToGlobalOrientation(Quaternion::QUAT_W);
|
||||
Quaternion ltg21 = thirdChainNode->localToGlobalOrientation(Quaternion::QUAT_W);
|
||||
Quaternion refQuat = q21 * q2;
|
||||
CPPUNIT_ASSERT(ax.getAngleBetween(ltg2.getAxis()) < eps && fabs(an - ltg2.getAngle()) < eps);
|
||||
CPPUNIT_ASSERT(refQuat.getAxis().getAngleBetween(ltg21.getAxis()) < eps && fabs(refQuat.getAngle() - ltg21.getAngle()) < eps);
|
||||
|
||||
Quaternion q3 = Quaternion(an, ax);
|
||||
firstChainNode->setOrientation(q3);
|
||||
secondChainNode->setOrientation(Quaternion::QUAT_W);
|
||||
thirdChainNode->setOrientation(Quaternion::QUAT_W);
|
||||
Quaternion ltg4 = firstChainNode->localToGlobalOrientation(Quaternion::QUAT_W);
|
||||
Quaternion ltg41 = secondChainNode->localToGlobalOrientation(Quaternion::QUAT_W);
|
||||
Quaternion ltg42 = thirdChainNode->localToGlobalOrientation(Quaternion::QUAT_W);
|
||||
CPPUNIT_ASSERT(ax.getAngleBetween(ltg4.getAxis()) < eps && fabs(an - ltg4.getAngle()) < eps);
|
||||
CPPUNIT_ASSERT(ax.getAngleBetween(ltg41.getAxis()) < eps && fabs(an - ltg41.getAngle()) < eps);
|
||||
CPPUNIT_ASSERT(ax.getAngleBetween(ltg42.getAxis()) < eps && fabs(an - ltg42.getAngle()) < eps);
|
||||
}
|
||||
void NodeTest::testDetachChild(){
|
||||
nodeA->dettachChild(nodeB);
|
||||
CPPUNIT_ASSERT(nodeA->getChild(0) != nodeB);
|
||||
|
||||
void NodeTest::testGlobalToLocalOrientation(){
|
||||
firstChainNode->setOrientation(Quaternion::QUAT_W);
|
||||
secondChainNode->setOrientation(Quaternion::QUAT_W);
|
||||
thirdChainNode->setOrientation(Quaternion::QUAT_W);
|
||||
|
||||
CPPUNIT_ASSERT(firstChainNode->globalToLocalOrientation(Quaternion::QUAT_W) == Quaternion::QUAT_W);
|
||||
CPPUNIT_ASSERT(secondChainNode->globalToLocalOrientation(Quaternion::QUAT_W) == Quaternion::QUAT_W);
|
||||
CPPUNIT_ASSERT(thirdChainNode->globalToLocalOrientation(Quaternion::QUAT_W) == Quaternion::QUAT_W);
|
||||
|
||||
float eps = .001;
|
||||
|
||||
float an = .4;
|
||||
Vector3 ax = Vector3(1, 1, 0).norm();
|
||||
|
||||
Quaternion q0 = Quaternion(an, ax);
|
||||
thirdChainNode->setOrientation(q0);
|
||||
Quaternion gtl0 = thirdChainNode->globalToLocalOrientation(Quaternion::QUAT_W);
|
||||
CPPUNIT_ASSERT(ax.getAngleBetween(-gtl0.getAxis()) < eps && fabs(an - gtl0.getAngle()) < eps);
|
||||
|
||||
Quaternion q2 = Quaternion(an, ax);
|
||||
Quaternion q21 = Quaternion(an, ax);
|
||||
secondChainNode->setOrientation(q2);
|
||||
thirdChainNode->setOrientation(q21);
|
||||
Quaternion gtl21 = thirdChainNode->globalToLocalOrientation(Quaternion::QUAT_W);
|
||||
Quaternion refQuat = q21 * q2;
|
||||
CPPUNIT_ASSERT(refQuat.getAxis().getAngleBetween(-gtl21.getAxis()) < eps && fabs(refQuat.getAngle() - gtl21.getAngle()) < eps);
|
||||
|
||||
Quaternion q3 = Quaternion(an, ax);
|
||||
firstChainNode->setOrientation(q3);
|
||||
secondChainNode->setOrientation(Quaternion::QUAT_W);
|
||||
thirdChainNode->setOrientation(Quaternion::QUAT_W);
|
||||
Quaternion gtl3 = firstChainNode->globalToLocalOrientation(Quaternion::QUAT_W);
|
||||
Quaternion gtl31 = secondChainNode->globalToLocalOrientation(Quaternion::QUAT_W);
|
||||
Quaternion gtl32 = thirdChainNode->globalToLocalOrientation(Quaternion::QUAT_W);
|
||||
CPPUNIT_ASSERT(ax.getAngleBetween(-gtl3.getAxis()) < eps && fabs(an - gtl3.getAngle()) < eps);
|
||||
CPPUNIT_ASSERT(ax.getAngleBetween(-gtl31.getAxis()) < eps && fabs(an - gtl31.getAngle()) < eps);
|
||||
CPPUNIT_ASSERT(ax.getAngleBetween(-gtl32.getAxis()) < eps && fabs(an - gtl32.getAngle()) < eps);
|
||||
}
|
||||
|
||||
void NodeTest::testAdjustDir(){
|
||||
@@ -139,48 +223,47 @@ namespace vb01{
|
||||
int numDirs = sizeof(dir) / sizeof(Vector3);
|
||||
|
||||
for(int i = 0; i < numDirs; i++){
|
||||
nodeA->lookAt(dir[i], rootNode);
|
||||
CPPUNIT_ASSERT(nodeA->getGlobalAxis(2).getAngleBetween(dir[i]) < maxAngle);
|
||||
lookNode->lookAt(dir[i]);
|
||||
CPPUNIT_ASSERT(lookNode->getGlobalAxis(2).getAngleBetween(dir[i]) < maxAngle);
|
||||
}
|
||||
|
||||
Quaternion rotQuat = Quaternion(.707, Vector3(1, 0 ,0));
|
||||
lookNodeParent->setOrientation(rotQuat);
|
||||
|
||||
for(int i = 0; i < numDirs; i++){
|
||||
lookNode->lookAt(dir[i]);
|
||||
CPPUNIT_ASSERT(lookNode->getGlobalAxis(2).getAngleBetween(rotQuat * dir[i]) < maxAngle);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeTest::testAdjustUp(){
|
||||
float maxAngle = .001;
|
||||
|
||||
Vector3 dir[]{
|
||||
Vector3(0, 1, 0),
|
||||
Vector3 up[]{
|
||||
Vector3(1, 0, 0),
|
||||
Vector3(.8, .2, 0).norm(),
|
||||
Vector3(-.6, 0, .9).norm(),
|
||||
Vector3(0, -1, -.4).norm(),
|
||||
Vector3(1, 1, 1).norm()
|
||||
};
|
||||
|
||||
int numDirs = sizeof(dir) / sizeof(Vector3);
|
||||
int numDirs = sizeof(up) / sizeof(Vector3);
|
||||
|
||||
lookNodeParent->setOrientation(Quaternion::QUAT_W);
|
||||
|
||||
for(int i = 0; i < numDirs; i++){
|
||||
/*
|
||||
nodeA->lookAt(dir[i], rootNode);
|
||||
CPPUNIT_ASSERT(nodeA->getGlobalAxis(2).getAngleBetween(dir[i]) < maxAngle);
|
||||
*/
|
||||
lookNode->lookAt(Vector3::VEC_K, up[i]);
|
||||
Vector3 upClamped = Vector3(up[i].x, up[i].y, 0).norm();
|
||||
CPPUNIT_ASSERT(lookNode->getGlobalAxis(1).getAngleBetween(upClamped) < maxAngle);
|
||||
}
|
||||
|
||||
Quaternion rotQuat = Quaternion(.707, Vector3(1, 0 ,0));
|
||||
lookNodeParent->setOrientation(rotQuat);
|
||||
|
||||
for(int i = 0; i < numDirs; i++){
|
||||
lookNode->lookAt(Vector3::VEC_K, up[i]);
|
||||
Vector3 upClamped = Vector3(up[i].x, up[i].y, 0).norm();
|
||||
CPPUNIT_ASSERT(lookNode->getGlobalAxis(1).getAngleBetween(rotQuat * upClamped) < maxAngle);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeTest::testGetDescendants(){
|
||||
vector<Node*> parentADescendants;
|
||||
vector<Node*> parentBDescendants;
|
||||
vector<Node*> parentCDescendants;
|
||||
vector<Node*> parentDDescendants;
|
||||
|
||||
/*
|
||||
parentA->getDescendants(parentADescendants);
|
||||
parentB->getDescendants(parentBDescendants);
|
||||
parentC->getDescendants(parentCDescendants);
|
||||
parentD->getDescendants(parentDDescendants);
|
||||
|
||||
parentD->getDescendants(parentDDescendants);
|
||||
CPPUNIT_ASSERT(parentDDescendants[0] == childD0);
|
||||
CPPUNIT_ASSERT(parentDDescendants[1] == childD1);
|
||||
CPPUNIT_ASSERT(parentDDescendants[2] == childD2);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
+8
-9
@@ -9,12 +9,9 @@ namespace vb01{
|
||||
|
||||
class NodeTest : public CppUnit::TestFixture{
|
||||
CPPUNIT_TEST_SUITE(NodeTest);
|
||||
/*
|
||||
CPPUNIT_TEST(testDetachChild);
|
||||
CPPUNIT_TEST(testGetAncestors);
|
||||
CPPUNIT_TEST(testAdjustDir);
|
||||
CPPUNIT_TEST(testAdjustUp);
|
||||
CPPUNIT_TEST(testGetDescendants);
|
||||
*/
|
||||
CPPUNIT_TEST(testLocalToGlobalPosition);
|
||||
CPPUNIT_TEST(testGlobalToLocalPosition);
|
||||
CPPUNIT_TEST(testLocalToGlobalOrientation);
|
||||
@@ -29,17 +26,19 @@ namespace vb01{
|
||||
void testAdjustDir();
|
||||
void testAdjustUp();
|
||||
void testDetachChild();
|
||||
void testGetDescendants();
|
||||
void testGetAncestors();
|
||||
void testLocalToGlobalPosition();
|
||||
void testGlobalToLocalPosition();
|
||||
void testLocalToGlobalOrientation();
|
||||
void testGlobalToLocalOrientation();
|
||||
|
||||
Node *rootNode = nullptr,
|
||||
*nodeA = nullptr,
|
||||
*nodeB = nullptr,
|
||||
*nodeC = nullptr,
|
||||
*nodeD = nullptr,
|
||||
*ancestorA = nullptr,
|
||||
*ancestorB = nullptr,
|
||||
*ancestorC = nullptr,
|
||||
*ancestorD = nullptr,
|
||||
*lookNodeParent = nullptr,
|
||||
*lookNode = nullptr,
|
||||
*firstChainNode = nullptr,
|
||||
*secondChainNode = nullptr,
|
||||
*thirdChainNode = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user