00001 #ifndef COLLIDE_OPERATOR
00002 #define COLLIDE_OPERATOR
00003 #include <vector>
00004 #include <ani/Dynamics/Operator.h>
00005 #include <ani/Dynamics/DynamicSystem.h>
00006 #include <gator/Collision.h>
00007 #include <gator/PlaneCollisionDetector.h>
00008
00009 namespace gator
00010 {
00018 class CollisionResponseOperator : public ani::Operator<ani::Body>
00019 {
00020 public:
00021 typedef boost::shared_ptr<ani::Body> EntityTypePtr;
00022
00023 public:
00024
00025 CollisionResponseOperator() : ani::Operator<ani::Body>(),
00026 mFrictionCoef( 0.0f ), mElasticCoef( 1.0f )
00027 {
00028 }
00029
00030
00031 virtual ~CollisionResponseOperator()
00032 {
00033 }
00034
00036 void setElastic( float e )
00037 {
00038 mElasticCoef = e;
00039 }
00040
00042 void setFriction( float f )
00043 {
00044 mFrictionCoef = f;
00045 }
00046
00047 virtual void exec( ani::DynamicSystem<ani::Body>& ps, float timeDelta )
00048 {
00049 std::vector<EntityTypePtr>& entities = ps.entities();
00050 std::vector<EntityTypePtr>::iterator it;
00051
00052 for (it = entities.begin(); it != entities.end(); ++it)
00053 {
00054 ani::Body& p = *(*it);
00055 gmtl::Vec3f incomingVector = p.linearVelocity();
00056
00057
00058 gmtl::Vec3f polygonNormal;
00059 float dist;
00060 bool collision_happened = mCollisionDetector->exec( p, dist, polygonNormal );
00061
00062
00063 if (collision_happened)
00064 {
00065 gmtl::Vec3f frictionForce, normalForce;
00066 computeCollisionForces( polygonNormal, incomingVector, mElasticCoef, mFrictionCoef, p.mass(), timeDelta, frictionForce, normalForce );
00067
00068
00069 p.applyForce( normalForce );
00070 p.applyForce( frictionForce );
00071
00072
00073 p.setPosition( p.position() + polygonNormal * (-dist) );
00074 }
00075 }
00076 }
00077
00082 virtual void setCollisionDetector( CollisionDetectorPtr detect )
00083 {
00084 mCollisionDetector = detect;
00085 }
00086
00087 private:
00088 float mFrictionCoef;
00089 float mElasticCoef;
00090 CollisionDetectorPtr mCollisionDetector;
00091 };
00092 }
00093
00094 #endif