NxOgre character
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.
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.
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
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>());
}
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());
}
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.
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.