cleaned up and fleshed out geom.h/geom.cc and preparing to add bounding
[laserbrain_demo] / src / geom.h
index e110193..24a0b86 100644 (file)
@@ -1,12 +1,17 @@
 #ifndef GEOMOBJ_H_
 #define GEOMOBJ_H_
 
+/* TODO:
+ * - implement distance functions
+ */
+
 #include <gmath/gmath.h>
 
 enum GeomObjectType {
        GOBJ_UNKNOWN,
        GOBJ_SPHERE,
        GOBJ_AABOX,
+       GOBJ_BOX,
        GOBJ_PLANE
 };
 
@@ -23,16 +28,16 @@ struct HitPoint {
 
 class GeomObject {
 public:
-       virtual ~GeomObject();
-       virtual GeomObjectType get_type() const = 0;
+       GeomObjectType type;
 
-       virtual void set_union(const GeomObject *obj1, const GeomObject *obj2) = 0;
-       virtual void set_intersection(const GeomObject *obj1, const GeomObject *obj2) = 0;
+       GeomObject();
+       virtual ~GeomObject();
 
        virtual bool intersect(const Ray &ray, HitPoint *hit = 0) const = 0;
        virtual bool contains(const Vec3 &pt) const = 0;
 
        virtual float distance(const Vec3 &v) const = 0;
+       virtual float signed_distance(const Vec3 &v) const = 0;
 };
 
 class Sphere : public GeomObject {
@@ -43,15 +48,11 @@ public:
        Sphere();
        Sphere(const Vec3 &center, float radius);
 
-       GeomObjectType get_type() const;
-
-       void set_union(const GeomObject *obj1, const GeomObject *obj2);
-       void set_intersection(const GeomObject *obj1, const GeomObject *obj2);
-
-       bool intersect(const Ray &ray, HitPoint *hit = 0) const;
-       bool contains(const Vec3 &pt) const;
+       virtual bool intersect(const Ray &ray, HitPoint *hit = 0) const;
+       virtual bool contains(const Vec3 &pt) const;
 
-       float distance(const Vec3 &v) const;
+       virtual float distance(const Vec3 &v) const;
+       virtual float signed_distance(const Vec3 &v) const;
 };
 
 class AABox : public GeomObject {
@@ -61,17 +62,34 @@ public:
        AABox();
        AABox(const Vec3 &min, const Vec3 &max);
 
-       GeomObjectType get_type() const;
+       virtual Vec3 get_corner(int idx) const;
+
+       virtual bool intersect(const Ray &ray, HitPoint *hit = 0) const;
+       virtual bool contains(const Vec3 &pt) const;
+
+       virtual float distance(const Vec3 &v) const;
+       virtual float signed_distance(const Vec3 &v) const;
+};
+
+class Box : public AABox {
+public:
+       Mat4 xform;
+
+       Box();
+       Box(const Vec3 &min, const Vec3 &max);
+       Box(const Vec3 &pos, const Vec3 &vi, const Vec3 &vj, const Vec3 &vk);
+       Box(const Vec3 *varr, int vcount);
 
-       void set_union(const GeomObject *obj1, const GeomObject *obj2);
-       void set_intersection(const GeomObject *obj1, const GeomObject *obj2);
+       virtual Vec3 get_corner(int idx) const;
 
-       bool intersect(const Ray &ray, HitPoint *hit = 0) const;
-       bool contains(const Vec3 &pt) const;
+       virtual bool intersect(const Ray &ray, HitPoint *hit = 0) const;
+       virtual bool contains(const Vec3 &pt) const;
 
-       float distance(const Vec3 &v) const;
+       virtual float distance(const Vec3 &v) const;
+       virtual float signed_distance(const Vec3 &v) const;
 };
 
+
 class Plane : public GeomObject {
 public:
        Vec3 pt, normal;
@@ -81,15 +99,62 @@ public:
        Plane(const Vec3 &p1, const Vec3 &p2, const Vec3 &p3);
        Plane(const Vec3 &normal, float dist);
 
-       GeomObjectType get_type() const;
+       virtual bool intersect(const Ray &ray, HitPoint *hit = 0) const;
+       virtual bool contains(const Vec3 &pt) const;
 
-       void set_union(const GeomObject *obj1, const GeomObject *obj2);
-       void set_intersection(const GeomObject *obj1, const GeomObject *obj2);
+       virtual float distance(const Vec3 &v) const;
+       virtual float signed_distance(const Vec3 &v) const;
+};
 
-       bool intersect(const Ray &ray, HitPoint *hit = 0) const;
-       bool contains(const Vec3 &pt) const;
+class Disc : public Plane {
+public:
+       float radius;
+
+       Disc();
+       Disc(const Vec3 &pt, const Vec3 &normal, float rad);
+       Disc(const Vec3 &normal, float dist, float rad);
 
-       float distance(const Vec3 &v) const;
+       virtual bool intersect(const Ray &ray, HitPoint *hit = 0) const;
+       //! true if the projection of pt to the plane is contained within the disc radius
+       virtual bool contains(const Vec3 &pt) const;
+
+       virtual float distance(const Vec3 &v) const;
+       virtual float signed_distance(const Vec3 &v) const;
 };
 
+//! project point to plane
+Vec3 proj_point_plane(const Vec3 &pt, const Plane &plane);
+
+//! calculate the bounding sphere of any object
+bool calc_bounding_sphere(Sphere *sph, const GeomObject *obj);
+//! calculate the bounding sphere of two objects
+bool calc_bounding_sphere(Sphere *sph, const GeomObject *a, const GeomObject *b);
+//! calculate the bounding sphere of multiple objects
+bool calc_bounding_sphere(Sphere *sph, const GeomObject **objv, int num);
+//! calculate the bounding sphere of multiple points, optionally transformed by `xform`
+bool calc_bounding_sphere(Sphere *sph, const Vec3 *v, int num, const Mat4 &xform = Mat4::identity);
+
+//! calculate the bounding axis-aligned box of any object
+bool calc_bounding_aabox(AABox *box, const GeomObject *obj);
+//! calculate the bounding axis-aligned box of two objects
+bool calc_bounding_aabox(AABox *box, const GeomObject *a, const GeomObject *b);
+//! calculate the bounding axis-aligned box of multiple objects
+bool calc_bounding_aabox(AABox *box, const GeomObject **objv, int num);
+//! calculate the bounding axis-aligned box of multiple points, optionally transformed by `xform`
+bool calc_bounding_aabox(AABox *box, const Vec3 *v, int num, const Mat4 &xform = Mat4::identity);
+
+//! calculate the intersection plane of two spheres. false if there is no plane or infinite planes.
+bool intersect_sphere_sphere(Plane *result, const Sphere &a, const Sphere &b);
+//! calculate the intersection line of two planes. returns false if planes are exactly parallel.
+bool intersect_plane_plane(Ray *result, const Plane &a, const Plane &b);
+/*! calculate the intesection circle of a plane and a sphere. returns false if they don't intersect.
+ * \{
+ */
+bool intersect_sphere_plane(Sphere *result, const Sphere &s, const Plane &p);
+bool intersect_plane_sphere(Sphere *result, const Plane &p, const Sphere &s);
+//! \}
+
+//! calculate the intersection of two axis-aligned bounding boxes
+bool intersect_aabox_aabox(AABox *res, const AABox &a, const AABox &b);
+
 #endif // GEOMOBJ_H_