AI and Z axis help
by Andy Simon · in Torque 3D Professional · 08/19/2009 (12:22 pm) · 1 replies
Hey guys,
Im making an elevator with movement that is controlled by the AI. I made a class based off AIplayer that uses a flying vehicle instead of a player. I was able to get it work :D. However its not moving naturally like an elevator should and moving more like an airplane. (its actually kind of funny watching it.)
So in my GetAIMove function, I need to figure out how to restrict movement to only the Z axis.
(this is from the ai complex flying vehicles resource)
I tried figuring out how this function calculates the movement. It seems that it aims itself to the location it wants to fly to. I'm not sure of the variables and other tools available to me to calculate only Z axis movement since I'm very new to this source code (and C++, I am intermediate in java and C#).
I think this is as simple as figuring out where the object is on the Z axis, and then figuring out where the next path node is on the Z axis, then deciding whether that is "up or down" and then applying the movement.
Hopefully someone can list out a few steps for me to figure out how to do Z axis movement. Thanks for everyones help!
Im making an elevator with movement that is controlled by the AI. I made a class based off AIplayer that uses a flying vehicle instead of a player. I was able to get it work :D. However its not moving naturally like an elevator should and moving more like an airplane. (its actually kind of funny watching it.)
So in my GetAIMove function, I need to figure out how to restrict movement to only the Z axis.
(this is from the ai complex flying vehicles resource)
bool AIElevator::getAIMove(Move *movePtr)
{
*movePtr = NullMove;
Point3F location;
Point3F rotation;
F32 myTol = mMoveTolerance * 7; //Andy Change from 7 to 1
// now we use local space
location.x = location.y = location.z = 0.0f;
rotation.x = rotation.z = 0.0f;
rotation.y = 1.0f;
MatrixF invTrans = getTransform();
invTrans.inverse();
// <- phdana testing
// Orient towards the aim point, aim object, or towards
// our destination.
// NOTE: you must change the protection these data members
// of AIElevator from private to protected to get this
// to compile...
if (mAimObject || mAimLocationSet || mMoveState == ModeMove)
{
// Update the aim position if we're aiming for an object
if (mAimObject)
{
Con::printf("---------wE were aiming for an object--------------3-3-3-3");
mAimLocation = mAimObject->getPosition();
}
// transform to local space
Point3F aimLocation;
invTrans.mulP(mAimLocation,&aimLocation);
F32 xDiff = aimLocation.x - location.x;
F32 yDiff = aimLocation.y - location.y;
if(!mIsZero(xDiff) || !mIsZero(yDiff)) {
// First do Yaw
// use the cur yaw between -Pi and Pi
F32 curYaw = rotation.z;
while (curYaw > M_2PI_F)
curYaw -= M_2PI_F;
while (curYaw < -M_2PI_F)
curYaw += M_2PI_F;
// find the yaw offset
F32 newYaw = mAtan2( xDiff, yDiff );
F32 yawDiff = newYaw - curYaw;
// make it between 0 and 2PI
if( yawDiff < 0.0f )
yawDiff += M_2PI;
else if( yawDiff >= M_2PI )
yawDiff -= M_2PI;
// now make sure we take the short way around the circle
if( yawDiff > M_PI )
yawDiff -= M_2PI;
else if( yawDiff < -M_PI )
yawDiff += M_2PI;
movePtr->yaw = yawDiff;
// Next do pitch. This should be adjusted to run from the
// eye point to the object's center position. Though this
// works well enough for now.
F32 vertDist = aimLocation.z - location.z;
F32 horzDist = mSqrt(xDiff * xDiff + yDiff * yDiff);
F32 newPitch = mAtan2( horzDist, vertDist ) - ( M_PI_F / 2.0f );
// phdana testing ->
//movePtr->pitch = newPitch - rotation.x;
// <- phdan testsing
}
}
else
{
// Level out if we're not doing anything else
// Point3F headRotation = getRotation();
// movePtr->pitch = -headRotation.x;
}
// Move towards the destination
if (mMoveState == ModeMove)
{
Con::printf("--------<Moving towards destination, hold on-------------2-2-");
// transform to local space
Point3F moveDestination;
invTrans.mulP(mMoveDestination,&moveDestination);
F32 xDiff = moveDestination.x - location.x;
F32 yDiff = moveDestination.y - location.y;
F32 zDiff = mMoveDestination.z - location.z;
// Check if we should mMove, or if we are 'close enough'
if ((mFabs(xDiff) < myTol) && (mFabs(yDiff) < myTol) && (mFabs(zDiff) < myTol ))
{
mMoveState = ModeStop;
throwCallback("onReachDestination");
}
else
{
// Build move direction in world space
if (mIsZero(xDiff))
{
movePtr->y = (location.y > mMoveDestination.y) ? -1.0f : 1.0f;
// andy change // movePtr->y = 1; Always go forward
}
else
{
if (mIsZero(yDiff))
{
movePtr->x = (location.x > mMoveDestination.x) ? -1.0f : 1.0f;
//andy change //movePtr->x = (location.x > mMoveDestination.x)? -1 : 1;
}
else
{
if (mFabs(xDiff) > mFabs(yDiff))
{
F32 value = mFabs(yDiff / xDiff);
movePtr->y = (location.y > mMoveDestination.y) ? -value : value;
movePtr->x = (location.x > mMoveDestination.x) ? -1.0f : 1.0f;
//F32 value = mFabs(yDiff / xDiff);
//movePtr->x = (location.x > mMoveDestination.x)? -1 : 1;
//movePtr->y = value;
}
else
{
F32 value = mFabs(xDiff / yDiff);
movePtr->x = (location.x > mMoveDestination.x) ? -value : value;
movePtr->y = (location.y > mMoveDestination.y) ? -1.0f : 1.0f;
//andy change some bullshit
//movePtr->x = (location.x > mMoveDestination.x)? -value : value;
//movePtr->y = 1;
}
}
}
}
// Rotate the move into object space (this really only needs
// a 2D matrix)
Point3F newMove;
MatrixF moveMatrix;
moveMatrix.set(EulerF(0.0f, 0.0f, -(rotation.z + movePtr->yaw)));
moveMatrix.mulV( Point3F( movePtr->x, movePtr->y, 0.0f ), &newMove );
// Set movement speed. We'll slow down once we get close
// to try and stop on the spot...
if (mMoveSlowdown)
{
F32 speed = mMoveSpeed;
F32 dist = mSqrt(xDiff*xDiff + yDiff*yDiff);
F32 maxDist = 5.0f;
if (dist < maxDist)
speed *= dist / maxDist;
movePtr->x *= speed;
movePtr->y *= speed;
}
else
{
movePtr->x *= mMoveSpeed;
movePtr->y *= mMoveSpeed;
}
// We should check to see if we are stuck...
if (location == mLastLocation)
{
throwCallback("onMoveStuck");
mMoveState = ModeStop;
}
}
// Test for target location in sight if it's an object. The LOS is
// run from the eye position to the center of the object's bounding,
// which is not very accurate.
if (mAimObject) {
MatrixF eyeMat;
getEyeTransform(&eyeMat);
eyeMat.getColumn(3,&location);
Point3F targetLoc = mAimObject->getBoxCenter();
// This ray ignores non-static shapes. Cast Ray returns true
// if it hit something.
RayInfo dummy;
if (getContainer()->castRay( location, targetLoc,
InteriorObjectType | StaticShapeObjectType | StaticObjectType |
TerrainObjectType, &dummy)) {
if (mTargetInLOS) {
throwCallback( "onTargetExitLOS" );
mTargetInLOS = false;
}
}
else
if (!mTargetInLOS) {
throwCallback( "onTargetEnterLOS" );
mTargetInLOS = true;
}
}
// Replicate the trigger state into the move so that
// triggers can be controlled from scripts.
for( int i = 0; i < MaxTriggerKeys; i++ )
movePtr->trigger[i] = getImageTriggerState(i);
return true;
}I tried figuring out how this function calculates the movement. It seems that it aims itself to the location it wants to fly to. I'm not sure of the variables and other tools available to me to calculate only Z axis movement since I'm very new to this source code (and C++, I am intermediate in java and C#).
I think this is as simple as figuring out where the object is on the Z axis, and then figuring out where the next path node is on the Z axis, then deciding whether that is "up or down" and then applying the movement.
Hopefully someone can list out a few steps for me to figure out how to do Z axis movement. Thanks for everyones help!
About the author
Torque 3D Owner Andy Simon
Either way, the elevator moves and I can jump on it.. I need to play with the phyics though because ill crash the elevator when i jump on haha