]> Dogcows Code - chaz/yoink/blobdiff - src/moof/aabb.hh
the massive refactoring effort
[chaz/yoink] / src / moof / aabb.hh
diff --git a/src/moof/aabb.hh b/src/moof/aabb.hh
new file mode 100644 (file)
index 0000000..64e8968
--- /dev/null
@@ -0,0 +1,274 @@
+
+/*]  Copyright (c) 2009-2010, Charles McGarvey  [**************************
+**]  All rights reserved.
+*
+* vi:ts=4 sw=4 tw=75
+*
+* Distributable under the terms and conditions of the 2-clause BSD license;
+* see the file COPYING for a complete text of the license.
+*
+**************************************************************************/
+
+#ifndef _MOOF_AABB_HH_
+#define _MOOF_AABB_HH_
+
+/**
+ * \file aabb.hh
+ * Axis-aligned Bounding Box
+ */
+
+#include <moof/cullable.hh>
+#include <moof/drawable.hh>
+#include <moof/math.hh>
+#include <moof/plane.hh>
+#include <moof/shape.hh>
+
+#include <moof/frustum.hh>             // FIXME: this file is quite broken
+#include <moof/opengl.hh>
+#include <moof/texture.hh>
+
+
+namespace moof {
+
+
+class script;
+
+
+template <int D = 3>
+struct aabb : public cullable, public drawable, public shape<D>
+{
+       typedef moof::vector< scalar, fixed<D> > vector;
+
+       vector min;
+       vector max;
+
+
+       aabb() {}
+
+       aabb(const vector& a, const vector& b)
+       {
+               init(a, b);
+       }
+
+       aabb(scalar x1, scalar y1, scalar x2, scalar y2)
+       {
+               vector a(x1, y1);
+               vector b(x2, y2);
+
+               init(a, b);
+       }
+
+       aabb(scalar x1, scalar y1, scalar z1, scalar x2, scalar y2, scalar z2)
+       {
+               vector a(x1, y1, z1);
+               vector b(x2, y2, z2);
+
+               init(a, b);
+       }
+
+
+       void init(const vector2& a, const vector2& 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];
+               }
+       }
+
+       void init(const vector3& a, const vector3& 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 center() const
+       {
+               return (min + max) / 2.0;
+       }
+
+
+       plane xy_plane() const
+       {
+               plane plane;
+               plane.normal = vector3(0.0, 0.0, 1.0);
+               plane.d = dot(-plane.normal, center());
+               return plane;
+       }
+
+       plane xz_plane() const
+       {
+               plane plane;
+               plane.normal = vector3(0.0, 1.0, 0.0);
+               plane.d = dot(-plane.normal, center());
+               return plane;
+       }
+
+       plane yz_plane() const
+       {
+               plane plane;
+               plane.normal = vector3(1.0, 0.0, 0.0);
+               plane.d = dot(-plane.normal, center());
+               return plane;
+       }
+
+
+       void get_corners(vector2 corners[4]) const
+       {
+               corners[0][0] = min[0]; corners[0][1] = min[1];
+               corners[1][0] = max[0]; corners[1][1] = min[1];
+               corners[2][0] = max[0]; corners[2][1] = max[1];
+               corners[3][0] = min[0]; corners[3][1] = max[1];
+       }
+
+       void get_corners(vector3 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 enclose_vertices(const vector vertices[], unsigned count)
+       {
+               min.zero();
+               max.zero();
+
+               for (unsigned i = 1; i < count; ++i)
+               {
+                       min.minimize(vertices[i]);
+                       max.maximize(vertices[i]);
+               }
+       }
+
+
+       void draw(scalar alpha = 0.0) const
+       {
+               glRect(min[0], min[1], max[0], max[1]);
+       }
+
+       bool is_visible(const frustum& frustum) const
+       {
+               return true;
+       }
+};
+
+
+void import_aabb_class(script& script);
+
+template <>
+inline void aabb<3>::draw(scalar alpha) 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::reset_binding();
+
+       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);
+}
+
+template <>
+inline bool aabb<3>::is_visible(const frustum& frustum) const
+{
+       return frustum.contains(*this);
+}
+
+
+typedef aabb<2>                aabb2;
+typedef aabb2          rectangle;
+typedef aabb<3>                aabb3;
+
+
+} // namespace moof
+
+#endif // _MOOF_AABB_HH_
+
This page took 0.026334 seconds and 4 git commands to generate.