GPWiki.org
GPWiki.org
It is currently Sat May 25, 2013 1:57 pm

All times are UTC




Post new topic Reply to topic  [ 3 posts ] 
Author Message
PostPosted: Tue Jan 26, 2010 10:12 pm 
Hi,

I'm experiencing some difficulties when trying to apply a quaternion's rotation matrix to openGL and displaying a mesh's bounding box.

Although I'm quite sure that my mesh's bounding box calculation is correct, it somehow never fits around the mesh.
I carefully read the Quaternion article on http://gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation and implemented it directly that way.
I do not know where to start explaining, I think I first post some code.
Note that the AABB itself should not be rotated, that's why I apply the rotation later. The AABB is recalculated after every rotation.

Code:
// within drawing function

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glPushMatrix(); // this is done because I'm rendering multiple meshes

// draw AABB
glDisable(GL_TEXTURE_2D);
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_LINES);
glVertex3f(m_AABB.m_xMin, m_AABB.m_yMin, m_AABB.m_zMin);
glVertex3f(m_AABB.m_xMin, m_AABB.m_yMin, m_AABB.m_zMax);

glVertex3f(m_AABB.m_xMax, m_AABB.m_yMin, m_AABB.m_zMin);
glVertex3f(m_AABB.m_xMax, m_AABB.m_yMin, m_AABB.m_zMax);

glVertex3f(m_AABB.m_xMin, m_AABB.m_yMax, m_AABB.m_zMin);
glVertex3f(m_AABB.m_xMin, m_AABB.m_yMax, m_AABB.m_zMax);

glVertex3f(m_AABB.m_xMax, m_AABB.m_yMax, m_AABB.m_zMin);
glVertex3f(m_AABB.m_xMax, m_AABB.m_yMax, m_AABB.m_zMax);

glVertex3f(m_AABB.m_xMin, m_AABB.m_yMin, m_AABB.m_zMin);
glVertex3f(m_AABB.m_xMax, m_AABB.m_yMin, m_AABB.m_zMin);

glVertex3f(m_AABB.m_xMin, m_AABB.m_yMin, m_AABB.m_zMin);
glVertex3f(m_AABB.m_xMin, m_AABB.m_yMax, m_AABB.m_zMin);

glVertex3f(m_AABB.m_xMax, m_AABB.m_yMin, m_AABB.m_zMin);
glVertex3f(m_AABB.m_xMax, m_AABB.m_yMax, m_AABB.m_zMin);

glVertex3f(m_AABB.m_xMin, m_AABB.m_yMax, m_AABB.m_zMin);
glVertex3f(m_AABB.m_xMax, m_AABB.m_yMax, m_AABB.m_zMin);

glVertex3f(m_AABB.m_xMin, m_AABB.m_yMin, m_AABB.m_zMax);
glVertex3f(m_AABB.m_xMax, m_AABB.m_yMin, m_AABB.m_zMax);

glVertex3f(m_AABB.m_xMin, m_AABB.m_yMin, m_AABB.m_zMax);
glVertex3f(m_AABB.m_xMin, m_AABB.m_yMax, m_AABB.m_zMax);

glVertex3f(m_AABB.m_xMax, m_AABB.m_yMin, m_AABB.m_zMax);
glVertex3f(m_AABB.m_xMax, m_AABB.m_yMax, m_AABB.m_zMax);

glVertex3f(m_AABB.m_xMin, m_AABB.m_yMax, m_AABB.m_zMax);
glVertex3f(m_AABB.m_xMax, m_AABB.m_yMax, m_AABB.m_zMax);
glEnd();
glEnable(GL_TEXTURE_2D);

// rotate object
glMultMatrixd(m_orientation.getRotationMatrix()->getAsColumnMatrix());
glCallList(m_displayList); // draw object



m_orientation is a quaternion and getRotationMatrix returns a 4x4 Matrix:

Code:
// Convert to Matrix
Matrix4* Quaternion::getRotationMatrix() {
   Real x2 = m_x * m_x;
   Real y2 = m_y * m_y;
   Real z2 = m_z * m_z;
   Real xy = m_x * m_y;
   Real xz = m_x * m_z;
   Real yz = m_y * m_z;
   Real wx = m_w * m_x;
   Real wy = m_w * m_y;
   Real wz = m_w * m_z;

   // This calculation would be a lot more complicated for non-unit length quaternions
   // Note: The constructor of Matrix4 expects the Matrix in column-major format like expected by
   //   OpenGL
   m_rotationMatrix = Matrix4( 1.0f - 2.0f * (y2 + z2), 2.0f * (xy - wz), 2.0f * (xz + wy), 0.0f,
         2.0f * (xy + wz), 1.0f - 2.0f * (x2 + z2), 2.0f * (yz - wx), 0.0f,
         2.0f * (xz - wy), 2.0f * (yz + wx), 1.0f - 2.0f * (x2 + y2), 0.0f,
         0.0f, 0.0f, 0.0f, 1.0f);


   return &m_rotationMatrix;
}


while Matrix4 contains a simple double matrix[4][4] for representing the values. I'm correctly filling the values column-aligned like desired by openGL.


The AABB itself is calculated like this:

Code:
void calculateAABB() {
   m_AABB.m_xMin = std::numeric_limits<Real>::infinity();
   m_AABB.m_yMin = std::numeric_limits<Real>::infinity();
   m_AABB.m_zMin = std::numeric_limits<Real>::infinity();
   m_AABB.m_xMax = -std::numeric_limits<Real>::infinity();
   m_AABB.m_yMax = -std::numeric_limits<Real>::infinity();
   m_AABB.m_zMax = -std::numeric_limits<Real>::infinity();

   for (int i=0; i<m_numVertices; i++) {
      Vector3 newLocation = m_orientation*m_vertices[i].m_location;

      if (newLocation.m_x < m_AABB.m_xMin)
         m_AABB.m_xMin = newLocation.m_x;
      if (newLocation.m_x > m_AABB.m_xMax)
         m_AABB.m_xMax = newLocation.m_x;
      if (newLocation.m_y < m_AABB.m_yMin)
         m_AABB.m_yMin = newLocation.m_y;
      if (newLocation.m_y > m_AABB.m_yMax)
         m_AABB.m_yMax = newLocation.m_y;
      if (newLocation.m_z < m_AABB.m_zMin)
         m_AABB.m_zMin = newLocation.m_z;
      if (newLocation.m_z > m_AABB.m_zMax)
         m_AABB.m_zMax = newLocation.m_z;
   }
}


m_orientation again is a simple quaternion.
I think that there is some mistake in multiplying the matrix...

The result:

Image


However, when I remove multiplying the quaternion with the vector in the calculateAABB function but rotate the bounding box as well, the result is right, but then isn't axis aligned any more.

I hardly suspect an error when multiplying the quaternion with the vector, but I've checked a thousand times on the gpwiki page for errors but couldn't find any... :(
So here's how I multiply a quaternion with a vector:

Code:
   // Multiplying a quaternion q with a vector v applies the q-rotation to v
   Vector3 operator* (const Vector3 &vec) {
      Vector3 vn(vec);
      //vn = Vector3::normalizeVector(vn);

      Quaternion vecQuat, resQuat;
      vecQuat.m_x = vn.m_x;
      vecQuat.m_y = vn.m_y;
      vecQuat.m_z = vn.m_z;
      vecQuat.m_w = 0.0f;

      resQuat = vecQuat * getConjugate();
      resQuat = *this * resQuat;

      return (Vector3(resQuat.m_x, resQuat.m_y, resQuat.m_z));
   }

OK i modified the code by commenting the normalization part out, but I could as well left it in and multiply it with the inverse value when calculating the bounding box in calculateAAB, which results in the exactely same...

What am I doing wrong? There must be something very severe....
Thank you a thousand times for helping me!


Top
  
 
PostPosted: Fri Aug 24, 2012 11:19 pm 
The AABB draw code is wrong...


Top
  
 
PostPosted: Wed Oct 24, 2012 6:43 pm 
Code:
Vec3 v0(mvMin.x, mvMin.y, mvMin.z);
Vec3 v1(mvMax.x, mvMin.y, mvMin.z);
Vec3 v2(mvMax.x, mvMax.y, mvMin.z);
Vec3 v3(mvMin.x, mvMax.y, mvMin.z);
Vec3 v4(mvMin.x, mvMin.y, mvMax.z);
Vec3 v5(mvMax.x, mvMin.y, mvMax.z);
Vec3 v6(mvMax.x, mvMax.y, mvMax.z);
Vec3 v7(mvMin.x, mvMax.y, mvMax.z);

glBegin(GL_LINES);
{
               glVertex3fv(&v0.x); glVertex3fv(&v1.x);
               glVertex3fv(&v1.x); glVertex3fv(&v2.x);
               glVertex3fv(&v2.x); glVertex3fv(&v3.x);
               glVertex3fv(&v3.x); glVertex3fv(&v0.x);
               glVertex3fv(&v4.x); glVertex3fv(&v5.x);
               glVertex3fv(&v5.x); glVertex3fv(&v6.x);
               glVertex3fv(&v6.x); glVertex3fv(&v7.x);
               glVertex3fv(&v7.x); glVertex3fv(&v4.x);
               glVertex3fv(&v0.x); glVertex3fv(&v4.x);
               glVertex3fv(&v1.x); glVertex3fv(&v5.x);
               glVertex3fv(&v2.x); glVertex3fv(&v6.x);
               glVertex3fv(&v3.x); glVertex3fv(&v7.x);
}
glEnd();


Top
  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group