Hi all - how to skip a particular body in the ClosestRayResultCallback? I want to check that the ray is colliding with some objects, but want to do not test (just skip) another. Any ideas?
Thanks!
How to skip a body in the ClosestRayResultCallback?
-
- Posts: 11
- Joined: Fri Jan 16, 2009 12:01 pm
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: How to skip a body in the ClosestRayResultCallback?
You can derive your custom class from btCollisionWorld::ClosestRayResultCallback and override the virtual 'addSingleResult'.
See for example in Bullet/src/BulletDynamics/Character/btKinematicCharacterController.cpp:
Hope this helps,
Erwin
See for example in Bullet/src/BulletDynamics/Character/btKinematicCharacterController.cpp:
Code: Select all
class btKinematicClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
{
public:
btKinematicClosestNotMeRayResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
{
m_me = me;
}
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
{
if (rayResult.m_collisionObject == m_me)
return 1.0;
return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace);
}
protected:
btCollisionObject* m_me;
};
Erwin
-
- Posts: 11
- Joined: Fri Jan 16, 2009 12:01 pm
Re: How to skip a body in the ClosestRayResultCallback?
Thanks, but in this way, the ray test just stops on this body and return 1.0. I want to make this body "invisible" for the ray...
-
- Posts: 169
- Joined: Sun Jan 14, 2007 7:56 pm
- Location: Norway
Re: How to skip a body in the ClosestRayResultCallback?
You need to re-implement the needsCollision function, so that it returns false in the cases where you don't want a hit. Here's an example from my engine, where sensors and the terrain is filtered out (I have my own sensor class that is derived from btCollisionObject).
So you see, just do whatever checks you need, return false if it should be rejected.
The last 3 lines are copied from the original needsCollision function, could be that you could also just type
instead, or something like that, so that you're up-to-date if the original function is changed. Just haven't tried that myself yet.
Best regards,
Ola
Code: Select all
struct MyPositionRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
{
MyPositionRayResultCallback( const btVector3& rayFromWorld,
const btVector3& rayToWorld)
: btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld)
{
}
virtual bool needsCollision(btBroadphaseProxy* proxy0) const
{
const btCollisionObject* co = (btCollisionObject*)proxy0->m_clientObject;
const MySensorObject* so = dynamic_cast<const MySensorObject*>(co);
if(so)
return false;
if(co->getCollisionShape()->getShapeType() == TERRAIN_SHAPE_PROXYTYPE)
return false;
bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0;
collides = collides && (m_collisionFilterGroup & proxy0->m_collisionFilterMask);
return collides;
}
};
The last 3 lines are copied from the original needsCollision function, could be that you could also just type
Code: Select all
return btCollisionWorld::ClosestRayResultCallback::needsCollision(proxy0)
Best regards,
Ola
-
- Posts: 11
- Joined: Fri Jan 16, 2009 12:01 pm
Re: How to skip a body in the ClosestRayResultCallback?
That was very helpful! Thanks Ola!
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: How to skip a body in the ClosestRayResultCallback?
Are you sure and have you tested it? Returning 1.0 in 'addSingleResult' will basically ignore the object, making it effectively invisible to the ray.kakuro777 wrote:Thanks, but in this way, the ray test just stops on this body and return 1.0. I want to make this body "invisible" for the ray...
Nevertheless, Ole's recommendation is better, 'needsCollision ' culls the object before testing, while 'addSingleResult' culls it after the actual ray-object test.
Thanks,
Erwin