]> Dogcows Code - chaz/yoink/blob - src/moof/sphere.hh
fixed documentation about where to find licenses
[chaz/yoink] / src / moof / sphere.hh
1
2 /*] Copyright (c) 2009-2011, Charles McGarvey [*****************************
3 **] All rights reserved.
4 *
5 * Distributable under the terms and conditions of the 2-clause BSD license;
6 * see the file COPYING for a complete text of the license.
7 *
8 *****************************************************************************/
9
10 #ifndef _MOOF_SPHERE_HH_
11 #define _MOOF_SPHERE_HH_
12
13 #include <moof/contact.hh>
14 #include <moof/cullable.hh>
15 #include <moof/drawable.hh>
16 #include <moof/frustum.hh>
17 #include <moof/math.hh>
18 #include <moof/opengl.hh>
19 #include <moof/shape.hh>
20
21
22 /**
23 * \file sphere.hh
24 * A round shape like a circle or sphere.
25 * TODO: This class needs some work.
26 */
27
28 namespace moof {
29
30
31 /**
32 * A round object.
33 */
34 template <int D = 3>
35 struct sphere : public cullable, public drawable, public shape<D>
36 {
37 typedef moof::vector< scalar, fixed<D> > vector;
38
39 vector point;
40 scalar radius;
41
42 sphere() {}
43
44 sphere(const vector& p, scalar r) :
45 point(p),
46 radius(r) {}
47
48 void init(const vector& p, scalar r)
49 {
50 point = p;
51 radius = r;
52 }
53
54 void init(const vector& p, const vector& o)
55 {
56 point = p;
57 radius = (o - p).length();
58 }
59
60 //void enclose_vertices(const vector vertices[], unsigned count);
61
62 //void draw(scalar alpha = 0.0) const;
63 //bool is_visible(const frustum& frustum) const;
64
65 void enclose_vertices(const vector vertices[], unsigned count)
66 {
67 // TODO
68 }
69
70 void draw(scalar alpha = 0.0) const;
71
72 bool is_visible(const frustum& frustum) const
73 {
74 return true;
75 }
76
77 bool intersect(const sphere<D>& sphere, contact<D>& hit) const
78 {
79 vector n = sphere.point - point;
80 scalar distance = n.length();
81 scalar limit = radius + sphere.radius;
82
83 if (distance > limit) return false;
84
85 hit.normal = n.normalize();
86 hit.distance = limit - distance;
87 hit.point = hit.normal * radius;
88
89 return true;
90 }
91
92 bool intersect(const vector& point2, contact<D>& hit) const
93 {
94 vector n = point2 - point;
95 scalar distance = n.length();
96
97 if (distance > radius) return false;
98
99 hit.normal = n.normalize();
100 hit.distance = radius - distance;
101 hit.point = point2;
102
103 return true;
104 }
105
106 // a ray inside the sphere will not intersect on its way out
107 bool intersect(const ray<D>& ray,
108 typename moof::ray<D>::contact& hit) const
109 {
110 vector b = point - ray.point;
111 scalar z = dot(b, ray.direction);
112
113 // check if the ball is behind the ray
114 if (z < SCALAR(0.0)) return false;
115
116 scalar d2 = dot(b, b) - z*z;
117 scalar r2 = radius * radius;
118
119 // check for an intersection
120 if (d2 > r2) return false;
121
122 hit.distance = z - std::sqrt(r2 - d2);
123 if (hit.distance < SCALAR(0.0)) return false;
124
125 vector surfacePoint;
126 ray.solve(surfacePoint, hit.distance);
127 hit.normal = surfacePoint - point;
128 return true;
129 }
130 };
131
132 typedef sphere<2> circle;
133 typedef sphere<2> sphere2;
134 typedef sphere<3> sphere3;
135
136
137 template <>
138 inline bool sphere3::is_visible(const frustum& frustum) const
139 {
140 return frustum.contains(*this);
141 }
142
143 template <>
144 inline void sphere2::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 sphere3::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 } // namespace moof
184
185 #endif // _MOOF_SPHERE_HH_
186
This page took 0.03847 seconds and 4 git commands to generate.