Help: Collisions Arn't Working?

Post Reply
sizeak
Posts: 8
Joined: Thu Jan 07, 2010 6:39 pm

Help: Collisions Arn't Working?

Post by sizeak »

Hey,

After fixing the issues I had in my other topic (which no one replied to :( ) I now have a pretty smooth first person camera and movement interface setup using a kinematic character controller. The code is hacked and messy as hell from all my attempts of getting it to work and is mainly just modified demo code at this point but it works now so I can tidy it later.

The main problem now is that collisions don't seem to be happening, I can still walk through walls. I imagine its something I'm doing/Not doing as it maybe, but I'm not sure what. So if I post the code of the relevant functions and how I'm using them, could someone take a look and see why its not working correctly?

I've probably posted more code than is neccesary but I wanted to make sure I didn't miss anything, chances are you won't have to look at all of it to see what idiotitc thing I've missed.


Here is the init function I'm using:

Code: Select all

void Scene::physicsInit()
{
	maxRigidBodies = 1024; //maybe this should be in the scene file instead
	btVector3 worldAabbMin(-10000, -10000, -10000); //world size for broadphase.
	btVector3 worldAabbMax(10000, 10000, 10000);	//should probs be loaded from scene file to
	broadphase = new btAxisSweep3(worldAabbMin, worldAabbMax, (unsigned short)maxRigidBodies);
	m_overlappingPairCache = broadphase;
	collisionConfig = new btDefaultCollisionConfiguration();
	dispatcher = new btCollisionDispatcher(collisionConfig);
	solver = new btSequentialImpulseConstraintSolver;
	dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, m_overlappingPairCache, solver, collisionConfig);
}
And heres the char controller init:

Code: Select all

void Scene::initPlayer()
{
	btTransform startTransform;
	startTransform.setIdentity();
	startTransform.setOrigin(btVector3(0.0, 0.0, 10.0));

	m_ghostObject = new btPairCachingGhostObject();
	m_ghostObject->setWorldTransform(startTransform);
	broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
	btScalar characterHeight = 0.75;
	btScalar characterWidth = 0.75;
	btConvexShape* capsule = new btCapsuleShape(characterWidth,characterHeight);
	m_ghostObject->setCollisionShape (capsule);
	m_ghostObject->setCollisionFlags (btCollisionObject::CF_CHARACTER_OBJECT);

	btScalar stepHeight = btScalar(0.0);
	m_character = new btKinematicCharacterController (m_ghostObject,capsule,stepHeight);
	dynamicsWorld->addCollisionObject(m_ghostObject,btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter|btBroadphaseProxy::DefaultFilter);
	dynamicsWorld->addCharacter(m_character);
	
	//not sure these lines needed or not
	dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_ghostObject->getBroadphaseHandle(),dispatcher);
	m_character->reset ();	
	//m_character->warp (btVector3(0.0f, 0.0f, 0.0f));
}
Getting the controllers position:

Code: Select all

void Scene::getPlayerPos(cnVertex *vert, cnRotationVertex *rot)
{
	btTransform trans;
	trans = m_ghostObject->getWorldTransform();
			
	vert->x = trans.getOrigin().getX();
	vert->y = trans.getOrigin().getY();
	vert->z = trans.getOrigin().getZ();
	
	btQuaternion qTemp;
	qTemp = trans.getRotation();
	btVector3 vTemp = qTemp.getAxis();
	
	rot->x = (float)vTemp.x();
	rot->y = (float)vTemp.y();
	rot->z = (float)vTemp.z();
	rot->angle = (float)(qTemp.getAngle() * radToDeg);
}
Settings its velocity/rotation:

Code: Select all

void Scene::setVel(bool gForward, bool gBackward, float yRot,float dt)
{	
	///set walkDirection for our character
		btTransform xform;
		xform = m_ghostObject->getWorldTransform();

		btVector3 forwardDir = xform.getBasis()[2];
	//	printf("forwardDir=%f,%f,%f\n",forwardDir[0],forwardDir[1],forwardDir[2]);
		btVector3 upDir = xform.getBasis()[1];
		btVector3 strafeDir = xform.getBasis()[0];
		forwardDir.normalize();
		upDir.normalize();
		strafeDir.normalize();

		btVector3 walkDirection = btVector3(0.0, 0.0, 0.0);
		btScalar walkVelocity = btScalar(1.1) * 4.0; // 4 km/h -> 1.1 m/s
		btScalar walkSpeed = walkVelocity * dt;

		//rotate view
		if (yRot)
		{
			btMatrix3x3 orn = m_ghostObject->getWorldTransform().getBasis();
			orn *= btMatrix3x3(btQuaternion(btVector3(0,1,0),yRot));
			m_ghostObject->getWorldTransform().setBasis(orn);
		}

	/*	if (gRight)
		{
			btMatrix3x3 orn = m_ghostObject->getWorldTransform().getBasis();
			orn *= btMatrix3x3(btQuaternion(btVector3(0,1,0),gRight));
			m_ghostObject->getWorldTransform().setBasis(orn);
		}*/

		if (gForward)
			walkDirection += forwardDir;

		if (gBackward)
			walkDirection -= forwardDir;

		m_character->setWalkDirection(walkDirection*walkSpeed);
}
This is how Im using the controller functions:

Code: Select all

cnVertex TVert;
cnRotationVertex TRot;
scene->setVel(forward, backward, Yrot,(1.0f/420.0f));			
scene->getPlayerPos(&TVert, &TRot);
glRotatef(TRot.angle, TRot.x, TRot.y, TRot.z);		
glTranslatef(TVert.x, TVert.y, TVert.z);
scene->drawSCOs((1.0f/420.0f));			
SDL_GL_SwapBuffers();
And this is how I'm drawing all the background objects:

Code: Select all

void Scene::drawSCOs(float dt)
{
	GLint mode = 0;
	
	glGetIntegerv(GL_RENDER_MODE, &mode);
	
	if(mode == GL_RENDER)
	{
		for(int i=0; i<header.numRSO; i++)
		{	
			dynamicsWorld->stepSimulation(dt, 10);
			btTransform trans;
			RSOs[i].getRigidBody()->getMotionState()->getWorldTransform(trans);
			unsigned int typetemp = RSOs[i].getModelType();
			cnVertex vertemp;
			cnRotationVertex rotemp;
			
			vertemp.x = trans.getOrigin().getX();
			vertemp.y = trans.getOrigin().getY();
			vertemp.z = trans.getOrigin().getZ();
			
			btQuaternion qTemp;
			qTemp = trans.getRotation();
			btVector3 vTemp = qTemp.getAxis();
			
			rotemp.x = (float)vTemp.x();
			rotemp.y = (float)vTemp.y();
			rotemp.z = (float)vTemp.z();
			rotemp.angle = (float)(qTemp.getAngle() * radToDeg);
			
			models[typetemp].setPosition(vertemp);
			models[typetemp].setRotation(rotemp);
			models[typetemp].draw();
		}
	}
...}
.jayderyu
Posts: 19
Joined: Sat Jan 17, 2009 10:51 am

Re: Help: Collisions Arn't Working?

Post by .jayderyu »

I could be wrong but from my understanding.
"The btGhostObject can keep track of all objects that are overlapping By default, this overlap is based on the AABB This is useful for creating a character controller, collision sensors/triggers, explosions etc."

Triggers/sensors/explosions are meant not to prevent movement, but instead for call backs. So you know how your character to respond to various objects. Instead you probably should be stopping your character from walking through walls manually. Just make your ghostbody a bit bigger than you model to allow some leeway on call back checks.
sizeak
Posts: 8
Joined: Thu Jan 07, 2010 6:39 pm

Re: Help: Collisions Arn't Working?

Post by sizeak »

Ahh so I need to write a call back? I guess that kind of makes sense, I'll give it a go. ty
sizeak
Posts: 8
Joined: Thu Jan 07, 2010 6:39 pm

Re: Help: Collisions Arn't Working?

Post by sizeak »

I tried a callback which printed out the vectors of the collision, but nothing was printed when i went through walls so I'm assuming no collision was registered
Post Reply