X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fmoof%2Fsphere.hh;fp=src%2Fmoof%2Fsphere.hh;h=dd4decec8d4224c16945467b820118a9ecdd4d4f;hb=831f04d4bc19a390415ac0bbac4331c7a65509bc;hp=0000000000000000000000000000000000000000;hpb=299af4f2047e767e5d79501c26444473bda64c64;p=chaz%2Fyoink diff --git a/src/moof/sphere.hh b/src/moof/sphere.hh new file mode 100644 index 0000000..dd4dece --- /dev/null +++ b/src/moof/sphere.hh @@ -0,0 +1,191 @@ + +/*] Copyright (c) 2009-2010, Charles McGarvey [************************** +**] All rights reserved. +* +* vi:ts=4 sw=4 tw=75 +* +* Distributable under the terms and conditions of the 2-clause BSD license; +* see the file COPYING for a complete text of the license. +* +**************************************************************************/ + +#ifndef _MOOF_SPHERE_HH_ +#define _MOOF_SPHERE_HH_ + +/** + * \file sphere.hh + * A round shape like a circle or sphere. + * TODO: This class needs some work. + */ + +#include +#include +#include +#include +#include +#include +#include + + +namespace moof { + + +/** + * A round object. + */ +template +struct sphere : public cullable, public drawable, public shape +{ + typedef moof::vector< scalar, fixed > vector; + + vector point; + scalar radius; + + + sphere() {} + + sphere(const vector& p, scalar r) : + point(p), + radius(r) {} + + + void init(const vector& p, scalar r) + { + point = p; + radius = r; + } + + void init(const vector& p, const vector& o) + { + point = p; + radius = (o - p).length(); + } + + //void enclose_vertices(const vector vertices[], unsigned count); + + //void draw(scalar alpha = 0.0) const; + //bool is_visible(const frustum& frustum) const; + + void enclose_vertices(const vector vertices[], unsigned count) + { + // TODO + } + + void draw(scalar alpha = 0.0) const; + + bool is_visible(const frustum& frustum) const + { + return true; + } + + + bool intersect(const sphere& sphere, contact& hit) const + { + vector n = sphere.point - point; + scalar distance = n.length(); + scalar limit = radius + sphere.radius; + + if (distance > limit) return false; + + hit.normal = n.normalize(); + hit.distance = limit - distance; + hit.point = hit.normal * radius; + + return true; + } + + bool intersect(const vector& point2, contact& hit) const + { + vector n = point2 - point; + scalar distance = n.length(); + + if (distance > radius) return false; + + hit.normal = n.normalize(); + hit.distance = radius - distance; + hit.point = point2; + + return true; + } + + // a ray inside the sphere will not intersect on its way out + bool intersect(const ray& ray, typename ray::contact& hit) const + { + vector b = point - ray.point; + scalar z = dot(b, ray.direction); + + // check if the ball is behind the ray + if (z < SCALAR(0.0)) return false; + + scalar d2 = dot(b, b) - z*z; + scalar r2 = radius * radius; + + // check for an intersection + if (d2 > r2) return false; + + hit.distance = z - std::sqrt(r2 - d2); + if (hit.distance < SCALAR(0.0)) return false; + + vector surfacePoint; + ray.solve(surfacePoint, hit.distance); + hit.normal = surfacePoint - point; + return true; + } +}; + + +template <> +inline bool sphere<3>::is_visible(const frustum& frustum) const +{ + return frustum.contains(*this); +} + +template <> +inline void sphere<2>::draw(scalar alpha) const +{ + GLUquadricObj* sphereObj = gluNewQuadric(); + gluQuadricDrawStyle(sphereObj, GLU_LINE); + + glPushMatrix(); + + glTranslate(promote(point)); + gluSphere(sphereObj, GLdouble(radius), 16, 16); + + glPopMatrix(); + + gluDeleteQuadric(sphereObj); +} + +template <> +inline void sphere<3>::draw(scalar alpha) const +{ + GLUquadricObj* sphereObj = gluNewQuadric(); + gluQuadricDrawStyle(sphereObj, GLU_LINE); + + glPushMatrix(); + + glTranslate(point); + gluSphere(sphereObj, GLdouble(radius), 16, 16); + + glPopMatrix(); + + gluDeleteQuadric(sphereObj); +} + +template +inline bool checkCollision(const sphere& a, const sphere& b) +{ + scalar d = (a.point - b.point).length(); + return d < (a.radius + b.radius); +} + + +typedef sphere<2> sphere2; +typedef sphere2 circle; +typedef sphere<3> sphere3; + + +} // namespace moof + +#endif // _MOOF_SPHERE_HH_ +