-/******************************************************************************
+/*******************************************************************************
Copyright (c) 2009, Charles McGarvey
All rights reserved.
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-******************************************************************************/
+*******************************************************************************/
#ifndef _MOOF_AABB_HH_
#define _MOOF_AABB_HH_
+#include <Moof/Cullable.hh>
+#include <Moof/Drawable.hh>
#include <Moof/Math.hh>
+#include <Moof/Plane.hh>
+#include <Moof/Shape.hh>
+
+#include <Moof/Frustum.hh>
+#include <Moof/OpenGL.hh>
+#include <Moof/Texture.hh>
namespace Mf {
* Axis-aligned Bounding Box
*/
-struct Aabb
+template <int D = 3>
+struct Aabb : public Cullable, public Drawable, public Shape<D>
{
+ typedef cml::vector< Scalar, cml::fixed<D> > Vector;
+
+ Vector min;
+ Vector max;
+
Aabb() {}
- Aabb(const Vector3& minPoint, const Vector3& maxPoint) :
- min(minPoint),
- max(maxPoint) {}
+ Aabb(const Vector& a, const Vector& b)
+ {
+ init(a, b);
+ }
+
+ Aabb(Scalar ax, Scalar ay, Scalar az,
+ Scalar bx, Scalar by, Scalar bz)
+ {
+ Vector a(ax, ay, az);
+ Vector b(bx, by, bz);
+
+ init(a, b);
+ }
+
+ void init(const Vector& a, const Vector& b)
+ {
+ if (a[0] < b[0])
+ {
+ min[0] = a[0];
+ max[0] = b[0];
+ }
+ else
+ {
+ min[0] = b[0];
+ max[0] = a[0];
+ }
+ if (a[1] < b[1])
+ {
+ min[1] = a[1];
+ max[1] = b[1];
+ }
+ else
+ {
+ min[1] = b[1];
+ max[1] = a[1];
+ }
+ if (a[2] < b[2])
+ {
+ min[2] = a[2];
+ max[2] = b[2];
+ }
+ else
+ {
+ min[2] = b[2];
+ max[2] = a[2];
+ }
+ }
+
+ Vector getCenter() const
+ {
+ return Vector((min[0] + max[0]) / 2.0,
+ (min[1] + max[1]) / 2.0,
+ (min[2] + max[2]) / 2.0);
+ }
+
+ //void getOctant(Aabb& octant, int num) const;
+
+ Plane getPlaneXY() const
+ {
+ Plane plane;
+ plane.normal = Vector(0.0, 0.0, 1.0);
+ plane.d = cml::dot(-plane.normal, getCenter());
+ return plane;
+ }
+
+ Plane getPlaneXZ() const
+ {
+ Plane plane;
+ plane.normal = Vector(0.0, 1.0, 0.0);
+ plane.d = cml::dot(-plane.normal, getCenter());
+ return plane;
+ }
+
+ Plane getPlaneYZ() const
+ {
+ Plane plane;
+ plane.normal = Vector(1.0, 0.0, 0.0);
+ plane.d = cml::dot(-plane.normal, getCenter());
+ return plane;
+ }
+
+ /*
+ void getCorners(Vector3 corners[8]) const;
+
+ void encloseVertices(const Vector3 vertices[], unsigned count);
+
+ void draw(Scalar alpha = 0.0) const;
+ bool isVisible(const Frustum& frustum) const;
+ */
+
+
+void getCorners(Vector corners[8]) const
+{
+ corners[0][0] = min[0]; corners[0][1] = min[1]; corners[0][2] = max[2];
+ corners[1][0] = max[0]; corners[1][1] = min[1]; corners[1][2] = max[2];
+ corners[2][0] = max[0]; corners[2][1] = max[1]; corners[2][2] = max[2];
+ corners[3][0] = min[0]; corners[3][1] = max[1]; corners[3][2] = max[2];
+ corners[4][0] = min[0]; corners[4][1] = min[1]; corners[4][2] = min[2];
+ corners[5][0] = max[0]; corners[5][1] = min[1]; corners[5][2] = min[2];
+ corners[6][0] = max[0]; corners[6][1] = max[1]; corners[6][2] = min[2];
+ corners[7][0] = min[0]; corners[7][1] = max[1]; corners[7][2] = min[2];
+}
+
+
+void encloseVertices(const Vector vertices[], unsigned count)
+{
+ min.zero();
+ max.zero();
+
+ for (unsigned i = 1; i < count; ++i)
+ {
+ min.minimize(vertices[i]);
+ max.maximize(vertices[i]);
+ }
+}
- Aabb (Scalar minX, Scalar minY, Scalar minZ,
- Scalar maxX, Scalar maxY, Scalar maxZ) :
- min(minX, minY, minZ),
- max(maxX, maxY, maxZ) {}
- Vector3 min;
- Vector3 max;
+void draw(Scalar alpha = 0.0) const
+{
+ Scalar vertices[] = {min[0], min[1], min[2],
+ min[0], max[1], min[2],
+ max[0], max[1], min[2],
+ max[0], min[1], min[2],
+ min[0], max[1], max[2],
+ min[0], min[1], max[2],
+ max[0], min[1], max[2],
+ max[0], max[1], max[2]};
+
+ GLubyte indices[] = {0, 1, 2, 3,
+ 1, 2, 7, 4,
+ 3, 0, 5, 6,
+ 2, 3, 6, 7,
+ 5, 0, 1, 4,
+ 4, 5, 6, 7};
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glVertexPointer(3, GL_SCALAR, 0, vertices);
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ Texture::resetBind();
+
+ glDrawElements(GL_QUADS, sizeof(indices), GL_UNSIGNED_BYTE, indices);
+
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ //glDisableClientState(GL_VERTEX_ARRAY);
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+}
+
+bool isVisible(const Frustum& frustum) const
+{
+ return frustum.contains(*this);
+}
};