This is a legacy Trac instance left read-only for reference purposes. More info. dev main | home

Changeset 186

Show
Ignore:
Timestamp:
02/27/2010 09:37:52 PM (2 years ago)
Author:
mceier
Message:

Collision detection support

Signed-off-by: Mariusz Ceier <mceier@gmail.com>

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/include/waterworld/sim2/Animat.h

    r185 r186  
    5959                 */ 
    6060                boost::intrusive_ptr<PhysicalBody> m_body; 
    61                 /** 
    62                  * Pointer to a function called on collision detect 
    63                  */ 
    64                 void (*collision)(); 
    65                 /** 
    66                  * On/Off collision detection for this body/animat 
    67                  */ 
    68                 bool cde;       //CollisiondDetectionEnabled 
    6961                /** 
    7062                 * True if collisions are enabled ... 
     
    7264                bool m_enabled_collisions; 
    7365        public: 
    74                 /** 
    75                  * \Set a pointer to a function called on collision detect 
    76                  */ 
    77                 void setCollisionFunction(void (*)()); 
    78  
    79                 /** 
    80                  * \Get a pointer to a function called on collision detect 
    81                  */ 
    82                 void* getCollisionFunction(); 
    83  
    84                 /** 
    85                  * \Set on/of collision detectcion 
    86                  */ 
    87                 void setCollisionEnabled(bool); 
    88  
    89                 /** 
    90                  * \Get on/of collision detect 
    91                  */ 
    92                 bool isCollisionEnabled(); 
    93  
    9466                /** 
    9567                 * \return constant chemical signals that this animat "emits" ( read-only ) 
     
    143115                 * Enable collisions - use getContactPoints method to access collision points 
    144116                 */ 
    145                 void enableCollisions(); 
     117                void enableCollisions(boost::intrusive_ptr<World> world); 
    146118                /** 
    147119                 * Disable collisions 
    148120                 */ 
    149                 void disableCollisions(); 
     121                void disableCollisions(boost::intrusive_ptr<World> world); 
    150122                /** 
    151123                 * \return True if detection of collisions for this animat is enabled 
  • trunk/include/waterworld/sim2/CollisionSensor.h

    r185 r186  
    1212 
    1313#include "Sensor.h" 
     14#include "ContactPoint.h" 
    1415 
    1516namespace waterworld 
     
    3132                 */ 
    3233                virtual void onCollision(boost::intrusive_ptr<Animat> animat1, 
    33                         boost::intrusive_ptr<Animat> animat2, 
    34                         Position contactPoint, 
     34                        ContactPoint const &contactPoint, 
    3535                        boost::intrusive_ptr<World> world, 
    3636                        real_t dt) = 0; 
  • trunk/include/waterworld/sim2/ContactPoint.h

    r185 r186  
    2020        { 
    2121                boost::intrusive_ptr<Animat> m_animat; 
    22                 Position m_contact_point; 
     22                Position m_contact_position; 
     23                vec3r m_contact_normal; 
    2324        public: 
    2425                /** 
    2526                 * \param animat Colliding animat 
    26                  * \param contactPoint Contact point 
     27                 * \param contactPosition Contact position 
     28                 * \param contactNormal Contact normal 
    2729                 */ 
    2830                ContactPoint(boost::intrusive_ptr<Animat> animat,  
    29                         Position contactPoint); 
     31                        Position contactPosition, 
     32                        vec3r contactNormal); 
    3033                ContactPoint(ContactPoint const &cp); 
    3134                ContactPoint &operator=(ContactPoint const &cp); 
     
    3538                boost::intrusive_ptr<Animat> getCollidingAnimat() const; 
    3639                /** 
    37                  * \return Contact point 
     40                 * \return Contact position 
    3841                 */ 
    39                 Position getContactPoint() const; 
     42                Position getContactPosition() const; 
     43                /** 
     44                 * \return Contact normal 
     45                 */ 
     46                vec3r getContactNormal() const; 
    4047                virtual ~ContactPoint(); 
    4148        }; 
  • trunk/include/waterworld/sim2/ContactPoints.h

    r185 r186  
    33 
    44#include "ContactPoint.h" 
    5 #include <boost/smart_ptr.hpp> 
    65#include <vector> 
    76 
     
    1110         * List of contact points 
    1211         */ 
    13         typedef std::vector<boost::intrusive_ptr<ContactPoint> > ContactPoints; 
     12        typedef std::vector<ContactPoint> ContactPoints; 
    1413} 
    1514 
  • trunk/include/waterworld/sim2/Types.h

    r175 r186  
    3333 
    3434        /** 
     35         * Create Vec3 
     36         */ 
     37        template<typename T> 
     38        inline boost::numeric::ublas::bounded_vector<T,3> makeVec3(T x,T y,T z) 
     39        { 
     40                boost::numeric::ublas::bounded_vector<T,3> tmp; 
     41                tmp(0) = x; 
     42                tmp(1) = y; 
     43                tmp(2) = z; 
     44                return tmp; 
     45        } 
     46 
     47        /** 
    3548         * Create force 
    3649         */ 
  • trunk/include/waterworld/sim2/World.h

    r182 r186  
    1515#include <boost/thread.hpp> 
    1616 
     17/** 
     18 * PAL classes 
     19 */ 
     20class palPhysics; 
     21class palCollisionDetection; 
     22 
    1723namespace waterworld 
    1824{ 
     
    3036                void stopEventsThread(); 
    3137                void step(real_t dt); 
     38                palPhysics *getPhysics() const; 
     39                palCollisionDetection *getCollisionDetection() const; 
    3240                boost::intrusive_ptr<PhysicalBody> createAnimatsBody( 
    3341                        boost::intrusive_ptr<Animat> animat, 
  • trunk/src/CMakeLists.txt

    r175 r186  
    1919                QuitEventHandler.cpp) 
    2020        TARGET_LINK_LIBRARIES(WaterWorld3 ${WATERWORLD_LIBRARY} ${WATERWORLD_LIBRARIES}) 
     21        ADD_EXECUTABLE(WaterWorld5 
     22                waterworld5.cpp  
     23                SerializeEventHandler.cpp 
     24                QuitEventHandler.cpp) 
     25        TARGET_LINK_LIBRARIES(WaterWorld5 ${WATERWORLD_LIBRARY} ${WATERWORLD_LIBRARIES}) 
    2126ELSE(USE_SIM2) 
    2227        ADD_EXECUTABLE(WaterWorld2 waterworld2.cpp) 
  • trunk/src/waterworld/sim2/Animat.cpp

    r185 r186  
    11#include <waterworld/sim2/Animat.h> 
     2#include <pal/palCollision.h> 
    23 
    34namespace waterworld 
     
    5152        { 
    5253        } 
    53  
    54         void Animat::setCollisionFunction(void ptr()) 
    55         { 
    56             collision = ptr; 
    57         } 
    58  
    59         void* Animat::getCollisionFunction() 
    60         { 
    61             return (void*)collision; 
    62         } 
    63  
    64         void Animat::setCollisionEnabled(bool e) 
    65         { 
    66             cde = e; 
    67         } 
    68  
    69         bool Animat::isCollisionEnabled() 
    70         { 
    71             return cde; 
    72         } 
    7354 
    7455        ChemicalSignals const &Animat::getChemicalSignals() const 
     
    133114        void Animat::setPhysicalBody(boost::intrusive_ptr<PhysicalBody> newBody) 
    134115        { 
     116                if (m_body!=newBody) 
     117                        m_enabled_collisions = false; 
    135118                m_body = newBody; 
    136119        } 
    137120 
    138         void Animat::enableCollisions(
     121        void Animat::enableCollisions(boost::intrusive_ptr<World> world
    139122        { 
    140                 m_enabled_collisions = true; 
     123                if ((getPhysicalBody())&&(getPhysicalBody()->getBody())) 
     124                { 
     125                        palCollisionDetection *pcd = world->getCollisionDetection(); 
     126                        if(pcd) 
     127                        { 
     128                                pcd->NotifyCollision(getPhysicalBody()->getBody(),true);        //enable collision detection for the body 
     129                                m_enabled_collisions = true; 
     130                        } 
     131                } 
    141132        } 
    142133 
    143         void Animat::disableCollisions(
     134        void Animat::disableCollisions(boost::intrusive_ptr<World> world
    144135        { 
    145                 m_enabled_collisions = false; 
     136                if ((getPhysicalBody())&&(getPhysicalBody()->getBody())) 
     137                { 
     138                        palCollisionDetection *pcd = world->getCollisionDetection(); 
     139                        if(pcd) 
     140                        { 
     141                                pcd->NotifyCollision(getPhysicalBody()->getBody(),false);        //disable collision detection for the body 
     142                                m_enabled_collisions = false; 
     143                        } 
     144                } 
    146145        } 
    147146 
     
    157156        void Animat::update(boost::intrusive_ptr<World> world, real_t dt) 
    158157        { 
     158                m_contact_points.clear(); 
     159                if (hasEnabledCollisions()) 
     160                { 
     161                        palContact contacts; 
     162                        world->getCollisionDetection()->GetContacts(getPhysicalBody()->getBody(),contacts); 
     163                        m_contact_points.reserve(contacts.m_ContactPoints.size()); 
     164                        for(PAL_VECTOR<palContactPoint>::iterator i=contacts.m_ContactPoints.begin(); 
     165                                i!=contacts.m_ContactPoints.end();++i) 
     166                        { 
     167                                m_contact_points.push_back(ContactPoint(((PhysicalBody*)i->m_pBody1->GetUserData())->getAnimat(), 
     168                                        makePosition(i->m_vContactPosition[0],i->m_vContactPosition[1],i->m_vContactPosition[2]), 
     169                                        makeVec3(i->m_vContactNormal[0], i->m_vContactNormal[1],i->m_vContactNormal[2]))); 
     170                        } 
     171                } 
    159172                for(Sensors::iterator i=m_sensors.begin();i!=m_sensors.end();++i) 
    160173                        (*i)->update(this, world, dt); 
  • trunk/src/waterworld/sim2/CollisionSensor.cpp

    r185 r186  
    2828                        ContactPoints cp(animat->getContactPoints()); 
    2929                        for(ContactPoints::iterator i=cp.begin();i!=cp.end();++i) 
    30                                 onCollision(animat,(*i)->getCollidingAnimat(),(*i)->getContactPoint(),world,dt); 
     30                                onCollision(animat,*i,world,dt); 
    3131                } 
    3232        } 
  • trunk/src/waterworld/sim2/ContactPoint.cpp

    r185 r186  
    55 
    66        ContactPoint::ContactPoint(boost::intrusive_ptr<Animat> animat, 
    7                 Position contactPoint) : 
    8                 m_animat(animat), m_contact_point(contactPoint) 
     7                Position contactPosition, 
     8                vec3r contactNormal) : 
     9                m_animat(animat), 
     10                m_contact_position(contactPosition), 
     11                m_contact_normal(contactNormal) 
    912        { 
    1013        } 
     
    1316                IntrusivePtrBase(cp), 
    1417                m_animat(cp.m_animat), 
    15                 m_contact_point(cp.m_contact_point) 
     18                m_contact_position(cp.m_contact_position), 
     19                m_contact_normal(cp.m_contact_normal) 
    1620        { 
     21        } 
     22 
     23        ContactPoint &ContactPoint::operator=(ContactPoint const &cp) 
     24        { 
     25                if(this!=&cp) 
     26                { 
     27                        m_animat = cp.m_animat; 
     28                        m_contact_position = cp.m_contact_position; 
     29                        m_contact_normal = cp.m_contact_normal; 
     30                } 
     31                return *this; 
    1732        } 
    1833 
     
    2237        } 
    2338 
    24         Position ContactPoint::getContactPoint() const 
     39        Position ContactPoint::getContactPosition() const 
    2540        { 
    26                 return m_contact_point; 
     41                return m_contact_position; 
     42        } 
     43 
     44        vec3r ContactPoint::getContactNormal() const 
     45        { 
     46                return m_contact_normal; 
    2747        } 
    2848 
  • trunk/src/waterworld/sim2/World.cpp

    r184 r186  
    99        namespace 
    1010        { 
     11                /* TODO: Put this code in separate class */ 
    1112                static palPhysics *g_physics = NULL; 
    12                 static palCollisionDetection *pcd = NULL; 
     13                static palCollisionDetection *g_pcd = NULL; 
    1314 
    1415                static void initPhysics() 
     
    2122                        if (g_physics) 
    2223                        { 
    23                                 pcd = dynamic_cast<palCollisionDetection *>(g_physics); 
     24                                g_pcd = dynamic_cast<palCollisionDetection *>(g_physics); 
    2425                                palPhysicsDesc tmpDesc; 
    2526                                tmpDesc.m_vGravity[0] = palPhysicsDesc::DEFAULT_GRAVITY_X; 
     
    3536                        // PF->SetActivePhysics(g_physics); // Does not work 
    3637                        return g_physics; 
     38                } 
     39 
     40                static palCollisionDetection *getCollisionDetection() 
     41                { 
     42                        return g_pcd; 
    3743                } 
    3844        } 
     
    5662        void World::step(real_t dt) 
    5763        { 
    58                 for(Animats::iterator i=m_animats.begin();i!=m_animats.end();++i) 
    59                 { 
     64                Animats animats(m_animats); 
     65                for(Animats::iterator i=animats.begin();i!=animats.end();++i) 
    6066                        (*i)->update(this, dt); 
    61  
    62                         if((*i)->isCollisionEnabled()) 
    63                         { 
    64                             palContact contact; 
    65                             pcd->GetContacts((palBodyBase *)(*i)->getPhysicalBody()->getBody(),contact); 
    66                         } 
    67                 } 
    6867                palPhysics *tmp = getPhysics(); 
    6968                if (tmp!=NULL) 
     
    9190        } 
    9291 
     92        palPhysics *World::getPhysics() const 
     93        { 
     94                return waterworld::getPhysics(); 
     95        } 
     96 
     97        palCollisionDetection *World::getCollisionDetection() const 
     98        { 
     99                return waterworld::getCollisionDetection(); 
     100        } 
     101 
    93102        boost::intrusive_ptr<PhysicalBody> World::createAnimatsBody( 
    94103                boost::intrusive_ptr<Animat> animat, 
     
    100109                body->setBody(sphere); 
    101110                animat->setPhysicalBody(body); 
    102  
    103                 if(pcd)pcd->NotifyCollision((palBodyBase *) sphere,true);        //enable collision detection for the body 
    104  
    105111                return body; 
    106112        } 
  • trunk/src/waterworld4.cpp

    r179 r186  
    11#include <waterworld/sim2/World.h> 
     2#include <waterworld/sim2/CollisionSensor.h> 
    23#include <gui2/Application.h> 
    34#include "EventTypes.h" 
     
    2930                setForce(20.0*makeForce(cos(m_alpha), sin(m_alpha), 0)); 
    3031                //cout << "updating force: alpha = " << m_alpha << endl; 
     32        } 
     33}; 
     34 
     35class MyCollSensor : public waterworld::CollisionSensor 
     36{ 
     37public: 
     38        void onCollision(boost::intrusive_ptr<waterworld::Animat> animat, 
     39                waterworld::ContactPoint const &cp, 
     40                boost::intrusive_ptr<waterworld::World> world, 
     41                waterworld::real_t dt) 
     42        { 
     43                using namespace std; 
     44                using namespace waterworld; 
     45                Position p(cp.getContactPosition()); 
     46                cout << "Collision at: " << p(0) << ',' << p(1) << ',' << p(2) << endl; 
     47                cout << "ID1: " << animat->getID() << ' ' << "ID2: " << cp.getCollidingAnimat()->getID() << endl; 
     48                world->getAnimats().erase(cp.getCollidingAnimat()); 
    3149        } 
    3250}; 
     
    7492        animat4->getActuators().push_back(new Actuator(makeForce(0.0,-0.1*palPhysicsDesc::DEFAULT_GRAVITY_Y,0.0), makePosition(0,0,0))); 
    7593        myWorld->getAnimats().insert(animat4); 
     94 
     95        animat->enableCollisions(myWorld); 
     96        animat->getSensors().push_back(new MyCollSensor()); 
     97 
    7698        gui::Application app(myWorld); 
    7799        quit=!app.init(640,480,16); 
  • trunk/src/waterworld5.cpp

    r179 r186  
    11#include <waterworld/sim2/World.h> 
    2 #include <gui2/Application.h> 
     2#include <waterworld/sim2/CollisionSensor.h> 
    33#include "EventTypes.h" 
    44#include "SerializeEventHandler.h" 
     
    77#include <iostream> 
    88#include <pal/palFactory.h> 
    9 #include <cmath> 
    109 
    11 class SimpleActuator : public waterworld::Actuator 
     10class MyCollSensor : public waterworld::CollisionSensor 
    1211{ 
    13         waterworld::real_t m_alpha; 
    14         waterworld::real_t m_omega; 
    1512public: 
    16         SimpleActuator(waterworld::real_t current, waterworld::real_t omega) :  
    17                 waterworld::Actuator(waterworld::makeForce(0.002,0,0),  
    18                         waterworld::makePosition(0,0,0)), 
    19                 m_alpha(current), m_omega(omega) 
    20         { 
    21         } 
    22         void update(boost::intrusive_ptr<waterworld::Animat> animat,  
    23                 boost::intrusive_ptr<waterworld::World> world,  
     13        void onCollision(boost::intrusive_ptr<waterworld::Animat> animat, 
     14                waterworld::ContactPoint const &cp, 
     15                boost::intrusive_ptr<waterworld::World> world, 
    2416                waterworld::real_t dt) 
    2517        { 
     18                using namespace std; 
    2619                using namespace waterworld; 
    27                 using namespace std
    28                 m_alpha += m_omega*dt
    29                 setForce(20.0*makeForce(cos(m_alpha), sin(m_alpha), 0))
    30                 //cout << "updating force: alpha = " << m_alpha << endl
     20                Position p(cp.getContactPosition())
     21                cout << "Collision at: " << p(0) << ',' << p(1) << ',' << p(2) << endl
     22                cout << "ID1: " << animat->getID() << ' ' << "ID2: " << cp.getCollidingAnimat()->getID() << endl
     23                world->getAnimats().erase(cp.getCollidingAnimat())
    3124        } 
    3225}; 
     
    7467        animat4->getActuators().push_back(new Actuator(makeForce(0.0,-0.1*palPhysicsDesc::DEFAULT_GRAVITY_Y,0.0), makePosition(0,0,0))); 
    7568        myWorld->getAnimats().insert(animat4); 
    76         gui::Application app(myWorld); 
    77         quit=!app.init(640,480,16); 
     69        animat->enableCollisions(myWorld); 
     70        animat->getSensors().push_back(new MyCollSensor()); 
    7871        while(!quit) 
    7972        { 
    8073                for(unsigned int i=0;(!quit) && (i<100);++i) 
    81                 { 
    8274                        myWorld->step(0.001); 
    83                         app.draw(); 
    84                 } 
    8575                myWorld->getEventsQueue()->addEvent(new Event(SerializeEventType)); 
    8676        }