using aabb planes as mirror planes
[laserbrain_demo] / src / geom.h
1 #ifndef GEOMOBJ_H_
2 #define GEOMOBJ_H_
3
4 /* TODO:
5  * - implement distance functions
6  */
7
8 #include <gmath/gmath.h>
9
10 enum GeomObjectType {
11         GOBJ_UNKNOWN,
12         GOBJ_SPHERE,
13         GOBJ_AABOX,
14         GOBJ_BOX,
15         GOBJ_PLANE,
16         GOBJ_DISC
17 };
18
19 enum {
20         AABOX_PLANE_PX,
21         AABOX_PLANE_NX,
22         AABOX_PLANE_PY,
23         AABOX_PLANE_NY,
24         AABOX_PLANE_PZ,
25         AABOX_PLANE_NZ
26 };
27
28 class GeomObject;
29 class Plane;
30
31 struct HitPoint {
32         float dist;                     // parametric distance along the ray
33         Vec3 pos;                       // position of intersection (orig + dir * dist)
34         Vec3 normal;            // normal at the point of intersection
35         Ray ray, local_ray;
36         const GeomObject *obj;  // pointer to the intersected geom-object
37         void *data;                     // place to hang extra data
38 };
39
40 class GeomObject {
41 public:
42         GeomObjectType type;
43
44         GeomObject();
45         virtual ~GeomObject();
46
47         virtual bool valid() const;
48         virtual void invalidate();
49
50         virtual bool intersect(const Ray &ray, HitPoint *hit = 0) const = 0;
51         virtual bool contains(const Vec3 &pt) const = 0;
52
53         virtual float distance(const Vec3 &v) const;
54         virtual float signed_distance(const Vec3 &v) const;
55
56         virtual float distance_sq(const Vec3 &v) const = 0;
57         virtual float signed_distance_sq(const Vec3 &v) const = 0;
58 };
59
60 class Sphere : public GeomObject {
61 public:
62         Vec3 center;
63         float radius;
64
65         Sphere();
66         Sphere(const Vec3 &center, float radius);
67
68         virtual bool valid() const;
69         virtual void invalidate();
70
71         virtual bool intersect(const Ray &ray, HitPoint *hit = 0) const;
72         virtual bool contains(const Vec3 &pt) const;
73
74         virtual float distance_sq(const Vec3 &v) const;
75         virtual float signed_distance_sq(const Vec3 &v) const;
76 };
77
78 class AABox : public GeomObject {
79 public:
80         Vec3 min, max;
81
82         AABox();
83         AABox(const Vec3 &min, const Vec3 &max);
84
85         virtual bool valid() const;
86         virtual void invalidate();
87
88         virtual Vec3 get_corner(int idx) const;
89         virtual Plane get_plane(int pidx) const;
90
91         virtual bool intersect(const Ray &ray, HitPoint *hit = 0) const;
92         virtual bool contains(const Vec3 &pt) const;
93
94         virtual float distance_sq(const Vec3 &v) const;
95         virtual float signed_distance_sq(const Vec3 &v) const;
96 };
97
98 class Box : public AABox {
99 public:
100         Mat4 xform;
101
102         Box();
103         Box(const AABox &aabox, const Mat4 &xform);
104         Box(const Vec3 &min, const Vec3 &max);
105         Box(const Vec3 &min, const Vec3 &max, const Mat4 &xform);
106         Box(const Vec3 &pos, const Vec3 &vi, const Vec3 &vj, const Vec3 &vk);
107         Box(const Vec3 *varr, int vcount);
108
109         virtual void invalidate();
110
111         virtual Vec3 get_corner(int idx) const;
112
113         virtual bool intersect(const Ray &ray, HitPoint *hit = 0) const;
114         virtual bool contains(const Vec3 &pt) const;
115
116         virtual float distance_sq(const Vec3 &v) const;
117         virtual float signed_distance_sq(const Vec3 &v) const;
118 };
119
120
121 class Plane : public GeomObject {
122 public:
123         Vec3 pt, normal;
124
125         Plane();
126         Plane(const Vec3 &pt, const Vec3 &normal);
127         Plane(const Vec3 &p1, const Vec3 &p2, const Vec3 &p3);
128         Plane(const Vec3 &normal, float dist);
129
130         virtual bool intersect(const Ray &ray, HitPoint *hit = 0) const;
131         virtual bool contains(const Vec3 &pt) const;
132
133         virtual float distance(const Vec3 &v) const;
134         virtual float signed_distance(const Vec3 &v) const;
135
136         virtual float distance_sq(const Vec3 &v) const;
137         virtual float signed_distance_sq(const Vec3 &v) const;
138 };
139
140 class Disc : public Plane {
141 public:
142         float radius;
143
144         Disc();
145         Disc(const Vec3 &pt, const Vec3 &normal, float rad);
146         Disc(const Vec3 &normal, float dist, float rad);
147
148         virtual bool valid() const;
149         virtual void invalidate();
150
151         virtual bool intersect(const Ray &ray, HitPoint *hit = 0) const;
152         //! true if the projection of pt to the plane is contained within the disc radius
153         virtual bool contains(const Vec3 &pt) const;
154
155         virtual float distance_sq(const Vec3 &v) const;
156         virtual float signed_distance_sq(const Vec3 &v) const;
157 };
158
159 //! project point to plane
160 Vec3 proj_point_plane(const Vec3 &pt, const Plane &plane);
161
162 //! calculate the bounding sphere of any object
163 bool calc_bounding_sphere(Sphere *sph, const GeomObject *obj);
164 //! calculate the bounding sphere of two objects
165 bool calc_bounding_sphere(Sphere *sph, const GeomObject *a, const GeomObject *b);
166 //! calculate the bounding sphere of multiple objects
167 bool calc_bounding_sphere(Sphere *sph, const GeomObject **objv, int num);
168 //! calculate the bounding sphere of multiple points, optionally transformed by `xform`
169 bool calc_bounding_sphere(Sphere *sph, const Vec3 *v, int num, const Mat4 &xform = Mat4::identity);
170
171 //! calculate the bounding axis-aligned box of any object
172 bool calc_bounding_aabox(AABox *box, const GeomObject *obj);
173 //! calculate the bounding axis-aligned box of two objects
174 bool calc_bounding_aabox(AABox *box, const GeomObject *a, const GeomObject *b);
175 //! calculate the bounding axis-aligned box of multiple objects
176 bool calc_bounding_aabox(AABox *box, const GeomObject **objv, int num);
177 //! calculate the bounding axis-aligned box of multiple points, optionally transformed by `xform`
178 bool calc_bounding_aabox(AABox *box, const Vec3 *v, int num, const Mat4 &xform = Mat4::identity);
179
180 //! calculate the bounding box of any object
181 bool calc_bounding_box(Box *box, const GeomObject *obj);
182
183 //! calculate the intersection plane of two spheres. false if there is no plane or infinite planes.
184 bool intersect_sphere_sphere(Plane *result, const Sphere &a, const Sphere &b);
185 //! calculate the intersection line of two planes. returns false if planes are exactly parallel.
186 bool intersect_plane_plane(Ray *result, const Plane &a, const Plane &b);
187 /*! calculate the intesection circle of a plane and a sphere. returns false if they don't intersect.
188  * \{
189  */
190 bool intersect_sphere_plane(Sphere *result, const Sphere &s, const Plane &p);
191 bool intersect_plane_sphere(Sphere *result, const Plane &p, const Sphere &s);
192 //! \}
193
194 //! calculate the intersection of two axis-aligned bounding boxes
195 bool intersect_aabox_aabox(AABox *res, const AABox &a, const AABox &b);
196
197 //! determine if a sphere and an axis-aligned box collide
198 bool collision_sphere_aabox(const Sphere &s, const AABox &b);
199
200 #endif  // GEOMOBJ_H_