]> Dogcows Code - chaz/yoink/blob - src/Moof/Sphere.hh
initial network stuff
[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 #include <Moof/Contact.hh>
16 #include <Moof/Cullable.hh>
17 #include <Moof/Drawable.hh>
18 #include <Moof/Frustum.hh>
19 #include <Moof/Math.hh>
20 #include <Moof/OpenGL.hh>
21 #include <Moof/Shape.hh>
22
23 // TODO this needs work
24
25 namespace Mf {
26
27
28 /**
29 * A round object.
30 */
31
32
33 template <int D = 3>
34 struct Sphere : public Cullable, public Drawable, public Shape<D>
35 {
36 typedef cml::vector< Scalar, cml::fixed<D> > Vector;
37
38 Vector point;
39 Scalar radius;
40
41
42 Sphere() {}
43
44 Sphere(const Vector& p, Scalar r) :
45 point(p),
46 radius(r) {}
47
48
49 void init(const Vector& p, Scalar r)
50 {
51 point = p;
52 radius = r;
53 }
54
55 void init(const Vector& p, const Vector& o)
56 {
57 point = p;
58 radius = (o - p).length();
59 }
60
61 //void encloseVertices(const Vector vertices[], unsigned count);
62
63 //void draw(Scalar alpha = 0.0) const;
64 //bool isVisible(const Frustum& frustum) const;
65
66 void encloseVertices(const Vector vertices[], unsigned count)
67 {
68 // TODO
69 }
70
71 void draw(Scalar alpha = 0.0) const;
72
73 bool isVisible(const Frustum& frustum) const
74 {
75 return true;
76 }
77
78
79 bool intersect(const Sphere<D>& sphere, Contact<D>& hit) const
80 {
81 Vector n = sphere.point - point;
82 Scalar distance = n.length();
83 Scalar limit = radius + sphere.radius;
84
85 if (distance > limit) return false;
86
87 hit.normal = n.normalize();
88 hit.distance = limit - distance;
89 hit.point = hit.normal * radius;
90
91 return true;
92 }
93
94 bool intersect(const Vector& point2, Contact<D>& hit) const
95 {
96 Vector n = point2 - point;
97 Scalar distance = n.length();
98
99 if (distance > radius) return false;
100
101 hit.normal = n.normalize();
102 hit.distance = radius - distance;
103 hit.point = point2;
104
105 return true;
106 }
107
108 // a ray inside the sphere will not intersect on its way out
109 bool intersect(const Ray<D>& ray, typename Ray<D>::Contact& hit) const
110 {
111 Vector b = point - ray.point;
112 Scalar z = cml::dot(b, ray.direction);
113
114 // check if the ball is behind the ray
115 if (z < SCALAR(0.0)) return false;
116
117 Scalar d2 = cml::dot(b, b) - z*z;
118 Scalar r2 = radius * radius;
119
120 // check for an intersection
121 if (d2 > r2) return false;
122
123 hit.distance = z - std::sqrt(r2 - d2);
124 if (hit.distance < SCALAR(0.0)) return false;
125
126 Vector surfacePoint;
127 ray.solve(surfacePoint, hit.distance);
128 hit.normal = surfacePoint - point;
129 return true;
130 }
131 };
132
133
134 template <>
135 inline bool Sphere<3>::isVisible(const Frustum& frustum) const
136 {
137 return frustum.contains(*this);
138 }
139
140 template <>
141 inline void Sphere<2>::draw(Scalar alpha) const
142 {
143 GLUquadricObj* sphereObj = gluNewQuadric();
144 gluQuadricDrawStyle(sphereObj, GLU_LINE);
145
146 glPushMatrix();
147
148 glTranslate(promote(point));
149 gluSphere(sphereObj, GLdouble(radius), 16, 16);
150
151 glPopMatrix();
152
153 gluDeleteQuadric(sphereObj);
154 }
155
156 template <>
157 inline void Sphere<3>::draw(Scalar alpha) const
158 {
159 GLUquadricObj* sphereObj = gluNewQuadric();
160 gluQuadricDrawStyle(sphereObj, GLU_LINE);
161
162 glPushMatrix();
163
164 glTranslate(point);
165 gluSphere(sphereObj, GLdouble(radius), 16, 16);
166
167 glPopMatrix();
168
169 gluDeleteQuadric(sphereObj);
170 }
171
172 template <int D>
173 inline bool checkCollision(const Sphere<D>& a, const Sphere<D>& b)
174 {
175 Scalar d = (a.point - b.point).length();
176 return d < (a.radius + b.radius);
177 }
178
179
180 typedef Sphere<2> Sphere2;
181 typedef Sphere2 Circle;
182 typedef Sphere<3> Sphere3;
183
184
185 } // namespace Mf
186
187 #endif // _MOOF_SPHERE_HH_
188
This page took 0.040666 seconds and 4 git commands to generate.