Racing Game, Car Characteristics Out of Control

smuffer
Posts: 16
Joined: Fri Dec 04, 2009 7:14 pm

Racing Game, Car Characteristics Out of Control

Post by smuffer »

Currently we're designing a game using bullet and directx, but we're having problems with the vehicle itself and its collison. Firstly whenever we go over the slightest hill it takes off into a huge jump from which it spins uncontrollably and unable to recover let alone land back on the track. If it does manage to land on the track or a decent speed is achieved then it will usually penetrate the track. Were aiming for a hovering car racing game similar to wipeout but felt it would be easier to implement this by using the bt raycast vehicle and obviously not render the wheels. there are loops and turns and rounded sides to the track and the vehicle never seems to go over them smoothly as a wipeout vehicle would. We have tried lots of hacks to keep the car stuck to the track such as increasing gravity and applying it in the invers direction of the normal which the front wheel collides with the track but this is sketchy.

here is how the vehicle is being created:

Code: Select all

	m_mass = 600.0f;

	//get chassis id from VIS
	m_modelID = VIS->ModelExists(chassisFilename);
	btCollisionShape* colShape;

	//get wheel id
	m_wheelModelID = VIS->ModelExists(wheelFilename);
	btBoxShape* wheelColShape = new btBoxShape(btVector3());	//not for actual use - to keep physics vec and model vec alligned

	//search for collision shape
	if(m_modelID < PHYS->GetCollisionShapeArraySize())
	{
		colShape = (btBoxShape*)PHYS->GetCollisionShape(m_modelID);
	}
	else		//create the collision shape if it does not exist
	{
		colShape = new btBoxShape(btVector3(1.0f, 0.5f, 1.5f));
		colShape->setLocalScaling(btVector3(1, 1, 1));

		PHYS->PushCollisionShape(colShape);
	}
//make compound shape for centre of gravity manipulation
	btTransform shapeTrans;
	shapeTrans.setIdentity();
	shapeTrans.setOrigin(btVector3(1.0f, 1.0f, 0.0f));

	btCompoundShape *compoundShape = new btCompoundShape(true);
	compoundShape->addChildShape(shapeTrans, colShape);

	btVector3 inertia(0,0,0);
	if( m_mass != 0)
		compoundShape->calculateLocalInertia(m_mass,inertia);

	btTransform trans;
	trans.setIdentity();
	trans.setOrigin(ConvertVector(position));

	//create motion state
	btDefaultMotionState* motionState = new btDefaultMotionState(trans);
	btRigidBody::btRigidBodyConstructionInfo cInfo(m_mass,motionState,compoundShape,inertia);
	cInfo.m_friction = 0.0f;
	cInfo.m_restitution = 0.0f;
	cInfo.m_linearDamping = 0.0f;
	cInfo.m_angularDamping = 0.0f;

	m_rigidBody = new btRigidBody(cInfo);
	m_rigidBody->setUserPointer(this);


	//create vehicalraycast
	trans.setOrigin(ConvertVector(position));
	m_rigidBody->setCenterOfMassTransform(trans);
	m_rigidBody->setLinearVelocity(btVector3(0,0,0));
	m_rigidBody->setAngularVelocity(btVector3(0,0,0));	

	//m_rigidBody->setDamping(0, 0.5f);
	PHYS->GetDynamicsWorld()->addRigidBody(m_rigidBody);

	 PHYS->GetDynamicsWorld()->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_rigidBody->getBroadphaseHandle(),                                                 PHYS->GetDynamicsWorld()->getDispatcher());

	m_vehicleRaycaster = new btDefaultVehicleRaycaster(PHYS->GetDynamicsWorld());
	m_raycastVehicle = new btRaycastVehicle(m_vehicleTuning, m_rigidBody, m_vehicleRaycaster);

	//vehicle may never be deactivated
	m_rigidBody->setActivationState(DISABLE_DEACTIVATION);

	PHYS->GetDynamicsWorld()->addAction(m_raycastVehicle);

	//add wheels to the vehicle
	PHYS->PushCollisionShape(wheelColShape);

	float connectionHeight = 1.2f;//0.6f;
	bool isFrontWheel = true;
	int rightIndex = 0;
	int upIndex = 1;
	int forwardIndex = 2;
	btVector3 wheelDirectionCS0(0, -1, 0);
	btVector3 wheelAxisCS(-1, 0, 0);
	btScalar suspentionRestLength(1.0f);//(0.6f);

	float vehicleSize = 1.0f;

	//(set coordinate system)
	m_raycastVehicle->setCoordinateSystem(rightIndex, upIndex, forwardIndex);
	
	btVector3 connectionPointCS0 = btVector3(1.0f - .3f * m_wheelWidth, connectionHeight, 2 * 1.0f - m_wheelRadius);
	m_raycastVehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxisCS, suspentionRestLength, m_wheelRadius, m_vehicleTuning, isFrontWheel);
	
	connectionPointCS0 = btVector3(-1.0f + .3f * m_wheelWidth, connectionHeight, 2 * 1.0f - m_wheelRadius);
	m_raycastVehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxisCS, suspentionRestLength, m_wheelRadius, m_vehicleTuning, isFrontWheel);
	
	isFrontWheel = false;

	//rear right
	connectionPointCS0 = btVector3(-1.0f + .3f * m_wheelWidth, connectionHeight, -2 * 1.0f + m_wheelRadius);
	m_raycastVehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxisCS, suspentionRestLength, m_wheelRadius, m_vehicleTuning, isFrontWheel);
	//rear left
	connectionPointCS0 = btVector3(1.0f - .3f * m_wheelWidth, connectionHeight, -2 * 1.0f + m_wheelRadius);
	m_raycastVehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxisCS, suspentionRestLength, m_wheelRadius, m_vehicleTuning, isFrontWheel);


	for(int i = 0; i < m_raycastVehicle->getNumWheels(); i++)
	{
		if(i == 0 || i == 1)		//front wheels
		{
			btWheelInfo& wheelInfo = m_raycastVehicle->getWheelInfo(i);
			wheelInfo.m_suspensionStiffness = m_suspensionStiffness;
			wheelInfo.m_wheelsDampingRelaxation = m_suspensionDamping;
			wheelInfo.m_wheelsDampingCompression = m_suspensionCompression;
			wheelInfo.m_frictionSlip = m_wheelFriction;
			wheelInfo.m_rollInfluence = m_rollInfluence;
		}
		else		//rear wheels
		{
			btWheelInfo& wheelInfo = m_raycastVehicle->getWheelInfo(i);
			wheelInfo.m_suspensionStiffness = m_suspensionStiffness;
			wheelInfo.m_wheelsDampingRelaxation = m_suspensionDamping;
			wheelInfo.m_wheelsDampingCompression = m_suspensionCompression;
			wheelInfo.m_frictionSlip = m_wheelFriction;
			wheelInfo.m_rollInfluence = m_rollInfluence;
			//wheelInfo.m_suspensionRestLength1 = 0.6f;

		}
	}
}
and how the car is updated:

Code: Select all

	if(INPUT->KeyPressed(DIK_F))
	{
		m_engineForce = m_maxEngineForce;
	}

	//back wheels first
	int wheelIndex = 2;
	m_raycastVehicle->applyEngineForce(m_engineForce, wheelIndex);
	wheelIndex = 3;
	m_raycastVehicle->applyEngineForce(m_engineForce, wheelIndex);

	//front wheels
	wheelIndex = 0;
	m_raycastVehicle->applyEngineForce(m_engineForce, wheelIndex);
	m_raycastVehicle->setSteeringValue(m_steeringValue, wheelIndex);
	wheelIndex = 1;
	m_raycastVehicle->applyEngineForce(m_engineForce, wheelIndex);
	m_raycastVehicle->setSteeringValue(m_steeringValue, wheelIndex);


	// Update vehicle direction
	btWheelInfo& wheel = m_raycastVehicle->getWheelInfo( 0 );
	btVector3 up = -wheel.m_raycastInfo.m_wheelDirectionWS;
	const btVector3& right = wheel.m_raycastInfo.m_wheelAxleWS;
	m_forward = up.cross(right);
	m_forward.normalize();	

	btWheelInfo& frontWheelInfo = m_raycastVehicle->getWheelInfo(0);
	btWheelInfo& backWheelInfo = m_raycastVehicle->getWheelInfo(1);

	btVector3 frontPos, backPos;
	frontPos = frontWheelInfo.m_raycastInfo.m_contactPointWS;
	backPos = backWheelInfo.m_raycastInfo.m_contactPointWS;

	btVector3 newGrav;
	
	//set gravity to act downwards if the car jumps
	if(!m_raycastVehicle->getWheelInfo(0).m_raycastInfo.m_isInContact 
		&& !m_raycastVehicle->getWheelInfo(1).m_raycastInfo.m_isInContact 
		&& !m_raycastVehicle->getWheelInfo(2).m_raycastInfo.m_isInContact)
	{
		newGrav = btVector3(0, -15.0f, 0);
	}
	else
	{
		newGrav = -m_raycastVehicle->getWheelInfo(1).m_raycastInfo.m_contactNormalWS * 15;
	}

	m_rigidBody->setGravity(newGrav);
}
The track collision shape is a btBvhTriangleMeshShape.

Any help to tune this into something playable would be greatly appreciated.
razer
Posts: 82
Joined: Sun Apr 04, 2010 10:08 pm

Re: Racing Game, Car Characteristics Out of Control

Post by razer »

I have unanswered topic about triangle mesh.
It does not work for me. Try to use convex instead.

Raycast vehicle simulates springs and will jump.