NxOgre character

zync

08-07-2010 15:34:24

Hi,
I'm new to NxOgre and I'm trying to make a 3d person game for a college project and it must be finished by next friday so I really can't spend much time looking through documentation as I would like.

My question is: how can I implement the characters?
I'm using version 1.5.4.

I tried using the Character class but it doesn't seem to exist in this version.

I really need some help. (my teachers are crazy xD)

betajaen

08-07-2010 15:44:39

The Character system exists in the latest commit of Detritus (NxOgre 1.5.6) it just doesn't have any helper scenenode/entity classes and functions as you would expect - you'd have to write it yourself. Tisn't difficult.

I am writing that in Critter now (with some extra features such as animation support, basic collision detection/response) but it may be a while.

zync

10-07-2010 02:40:44

Thanks for the reply.

I'm a bit confused.. I downloaded detritus version 1.6.3329, the thing is, the VC solution only has the NXOgre project. I found a tutorial (http://www.ogre3d.org/tikiwiki/Detritus ... =Libraries) saying that it should also have the project NxOgreCharacterController.
Version 1.5.4 also had the OGRE3DRenderSystem project.

I know I'm jumping in on advanced things without knowing the basics, but right now all I need is to have character's standing up and not falling through the terrain.

thanks again

betajaen

10-07-2010 09:33:23

It's all in one now project file.

But you do need to enable it. Go into the file NxOgreConfiguration.h and set the line

#define NxOgreHasCharacterController 0

So it's

#define NxOgreHasCharacterController 1

Then recompile.

zync

10-07-2010 22:58:40

What about NxOgre::TimeController? Can't find it..
is there example code for this version? where can I find it?

betajaen

10-07-2010 23:08:58

http://github.com/betajaen/nxogretutorials

It has been merged into World.

mWorld->advance(deltaTime);

zync

11-07-2010 05:20:14

I think I created a character, at least there's something in the visual debugger, but it isn't affected by gravity

I used this line of code:
mCharacterController = scene->createCharacterController(NxOgre::SimpleCapsule(50,120) ,NxOgre::Vec3(0,0,0));

I can move it and other actors collide with it.

thanks

betajaen

11-07-2010 09:49:32

No it wouldn't, that behaviour isn't really default with the character controller. Actually the PhysX Character is quite bare, and you have to fill in some bits yourself.

What I normally do is;

- Sub-class the character controller, and create a "move" function of my own.
- From the last collision flags, you can tell if it's on the ground or not, hit the ceiling or touching anything.
- If it's not on the ground then you should add some sort of gravity acceleration.
- Move the character.
- Look at the flags, and decide if its on the ground again.

[Edit]

Eventually it can be a little complicated, as per the main current Critter AnimatedCharacter functions I've been working on.

void AnimatedCharacter::move(const NxOgre::Vec3& normalised_movement_vector)
{
mMoveVector += normalised_movement_vector;
mMoveVector.clamp(NxOgre::Vec3::NEGATIVE_1_1_1, NxOgre::Vec3::POSITIVE_1_1_1);
}

void AnimatedCharacter::_processSituation(float deltaTime)
{
// CALCULATE_HORIZONTAL_MOVEMENT
//////////////////////////////////////////////////////////
mMoveVector.x = getHorizontalVelocity(mMoveVector.x);
mMoveVector.z = getHorizontalVelocity(mMoveVector.z);

if (mInAir)
{
mMoveVector.x *= mHorizontalAirModifier;
mMoveVector.z *= mHorizontalAirModifier;
}

//////////////////////////////////////////////////////////

// CALCULATE_VERTICAL_MOVEMENT
//////////////////////////////////////////////////////////
if (mInAir == false)
{
if (mMoveVector.y > 0)
mMoveVector.y *= mJumpVelocity;
}
//////////////////////////////////////////////////////////

// CALCULATE_GRAVITY_ACCELERATION
//////////////////////////////////////////////////////////
if (mGravityModifier != 0.0f && lastCollisionDown() == false && mInAir)
mMoveVector += (mScene->getGravity() * mGravityModifier);
//////////////////////////////////////////////////////////


// CALCULATE_TURNING
//////////////////////////////////////////////////////////
mYaw += mTurningYaw;
// TODO: Multiply vector with yaw for a direction.
mDirection.fromAngleAxis(mYaw, mUpAxis);
//////////////////////////////////////////////////////////

// PLANE CHECK
//////////////////////////////////////////////////////////
if (getFootPosition().y < 0)
{
mMoveVector.y = -getFootPosition().y;
}

// MULTIPLY_VECTOR_BY_TIME_PASSED
//////////////////////////////////////////////////////////
mMoveVector *= deltaTime;
//////////////////////////////////////////////////////////

// APPLY CHANGES
//////////////////////////////////////////////////////////

CharacterController::move(mMoveVector);
mMoveVector.zero();
mTurningYaw = 0;
//////////////////////////////////////////////////////////


// POST COLLISION CHECK
//////////////////////////////////////////////////////////
// TODO: Check flags to see if off ground or touched something.
//
// Check to see if we are in the air.
if (lastCollisionDown() == false)
{

mAirTimer += deltaTime;

// Check to see if we've been in the air long enough to stop any real movement.
if (mAirTimer >= ANIMATED_CHARACTER_MIN_AIR_TIME)
{
mInAir = true;
// TODO: Store a copy of the velocity at this point and add it to future updates whilst in
// air to keep the momentum.
// animate falling begin
// call callback
}
else
{
// animated falling loop
}

}
else if (lastCollisionDown())
{
// We've been in the air for more than MIN_AIR_TIME
if (mInAir)
{
mInAir = false;
// animated falling end
// call callback.
}

// Reset the air timer if needed.
if (mAirTimer)
mAirTimer = 0.0f;

}
//
//
//////////////////////////////////////////////////////////

}

void AnimatedCharacter::_processRendering(float deltaTime)
{
mNode->setPosition(getRenderPosition().as<Ogre::Vector3>());
mNode->setOrientation(mDirection.as<Ogre::Quaternion>());
}

zync

11-07-2010 17:46:42

move() doesn't seem to update the position. The capsule moves in the visual debugger but the position vector isn't updated.

betajaen

11-07-2010 19:00:21

Yeah, it's a bug I found with the PhysX CC, over a year ago. Which I then forgot, and remembered when I started using it again. I don't know why they haven't fixed it yet.

If you change the following function in NxOgreCharacterController.cpp and recompile it should work:

Vec3 CharacterController::getPosition() const
{
return Vec3(mActor->getGlobalPosition());
}

zync

11-07-2010 23:46:37

Sorry to be constantly annoying you.

This code belongs to a sub-class of character controller:

move(NxOgre::Vec3(0,-1,0));
getBodyNode()->setPosition(getPosition().as<Ogre::Vector3>() - Ogre::Vector3(0,68,0));

if(getLastCollisionFlags()!=0)
{
MessageBoxA( NULL, StringConverter::toString(getLastCollisionFlags()).c_str(), "lastCollisionFlags", MB_OK | MB_ICONERROR | MB_TASKMODAL);
}


getLastCollisionFlags() never changes, even if there is a collision. Do I need to initialize it somehow?

betajaen

12-07-2010 08:47:12

Those flags should change if you move against something solid. Remember "move" is a like a directional vector, not a target position. It should be small in values and normalised.

I've attached my AnimatedCharacter files that come with Critter. I can't make a commit yet, because it's still incomplete. Hopefully, you should make some use out of it.

zync

12-07-2010 12:25:59

Those flags only change when it collides with another character.. the characters collide just fine without any intersection

I have a plane:

NxOgre::PlaneGeometryDescription plane;
scene->createSceneGeometry(plane);


and a box shaped body:

Critter::BodyDescription bodyDescription;
bodyDescription.mMass = 40.0f; // Set the mass to 40kg.
// Finally create the body.
NxOgre::BoxDescription bdesc(100,1,100);
Critter::Body *b = mRenderSystem->createBody(bdesc, NxOgre::Vec3(0,0,0), "EbonySword.mesh", bodyDescription);


the box collides with both the plane and the character but there are no flags raised.

betajaen

12-07-2010 12:52:21

Ahh, yes. This has been a bug with PhysX for the last five years.

I found the best way to get around that is to have a really large flatish cube (0.5 metres thick) about the same size of your geometry placed where the plane is. The character will collide with the cube whilst everything else will collide with both the plane and cube.