CollisionWorld.ClosestRayResultCallback does not hit object

hgmarques
Posts: 4
Joined: Tue Mar 24, 2009 7:25 pm

CollisionWorld.ClosestRayResultCallback does not hit object

Post by hgmarques »

Hello...

I think this is just a very stupid rookie mistake. I've been looking for a reason why my call to CollisionWorld.ClosestRayResultCallback does not hit a static box object I have in the centre of my world. I'm using JBullet but this is a general Bullet question: are the arguments of the function CollisionWorld.ClosestRayResultCallback the initial position and the direction of the ray in the physical world? And if so, why does the following code not work?

- my box is static, it has dimensions 20,20,20 and is set around the origin. I'm not doing any transformations either in my physical world or in opengl
- my ray is set from p = new Vector3f(0,0,-100f) with direction d = new Vector3f(0,0,10000);

---------------------- The rayCallBack -------------------------------------

CollisionWorld.ClosestRayResultCallback rayCallback = new CollisionWorld.ClosestRayResultCallback(p, d);
dWorld.rayTest(p, d, rayCallback);

if (rayCallback.hasHit()) {
RigidBody body = RigidBody.upcast(rayCallback.collisionObject);
if (body != null) {
System.err.println("is static? "+ body.isStaticObject());
}
}


------------------------------------- The initialisation of the physics world

time = 0.0f;
gravity = new Vector3f(0f,-9.8f,0f);

clock = new Clock();
collision_config = new DefaultCollisionConfiguration();

dispatcher = new CollisionDispatcher(collision_config);

worldMin = new Vector3f(-10000,-10000,-10000);
worldMax = new Vector3f(10000,10000,10000);
overlappingPairCache = new AxisSweep3(worldMin, worldMax);

constraintSolver = new SequentialImpulseConstraintSolver();

dynamicsWorld = new DiscreteDynamicsWorld(dispatcher, overlappingPairCache, constraintSolver, collision_config);
dynamicsWorld.setGravity(gravity);

for (BulletGLBody body : bodies) {
body.createPhysicalBody(dynamicsWorld);
}


--------------------------------------------- the creation of the physical box

cShape = new BoxShape(size);

if(bodyType == BodyType.DYNAMIC_BODY){
cShape.calculateLocalInertia(mass, inertia);
}

final DefaultMotionState mState = new DefaultMotionState(poseMatrix); // motion state
final RigidBodyConstructionInfo cInfo = new RigidBodyConstructionInfo(mass, mState, cShape, inertia);
final RigidBody body = new RigidBody(cInfo);
dynamicsWorld.addRigidBody(body);

------------------------------------------------------------------------

I tried to play around with vectors p and d and strangely if I set point p to -20 a collision is detected with my box, but not for any other nearby points.

Thank you very much for your help in advance

cheers
hgmarques
pico
Posts: 229
Joined: Sun Sep 30, 2007 7:58 am

Re: CollisionWorld.ClosestRayResultCallback does not hit object

Post by pico »

Hi,

to me it looks like you forgot to set the filterGroup and filterMask in the callback.
hgmarques
Posts: 4
Joined: Tue Mar 24, 2009 7:25 pm

Re: CollisionWorld.ClosestRayResultCallback does not hit object

Post by hgmarques »

hi pico...

thank you for your reply... I've put together a very simple example of my code so that my results can be reproduced (see below). I've played around with the time step, the mask and group filters, as well as the object's shape, but it simply does not seem to work. For most values of variable a (see below) no collision is detected; but for example for a=-20 and a=54 a collision is detected. I'm new in using bullet and I really don't understand these results... Any guidance would be very very appreciated... Thank you very much...

regards
hgmarques

------------------------------------------------------------ Test code

public class RayTest {


public static void main(String[] args) {


float time = 0.0f;
Vector3f gravity = new Vector3f(0f,-9.8f,0f);

Clock clock = new Clock();
DefaultCollisionConfiguration collision_config = new DefaultCollisionConfiguration();

CollisionDispatcher dispatcher = new CollisionDispatcher(collision_config);

Vector3f worldMin = new Vector3f(-10000,-10000,-10000);
Vector3f worldMax = new Vector3f(10000,10000,10000);
BroadphaseInterface overlappingPairCache = new AxisSweep3(worldMin, worldMax);

//BroadphaseInterface overlappingPairCache = new SimpleBroadphase();

ConstraintSolver constraintSolver = new SequentialImpulseConstraintSolver();

DynamicsWorld dynamicsWorld = new DiscreteDynamicsWorld(dispatcher, overlappingPairCache, constraintSolver, collision_config);
dynamicsWorld.setGravity(gravity);

// CollisionShape cShape = new BoxShape(new Vector3f(10,10,10));
CollisionShape cShape = new SphereShape(10);

// using motionstate is recommended, it provides interpolation capabilities,
// and only synchronizes 'active' bulletglsimulator.bodies
Transform t = new Transform();
t.origin.set(0,0,0);
DefaultMotionState mState = new DefaultMotionState(t); // motion state
RigidBodyConstructionInfo cInfo = new RigidBodyConstructionInfo(0, mState, cShape, new Vector3f(0,0,0));

RigidBody body = new RigidBody(cInfo);
dynamicsWorld.addRigidBody(body);

while(true){

final int a = -20, b =100;

Vector3f p = new Vector3f(a,0,0);
Vector3f d = new Vector3f(b,0,0);
d.normalize();
d.scale(10000);

CollisionWorld.ClosestRayResultCallback rayCallback = new CollisionWorld.ClosestRayResultCallback(p, d);
rayCallback.collisionFilterGroup = CollisionFilterGroups.DEFAULT_FILTER;
rayCallback.collisionFilterMask = CollisionFilterGroups.ALL_FILTER;
dynamicsWorld.rayTest(p, d, rayCallback);

System.err.println("ray hit? "+rayCallback.hasHit());

if(rayCallback.hasHit()){

Vector3f v = new Vector3f();
((RigidBody) rayCallback.collisionObject).getCenterOfMassPosition(v);

float ms = clock.getTimeMicroseconds();
clock.reset();
float minFPS = 1000000f / 60f;
if (ms > minFPS) {
ms = minFPS;
}

time+=ms;
dynamicsWorld.stepSimulation(ms / 100000f);
dynamicsWorld.debugDrawWorld();

try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}

}

}

}

}
pico
Posts: 229
Joined: Sun Sep 30, 2007 7:58 am

Re: CollisionWorld.ClosestRayResultCallback does not hit object

Post by pico »

Hi,

just a guess, but i don't see in the above code that you set the filtermask and filtergroup of the static body. The filtermask of the static body must not be zero, otherwise the ray can't hit. This behaviour can be changed by overiding the virtual needsResponse code of the callback.
hgmarques
Posts: 4
Joined: Tue Mar 24, 2009 7:25 pm

Re: CollisionWorld.ClosestRayResultCallback does not hit object

Post by hgmarques »

thanks pico...

I'm not sure if I got what you mean (I mentioned my inexperienced before) but... I added this line

--------------- BroadphaseProxy proxy = new BroadphaseProxy(body, CollisionFilterGroups.DEFAULT_FILTER, CollisionFilterGroups.ALL_FILTER);

after creating the RigidBody and added this line

--------------- rayCallback.needsCollision(proxy);

after creating the rayCallback object. I also tried to play around with the mask and group filters but no success... I obtain exactly the same results. And the thing that intrigues me the most is why when a=-20 for example, the ray gets a hit and not for points around this point.

thanks once again...

regards...
hugo