Physx Chararacter controller - collide with floor

joaopccosta

07-12-2010 14:53:03

Hi guys!

This might be my "noobishness" about nxogre and physx in general but... i'm trying to use the PhysX Character Controller within NxOgre. I've created a capsule... all is fine but i can't seem to get the capsule to "collide" with the floor, which was made with nxogre.
It just runs through it (because of the deafult gravity). I can't get it to collide with triangle static meshes either :\
But it collides with some convex meshes i have around (some spheres).

Am i missing something? o.O

Thanks!


Ogre::MeshManager::getSingleton().createPlane("floor", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Ogre::Plane(Ogre::Vector3::UNIT_Y, 0),
1000,1000,1,1,true,1,1,1, Ogre::Vector3::UNIT_Z);

Ogre::Entity* floor = mSceneMgr->createEntity("Floor", "floor");
floor->setMaterialName(name);

floor->setCastShadows(false);
mSceneMgr->getRootSceneNode()->attachObject(floor);


Character controller creation (based on the MyCharacterController used in Lesson1201 of the PhysX SDK)

gAllocator = new UserAllocator;

mManager = NxCreateControllerManager(gAllocator);
mCharacterController = new MyCharacterController(mManager,mScene->getScene(),NxVec3(0,10,0),0.8,1.5);


frameRenderingQueued updates the character controller

updateCharacters();
mScene->getScene()->simulate(evt.timeSinceLastFrame);
mScene->getScene()->flushStream();
mScene->getScene()->fetchResults(NX_RIGID_BODY_FINISHED, true);


updateCharacters() moves the character around

NxU32 collisionFlags;
NxVec3 disp = defaultGravity;
disp.x+=mX;
disp.y+=mY;
disp.z+=mZ;

mCharacterController->Move(disp,collisionFlags);
mManager->updateControllers();

betajaen

07-12-2010 15:49:24

You need to set the collision flags to include the floor's group.

I'm probably going to release some of the new CC code on BuggySwires in a few days, you can use that if you like.

http://img37.imageshack.us/img37/4869/animz.jpg

joaopccosta

09-12-2010 10:31:49

Hmmm I'll give it a shot with PhysX and then i'll try it with your new code then. At least will make the code cleaner and simpler i guess 8)

Thanks!

betajaen

09-12-2010 10:37:05

Basically it goes;

enum ControllerShapeGroups
{
NonCollidable = 0, // Things that the character controller can go through such as Ghosts or tiny
// objects like small rocks.
Walls = 1, // Walls, Floors and other static geometry that can't be moved.
Objects = 2 // Boxes, Barrels and other dynamic parts of the scene that can be moved by pushing.
};

unsigned int mask = (Walls << 1) | (Objects << 1);


Making sure you set the groups up for the appropriate shapes
BoxDescription box_desc(2500,1,2500);
box_desc.mGroup = Walls;


Then passing on the mask to the character when moving:

character->move(direction, mask, 0.001f, collisionFlags, sharpness);


Edit

I forgot to mention. The PhysX character controller, does not collide with ground planes - ever. I don't think it's mentioned in the documentation, and something I've had to bear all these years. Just use a very large flat cube (1m thickness), just underneath the ground plane attached to a static geometry (usually the same one the plane is attached to).

joaopccosta

09-12-2010 12:09:40

Holy sh***!
Ahaha that's like... wierd! PhysX is "super advanced" but... oh well... i'll try it with the giant "cube" floor for now :P

joaopccosta

09-12-2010 14:56:21

Hmmm my character controller is not colliding with static meshes either. :\

the header file defines the groups:

enum CollisionGroup
{
GROUP_NON_COLLIDABLE, // = 0
GROUP_COLLIDABLE_NON_PUSHABLE, // = 1
GROUP_COLLIDABLE_PUSHABLE, // = 2
};


i've defined the mask like you suggested in the mycontroller class, since the move method is defined here:
//#define COLLIDABLE_MASK (1<<GROUP_COLLIDABLE_NON_PUSHABLE)
unsigned int COLLIDABLE_MASK = (GROUP_COLLIDABLE_NON_PUSHABLE << 1) | (GROUP_COLLIDABLE_PUSHABLE << 1);


void MyCharacterController::Move(const NxVec3 &disp, NxU32 &flag)
{
mController->move(disp, COLLIDABLE_MASK, 0.001, flag);
}


then, basically, by creating the floor with the really wide cube as a triangle mesh, it should work right? :\ (by assigning the BoxDescription.mGroup = GROUP_COLLIDABLE_NON_PUSHABLE or just putting it = 1)

i don't know if i made myself clear... :s
thanks :)

joaopccosta

09-12-2010 15:03:30

talked too soon :P
problem solved (regarding static meshes around the scenario).
Moving on to the floor problem...

betajaen

09-12-2010 15:03:51

Yep, it should work.

Remember though Triangle Meshes have materials per *face*, by default they are all zero. So you may want to re-cook them to the new group number. If that is a pain to do so; what you could do is use the latest flour to disassemble the mesh, then do a find/replace in the flower file on the group numbers, then cook it again.

[Edit]

Argh, replied to me whilst I was typing that up. Job almost done then. This is what Tutorial 1201 uses for a cube floor, it should work with you;

BoxDescription box_desc(2500,1,2500);
box_desc.mGroup = Walls;
mScene->createSceneGeometry(box_desc, Vec3(0,-0.5,0));

joaopccosta

09-12-2010 16:01:20

Problem solved.

Yeah i made a private method for on-the-fly nxs cooking :P
It works! You sir, saved my life!

cheers!

joaopccosta

10-12-2010 11:18:14

one more little thing...

i've got a vector<MyCharacterController*> mCharacters;

but i get a runtime error when trying to destroy each created controller :S
(Runtime Error R6025 - pure virtual function call)


for (i = 0; i<mCharacters.size(); i++){
mRenderSystem->destroy
character = mCharacters.at(0);
character->~MyCharacterController();
}
createdCharacters = 0;


any clue? :\

betajaen

10-12-2010 11:54:14

for (i = 0; i<mCharacters.size(); i++){
delete mCharacters[i];
}
mCharacters.clear();
createdCharacters = 0;


?

joaopccosta

10-12-2010 14:03:07

i feel dumb... :P