ContactTest tunneling

Trioxin
Posts: 7
Joined: Mon Aug 15, 2011 4:58 am

ContactTest tunneling

Post by Trioxin »

Evening bullet forums,
I've recently encountered an issue when I implemented ContactTest into a kinematic object.
If the object is moving slow enough per frame, it will behave exactly as expected, except that the object will "sink" into the collision surface a little bit, but otherwise will be stopped from leaving the field.
However if it's moving fast enough it will pass right through.

Below is a snippet of code I'm using. I tried to keep it to the relevant parts, since the project is a little big to just dump it all here.

I've simulated throughout the code a 60 frames per second update.

Code: Select all


struct ContactSensorCallback : public btCollisionWorld::ContactResultCallback
{
	btVector3 m_Contact;

	ContactSensorCallback()
		: btCollisionWorld::ContactResultCallback()
	{
		m_Contact = btVector3(0,0,0);
	}

	virtual	btScalar	addSingleResult(btManifoldPoint& cp,
		const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,
		const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
	{
		btVector3 nor = cp.getPositionWorldOnB() - cp.getPositionWorldOnA();
		float dist = cp.getDistance();
		if (dist < 0) {
			m_Contact -= nor * dist;
		}
		return 0;
	}
};




void KCC::update() {
	float DELTA = 1.0f/60;
	float SPEED = 60.0f;
	rotate();

	float t_Z = 0;
	if (m_Forward) t_Z = -SPEED; else if (m_Backward) t_Z = SPEED;

	Ogre::Vector3 t_Vec = Ogre::Vector3(0, 0, t_Z);
	t_Vec = m_YawNode->getOrientation() * t_Vec;
	btVector3 vel = btVector3(t_Vec.x, t_Vec.y, t_Vec.z) * DELTA;
	fallRigidBody->translate(vel);

	ContactSensorCallback collisions;
	Engine::getSingleton()->m_DynamicsWorld->contactTest(fallRigidBody, collisions);
	fallRigidBody->translate(collisions.m_Contact);

	((OgreMotionState*)fallRigidBody->getMotionState())->
		setKinematicPos(fallRigidBody->getWorldTransform());
}


if I set the SPEED variable to 5-10, everything goes relatively well, but setting it to about 15+ I get the tunnelling effect with increasing consistency the higher I set the speed.

I reckon it's due to a need to take into account current velocity, though I'm not entirely sure how to do that, particularly at super fast movement speeds.

I'm not really sure what to ask, specifically.
Does the test take into account only the objects position directly after a stepSimulation?
Is it independent and thus take its position exactly as held since the last translate()?
Is there a flag I need to set to implement some kind of kinematic CCD?
Is there a relatively simple method I'm overlooking somewhere?
is this unusual behaviour?
What is the meaning of life?

Any suggestions are welcome, thanks :)