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