No Collisions Between Mesh and KinematicCharacterController

Post Reply
ckoeber
Posts: 7
Joined: Sat May 10, 2014 2:23 am

No Collisions Between Mesh and KinematicCharacterController

Post by ckoeber »

Hello,

I am a newbie at Bullet Physics here and I am attempting to set up collisions between a KinematicCharacterController and Static mesh that I have loaded in my Physics world.

The ultimate goal is that I can have a character that can walk through the environment.

Currently my KinematicCharacterController object in the Physics world "falls through" everything in the 3D environment regardless of what I have set up. I attempted to follow the Character Demo and documentation closely but I am not sure if I missed something.

Thanks to previous help on this forum and the Debug Drawer I know that the following code below for loading my static mesh works as I can see the lines drawn for this custom mesh.

But first, here is my collision mask setup:

Code: Select all


enum CollisionTypes {
	COLL_NOTHING = 0,
	COLL_PERSON = 1,
	COLL_WALLS = 2,
	COLL_MARKERS = 4
};

short WhatWallsCollideWith, WhatPersonCollidesWith, WhatMarkersCollidesWith;

WhatWallsCollideWith = CollisionTypes::COLL_PERSON | CollisionTypes::COLL_MARKERS;
WhatPersonCollidesWith = CollisionTypes::COLL_WALLS | CollisionTypes::COLL_MARKERS;
WhatMarkersCollidesWith = CollisionTypes::COLL_PERSON | CollisionTypes::COLL_WALLS;

Now, here is my static mesh loading function. As mentioned before; I see the mesh loaded fine (in green for static, I assume?):

Code: Select all

void PhysicsController::AddStaticBasicMesh(PhysicsObject* NewObject, bool ReducePolygonCount = true)
{
	btTriangleIndexVertexArray* meshInterface = new btTriangleIndexVertexArray();
	btIndexedMesh* NewMesh = new btIndexedMesh();
	NewMesh->m_triangleIndexBase = (const unsigned char *)NewObject->Indices;
	NewMesh->m_triangleIndexStride = 3 * sizeof(unsigned int);
	NewMesh->m_vertexBase = (const unsigned char *)NewObject->Vertices;
	NewMesh->m_vertexStride = 3 * sizeof(float);
	NewMesh->m_numVertices = NewObject->NumberOfVertices;
	NewMesh->m_numTriangles = NewObject->NumberOfTriangles;
	NewMesh->m_indexType = PHY_INTEGER;
	meshInterface->addIndexedMesh((*NewMesh), PHY_INTEGER);
	bool	useQuantizedAabbCompression = true;
	btBvhTriangleMeshShape* trimeshShape = new btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression);

	if (ReducePolygonCount == true) {
		StaticShapes.push_back(trimeshShape);
		btDefaultMotionState* StaticMotionState = new btDefaultMotionState((*NewObject->PositionAndOrientation));
		btRigidBody::btRigidBodyConstructionInfo StaticMeshRigidBodyInfo(0, StaticMotionState, trimeshShape, btVector3(0.0f, 0.0f, 0.0f));
		btRigidBody* StaticRigidMesh = new btRigidBody(StaticMeshRigidBodyInfo);
		NewObject->Body = StaticRigidMesh;
		StaticRigidMesh->setCollisionFlags(StaticRigidMesh->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
		MainPhysicsWorld->addRigidBody(StaticRigidMesh, CollisionTypes::COLL_WALLS, WhatWallsCollideWith);
		AllRigidBodies.push_back(NewObject);
		StaticRigidMesh->setUserPointer(AllRigidBodies[AllRigidBodies.size() - 1]);
	} else {
		StaticShapes.push_back(trimeshShape);
		btDefaultMotionState* StaticMotionState = new btDefaultMotionState((*NewObject->PositionAndOrientation));
		btRigidBody::btRigidBodyConstructionInfo StaticMeshRigidBodyInfo(0, StaticMotionState, trimeshShape, btVector3(0.0f, 0.0f, 0.0f));
		btRigidBody* StaticRigidMesh = new btRigidBody(StaticMeshRigidBodyInfo);
		NewObject->Body = StaticRigidMesh;
		StaticRigidMesh->setCollisionFlags(StaticRigidMesh->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
		MainPhysicsWorld->addRigidBody(StaticRigidMesh, CollisionTypes::COLL_WALLS, WhatWallsCollideWith);
		AllRigidBodies.push_back(NewObject);
		StaticRigidMesh->setUserPointer(AllRigidBodies[AllRigidBodies.size() - 1]);
	}
}
And here is my simple character object (as a capsule):

Code: Select all

unsigned int PhysicsController::AddCameraCapsule(PhysicsObject* NewObject, float WeightOfPerson,
    btScalar RadiusOfCapsule, btScalar HeightOfCapsule, btScalar StepHeight)
{
	if (PhysicsCameraInitialized == false) {
		btPairCachingGhostObject* NewCameraController = new btPairCachingGhostObject();
		NewCameraController->setWorldTransform((*NewObject->PositionAndOrientation));
		btVector3 FallingInertia = btVector3(0.0f, 0.0f, 0.0f);
		btConvexShape* NewCameraCapsule = new btCapsuleShape(RadiusOfCapsule, HeightOfCapsule);
		btDefaultMotionState* CameraMotionState = new btDefaultMotionState((*NewObject->PositionAndOrientation));
		NewCameraCapsule->calculateLocalInertia(WeightOfPerson, FallingInertia);
		btRigidBody::btRigidBodyConstructionInfo CameraCapsuleRigidBodyInfo(WeightOfPerson, CameraMotionState, NewCameraCapsule, FallingInertia);
		NewCameraController->setCollisionShape(NewCameraCapsule);
		NewCameraController->setCollisionFlags(NewCameraController->getCollisionFlags() | btCollisionObject::CF_CHARACTER_OBJECT);
		StaticShapes.push_back(NewCameraCapsule);
		NewObject->Body = NewCameraController;
		MainPhysicsWorld->addCollisionObject(NewCameraController, CollisionTypes::COLL_PERSON, WhatPersonCollidesWith);
		AllRigidBodies.push_back(NewObject);
		unsigned int PointerToCamera = 0;
		PointerToCamera = AllRigidBodies.size() - 1;
		NewCameraController->setUserPointer(AllRigidBodies[PointerToCamera]);
		MainKinematicCharacter = new btKinematicCharacterController(NewCameraController,
		    NewCameraCapsule, StepHeight);
		//MainKinematicCharacter->setUseGhostSweepTest(false);
		MainPhysicsWorld->addAction(MainKinematicCharacter);
		PhysicsCameraInitialized = true;
		return PointerToCamera;
	} else {
		return 0;
	}
}
Just to make sure I cover all bases, here is my initialization code for the physics world:

Code: Select all

		MainBroadPhase = new btDbvtBroadphase();
		MainCollisionConfiguration = new btDefaultCollisionConfiguration();
		MainDispatcher = new btCollisionDispatcher(MainCollisionConfiguration);
		MainPhysicsSolver = new btSequentialImpulseConstraintSolver;
		MainPhysicsWorld = new btDiscreteDynamicsWorld(MainDispatcher, MainBroadPhase,
		    MainPhysicsSolver, MainCollisionConfiguration);
		MainPhysicsWorld->setGravity(btVector3(0, -9.81f, 0));
		MainPhysicsWorld->getDispatchInfo().m_allowedCcdPenetration = 0.0001f;
		gContactAddedCallback = CollisionCallBack;
And my contact callback. I have it writing to a log file for debugging purposes but nothing gets written:

Code: Select all

bool PhysicsController::CollisionCallBack(btManifoldPoint& cp, const btCollisionObjectWrapper* obj1, int id1, int index1, const btCollisionObjectWrapper* obj2, int id2, int index2)
{
	std::ofstream MainDebugFile;
	std::string EndLine = "\n";
	std::string PhysicsErrorWarningString;
	PhysicsErrorWarningString = "Collision occured!";
	PhysicsErrorWarningString += EndLine;
	std::streamsize sizeofPhysicsErrorWarningString = PhysicsErrorWarningString.length();
	MainDebugFile.open("C:\PhysicsErrorsWarnings.txt", std::ios_base::app);
	MainDebugFile.write(PhysicsErrorWarningString.c_str(), sizeofPhysicsErrorWarningString);
	MainDebugFile.close();
	return false;
}
Any ideas?

Thank you in advance for your time.
ckoeber
Posts: 7
Joined: Sat May 10, 2014 2:23 am

Re: No Collisions Between Mesh and KinematicCharacterControl

Post by ckoeber »

Anything I can try?

I can tell you that the Physics engine seems to be initialized properly as when I turn it on and attach my "OpenGL" position to the KinematicCharacterController's position I fall under the influence of gravity.

I appreciate this great project as well as this community; I need to incorporate this in what I have going forward.

Has anyone experienced this problem before?

Thank you for your time.
ckoeber
Posts: 7
Joined: Sat May 10, 2014 2:23 am

Re: No Collisions Between Mesh and KinematicCharacterControl

Post by ckoeber »

Are any experts around? If someone can just point to a simple mistake I am making that would help.

I would love to compare with the Character Demo but it doesn't actually run.

If there is a working example somewhere where I can compare the code against that would help.

Image
Flix
Posts: 456
Joined: Tue Dec 25, 2007 1:06 pm

Re: No Collisions Between Mesh and KinematicCharacterControl

Post by Flix »

The Bullet official character demo loads a a level (.bsp extension as far as I remember) and converts it to a series of btConvexHullShapes.

I don't know why you can't run it, but this is not very important as far as I can understand, since you're using a btBvhTriangleMeshShape as a background (this can create additional issues according to many Bullet users).

What I can suggest is:
1) Be sure you can use the btBvhTriangleMeshShape background you have chosen in a Bullet simulation without any character controller (just throw some cubes on it and see if it's all OK).
2) Look at this demo: http://www.bulletphysics.org/Bullet/php ... =17&t=9666. It uses a btKinamaticCharacterController on a btBvhTriangleMeshShape. You can download the source code and enable a preprocessor macro (probably in CharacterDemo.cpp) that completely disables the Detour Crowd support, so that you can have a plain Character Demo.
3) Please remember that in Bullet the btKinematicCharacterController is marked as unfinished/unreliable (as far as I remember), so use it only if you're ready to face some additional issue :roll:. There are already other forum posts that can be useful (for example: http://www.bulletphysics.org/Bullet/php ... f=9&t=9671 and http://www.bulletphysics.org/Bullet/php ... Controller), but they do not solve all the possible problems.
ckoeber
Posts: 7
Joined: Sat May 10, 2014 2:23 am

Re: No Collisions Between Mesh and KinematicCharacterControl

Post by ckoeber »

First, I really want to thank you and all of the folks who have looked at this issue, even in passing.

The demo you posted does work, so there is at least something to compare to.

I do have a lot of objects, so I may be running into an issue with performance because for some odd reason I get random collisions rather than consistent collisions.

I'll try and switch to a btConvexHullShape for my meshes.

Is there a recommended way to implement a walkable character using the Bullet Physics engine?

I asked a while back but maybe my question was too generic. I saw some people implemented their own character controllers but then people can't walk up stairs (at least no example shown did).

I am pulling my hair out and using my mind on this, so I'll appreciate any assistance provided.
Flix wrote:The Bullet official character demo loads a a level (.bsp extension as far as I remember) and converts it to a series of btConvexHullShapes.

I don't know why you can't run it, but this is not very important as far as I can understand, since you're using a btBvhTriangleMeshShape as a background (this can create additional issues according to many Bullet users).

What I can suggest is:
1) Be sure you can use the btBvhTriangleMeshShape background you have chosen in a Bullet simulation without any character controller (just throw some cubes on it and see if it's all OK).
2) Look at this demo: http://www.bulletphysics.org/Bullet/php ... =17&t=9666. It uses a btKinamaticCharacterController on a btBvhTriangleMeshShape. You can download the source code and enable a preprocessor macro (probably in CharacterDemo.cpp) that completely disables the Detour Crowd support, so that you can have a plain Character Demo.
3) Please remember that in Bullet the btKinematicCharacterController is marked as unfinished/unreliable (as far as I remember), so use it only if you're ready to face some additional issue :roll:. There are already other forum posts that can be useful (for example: http://www.bulletphysics.org/Bullet/php ... f=9&t=9671 and http://www.bulletphysics.org/Bullet/php ... Controller), but they do not solve all the possible problems.
Post Reply