Triggers and game feedback
-
- Posts: 2
- Joined: Sat Dec 06, 2008 9:54 pm
Triggers and game feedback
Hey guys
Quick question about implementing triggers...
In previous games I've worked on triggers always track objects when they enter and when they leave a trigger. This was done using callbacks that notified of object to object collisions. Easy enough.
I can't figure out how to get that same behavior using the Bullet library. The only callbacks that looked remotely useful (gContactAddedCallback, gContactProcessedCallback, and gContactDestroyedCallback) are all per CONTACT point and thus get called many, many times. I'm probably not understanding how to use them correctly (as there is no documentation on them) but it seems the contact destroyed callback is basically worthless. Finally, I am reluctant to do anything that requires me to check per tick the status of these objects. It seems pointless to have callbacks only to fallback on checking per tick (defeats the purpose of the callback...).
I found a few useful posts on the forums but nothing that gave a good solution to it that I could find. It seems like a common enough problem so how have people solved this?
Thanks!
Quick question about implementing triggers...
In previous games I've worked on triggers always track objects when they enter and when they leave a trigger. This was done using callbacks that notified of object to object collisions. Easy enough.
I can't figure out how to get that same behavior using the Bullet library. The only callbacks that looked remotely useful (gContactAddedCallback, gContactProcessedCallback, and gContactDestroyedCallback) are all per CONTACT point and thus get called many, many times. I'm probably not understanding how to use them correctly (as there is no documentation on them) but it seems the contact destroyed callback is basically worthless. Finally, I am reluctant to do anything that requires me to check per tick the status of these objects. It seems pointless to have callbacks only to fallback on checking per tick (defeats the purpose of the callback...).
I found a few useful posts on the forums but nothing that gave a good solution to it that I could find. It seems like a common enough problem so how have people solved this?
Thanks!
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: Triggers and game feedback
There are many ways to retrieve collision information. The best way is to simply iterate over all contact manifolds, and check if there are contact points.
You don't need to iterate over all pairs of objects, you can use a btGhostObject. See http://www.bulletphysics.com/mediawiki- ... d_Triggers
Hope this helps,
Erwin
You don't need to iterate over all pairs of objects, you can use a btGhostObject. See http://www.bulletphysics.com/mediawiki- ... d_Triggers
Hope this helps,
Erwin
-
- Posts: 2
- Joined: Sat Dec 06, 2008 9:54 pm
Re: Triggers and game feedback
That was the latest thing I've tried and it gives decent results but isn't always accurate.
I get the trigger activations consistently but if my objects exit their collisions too quickly, I miss the deactivation. Could this be a timing issue or something?
Thanks!
Code: Select all
void CollisionManager::OnInternalTickCallback( btScalar timeStep )
{
int numManifolds = m_pDispatcher->getNumManifolds( );
for( int i = 0; i < numManifolds; i++ )
{
btPersistentManifold* contactManifold = m_pDispatcher->getManifoldByIndexInternal(i);
if( contactManifold->getNumContacts( ) > 0 )
{
... Activate triggers here
}
else
{
... Deactivate trigger here
}
}
}
Thanks!
-
- Posts: 79
- Joined: Tue Sep 26, 2006 1:10 pm
Re: Triggers and game feedback
Hi,
I am trying to implement triggers with bullet and thought I might as well ask in this thread as jp_bt seems to have some experience with ghostobjects. I haven't quite figured out how to use the ghostobjects to make them tell me about a collision. Here is the code I use:
It is the last part I am not sure about. As I said is taking from the article that briefly mentions triggers. Do I have the Callback interface as the KinematicCharacter does instead?
I would be thankful if anyone could point me in the right direction here!
(Another question entirely: did anyone notice a change of physics behavior going from 2.72 to 2.73 making it seem more "nervous"?)
I am trying to implement triggers with bullet and thought I might as well ask in this thread as jp_bt seems to have some experience with ghostobjects. I haven't quite figured out how to use the ghostobjects to make them tell me about a collision. Here is the code I use:
Code: Select all
//somewhere during initialization-----------------------------------
m_broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
//----------------------------------------------------------------
//adding a trigger-------------------------------------------------
btPairCachingGhostObject *trigger = new btPairCachingGhostObject();
//both transform and shape are filled with something meaningful
trigger->setWorldTransform(transform);
trigger->setCollisionShape(shape);
trigger->setCollisionFlags(btCollisionObject::CF_NO_CONTACT_RESPONSE);
m_dynamicsWorld->addCollisionObject(trigger, btBroadphaseProxy::SensorTrigger);
m_triggers.push_back(trigger);
//----------------------------------------------------------------
//trying to get some feedback from the trigger, every frame or so----
//this is taken almost without change from http://www.bulletphysics.com/mediawiki-1.5.8/index.php?title=Collision_Callbacks_and_Triggers
for (size_t i = 0; i < m_triggers.size(); ++i)
{
btPairCachingGhostObject *ghostObject = m_triggers[i];
btManifoldArray manifoldArray;
for (int i = 0; i < ghostObject->getOverlappingPairCache()->getNumOverlappingPairs(); i++)
{
manifoldArray.resize(0);
btBroadphasePair* collisionPair = &ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
if (collisionPair->m_algorithm)
collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
for (int j=0;j<manifoldArray.size();j++)
{
btPersistentManifold* manifold = manifoldArray[j];
btScalar directionSign = manifold->getBody0() == ghostObject ? btScalar(-1.0) : btScalar(1.0);
for (int p=0;p<manifold->getNumContacts();p++)
{
const btManifoldPoint&pt = manifold->getContactPoint(p);
if (pt.getDistance()<0.f)
{
//a breakpoint here will never be reached ;(
const btVector3& ptA = pt.getPositionWorldOnA();
const btVector3& ptB = pt.getPositionWorldOnB();
const btVector3& normalOnB = pt.m_normalWorldOnB;
}
}
}
}
}
//----------------------------------------------------------------
I would be thankful if anyone could point me in the right direction here!
(Another question entirely: did anyone notice a change of physics behavior going from 2.72 to 2.73 making it seem more "nervous"?)
Last edited by B_old on Thu Dec 18, 2008 11:14 am, edited 1 time in total.
-
- Posts: 508
- Joined: Fri May 30, 2008 2:51 am
- Location: Ossining, New York
Re: Triggers and game feedback
Now that you mention it, I was watching a cube bounce around rather more animatedly than I'm sure they used to. It was a small cube though(.3,.3,.3) so i dismissed it at the time.B_old wrote: (Another question entirely: did anyone notice a change of physics behavior going from 2.72 to 2.73 making it seem more "nervous"?)
-
- Posts: 16
- Joined: Thu May 29, 2008 10:47 am
Re: Triggers and game feedback
2B_old
Here is mistake (this code is from wiki, I think):
Shoud be (from CharacterDemo):
Difference in that we need to get algorithm pointer from broadphase pair, not from ghostobject pair. Pair in ghostobject contains only information about two proxies, m_algorithm is always equal to 0. I don't know why, maybe it's a bug.
Here is mistake (this code is from wiki, I think):
Code: Select all
btBroadphasePair* collisionPair = &ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
if (collisionPair->m_algorithm)
collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
Code: Select all
btManifoldArray manifoldArray;
btBroadphasePairArray& pairArray = m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray();
int numPairs = pairArray.size();
for (int i=0;i<numPairs;i++)
{
manifoldArray.clear();
const btBroadphasePair& pair = pairArray[i];
btBroadphasePair* collisionPair = m_overlappingPairCache->getOverlappingPairCache()->findPair(pair.m_pProxy0,pair.m_pProxy1);
if (!collisionPair)
continue;
if (collisionPair->m_algorithm)
collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
for (int j=0;j<manifoldArray.size();j++)
{
btPersistentManifold* manifold = manifoldArray[j];
for (int p=0;p<manifold->getNumContacts();p++)
{
const btManifoldPoint&pt = manifold->getContactPoint(p);
/// work here
}
}
}
}
-
- Posts: 79
- Joined: Tue Sep 26, 2006 1:10 pm
Re: Triggers and game feedback
Mirat:
Thanks for the help! It now works the way I want it. Isn't there a callback function though, that can tell you when new contacts have been added. Do you think that this would be more efficient? Maybe I will look into that.
But right now I am happy about the working solution. Thanks again!
Thanks for the help! It now works the way I want it. Isn't there a callback function though, that can tell you when new contacts have been added. Do you think that this would be more efficient? Maybe I will look into that.
But right now I am happy about the working solution. Thanks again!
-
- Posts: 5
- Joined: Fri Jan 02, 2009 1:56 pm
Re: Triggers and game feedback
I've just started using Bullet in the last two days and need a bit of guidance on the best way to approach the following:
I'm trying to simulate 'sticky' balls similar to another thread on this forum however I trying to use a gravitational field around each so that they clump around static objects as well as around themselves.
After reading this post I decided to try and represent the grav fields as ghost objects and balls as dynamic rigid bodies.
Starting with an easy question..
I'm keeping two lists, one of the balls and another of corresponding grav ghosts and manually updating the ghost positions each cycle using the ball motion states.
Is there a better way of attaching the ghosts to the rigid bodies?
My main question is how to filter and check collisions correctly as I’m having problems picking up the ghost collisions.
When a grav ghost comes into contact with another grav ghost or with a static object then I need to do stuff so ...
I'm creating static objects like this, so that they collide with kinematic and sensor triggers
and ball objects with grav ghosts like this...(apologies for bad naming, I'm not a programmer)
My ghost collision pair detection is similar to the snippets on this thread however currently I'm not even getting a single pair.
Any help would be much appreciated.
Thanks
I'm trying to simulate 'sticky' balls similar to another thread on this forum however I trying to use a gravitational field around each so that they clump around static objects as well as around themselves.
After reading this post I decided to try and represent the grav fields as ghost objects and balls as dynamic rigid bodies.
Starting with an easy question..
I'm keeping two lists, one of the balls and another of corresponding grav ghosts and manually updating the ghost positions each cycle using the ball motion states.
Is there a better way of attaching the ghosts to the rigid bodies?
My main question is how to filter and check collisions correctly as I’m having problems picking up the ghost collisions.
When a grav ghost comes into contact with another grav ghost or with a static object then I need to do stuff so ...
I'm creating static objects like this, so that they collide with kinematic and sensor triggers
Code: Select all
m_seedbody = CreateRigidBody(0.0f, startTransform,m_trimeshShape,btBroadphaseProxy::StaticFilter,btBroadphaseProxy::KinematicFilter | btBroadphaseProxy::SensorTrigger);
Code: Select all
btRigidBody* CDemo::CreateSphereObj(btVector3& pos,float rad)
{
btCollisionShape* pshape = new btSphereShape(rad);
m_shapes.push_back(pshape);
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(pos);
float mass = BALLDENS*1.333f*M_PI*rad*rad*rad;
//collides with kinematic and static objects
btRigidBody* body = this->CreateRigidBody(mass, startTransform,pshape, btBroadphaseProxy::KinematicFilter,btBroadphaseProxy::KinematicFilter | btBroadphaseProxy::StaticFilter );
m_spheres.push_back(body);
btCollisionShape* pshape2 = new btSphereShape(rad*GRAVINF);
m_shapes.push_back(pshape2);
btPairCachingGhostObject* field = new btPairCachingGhostObject();
field->setWorldTransform(startTransform);
field->setCollisionShape(pshape2);
//collides with other sensors and static objects
m_dynamicsWorld->addCollisionObject(field, btBroadphaseProxy::SensorTrigger,btBroadphaseProxy::SensorTrigger | btBroadphaseProxy::StaticFilter);
//not sure what the following line does but it currently doesnt make any difference
//field->setCollisionFlags(btCollisionObject::CF_NO_CONTACT_RESPONSE);
m_fields.push_back(field);
return body;
}
Code: Select all
void CDemo::ProcessContacts()
{
for (int f=0;f<m_fields.size();f++)
{
btPairCachingGhostObject* field = m_fields[f];
btManifoldArray manifoldArray;
btBroadphasePairArray& pairArray = field->getOverlappingPairCache()->getOverlappingPairArray();
int numPairs = pairArray.size();
for (int i=0;i<numPairs;i++)
{
//not getting here
manifoldArray.clear();
const btBroadphasePair& pair = pairArray[i];
btBroadphasePair* collisionPair = m_broadphase->getOverlappingPairCache()->findPair(pair.m_pProxy0,pair.m_pProxy1);
if (!collisionPair)
continue;
//.........
}
}
}
Thanks
-
- Posts: 5
- Joined: Fri Jan 02, 2009 1:56 pm
Re: Triggers and game feedback
Sorted!
I forgot to add....
...after the ghost creation.
Works a dream, thanks Erwin.
I forgot to add....
Code: Select all
m_broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
Works a dream, thanks Erwin.
-
- Posts: 2
- Joined: Tue Jan 13, 2009 9:27 am
Re: Triggers and game feedback
I don't know if this is the same thing you're talking about, but I noticed the BasicDemo cubes were much more jittery when in their rest state than previously. (Noticeably so, particularly if you zoom the camera in a little.)(Another question entirely: did anyone notice a change of physics behavior going from 2.72 to 2.73 making it seem more "nervous"?)
However when I dug into it, it turned out that in the 2.73 demo the cubes had been scaled down by a factor of 10 -- see the SCALING define at the top of BasicDemo.cpp. If you make the same change to the 2.72 demo, you see very similar behaviour. So it's not a simulation engine regression in this case.
-
- Posts: 79
- Joined: Tue Sep 26, 2006 1:10 pm
Re: Triggers and game feedback
Hm. I noticed different behavior in my own application and did not change the scale of anything. Maybe there is something else that I forgot and is important in 2.73. Don't kow...AndrewWillmott wrote: I don't know if this is the same thing you're talking about, but I noticed the BasicDemo cubes were much more jittery when in their rest state than previously. (Noticeably so, particularly if you zoom the camera in a little.)
However when I dug into it, it turned out that in the 2.73 demo the cubes had been scaled down by a factor of 10 -- see the SCALING define at the top of BasicDemo.cpp. If you make the same change to the 2.72 demo, you see very similar behaviour. So it's not a simulation engine regression in this case.
-
- Posts: 508
- Joined: Fri May 30, 2008 2:51 am
- Location: Ossining, New York
Re: Triggers and game feedback
The behaviour of boxes that i mentioned above was actually due to me switching from static plane to triangle mesh for my floor.