Physics Simulation Forum

 

All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: Wed Apr 18, 2012 12:15 am 
Offline

Joined: Mon Apr 02, 2012 2:25 pm
Posts: 10
Hi everybody!

This is my problem: I'm currently developing a game were the AI's are using the btKinematicCharacterController of bullet. And my question is, has anybody implemented collision btKinematicCharacterControllers between btKinematicCharacterControllers??

thanks!!


Top
 Profile  
 
PostPosted: Fri Apr 20, 2012 3:12 pm 
Offline

Joined: Mon Apr 02, 2012 2:25 pm
Posts: 10
I detect my problem. I'm currently using the 'needBroadphaseCollision' method inherited from btOverlapfilterCallback. Well, some of my classes, were implementing it and of course, registering it with this sentence:

- _physicServer->getScene()->GetbtDiscreteDynamicWorld()->getPairCache()->setOverlapFilterCallback(this);


The problem is that you can only register one FilterCallback in bullet world. So now, I'm developing my own filter Callback that will dispatch all the collision to the desired entity. This can be done with polymorphism technics of C++.

ciao!

p.d.: If u are having troubles with this, ask me directly.


Top
 Profile  
 
PostPosted: Mon Apr 23, 2012 5:32 pm 
Offline

Joined: Fri Jun 24, 2011 8:53 am
Posts: 130
Interesting. Would you elaborate?


Top
 Profile  
 
PostPosted: Mon Apr 23, 2012 6:27 pm 
Offline

Joined: Mon Apr 02, 2012 2:25 pm
Posts: 10
Well, in bullet user manual, you could find this:
Filtering Collisions Using a Broadphase Filter Callback
One efficient way is to register a broadphase filter callback. This callback is called at a very early stage in the collision pipeline, and prevents collision pairs from being generated.

Code:
struct YourOwnFilterCallback : public btOverlapFilterCallback {
// return true when pairs need collision
virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const {
} };
bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);


//add some additional logic here that modified 'collides' return collides;
And then create an object of this class and register this callback using:

Code:
btOverlapFilterCallback * filterCallback = new YourOwnFilterCallback(); dynamicsWorld->getPairCache()->setOverlapFilterCallback(filterCallback);




I thought that you could register all the callback that you desire. Well, that's wrong thinking. You can only register ONE callback in bullet world.

Solution?: the one I mentioned above. Implementing your own broadPhaseCollision Dispatcher. I'm going to paste my code, but is specific of my game:


//PhysicFilterCallback.h
Code:
class PhysicFilterCallback : public btOverlapFilterCallback
{
public:
   
    PhysicFilterCallback();
    ~PhysicFilterCallback();
   
    // return true when pairs need collision
    virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
   
    void SetOverlapFilterCallback();
   
private:
    std::map<btCollisionObject *,int>           _objectsColliding;
   
    std::map<btCollisionObject *,int>::iterator _it;
   
    bool                                        _colCharacterTrigger;
    bool                                        _colCharacterCharacter;
};


//PhysicFilterCallback.cpp
Code:

PhysicFilterCallback::PhysicFilterCallback() : _colCharacterTrigger(false), _colCharacterCharacter(false)
{
   
}

PhysicFilterCallback::~PhysicFilterCallback()
{
    _objectsColliding.clear();
}


void PhysicFilterCallback::SetOverlapFilterCallback()
{
    //Registrando el callback en el mundo fisico de bullet.
    CServer::getSingletonPtr()->getScene()->GetbtDiscreteDynamicWorld()->getPairCache()->setOverlapFilterCallback(this);
}




bool PhysicFilterCallback::needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
{
    btCollisionObject* objTrigger = NULL;
    btCollisionObject* objCharacter0 = NULL;
    btCollisionObject* objCharacter1 = NULL;
   
    btBroadphaseProxy* proxyTrigger = NULL;
    btBroadphaseProxy* proxyChart0 = NULL;
    btBroadphaseProxy* proxyChart1 = NULL;
   
   
    //Colision entre trigger y character.
    if (proxy0->m_collisionFilterGroup == btBroadphaseProxy::CharacterFilter &&
        proxy1->m_collisionFilterGroup == btBroadphaseProxy::SensorTrigger)
    {
        objCharacter0 = (btCollisionObject*)proxy0->m_clientObject;
        proxyChart0 = proxy0;
        objTrigger = (btCollisionObject*)proxy1->m_clientObject;
        proxyTrigger = proxy1;
        _colCharacterTrigger = true;
    }
    else if (proxy1->m_collisionFilterGroup == btBroadphaseProxy::CharacterFilter &&
             proxy0->m_collisionFilterGroup == btBroadphaseProxy::SensorTrigger)
    {
        objCharacter0 = (btCollisionObject*)proxy1->m_clientObject;
        proxyChart0 = proxy1;
        objTrigger = (btCollisionObject*)proxy0->m_clientObject;
        proxyTrigger = proxy0;
        _colCharacterTrigger = true;
    }
    //Colsion entre character y character.
    else if (proxy1->m_collisionFilterGroup == btBroadphaseProxy::CharacterFilter &&
             proxy0->m_collisionFilterGroup == btBroadphaseProxy::CharacterFilter)
    {
        objCharacter0 = (btCollisionObject*)proxy0->m_clientObject;
        proxyChart0 = proxy0;
        objCharacter1 = (btCollisionObject*)proxy1->m_clientObject;
        proxyChart1 = proxy1;       
        _colCharacterCharacter = true;
    }
   
   
    if ( _colCharacterCharacter ) //Character -> Character
    {
        //Obteniendo la parte logica del character0.
        TActorInfo *infoChart0 = (TActorInfo *)(objCharacter0->getUserPointer());
        assert(infoChart0 != NULL && "No se ha encontrado UserData asociada al objetos fisico de bullet");
        Logic::CPhysicEntity *physicCharacter0 = reinterpret_cast<Logic::CPhysicEntity*> (infoChart0->pPhysicObj->userData);
        Logic::CEntity *logicCharacter0 = physicCharacter0->getEntity();

        TActorInfo *infoChart1 = (TActorInfo *)(objCharacter1->getUserPointer());
        assert(infoChart1 != NULL && "No se ha encontrado UserData asociada al objetos fisico de bullet");
        Logic::CPhysicEntity *physicCharacter1 = reinterpret_cast<Logic::CPhysicEntity*> (infoChart1->pPhysicObj->userData);
        Logic::CEntity *logicCharacter1 = physicCharacter1->getEntity();
       
        //Invocacion mediante polimorfismo.
       
    }
    else if ( _colCharacterTrigger ) //Character -> Trigger
    {
        //Obteniendo la parte logica del trigger.
        TActorInfo *infoTrigger = (TActorInfo *)(objTrigger->getUserPointer());
        assert(infoTrigger != NULL && "No se ha encontrado UserData asociada al objetos fisico de bullet");
        Logic::CManualTrigger *physicTrigger = reinterpret_cast<Logic::CManualTrigger*> (infoTrigger->pPhysicObj->userData);
        Logic::CEntity *logicTrigger = physicTrigger->getEntity();
       
        //Obteniendo la parte logica del character0.
        TActorInfo *infoChart0 = (TActorInfo *)(objCharacter0->getUserPointer());
        assert(infoChart0 != NULL && "No se ha encontrado UserData asociada al objetos fisico de bullet");
        Logic::CPhysicEntity *physicCharacter0 = reinterpret_cast<Logic::CPhysicEntity*> (infoChart0->pPhysicObj->userData);
        Logic::CEntity *logicCharacter0 = physicCharacter0->getEntity();
       
        //using polimorphysm.
        physicTrigger->needBroadphaseCollision(logicTrigger, proxyTrigger, logicCharacter0, proxyChart0);
    }
   
    _colCharacterCharacter = _colCharacterTrigger = false;
   
    return true;
}




I hope this can be useful.

ciao!


Top
 Profile  
 
PostPosted: Tue Apr 24, 2012 5:51 am 
Offline

Joined: Fri Jun 24, 2011 8:53 am
Posts: 130
Thank you very much for your very detailed answer. I was hoping at an overview at best.
So basically you're relying on reintepret_cast to cast the userData pointer to a base interface and then dispatch there.

I am rather currently using a different approach based on manifold inspection by a custom controller. The goal was to stay out of physics pipeline as much as possible.


Top
 Profile  
 
PostPosted: Tue Apr 24, 2012 9:34 am 
Offline

Joined: Mon Apr 02, 2012 2:25 pm
Posts: 10
Quote:
The goal was to stay out of physics pipeline as much as possible.


Yep, that's my goal too. This is the more lightly way I've found.

It works quite well.


ciao!!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group