Swimming AI Bots and setMoveDestination
by Alex (Stalker) Sakablukow · in Torque Game Engine · 08/07/2007 (4:02 am) · 4 replies
I Have a problem with the "setMoveDestination"-Funktion.
I have added the swimming ressource:
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4348
so my players and bots can swim. All works fine, and if i command bot to follow with "followPlayer"-Function, he swim in all directions.
But if i use setMoveDestination, the bot swim only in xy, but not z-axis.
I have added z-axis to the getAIMove, but with no result.
With z-Axis in the function, and with out its still same. "followPlayer" works, but "setMoveDestination" ignore z-axis.
Maybe someone has already worked on similar problem and solwed it?
I have added the swimming ressource:
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4348
so my players and bots can swim. All works fine, and if i command bot to follow with "followPlayer"-Function, he swim in all directions.
But if i use setMoveDestination, the bot swim only in xy, but not z-axis.
I have added z-axis to the getAIMove, but with no result.
With z-Axis in the function, and with out its still same. "followPlayer" works, but "setMoveDestination" ignore z-axis.
Maybe someone has already worked on similar problem and solwed it?
#2
Its all right with the coordinates, and looks like this in the script code:
08/07/2007 (6:52 am)
No, it is another issue ;)Its all right with the coordinates, and looks like this in the script code:
%transform=$player.getTransform(); %Spos=getWord(%transform,0) SPC getWord(%transform,1) SPC getWord(%transform,2); %obj.setMoveDestination(%Spos);Where $player is my active player, and %obj ist my bot.
#3
08/07/2007 (6:54 am)
And here is my modifed getAIMove-function:bool AIBot::getAIMove(Move *movePtr)
{
*movePtr = NullMove;
// Use the eye as the current position.
MatrixF eye;
getEyeTransform(&eye);
Point3F location = eye.getPosition();
Point3F rotation = getRotation();
// Orient towards the aim point, aim object, or towards
// our destination.
if (mAimObject || mAimLocationSet || mMoveState == ModeMove) {
// Update the aim position if we're aiming for an object
if (mAimObject)
mAimLocation = mAimObject->getPosition() + mAimOffset;
else
if (!mAimLocationSet)
mAimLocation = mMoveDestination;
Point3F vDiff = mAimLocation - location;
vDiff.normalize();
mOrientation.normalize();
mOrientation.interpolate(mOrientation,vDiff,mTurningSpeed);
F32 xDiff = mOrientation.x;
F32 yDiff = mOrientation.y;
if (!isZero(xDiff) || !isZero(yDiff)) {
// First do Yaw
// use the cur yaw between -Pi and Pi
F32 curYaw = rotation.z;
while (curYaw > M_2PI)
curYaw -= M_2PI;
while (curYaw < -M_2PI)
curYaw += M_2PI;
// find the yaw offset
F32 newYaw = mAtan( 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.
if (!mAimObject && !mAimLocationSet) {
// Level out if were just looking at our next way point.
Point3F headRotation = getHeadRotation();
movePtr->pitch = -headRotation.x;
}
else {
// 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 = mAimLocation.z - location.z;
F32 horzDist = mSqrt(xDiff * xDiff + yDiff * yDiff);
F32 newPitch = mAtan( horzDist, vertDist ) - ( M_PI / 2.0f );
if (mFabs(newPitch) > 0.01) {
Point3F headRotation = getHeadRotation();
movePtr->pitch = newPitch - headRotation.x;
}
}
}
}
else {
// Level out if we're not doing anything else
Point3F headRotation = getHeadRotation();
movePtr->pitch = -headRotation.x;
}
// Move towards the destination
if (mMoveState == ModeMove) {
F32 xDiff = mMoveDestination.x - location.x;
F32 yDiff = mMoveDestination.y - location.y;
F32 zDiff = mMoveDestination.z - location.z;
// Check if we should mMove, or if we are 'close enough'
if (mFabs(xDiff) < mMoveTolerance && mFabs(yDiff) < mMoveTolerance && mFabs(zDiff) < mMoveTolerance) { // && mFabs(zDiff) < mMoveTolerance
mMoveState = ModeStop;
throwCallback("onReachDestination");
}
else {
// Build move direction in world space
//====================================================================================
// Movement Calculation with Z Axis
if (isZero(xDiff))
{
if (mFabs(yDiff)>mFabs(zDiff))
{
F32 value = mFabs(zDiff / yDiff);
movePtr->z = (location.z > mMoveDestination.z)? -value : value;
movePtr->y = (location.y > mMoveDestination.y)? -1 : 1;
}
else
{
F32 value = mFabs(yDiff / zDiff);
movePtr->y = (location.y > mMoveDestination.y)? -value : value;
movePtr->z = (location.z > mMoveDestination.z)? -1 : 1;
}
}
else
if (isZero(yDiff))
{
if (mFabs(xDiff)>mFabs(zDiff))
{
F32 value = mFabs(zDiff / xDiff);
movePtr->z = (location.z > mMoveDestination.z)? -value : value;
movePtr->x = (location.x > mMoveDestination.x)? -1 : 1;
}
else
{
F32 value = mFabs(xDiff / zDiff);
movePtr->x = (location.x > mMoveDestination.x)? -value : value;
movePtr->z = (location.z > mMoveDestination.z)? -1 : 1;
}
}
else
if (isZero(zDiff))
{
if (mFabs(yDiff)>mFabs(xDiff))
{
F32 value = mFabs(xDiff / yDiff);
movePtr->x = (location.x > mMoveDestination.x)? -value : value;
movePtr->y = (location.y > mMoveDestination.y)? -1 : 1;
}
else
{
F32 value = mFabs(yDiff / xDiff);
movePtr->y = (location.y > mMoveDestination.y)? -value : value;
movePtr->x = (location.x > mMoveDestination.x)? -1 : 1;
}
}
else
if ( mFabs(xDiff)>=mFabs(yDiff) && mFabs(xDiff)>=mFabs(zDiff) )
{
F32 value1 = mFabs(yDiff / xDiff);
F32 value2 = mFabs(zDiff / xDiff);
movePtr->y = (location.y > mMoveDestination.y)? -value1 : value1;
movePtr->z = (location.z > mMoveDestination.z)? -value2 : value2;
movePtr->x = (location.x > mMoveDestination.x)? -1 : 1;
}
else
if ((mFabs(yDiff)>=mFabs(xDiff)) && (mFabs(yDiff)>=mFabs(zDiff)))
{
F32 value1 = mFabs(xDiff / yDiff);
F32 value2 = mFabs(zDiff / yDiff);
movePtr->x = (location.x > mMoveDestination.x)? -value1 : value1;
movePtr->z = (location.z > mMoveDestination.z)? -value2 : value2;
movePtr->y = (location.y > mMoveDestination.y)? -1 : 1;
}
else
if ((mFabs(zDiff)>=mFabs(xDiff)) && (mFabs(zDiff)>=mFabs(yDiff)))
{
F32 value1 = mFabs(xDiff / zDiff);
F32 value2 = mFabs(yDiff / zDiff);
movePtr->x = (location.x > mMoveDestination.x)? -value1 : value1;
movePtr->y = (location.y > mMoveDestination.y)? -value2 : value2;
movePtr->z = (location.z > mMoveDestination.z)? -1 : 1;
}
// Rotate the move into object space
Point3F newMove;
MatrixF moveMatrix;
moveMatrix.set(EulerF(0, 0, 0));
moveMatrix.mulV( Point3F( movePtr->x, movePtr->y, movePtr->z ), &newMove );
movePtr->x = -newMove.x;
movePtr->y = -newMove.y;
movePtr->z = -newMove.z;
// 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;
if (dist < maxDist)
speed *= dist / maxDist;
movePtr->x *= speed;
movePtr->y *= speed;
movePtr->z *= speed;
}
else {
movePtr->x *= mMoveSpeed;
movePtr->y *= mMoveSpeed;
movePtr->z *= mMoveSpeed;
}
// We should check to see if we are stuck...
if (location == mLastLocation) {
throwCallback("onMoveStuck");
mMoveState = ModeStop;
}
}
}
if (mAimObject) {
MatrixF eyeMat;
getEyeTransform(&eyeMat);
eyeMat.getColumn(3,&location);
Point3F targetLoc = mAimObject->getBoxCenter();
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;
}
}
for( int i = 0; i < MaxTriggerKeys; i++ )
movePtr->trigger[i] = getImageTriggerState(i);
return true;
}Its not really optimized, i have wroten this in about 15 min ;) but it seems to work equal to the "old" function.
#4
one from this ressource:
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4348
one from this:
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=11543
and one written by me, but still with no result.
The bots CAN swim in all axis, since followPlayer works.
It must be something else, what broke setMoveDestination.
08/09/2007 (11:14 pm)
Hmm have tested it now with 3 different Player::updateMove-functions,one from this ressource:
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4348
one from this:
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=11543
and one written by me, but still with no result.
The bots CAN swim in all axis, since followPlayer works.
It must be something else, what broke setMoveDestination.
Torque Owner game4Rest
colyd studio
This is another thread talking about the issue you're talking about.