From a89fcb13fe3069f274a26e3a1007963cc3ec40ee Mon Sep 17 00:00:00 2001 From: "chappuis.daniel" Date: Sat, 12 Dec 2009 21:28:06 +0000 Subject: [PATCH] git-svn-id: https://reactphysics3d.googlecode.com/svn/trunk@227 92aac97c-a6ce-11dd-a772-7fcde58d38e6 --- sources/reactphysics3d/body/OBB.cpp | 41 ++++++-------------- sources/reactphysics3d/body/OBB.h | 58 +++++++++++++++++++++++------ 2 files changed, 59 insertions(+), 40 deletions(-) diff --git a/sources/reactphysics3d/body/OBB.cpp b/sources/reactphysics3d/body/OBB.cpp index 15acb651..f3e48cd9 100644 --- a/sources/reactphysics3d/body/OBB.cpp +++ b/sources/reactphysics3d/body/OBB.cpp @@ -133,50 +133,33 @@ void OBB::draw() const { } // Return all the vertices that are projected at the extreme of the projection of the bouding volume on the axis. -// The function returns the number of extreme vertices and a set that contains thoses vertices. -int OBB::getExtremeVertices(const Vector3D projectionAxis, std::vector& extremeVertices) const { - assert(extremeVertices.size() == 0); - assert(projectionAxis.length() != 0); +std::vector OBB::getExtremeVertices(const Vector3D axis) const { + assert(axis.length() != 0); - double maxProjectionLength = 0.0; // Longest projection length of a vertex onto the projection axis + std::vector extremeVertices; + double maxProjectionLength = 0.0; // Longest projection length of a vertex onto the projection axis - // Compute the vertices of the OBB - double e0 = extent[0]; - double e1 = extent[1]; - double e2 = extent[2]; - Vector3D vertices[8]; - vertices[0] = center + (axis[0]*e0) + (axis[1]*e1) - (axis[2]*e2); - vertices[1] = center + (axis[0]*e0) + (axis[1]*e1) + (axis[2]*e2); - vertices[2] = center - (axis[0]*e0) + (axis[1]*e1) + (axis[2]*e2); - vertices[3] = center - (axis[0]*e0) + (axis[1]*e1) - (axis[2]*e2); - vertices[4] = center + (axis[0]*e0) - (axis[1]*e1) - (axis[2]*e2); - vertices[5] = center + (axis[0]*e0) - (axis[1]*e1) + (axis[2]*e2); - vertices[6] = center - (axis[0]*e0) - (axis[1]*e1) + (axis[2]*e2); - vertices[7] = center - (axis[0]*e0) - (axis[1]*e1) - (axis[2]*e2); + // For each vertex of the OBB + for (unsigned int i=0; i<8; ++i) { + Vector3D vertex = getVertex(i); - for (int i=0; i<8; ++i) { // Compute the projection length of the current vertex onto the projection axis - double projectionLength = projectionAxis.scalarProduct(vertices[i]-center) / projectionAxis.length(); - - //std::cout << "Projection length : " << projectionLength << std::endl; - //std::cout << "Max Projection length : " << maxProjectionLength << std::endl; + double projectionLength = axis.scalarProduct(vertex-center) / axis.length(); // If we found a bigger projection length if (projectionLength > maxProjectionLength + EPSILON) { maxProjectionLength = projectionLength; extremeVertices.clear(); - extremeVertices.push_back(vertices[i]); - //std::cout << "PRINT 1" << std::endl; + extremeVertices.push_back(vertex); } else if (equal(projectionLength, maxProjectionLength)) { - extremeVertices.push_back(vertices[i]); - //std::cout << "PRINT 2" << std::endl; + extremeVertices.push_back(vertex); } } // An extreme should be a unique vertex, an edge or a face assert(extremeVertices.size() == 1 || extremeVertices.size() == 2 || extremeVertices.size() == 4); - // Return the number of extreme vertices - return extremeVertices.size(); + // Return the extreme vertices + return extremeVertices; } diff --git a/sources/reactphysics3d/body/OBB.h b/sources/reactphysics3d/body/OBB.h index df45cc14..ff3c4453 100644 --- a/sources/reactphysics3d/body/OBB.h +++ b/sources/reactphysics3d/body/OBB.h @@ -50,15 +50,16 @@ class OBB : public BoundingVolume { OBB(const OBB& obb); // Copy-Constructor virtual ~OBB(); // Destructor - Vector3D getCenter() const; // Return the center point of the OBB - void setCenter(const Vector3D& center); // Set the center point - Vector3D getAxis(unsigned int index) const throw(std::invalid_argument); // Return an axis of the OBB - void setAxis(unsigned int index, const Vector3D& axis) throw(std::invalid_argument); // Set an axis - double getExtent(unsigned int index) const throw(std::invalid_argument); // Return an extent value - void setExtent(unsigned int index, double extent) throw(std::invalid_argument); // Set an extent value - virtual int getExtremeVertices(const Vector3D projectionAxis, std::vector& extremeVertices) const; // Return all the vertices that are projected at the extreme of the projection of the bouding volume on the axis - virtual void updateOrientation(const Vector3D& newCenter, const Quaternion& rotationQuaternion); // Update the oriented bounding box orientation according to a new orientation of the rigid body - virtual void draw() const; // Draw the OBB (only for testing purpose) + Vector3D getCenter() const; // Return the center point of the OBB + void setCenter(const Vector3D& center); // Set the center point + Vector3D getAxis(unsigned int index) const throw(std::invalid_argument) const; // Return an axis of the OBB + void setAxis(unsigned int index, const Vector3D& axis) throw(std::invalid_argument); // Set an axis + Vector3D getVertex(unsigned int index) const throw (std::invalid_argument) const; // Return a vertex of the OBB + double getExtent(unsigned int index) const throw(std::invalid_argument) const; // Return an extent value + void setExtent(unsigned int index, double extent) throw(std::invalid_argument); // Set an extent value + virtual std::vector getExtremeVertices(const Vector3D axis) const; // Return all the vertices that are projected at the extreme of the projection of the bouding volume on the axis + virtual void updateOrientation(const Vector3D& newCenter, const Quaternion& rotationQuaternion); // Update the oriented bounding box orientation according to a new orientation of the rigid body + virtual void draw() const; // Draw the OBB (only for testing purpose) }; // Return the center point of the OBB @@ -72,7 +73,7 @@ inline void OBB::setCenter(const Vector3D& center) { } // Return an axis of the OBB -inline Vector3D OBB::getAxis(unsigned int index) const throw(std::invalid_argument) { +inline Vector3D OBB::getAxis(unsigned int index) const throw(std::invalid_argument) const { // Check if the index value is valid if (index >= 0 && index <3) { return axis[index]; @@ -95,8 +96,43 @@ inline void OBB::setAxis(unsigned int index, const Vector3D& axis) throw(std::in } } +// Return a vertex of the OBB +inline Vector3D OBB::getVertex(unsigned int index) const throw (std::invalid_argument) const { + // Check if the index value is valid + if (index >= 0 && index <8) { + Vector3D vertex; + + switch(index) { + case 0 : vertex = center + (axis[0]*extent[0]) + (axis[1]*extent[1]) - (axis[2]*extent[2]); + break; + case 1 : vertex = center + (axis[0]*extent[0]) + (axis[1]*extent[1]) + (axis[2]*extent[2]); + break; + case 2 : vertex = center - (axis[0]*extent[0]) + (axis[1]*extent[1]) + (axis[2]*extent[2]); + break; + case 3 : vertex = center - (axis[0]*extent[0]) + (axis[1]*extent[1]) - (axis[2]*extent[2]); + break; + case 4 : vertex = center + (axis[0]*extent[0]) - (axis[1]*extent[1]) - (axis[2]*extent[2]); + break; + case 5 : vertex = center + (axis[0]*extent[0]) - (axis[1]*extent[1]) + (axis[2]*extent[2]); + break; + case 6 : vertex = center - (axis[0]*extent[0]) - (axis[1]*extent[1]) + (axis[2]*extent[2]); + break; + case 7 : vertex = center - (axis[0]*extent[0]) - (axis[1]*extent[1]) - (axis[2]*extent[2]); + break; + } + + // Return the vertex + return vertex; + } + else { + // The index value is not valid, we throw an exception + throw std::invalid_argument("Exception : The index value has to be between 0 and 8"); + } +} + + // Return an extent value -inline double OBB::getExtent(unsigned int index) const throw(std::invalid_argument) { +inline double OBB::getExtent(unsigned int index) const throw(std::invalid_argument) const { // Check if the index value is valid if (index >= 0 && index <3) { return extent[index];