Multiple Character Controllers Issue

bsterling
Posts: 2
Joined: Sat Aug 15, 2009 7:30 am

Multiple Character Controllers Issue

Post by bsterling »

Hello,

I am using bullet version 2.70 on a 3d shooter and have been using a pretty modified version of the character demo for collision detection and resolution.

My issue is that we have multiple entities loaded as my game is multiplayer, and so i create multiple character style controllers.

When i create entities, i do the following...

Code: Select all

void PhysicController::Init( void )
{
EntityUnit* parent = (EntityUnit*)GetParent();
	SYSTEM_ASSERT(parent != NULL, "Controller not assigned to a valid entity" );
    core::Vector vecPos;
    parent->GetPosition(vecPos);
    mEntityPosition = btVector3(vecPos.x, vecPos.y, vecPos.z);

	m_currentPosition = mEntityPosition;//m_currentposition is a btVector3

    btTransform startTransform;
    startTransform.setIdentity ();
    startTransform.setOrigin (mEntityPosition);

    //create volume in local space
    btVector3 spherePositions[2];
    btScalar sphereRadii[2];

    sphereRadii[0] = .5f;
    sphereRadii[1] = .5f;
    spherePositions[0] = btVector3 (0.0, (mEntityPosition.getY() + 2/btScalar(2.0) ), 0.0);
    spherePositions[1] = btVector3 (0.0, (mEntityPosition.getY() + 4/btScalar(2.0) ), 0.0);

    m_halfHeight = 5/btScalar(2.0);

//mShape is a multisphere shape
    mShape = new btMultiSphereShape (btVector3(5/btScalar(2.0), 5/btScalar(2.0), 5/btScalar(2.0)), &spherePositions[0], &sphereRadii[0], 2);


    mCollisionObject = new btCollisionObject ();

    //move collision volume to world space
    mCollisionObject->setWorldTransform(startTransform);
    mCollisionObject->setCollisionShape (mShape);
    mCollisionObject->setCollisionFlags (btCollisionObject::CF_NO_CONTACT_RESPONSE);

	PhysicsManager::Get().GetCollisionWorld()->setInternalTickCallback(playerMoveCallback, this);

	//some custom callback sample
	m_customPairCallback = new MyCustomOverlappingPairCallback(mCollisionObject);
	PhysicsManager::Get().GetSweep()->setOverlappingPairUserCallback(m_customPairCallback);
	registerPairCacheAndDispatcher(m_customPairCallback->getOverlappingPairCache(), PhysicsManager::Get().GetDispatcher());

    PhysicsManager::Get().GetCollisionWorld()->addCollisionObject(mCollisionObject,btBroadphaseProxy::DebrisFilter, btBroadphaseProxy::StaticFilter);
}
This works great when i load only one entity, the callback gets called which calls my prestep and move functions, though i combined the stepUP(), stepforwardandstrafe() and stepdown() functions into one ResolveCollisionMovement() function with a 3d movement vector because we are flying...

now the next time i create an entity the setInternalTickCallback() function call seems to set the callback to call only the new entities controller and not the original one.

each entity is assigned an ID when they are loaded in the worldmanager so i know that with one character in the world it the callback calls the physicController functions i want on EntityID == 0, but once i create the second one, it only calls the physicController functions on EntityID == 1...

my callback function is declared as a static function as follows...

Code: Select all

static void playerMoveCallback(btDynamicsWorld* dynamicsWorld, btScalar timeStep)
{
	PhysicController* pPhysicController = (PhysicController*) dynamicsWorld->getWorldUserInfo();
	pPhysicController->PreStep();
	pPhysicController->ResolveCollisionMovement();
}
so it seems that the line ...

Code: Select all

PhysicController* pPhysicController = (PhysicController*) dynamicsWorld->getWorldUserInfo();
will only return the most recent callback set...

any ideas on how to have this return the right worlduserinfo* maybe i can overload the get function in the dynamics world or something...

i understand this is kind of complicated to explain, so if it is at all unclear i can give more information... but any help is appreciated.
bsterling
Posts: 2
Joined: Sat Aug 15, 2009 7:30 am

Re: Multiple Character Controllers Issue

Post by bsterling »

well for now i have added a check that the parent is the local entity before doing any of the PhysicController::Init stuff, so now each game only has one collision object in the world... which works for how we do locomotion and networking as collision only needs to be handled on the client, not the server...

it works, but i would still like to know this in case i decided to add more objects to my world... so far my environment is one giant btBvhTriangleMesh loaded one triangle at a time from .x files as a rigidbody and the above object for the character. the trianglemesh is about 10 000 polys i think.
S.Lundmark
Posts: 50
Joined: Thu Jul 09, 2009 1:46 pm

Re: Multiple Character Controllers Issue

Post by S.Lundmark »

You can always use btCollisionObject::getUserPointer / btCollisionObject::setUserPointer. It would be on the ghost-object that the character-controller owns.

I suggest that you upgrade to Bullet 2.76 since a lot has happened since bullet 2.70.

Cheers
/Simon