Physics Simulation Forum

 

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: Mon Apr 02, 2012 2:44 pm 
Offline

Joined: Mon Apr 02, 2012 2:25 pm
Posts: 10
(collisions between btPairCachingGhostObject)

Hi everybody,

Me and my team are currently developing a game using bullet physics. The genre of the is basically a tower defense. Well, I'm trying to use characters controllers for IA purposes, because using only rigidBody makes unstable behavior between IA's and the world.
I thought in configure the world to avoid this penetrations between rigid bodies, etc.

But finally I decided to use the KinematicCharacterController class. It works fine, but this is my problem:

-Before I take this decision, I implemented triggers for the game purposes using btPairCachingGhostObject. This works like a charm when I was using ridigBodies, the behavior was the expected. But well, when I change the IA physic part from rigidBodies to characterController (it uses internally a btPairCachingGhostObject, too), the behavior wasn't the expected.

After this little introduction I ask now:
-Is the collision between btPairCachingGhostObject provided?

Basically I'm using the next methods to detect the collision when a body joins into the trigger:
Code:


//---------------------------------------------------------
void CManualTrigger::TriggerTick()
{
    btDiscreteDynamicsWorld* m_dynamicsWorld = CPhysicEngine::Ref().GetbtSoftDynamicWorld();
    //Retrives the content from all ghost objects in the world and call ProcessObectsInsideGhostObjects(...) for each.      
    if ( m_dynamicsWorld )
    {
        btAlignedObjectArray < btCollisionObject* > objsInsidePairCachingGhostObject;   // We might want this to be a member variable...                     
        btAlignedObjectArray < btCollisionObject* >* pObjsInsideGhostObject = NULL;      // We will store a reference of the current array in this pointer
        const btAlignedObjectArray < btCollisionObject* >& objs = m_dynamicsWorld->getCollisionObjectArray();   
        for (int i=0,sz=objs.size();i<sz;i++)   
        {
            btCollisionObject* o = objs[i];
            btGhostObject* go = btGhostObject::upcast(o);
            if (go)   
            {
                objsInsidePairCachingGhostObject.resize(0);
                btPairCachingGhostObject* pgo = dynamic_cast < btPairCachingGhostObject* > (go);   // No upcast functionality...
                if (pgo)   
                {
                    GetCollidingObjectsInsidePairCachingGhostObject(static_cast < btDiscreteDynamicsWorld* > (m_dynamicsWorld),pgo,objsInsidePairCachingGhostObject);
                    pObjsInsideGhostObject = &objsInsidePairCachingGhostObject;
                }
                else
                {
                    // It's better not to try and copy the whole array, but to keep a reference to it!
                    pObjsInsideGhostObject = &go->getOverlappingPairs();
                   
                    // Side Note: (at the moment) makes my program crash on my system...
                    //btAlignedObjectArray < btCollisionObject* > objs = go->getOverlappingPairs();
                    // Nevermind, that was the wrong way of doing it:
                    //btAlignedObjectArray < btCollisionObject* >& objs2 = go->getOverlappingPairs();
                    //is much better.
                }   
                // Here pObjsInsideGhostObject should be valid.   
                ProcessObectsInsideGhostObjects(*pObjsInsideGhostObject, pgo);
            }
        }   
    }
}




//---------------------------------------------------------
// This static method is useful for the demo only. It's called by "void GhostObjectsDemo::clientMoveAndDisplay()".
// Basically we must find a way to "display" the objects inside ghost objects to the user.
// We choose to apply a vertical impulse to them (just because it's easier).
// (The strength of the impulse is different depending on the type of ghost object)
void CManualTrigger::ProcessObectsInsideGhostObjects(btAlignedObjectArray < btCollisionObject* >& objs, const bool isPairCachingGhostObject)   
{
    //Primer paso: Comprobando colisiones e insertando los nuevos objetos que no estaban ya insertados en el mapa de colisiones.
    for (int j=0,jsz=objs.size();j<jsz;j++)
    {

        btPairCachingGhostObject* b = dynamic_cast < btPairCachingGhostObject* >(objs[j]);
        //This line was the original one, before I change by the line above.
        //btRigidBody* c = btRigidBody::upcast(objs[j]);
        if (b)
        {
            //Obtenemos la informacion que relaciona bullet con la logica (TActorInfo).
            TActorInfo *info = (TActorInfo *)b->getUserPointer();
            //Obtenemos el componente entidad fisica al que pertenece el rigidBody 'b'.
            CPhysicEntity *physicEntity = reinterpret_cast<CPhysicEntity*> (info->pPhysicObj->userData);
            //Obtenemos la entidad logica que contiene el componente anterior.
            CEntity *entityCollisioned = physicEntity->getEntity();
           
            if (entityCollisioned->getType() == "StuffedAnimal" ||  entityCollisioned->getType() == "Player")
            {               
                //Primero comprobamos que el objeto no conste ya en el mapa de objetos colisionados con el trigger.
                _it = _objectsColliding.find(b);
                if (_it == _objectsColliding.end())
                {
                    //Si no estuviera, lo insertamos.
                    _objectsColliding.insert(std::pair<btCollisionObject*,bool>(b, true));
                    //Y mandamos el mensaje oportuno.
                    //Dependiendo de la trampa, habrĂ¡ un comportamiento u otro.
                    doAction(entityCollisioned);
                }
            }
        }   
    }
    //Si hay algo en contacto con el trigger.
    if (objs.size() > 0)
    {
        //Segundo paso: Marcando en el mapa de colisiones los objetos que ya no esten colisionando con el trigger.
        for (_it = _objectsColliding.begin(); _it != _objectsColliding.end(); ++_it)
        {
            //Si la busqueda devuelve un entero igual al tamanyo del map objs, es que no se ha encontrado el elemento.
            if ( objs.findLinearSearch(_it->first) == objs.size() )
            {
                _it->second = false;
            }
        }
        //Tercer paso: Notificar a las entidades que ya no estan colisionando con el trigger con su correspondiente mensaje.
        notifyingOnExitEntities();
    }
}


//---------------------------------------------------------
// Portable static method: prerequisite call: m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
void CManualTrigger::GetCollidingObjectsInsidePairCachingGhostObject(btDiscreteDynamicsWorld* m_dynamicsWorld,
                                                                    btPairCachingGhostObject* m_pairCachingGhostObject,
                                                                    btAlignedObjectArray<btCollisionObject*>& collisionArrayOut)   
{
    collisionArrayOut.resize(0);
    if (!m_pairCachingGhostObject || !m_dynamicsWorld)
        return;
    // With "false" things don't change much, and the code is a bit faster and cleaner...
    const bool addOnlyObjectsWithNegativeDistance(true);   
   
    btBroadphasePairArray& collisionPairs = m_pairCachingGhostObject->getOverlappingPairCache()->getOverlappingPairArray();
    const int   numObjects=collisionPairs.size();   
    static btManifoldArray   m_manifoldArray;
    bool added;
    for(int i=0;i<numObjects;i++)   
    {
        m_manifoldArray.resize(0);
        added = false;
        for (int j=0;j<m_manifoldArray.size();j++)   
        {
            btPersistentManifold* manifold = m_manifoldArray[j];
            // Here we are in the narrowphase, but can happen that manifold->getNumContacts()==0:
            if (addOnlyObjectsWithNegativeDistance)   
            {
                for (int p=0,numContacts=manifold->getNumContacts();p<numContacts;p++)         
                {
                    const btManifoldPoint&pt = manifold->getContactPoint(p);
                    if (pt.getDistance() < 0.0)    
                    {
                        // How can I be sure that the colObjs are all distinct ? I use the "added" flag.
                        collisionArrayOut.push_back((btCollisionObject*) (manifold->getBody0() == m_pairCachingGhostObject ? manifold->getBody1() : manifold->getBody0()));
                        added = true;
                        break;
                    }   
                }
                if (added)
                    break;
            }
            else if (manifold->getNumContacts()>0)
            {
                collisionArrayOut.push_back((btCollisionObject*) (manifold->getBody0() == m_pairCachingGhostObject ? manifold->getBody1() : manifold->getBody0()));
                break;
            }
        }
    }   
}






So, Is this possible?, I mean, Can we detect collision between characters controllers (between GhostObjects)?. This would be useful too, to avoid the overlapping between two or more btKinematicCharacterControllers.

Thanks!


Last edited by Knn0N on Tue Apr 03, 2012 2:01 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Tue Apr 03, 2012 1:36 pm 
Offline

Joined: Mon Apr 02, 2012 2:25 pm
Posts: 10
Any ideas?!??!

Am I in a wrong way??

Should I change the functionality of my triggers??

thanks!


Top
 Profile  
 
PostPosted: Tue Apr 03, 2012 4:11 pm 
Offline

Joined: Tue Feb 20, 2007 4:56 pm
Posts: 205
You might want to go back to the main forum page and read the red text regarding this sub-forum.


Top
 Profile  
 
PostPosted: Tue Apr 03, 2012 4:24 pm 
Offline

Joined: Mon Apr 02, 2012 2:25 pm
Posts: 10
ops! :oops:

sorry. I've been moved to the right sub forum.


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 4 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