Reputation: 51
I am trying to detect mouse-picks of a box shaped collision object, but somehow Bullet's rayTest shows a strange behavior.
Here ist my world setup:
public void create () {
Bullet.init();
Gdx.app.log("Bullet", "Version = " + LinearMath.btGetVersion());
// camera:
camera = new OrthographicCamera(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
camera.position.set(VIEWPORT_WIDTH/2, VIEWPORT_HEIGHT/2, 10f);
camera.up.set(0f, 1f, 0f);
camera.lookAt(VIEWPORT_WIDTH/2, VIEWPORT_HEIGHT/2, 0);
camera.near = 1f;
camera.far = +100f;
camera.update();
closestRayResultCallback = new ClosestRayResultCallback(Vector3.Zero, Vector3.Z);
btDefaultCollisionConfiguration collisionConfig = new btDefaultCollisionConfiguration();
btCollisionDispatcher dispatcher = new btCollisionDispatcher(collisionConfig);
btDbvtBroadphase broadphase = new btDbvtBroadphase();
collisionWorld = new btCollisionWorld(dispatcher, broadphase, collisionConfig);
btCollisionShape shape = new btBoxShape(new Vector3(0.50f, 0.50f, 0.50f));
btCollisionObject obj = new btCollisionObject();
obj.setCollisionShape(shape);
collisionWorld.addCollisionObject(obj);
Matrix4 transform = new Matrix4();
transform.setTranslation(0.90f, 0.90f, 0f);
obj.setWorldTransform(transform);
// Debug:
debugDrawer = new DebugDrawer();
collisionWorld.setDebugDrawer(debugDrawer);
debugDrawer.setDebugMode(btIDebugDraw.DebugDrawModes.DBG_MAX_DEBUG_DRAW_MODE);
}
The setup (I think) has nothing unusual - the exception is, maybe, that I use an orthographic camera.
The ray-testing code has nothing special, either:
private btCollisionObject rayTest(int x, int y) {
Ray ray = camera.getPickRay(x, y);
rayFrom.set(ray.origin);
rayTo.set(ray.direction.scl(50)).add(ray.origin);
Gdx.app.log("Bullet", "rayTest - rayFrom: " + rayFrom + ", rayTo: " + rayTo);
// we reuse the ClosestRayResultCallback, thus we need to reset its values:
closestRayResultCallback.setCollisionObject(null);
closestRayResultCallback.setClosestHitFraction(1f);
closestRayResultCallback.setRayFromWorld(rayFrom);
closestRayResultCallback.setRayToWorld(rayTo);
collisionWorld.rayTest(rayFrom, rayTo, closestRayResultCallback);
if (closestRayResultCallback.hasHit()) {
Gdx.app.log("Bullet", "rayTest - has hit");
return closestRayResultCallback.getCollisionObject();
}
return null;
}
In my render loop I 1) listen for mouse clicks and call in case of a click the rayTest method with the corresponding mouse coordinates and 2) render the box shape of the collision body using the debug drawer.
Now, my observation is:
the box is drawn as expected near the bottom left corner of the application window. But hitTest detects mouse clicks on the box shape only in the bottom left corner of the box. More precisely, a mouse click in the box is only detected if the mouse is between the bottom left corner of the box (here: (41, 41)) and (49, 49). Mouse clicks in the other part of the box remain undetected.
Am I missing something here?
Upvotes: 2
Views: 869
Reputation: 51
Apparently, rayTest has a bug (Bullet v2.82).
At least, http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=10187&p=34250&hilit=rayTest#p34250 and http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=10205&p=34323&hilit=rayTest#p34323 report on the same observation. And both of the work-arounds that are mentioned in these posts (either use btCollisionWorld.updateAAbbs() or use btDiscreteDynamicsWorld+btRigidBody+StepSimulation) worked for me.
Upvotes: 1