]> Dogcows Code - chaz/yoink/blob - src/moof/sphere.hh
begin cleaning up resource management
[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,
113 typename moof::ray<D>::contact& hit) const
114 {
115 vector b = point - ray.point;
116 scalar z = dot(b, ray.direction);
117
118 // check if the ball is behind the ray
119 if (z < SCALAR(0.0)) return false;
120
121 scalar d2 = dot(b, b) - z*z;
122 scalar r2 = radius * radius;
123
124 // check for an intersection
125 if (d2 > r2) return false;
126
127 hit.distance = z - std::sqrt(r2 - d2);
128 if (hit.distance < SCALAR(0.0)) return false;
129
130 vector surfacePoint;
131 ray.solve(surfacePoint, hit.distance);
132 hit.normal = surfacePoint - point;
133 return true;
134 }
135 };
136
137
138 template <>
139 inline bool sphere<3>::is_visible(const frustum& frustum) const
140 {
141 return frustum.contains(*this);
142 }
143
144 template <>
145 inline void sphere<2>::draw(scalar alpha) const
146 {
147 GLUquadricObj* sphereObj = gluNewQuadric();
148 gluQuadricDrawStyle(sphereObj, GLU_LINE);
149
150 glPushMatrix();
151
152 glTranslate(promote(point));
153 gluSphere(sphereObj, GLdouble(radius), 16, 16);
154
155 glPopMatrix();
156
157 gluDeleteQuadric(sphereObj);
158 }
159
160 template <>
161 inline void sphere<3>::draw(scalar alpha) const
162 {
163 GLUquadricObj* sphereObj = gluNewQuadric();
164 gluQuadricDrawStyle(sphereObj, GLU_LINE);
165
166 glPushMatrix();
167
168 glTranslate(point);
169 gluSphere(sphereObj, GLdouble(radius), 16, 16);
170
171 glPopMatrix();
172
173 gluDeleteQuadric(sphereObj);
174 }
175
176 template <int D>
177 inline bool checkCollision(const sphere<D>& a, const sphere<D>& b)
178 {
179 scalar d = (a.point - b.point).length();
180 return d < (a.radius + b.radius);
181 }
182
183
184 typedef sphere<2> sphere2;
185 typedef sphere2 circle;
186 typedef sphere<3> sphere3;
187
188
189 } // namespace moof
190
191 #endif // _MOOF_SPHERE_HH_
192
This page took 0.035357 seconds and 4 git commands to generate.