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