Collision shape units vs OpenGL units? Any difference?

memplant
Posts: 2
Joined: Thu Mar 05, 2009 9:00 am

Collision shape units vs OpenGL units? Any difference?

Post by memplant »

Hi guys,

For some reason I am having an issue when I try to use Bullet that seems like it could be a units problem or something.

My scenario is that I have created a box collision shape at the origin with a size of 1,1,1. Then I move the camera backwards 5 units and try to fire a ray from the clicked mouse position to the box (standard picking stuff like in the demo). The issue is that Bullet only registers that I have hit the box when the mouse coords are in the exact centre of the screen.

I have gone over the demos etc a couple of times and I just cant work out why the picking demo works with its boxes and my simple box at the origin doesn't.

I noticed that when I increased the collision shapes size to 4,4,4 it began registering collisions nearly everywhere on the screen so it seems as though the shape is just really small or something. It doesn't really make sense to me though because I also have a 1 unit sized cube being rendered by opengl in the same place and its volume doesn't correspond to the collision shape volume.

Hopefully that all makes sense. Anyway, has anyone else seen anything like this? Are opengl units and bullet units the same? And also how do I turn on debug drawing of bullet collision shapes?

Here's my world set up:

Code: Select all

	
       // Settings
	m_worldMin = btVector3(-10000, -10000, -10000);
	m_worldMax = btVector3(10000, 10000, 10000);
	m_maxProxies = 1024;
	
	// Init everything
	m_broadPhase = new btAxisSweep3(m_worldMin, m_worldMax, m_maxProxies);
	m_collisionConfig = new btDefaultCollisionConfiguration();
	m_dispatcher = new btCollisionDispatcher(m_collisionConfig);
	m_solver = new btSequentialImpulseConstraintSolver;
	m_world = new btDiscreteDynamicsWorld(m_dispatcher, m_broadPhase, m_solver, m_collisionConfig);
	m_world->setGravity(btVector3(0, 0, 0));
Object set up code:
m_pos = (0, 0, 0)
m_mas = 1.0f

Code: Select all

	btTransform bodyTransform;
	bodyTransform.setIdentity();
	bodyTransform.setOrigin(m_pos);

	m_collisionShape = new btBoxShape(btVector3(1, 1, 1));

	bool isDynamic = (m_mass != 0.f);
	btVector3 localInertia(0,0,0);
	if (isDynamic)
		m_collisionShape->calculateLocalInertia(m_mass, localInertia);
	
	m_motionState = new btDefaultMotionState(bodyTransform);
	btRigidBody::btRigidBodyConstructionInfo rbInfo(m_mass, m_motionState, m_collisionShape, localInertia);
	
	m_collisionBody = new btRigidBody(rbInfo);
		
	//add the body to the dynamics world
	m_sceneNode->getDynamicsWorld()->addRigidBody(m_collisionBody);
Ray casting code:

Code: Select all

btVector3 PhysicsManager::getRayTo(int x,int y, float nearPlane, float farPlane, btVector3 cameraUp, btVector3 cameraPosition, btVector3 cameraTargetPosition)
{
	float screenWidth = 320;
	float screenHeight = 480;
	float fov = 60;
		
	btVector3 rayFrom = cameraPosition;
	btVector3 rayForward = cameraTargetPosition - rayFrom;
	rayForward.normalize();
	rayForward *= farPlane;
		
	btVector3 vertical = cameraUp;
		
	btVector3 hor;
	hor = rayForward.cross( vertical );
	hor.normalize();
		
	float tanFov = tanf( 0.5f * fov );
	btScalar aspect = screenHeight / (btScalar) screenWidth;
		
	hor *= 2.f * farPlane * tanFov;
	vertical *= 2.f * farPlane * tanFov;
		
	if( aspect < 1 ) {
		hor /= aspect;
	} else {
		vertical *= aspect;
	}
		
	btVector3 rayToCenter = rayFrom + rayForward;
	btVector3 dHor = hor * 1.f / screenWidth;
	btVector3 dVert = vertical * 1.f / screenHeight;
		
	btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical;
	rayTo += x * dHor;
	rayTo -= y * dVert;
		
	return rayTo;
}
Thanks!
memplant
Posts: 2
Joined: Thu Mar 05, 2009 9:00 am

Re: Collision shape units vs OpenGL units? Any difference?

Post by memplant »

WHOOOOOOOOOOOOOOOOOOOOOOOooooooooooo

I really didn't expect to get this working tonight. :)

I managed to fix it by a) cutting and pasting in the exact rayTo() code from the DemoApplication (I had used a slight variant) and B) realising that the field of view that is being set in the rayTo() code is not the same as what my engine is using.

After jiggling things around I got it working, even after translating the object which is nice. I still need to investigate all of the code of the rayTo() function to make it work properly (I looked at the fov being generated by the rayTo() code and then set my rendering engine to the same thing, in this case 86 degs) because the example code seems to have some redundant stuff in there that makes it harder to understand.

Hope this helps someone else.