PF_API 0.52

Code/Libs/CD_LIB/CDVolume.h

Go to the documentation of this file.
00001 
00002 //    Copyright (C) 2004-2011 Dylan Blair
00003 //
00004 //    email: dblair@alumni.cs.utexas.edu
00005 //
00006 //    This library is free software; you can redistribute it and/or
00007 //    modify it under the terms of the GNU Lesser General Public
00008 //    License as published by the Free Software Foundation; either
00009 //    version 2.1 of the License, or (at your option) any later version.
00010 //
00011 //    This library is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 //    Lesser General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU Lesser General Public
00017 //    License along with this library; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021 #ifndef CDVOLUME_H
00022 #define CDVOLUME_H
00023 
00024 #include "../Math_LIB/MMatrix3x3.h"
00025 
00026 namespace OpenSkyNet {
00029     namespace CD {
00031         enum SHAPE_TYPE { SPHERE, BOX, PLANE };
00032 
00033         class Volume;
00034 
00036         struct HitInfo {
00038             Volume* _collider;
00039 
00040             float _hitSecs;
00041 
00042             Math::Point<> _hitPos, _hitNormal;
00043 
00044             HitInfo(Volume* collider_=0) : _collider(collider_), _hitSecs(Math::PSEUDO_INFINITY) {}
00045         };
00046 
00050         struct Shape {
00051             float _boundingRadius;
00052 
00053             Shape(const float& boundingRadius_=0.0f) : _boundingRadius(boundingRadius_) {}
00054 
00055             virtual ~Shape() {}
00056 
00057             virtual SHAPE_TYPE getType() const = 0;
00058 
00059             virtual float getDist(const Math::Point<>& thisCenter_, const Math::Matrix3x3& thisRot_, const Shape* otherShape_, 
00060                                   const Math::Point<>& otherCenter_, const Math::Matrix3x3& otherRot_) const;
00061 
00062             virtual bool getFirstIntersection(const Math::Point<>& thisCenter_, const Math::Matrix3x3& thisRot_, const Math::Point<>& thisVel_, const Shape* otherShape_, 
00063                                               const Math::Point<>& otherCenter_, const Math::Matrix3x3& otherRot_, const Math::Point<>& otherVel_, HitInfo& hitInfo_) const;
00064 
00069             virtual bool getClosestRayIntersection(const Math::Point<>& thisCenter_, const Math::Matrix3x3& thisRot_, 
00070                 const Math::Point<>& rayOrigin_, const Math::Point<>& rayDir_, 
00071                 Math::Point<>& hitPos_, float& t_, Math::Point<>& hitNormal_) const;
00072 
00073             virtual void scale(const Math::Point<>& factor_) { UNUSED(factor_); }
00074         };
00075 
00076         struct Sphere : public Shape {
00077             Sphere(const float& boundingRadius_) : Shape(boundingRadius_) {}
00078 
00079             virtual SHAPE_TYPE getType() const { return SPHERE; }
00080         };
00081 
00082         struct Box : public Shape {
00083             float _widthDiv2, _heightDiv2, _depthDiv2;
00084 
00085             Box(const float& boundingRadius_, const float& width_, const float& height_, const float& depth_) : Shape(boundingRadius_), 
00086                 _widthDiv2(width_), _heightDiv2(height_), _depthDiv2(depth_) { _widthDiv2 /= 2; _heightDiv2 /= 2; _depthDiv2 /= 2; }
00087 
00088             virtual SHAPE_TYPE getType() const { return BOX; }
00089 
00090             inline Math::Point<> getDimensions() const { return Math::Point<>(_widthDiv2, _heightDiv2, _depthDiv2); }
00091 
00093             virtual float getDist(const Math::Point<>& thisCenter_, const Math::Matrix3x3& thisRot_, const Shape* otherShape_, 
00094                                   const Math::Point<>& otherCenter_, const Math::Matrix3x3& otherRot_) const;
00095 
00096             virtual bool getFirstIntersection(const Math::Point<>& thisCenter_, const Math::Matrix3x3& thisRot_, const Math::Point<>& thisVel_, const Shape* otherShape_, 
00097                                               const Math::Point<>& otherCenter_, const Math::Matrix3x3& otherRot_, const Math::Point<>& otherVel_, HitInfo& hitInfo_) const;
00098 
00099             virtual void scale(const Math::Point<>& factor_);
00100         };
00101 
00102         struct Plane : public Shape {
00103             enum AXIS_ALIGNMENT { NONE, NEG_X, POS_X, NEG_Y, POS_Y, NEG_Z, POS_Z };
00104 
00105             Math::Point<> _n;
00106 
00107             Plane(const Math::Point<>& n_) : _n(n_) {}
00108 
00109             virtual SHAPE_TYPE getType() const { return PLANE; }
00110 
00114             virtual float getDist(const Math::Point<>& thisCenter_, const Math::Matrix3x3& thisRot_, const Shape* otherShape_, 
00115                                   const Math::Point<>& otherCenter_, const Math::Matrix3x3& otherRot_) const;
00116 
00117             inline float getDist(const Math::Point<>& thisP_, const Math::Point<>& otherP_) const {
00118                 Math::Point<> v(otherP_ - thisP_);
00119                 return _n.getDot3(v);
00120             }
00121 
00122             inline AXIS_ALIGNMENT getAxisAlignment() const {
00123                 if (_n.equals(Math::g_xAxis,Math::CLOSE_TO_ZERO)) return POS_X;
00124                 if (_n.equals(Math::g_yAxis,Math::CLOSE_TO_ZERO)) return POS_Y;
00125                 if (_n.equals(Math::g_zAxis,Math::CLOSE_TO_ZERO)) return POS_Z;
00126                 if (_n.equals(-Math::g_xAxis,Math::CLOSE_TO_ZERO)) return NEG_X;
00127                 if (_n.equals(-Math::g_yAxis,Math::CLOSE_TO_ZERO)) return NEG_Y;
00128                 if (_n.equals(-Math::g_zAxis,Math::CLOSE_TO_ZERO)) return NEG_Z;
00129                 return NONE;
00130             }
00131         };
00132 
00134         #define COL_GROUP_HIT_ALL_HIT_BY_ALL          0xFFFFFFFF
00135         #define COL_GROUP_HIT_ALL_HIT_BY_NONE         0xFFFF0000
00136         #define COL_GROUP_HIT_NONE_HIT_BY_ALL         0x0000FFFF
00137         #define COL_GROUP_HIT_NONE_HIT_BY_NONE        0x00000000
00138         #define COL_GROUP_HIT_NONE_HIT_BY_1           0x00000001
00139         #define COL_GROUP_HIT_ALL_BUT_1_HIT_BY_NONE   0xFFFE0000
00140         #define COL_GROUP_HITTABLE_MASK               0x0000FFFF
00141 
00142         class Collidable {
00143             Math::Point<> _center, _nonCollidingCenter;
00144             Math::Matrix3x3 _rot, _nonCollidingRot;
00145             void* _userPointer;
00146             Utils::uint _colGroup;
00147         public:
00148             Collidable(const Math::Point<>& center_=Math::g_origin, const Math::Matrix3x3& rot_=Math::g_identityMatrix3x3, 
00149                 void* userPointer_=0, Utils::uint colGroup_=COL_GROUP_HIT_ALL_HIT_BY_ALL) : _center(center_), 
00150                 _nonCollidingCenter(center_), _rot(rot_), _userPointer(userPointer_), _colGroup(colGroup_) {}
00151 
00152             virtual ~Collidable() {}
00153 
00154             inline void translate(const Math::Point<>& delta_) { _center += delta_; }
00155 
00156             inline void setCenter(const Math::Point<>& center_) { _center = center_; }
00157 
00158             inline Math::Point<> getCenter() const { return _center; }
00159 
00165             inline void setNonColTransform(const Math::Point<>& center_, const Math::Matrix3x3& rot_) {
00166                 _nonCollidingCenter = center_;
00167                 _nonCollidingRot = rot_;
00168             }
00169 
00171             inline Math::Point<> getNonColCenter() const { return _nonCollidingCenter; }
00172             inline Math::Matrix3x3 getNonColRot() const { return _nonCollidingRot; }
00173 
00174             inline void setRot(const Math::Matrix3x3& rot_) { _rot = rot_; }
00175 
00176             inline Math::Matrix3x3 getRot() const { return _rot; }
00177 
00179             inline void setUserPointer(void* userPointer_) { _userPointer = userPointer_; }
00180 
00182             inline void* getUserPointer() const { return _userPointer; }
00183 
00191             inline Utils::uint canGroupHitMe(Utils::uint colGroup_) const { return (colGroup_ & ((_colGroup & COL_GROUP_HITTABLE_MASK) << 16)); }
00192 
00194             inline Utils::uint getColGroup() const { return _colGroup; }
00195 
00196             inline void setColGroup(Utils::uint colGroup_) { _colGroup = colGroup_; }
00197 
00198             virtual Shape* getShape() = 0;
00199 
00200             virtual const Shape* getShape() const = 0;
00201 
00202             virtual SHAPE_TYPE getType() const { return getShape()->getType(); }
00203 
00204             virtual float getDist(const Collidable* aCollidable_) const {
00205                 return getShape()->getDist(_center, _rot, aCollidable_->getShape(), aCollidable_->getCenter(), aCollidable_->getRot());
00206             }
00207 
00208             virtual bool getFirstIntersection(const Math::Point<>& thisVel_, const Collidable* otherCollidable_, 
00209                                               const Math::Point<>& otherVel_, HitInfo& hitInfo_) const {
00210                 return getShape()->getFirstIntersection(_center, _rot, thisVel_, otherCollidable_->getShape(), 
00211                                                         otherCollidable_->getCenter(), otherCollidable_->getRot(), otherVel_, hitInfo_);
00212             }
00213 
00215             virtual bool getClosestRayIntersection(const Math::Point<>& rayOrigin_, const Math::Point<>& rayDir_, 
00216                 Math::Point<>& hitPos_, float& t_, Math::Point<>& hitNormal_) const {
00217                 return getShape()->getClosestRayIntersection(_center, _rot, rayOrigin_, rayDir_, hitPos_, t_, hitNormal_);
00218             }
00219         };
00220 
00221         class Volume : public Collidable {
00222             Shape* _shape;
00223         public:
00224             Volume(Shape* shape_, const Math::Point<>& center_=Math::g_origin, const Math::Matrix3x3& rot_=Math::g_identityMatrix3x3, 
00225                 void* userPointer_=0, Utils::uint colGroup_=COL_GROUP_HIT_ALL_HIT_BY_ALL) : Collidable(center_,rot_,userPointer_,colGroup_), 
00226                 _shape(shape_) {}
00227 
00228             inline void setBoundingRadius(const float& boundingRadius_) { _shape->_boundingRadius = boundingRadius_; }
00229 
00230             inline float getBoundingRadius() const { return _shape->_boundingRadius; }
00231 
00232             virtual Shape* getShape() { return _shape; }
00233 
00234             virtual const Shape* getShape() const { return _shape; }
00235         };
00236     }
00237 }
00238 
00239 #endif //CDVOLUME_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines