Obstacle.h

00001 // ----------------------------------------------------------------------------
00002 //
00003 // tagGame - Example code from the book:
00004 //
00005 //           Artficial Intelligence for Computer Games: An Introduction
00006 //           by John David Funge
00007 //
00008 //           www.ai4games.org
00009 //
00010 // Source code distributed under the Copyright (c) 2003-2007, John David Funge
00011 // Original author: John David Funge (www.jfunge.com)
00012 //
00013 // Licensed under the Academic Free License version 3.0 
00014 // (for details see LICENSE.txt in this directory).
00015 //
00016 // ----------------------------------------------------------------------------
00017 
00018 #ifndef TG_OBSTACLE_H
00019 #define TG_OBSTACLE_H
00020 
00021 #include "Vec.h"
00022 #include "Shape.h"
00023 
00024 namespace tagGame
00025 {
00026    class Renderer;
00027    class Obstacle;
00028 
00029    typedef SharedPtr<Renderer>::type RendererPtr;
00030    typedef SharedPtr<Obstacle>::type ObstaclePtr;
00031 
00033    class Obstacle
00034    {
00035    public:
00036       Obstacle(ShapePtr shape);
00037       virtual ~Obstacle();
00038 
00039       inline void setRenderer(function<void (Obstacle*)> renderer);
00040 
00041       inline void setRenderer(RendererPtr renderer);
00042       inline RendererPtr getRenderer();
00043 
00044       inline Shape const& getShape() const;
00045 
00046       inline RealVec const& getPosition() const;
00047       inline void setPosition(RealVec const& position);
00048       inline Real getSpeed() const;
00049       inline void setSpeed(Real const Speed);
00050       inline Real const& getMass() const;
00051       inline void setMass(Real const mass);
00052 
00053       inline RealVec getVelocity() const;
00054       inline void setVelocity(RealVec const& velocity);
00055 
00056       inline RealVec const& getOrientation() const;
00057       inline void setOrientation(RealVec const& orientation);
00058 
00059       void render();
00060 
00061       virtual std::ostream& output(std::ostream& out) const;
00062 
00063       inline bool isTouching(Obstacle const& o) const;
00064       inline bool isColliding(Obstacle const& o) const;
00065 
00068       inline RealVec nearestIntersection(RealVec const& p, RealVec const& v) const;
00069 
00071       inline RealVec normalTo(Obstacle const& o) const;
00072 
00073       inline Real distanceTo(Obstacle const& o) const;
00074 
00075       inline Real distanceSquaredTo(Obstacle const& o) const;
00076 
00077    protected:
00078       RendererPtr renderer;
00079 
00080    private:
00081       ShapePtr shape;
00082       Real speed;
00083       Real mass;
00084    };
00085 
00086    typedef std::vector<ObstaclePtr> ObstacleList;
00087    typedef ObstacleList::const_iterator ObstacleIteratorConst;
00088    typedef ObstacleList::iterator ObstacleIterator;
00089 
00090    std::ostream& operator<<(std::ostream& out, Obstacle const& o);
00091 
00092    RealVec const& Obstacle::getPosition() const
00093    {
00094       return shape->getPosition();
00095    }
00096 
00097    void Obstacle::setPosition(RealVec const& position)
00098    {
00099       shape->setPosition(position);
00100    }
00101 
00102    void Obstacle::setVelocity(RealVec const& velocity)
00103    {
00104       RealVec v(velocity);
00105       Real const s = v.length();
00106       if (MathUtil::isAlmostZero(s))
00107       {
00108          setSpeed(0);
00109          // Don't change the orientation if the speed is zero.
00110       }
00111       else
00112       {
00113          setSpeed(s);
00114          setOrientation(v.normalize());
00115       }
00116    }
00117 
00118    RealVec Obstacle::getVelocity() const
00119    {
00120       // TODO: cache v in a class variable and invalidate as appropriate.
00121       // Then make this return a const reference (remember to change the
00122       // corresponding percept too).
00123       RealVec v(shape->getOrientation());
00124       return v.scale(getSpeed());
00125    }
00126 
00127    Real Obstacle::getSpeed() const
00128    {
00129       return speed;
00130    }
00131 
00132    void Obstacle::setSpeed(Real const speed)
00133    {
00134       TG_ASSERT(mass < Inf); // Infinitely heavy object can't move
00135       this->speed = speed;
00136    }
00137 
00138    Real const& Obstacle::getMass() const
00139    {
00140       return mass;
00141    }
00142 
00143    void Obstacle::setMass(Real const mass)
00144    {
00145       this->mass = mass;
00146    }
00147 
00148    RealVec const& Obstacle::getOrientation() const
00149    {
00150       return shape->getOrientation();
00151    }
00152 
00153    void Obstacle::setOrientation(RealVec const& orientation)
00154    {
00155       TG_ASSERT(MathUtil::isAlmostEq(1, orientation.length()));
00156 
00157       shape->setOrientation(orientation);
00158    }
00159 
00160    bool Obstacle::isTouching(Obstacle const& o) const
00161    {
00162       return shape->isTouching(*o.shape);
00163    }
00164 
00165    bool Obstacle::isColliding(Obstacle const& o) const
00166    {
00167       RealVec const& v0(getVelocity());
00168       RealVec const& v1(o.getVelocity());
00169       RealVec const n(normalTo(o));
00170 
00171       return isTouching(o) && v0.dot(n) > v1.dot(n);
00172    }
00173 
00174    RealVec Obstacle::nearestIntersection(RealVec const& p, RealVec const& v) const
00175    {
00176       return shape->nearestIntersection(p, v);
00177    }
00178 
00179    RealVec Obstacle::normalTo(Obstacle const& o) const
00180    {
00181       return shape->normalTo(*o.shape);
00182    }
00183 
00184    Real Obstacle::distanceTo(Obstacle const& o) const
00185    {
00186       return shape->distanceTo(*o.shape);
00187    }
00188 
00189    Real Obstacle::distanceSquaredTo(Obstacle const& o) const
00190    {
00191       return shape->distanceSquaredTo(*o.shape);
00192    }
00193 
00194    void Obstacle::setRenderer(RendererPtr renderer)
00195    {
00196       // Not all shapes need renderers
00197       if (renderer) { this->renderer = renderer; }
00198    }
00199 
00200    Shape const& Obstacle::getShape() const
00201    {
00202       return *shape;
00203    }
00204 
00205    RendererPtr Obstacle::getRenderer()
00206    {
00207       return renderer;
00208    }
00209 }
00210 
00211 #endif

Generated on Sat Mar 31 22:30:54 2007 for tagGame by  doxygen 1.5.1