dd4decec8d4224c16945467b820118a9ecdd4d4f
[chaz/yoink] / src / moof / sphere.hh
1
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
4 *
5 * vi:ts=4 sw=4 tw=75
6 *
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
9 *
10 **************************************************************************/
11
12 #ifndef _MOOF_SPHERE_HH_
13 #define _MOOF_SPHERE_HH_
14
15 /**
16 * \file sphere.hh
17 * A round shape like a circle or sphere.
18 * TODO: This class needs some work.
19 */
20
21 #include <moof/contact.hh>
22 #include <moof/cullable.hh>
23 #include <moof/drawable.hh>
24 #include <moof/frustum.hh>
25 #include <moof/math.hh>
26 #include <moof/opengl.hh>
27 #include <moof/shape.hh>
28
29
30 namespace moof {
31
32
33 /**
34 * A round object.
35 */
36 template <int D = 3>
37 struct sphere : public cullable, public drawable, public shape<D>
38 {
39 typedef moof::vector< scalar, fixed<D> > vector;
40
41 vector point;
42 scalar radius;
43
44
45 sphere() {}
46
47 sphere(const vector& p, scalar r) :
48 point(p),
49 radius(r) {}
50
51
52 void init(const vector& p, scalar r)
53 {
54 point = p;
55 radius = r;
56 }
57
58 void init(const vector& p, const vector& o)
59 {
60 point = p;
61 radius = (o - p).length();
62 }
63
64 //void enclose_vertices(const vector vertices[], unsigned count);
65
66 //void draw(scalar alpha = 0.0) const;
67 //bool is_visible(const frustum& frustum) const;
68
69 void enclose_vertices(const vector vertices[], unsigned count)
70 {
71 // TODO
72 }
73
74 void draw(scalar alpha = 0.0) const;
75
76 bool is_visible(const frustum& frustum) const
77 {
78 return true;
79 }
80
81
82 bool intersect(const sphere<D>& sphere, contact<D>& hit) const
83 {
84 vector n = sphere.point - point;
85 scalar distance = n.length();
86 scalar limit = radius + sphere.radius;
87
88 if (distance > limit) return false;
89
90 hit.normal = n.normalize();
91 hit.distance = limit - distance;
92 hit.point = hit.normal * radius;
93
94 return true;
95 }
96
97 bool intersect(const vector& point2, contact<D>& hit) const
98 {
99 vector n = point2 - point;
100 scalar distance = n.length();
101
102 if (distance > radius) return false;
103
104 hit.normal = n.normalize();
105 hit.distance = radius - distance;
106 hit.point = point2;
107
108 return true;
109 }
110
111 // a ray inside the sphere will not intersect on its way out
112 bool intersect(const ray<D>& ray, typename ray<D>::contact& hit) const
113 {
114 vector b = point - ray.point;
115 scalar z = dot(b, ray.direction);
116
117 // check if the ball is behind the ray
118 if (z < SCALAR(0.0)) return false;
119
120 scalar d2 = dot(b, b) - z*z;
121 scalar r2 = radius * radius;
122
123 // check for an intersection
124 if (d2 > r2) return false;
125
126 hit.distance = z - std::sqrt(r2 - d2);
127 if (hit.distance < SCALAR(0.0)) return false;
128
129 vector surfacePoint;
130 ray.solve(surfacePoint, hit.distance);
131 hit.normal = surfacePoint - point;
132 return true;
133 }
134 };
135
136
137 template <>
138 inline bool sphere<3>::is_visible(const frustum& frustum) const
139 {
140 return frustum.contains(*this);
141 }
142
143 template <>
144 inline void sphere<2>::draw(scalar alpha) const
145 {
146 GLUquadricObj* sphereObj = gluNewQuadric();
147 gluQuadricDrawStyle(sphereObj, GLU_LINE);
148
149 glPushMatrix();
150
151 glTranslate(promote(point));
152 gluSphere(sphereObj, GLdouble(radius), 16, 16);
153
154 glPopMatrix();
155
156 gluDeleteQuadric(sphereObj);
157 }
158
159 template <>
160 inline void sphere<3>::draw(scalar alpha) const
161 {
162 GLUquadricObj* sphereObj = gluNewQuadric();
163 gluQuadricDrawStyle(sphereObj, GLU_LINE);
164
165 glPushMatrix();
166
167 glTranslate(point);
168 gluSphere(sphereObj, GLdouble(radius), 16, 16);
169
170 glPopMatrix();
171
172 gluDeleteQuadric(sphereObj);
173 }
174
175 template <int D>
176 inline bool checkCollision(const sphere<D>& a, const sphere<D>& b)
177 {
178 scalar d = (a.point - b.point).length();
179 return d < (a.radius + b.radius);
180 }
181
182
183 typedef sphere<2> sphere2;
184 typedef sphere2 circle;
185 typedef sphere<3> sphere3;
186
187
188 } // namespace moof
189
190 #endif // _MOOF_SPHERE_HH_
191
This page took 0.035455 seconds and 3 git commands to generate.