NxOgre + AI

mcaden

03-11-2008 08:30:43

So I have a basic AI - as in it "thinks" at certain intervals (rather than every frame) and wanders around randomly - it's rather stupid and walks clear into walls.

What I'm unsure of is the best way to proceed from there. I understand state systems for AI. I understand basic quaternion/vector math in setting 2 nodes to face eachother and such - but NxOGre can't really do that.

What I don't understand is the best way to do it through turning actors. I know I can't simply turn or relocate an actor in NxOgre, but I need to figure out like, what direction to turn closest to a destination, and how far to turn to get away from an obstacle.

The sweep API has been mentioned, but I see no tutorials or examples on it (even googling, still looking...).

So how do I figure out the Angular velocity to turn accurately and shortest direction to turn? And to complicate that I need my enemies to stay within a certain radius of their spawn point so on top of avoiding obstacles like other monsters walls I need them to steer away from the boundary.

nargil

03-11-2008 11:44:46

v1 = x1,y1,z1 - is your actor position
v2 = x2,y2,z2 - is destination point
v3 = x3,y3,z3 - is Ogre::Vector3::Unit_Z * actor orientation

Ignore the y component (up direction) and turn them into Vector2.

v3.normalize * [cos(r), sin(r); -sin(r), cos(r)] = (v2-v1).normalize

Solve the equation. r is your angle to rotate the actor.

pseudocodeif(r > actor_max_rot_speed * evt.TimeSinceLastFrame) actor.rotateY(actor_max_rot_speed * evt.TimeSinceLastFrame);
else actor.rotateY(r);


For obstacles: Hmmm maybe a bruteforce raycasting ? xD That would be a real AI.

mcaden

03-11-2008 13:12:44

Thanks a ton!

I'll code that in as soon as I finish dealing with eliminating memory leaks.

mcaden

06-11-2008 09:06:58

Hmm...had some difficulty following the equation, but this worked out great. Now I've just gotta deal with obstacle avoidance.


Ogre::Vector3 right = mMainNode->getOrientation()*Ogre::Vector3::UNIT_X;
Ogre::Vector3 dir = mHome - mMainNode->getPosition();
dir.y = 0;
dir.normalise();
Real turnAmount = Ogre::Radian( right.dotProduct(dir) * 200 ).valueRadians();

if( turnAmount < 20 && turnAmount > -20 )
{
forward();
}
else
{
setAngularVelocity( Vector3( 0, turnAmount, 0 ) );
}

mcaden

06-11-2008 10:15:07

No explanation of the sweep API seems available. I can't find on at nVidia or through google and there's nothing on the forums so I guess I'm using rays.

But I have a problem. My level is inside a cavern with the cavern itself being a static triangle mesh with the walls separate from the ground. All rays going in any direction in any distance hit the walls. I'm guessing because the cast is going for a bounding box and not a collision face?

So what would be the best way to test if I actually hit the collision mesh? I want to only hit a wall if I actually hit a wall rather than at all times. I can't really do obstacle avoidance if I'm always registering that there's a wall since I'm within it's bounding box.

NoodlesOnMyBack

06-11-2008 18:55:03

Maybe im wrong, but the origin position of the casted ray is it been occupied by an actor? I had to deactivate it temporaly, here you can see it:


NxF32 CCharacter::rayHitDistance(Vector3 cpos, Vector3 dir)
{

NxShape* characterShape = getCharacterActor(0)->getShapes()[0];

NxRay worldRay;
//worldRay.orig = NxVec3(588.064,900.998,988.782);
worldRay.orig = NxTools::convert(cpos);
worldRay.dir = NxTools::convert(dir);

NxRaycastHit hit;
characterShape->setFlag(NX_SF_DISABLE_RAYCASTING, true);
NxShape* shape = mScene->raycastClosestShape(worldRay, NX_ALL_SHAPES, hit);
characterShape->setFlag(NX_SF_DISABLE_RAYCASTING, false);

if(!mPause)
mWorldRay = worldRay;

return shape ? hit.distance : 0; //NX_MAX_F32
}



What if you check that the distance from the actor to the hit point is <= than the width of the actor, in that case the buddy hit the wall.

mcaden

07-11-2008 05:42:26

When I was testing raycasts to get them to work I was casting it from the camera itself straight down. The camera doesn't have an actor.

If I have:

Walls - Triangle Collision Mesh
Floor - Triangle Collision Mesh
Character - Sphere Shape
Various Enemies - Sphere Shape

Each cast going straight down would hit the Walls and the Floor. If I jumped the player over a mob and the camera followed my ray would hit walls, mob, floor. If I steered my camera over my character I'd get walls, character, floor.

The walls don't close on the bottom, but they register with every raycast straight down. That doesn't seem right to me.

I do thank you for the deactivation tip Noodles, when I start programming the obstacle avoidance I'll obviously need to have the origin being at the enemy. I took a break from AI to work on content a bit, but I'm going back to it soon.