Пример #1
0
void gearScenePreview::onDraw()
{
	monoWrapper::mono_engine_update(m_pPreviewWorldPtr, Timer::getDtinSec());
	followObject(Timer::getDtinSec(), m_pSelectedObj);

	monoWrapper::mono_engine_renderSingleObject(m_pPreviewWorldPtr, m_pSelectedObj, NULL, object3d::eObject3dBase_RenderFlag_NormalRenderPass);
}
Пример #2
0
/**
 * This method calculates the moves for the AI player
 *
 * @param movePtr Pointer to move the move list into
 */
bool AIPlayer::getAIMove(Move *movePtr)
{
   *movePtr = NullMove;

   // Use the eye as the current position.
   MatrixF eye;
   getEyeTransform(&eye);
   Point3F location = eye.getPosition();
   Point3F rotation = getRotation();

#ifdef TORQUE_NAVIGATION_ENABLED
   if(mDamageState == Enabled)
   {
      if(mMoveState != ModeStop)
         updateNavMesh();
      if(!mFollowData.object.isNull())
      {
         if(mPathData.path.isNull())
         {
            if((getPosition() - mFollowData.object->getPosition()).len() > mFollowData.radius)
               followObject(mFollowData.object, mFollowData.radius);
         }
         else
         {
            if((mPathData.path->mTo - mFollowData.object->getPosition()).len() > mFollowData.radius)
               repath();
            else if((getPosition() - mFollowData.object->getPosition()).len() < mFollowData.radius)
            {
               clearPath();
               mMoveState = ModeStop;
            throwCallback("onTargetInRange");
            }
            else if((getPosition() - mFollowData.object->getPosition()).len() < mAttackRadius)
            {
            throwCallback("onTargetInFiringRange");
            }
         }
      }
   }
#endif // TORQUE_NAVIGATION_ENABLED

   // Orient towards the aim point, aim object, or towards
   // our destination.
   if (mAimObject || mAimLocationSet || mMoveState != ModeStop) 
   {
      // Update the aim position if we're aiming for an object
      if (mAimObject)
         mAimLocation = mAimObject->getPosition() + mAimOffset;
      else
         if (!mAimLocationSet)
            mAimLocation = mMoveDestination;

      F32 xDiff = mAimLocation.x - location.x;
      F32 yDiff = mAimLocation.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_F;
         else if( yawDiff >= M_2PI_F )
            yawDiff -= M_2PI_F;

         // now make sure we take the short way around the circle
         if( yawDiff > M_PI_F )
            yawDiff -= M_2PI_F;
         else if( yawDiff < -M_PI_F )
            yawDiff += M_2PI_F;

         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 = mAtan2( horzDist, vertDist ) - ( M_PI_F / 2.0f );
            if (mFabs(newPitch) > 0.01f) 
            {
               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 != ModeStop) 
   {
      F32 xDiff = mMoveDestination.x - location.x;
      F32 yDiff = mMoveDestination.y - location.y;

      // Check if we should mMove, or if we are 'close enough'
      if (mFabs(xDiff) < mMoveTolerance && mFabs(yDiff) < mMoveTolerance) 
      {
         mMoveState = ModeStop;
         onReachDestination();
      }
      else 
      {
         // Build move direction in world space
         if (mIsZero(xDiff))
            movePtr->y = (location.y > mMoveDestination.y) ? -1.0f : 1.0f;
         else
            if (mIsZero(yDiff))
               movePtr->x = (location.x > mMoveDestination.x) ? -1.0f : 1.0f;
            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;
               }
               else 
               {
                  F32 value = mFabs(xDiff / yDiff);
                  movePtr->x = (location.x > mMoveDestination.x) ? -value : value;
                  movePtr->y = (location.y > mMoveDestination.y) ? -1.0f : 1.0f;
               }

         // 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 );
         movePtr->x = newMove.x;
         movePtr->y = newMove.y;

         // 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 = mMoveTolerance*2;
            if (dist < maxDist)
               speed *= dist / maxDist;
            movePtr->x *= speed;
            movePtr->y *= speed;

            mMoveState = ModeSlowing;
         }
         else 
         {
            movePtr->x *= mMoveSpeed;
            movePtr->y *= mMoveSpeed;

            mMoveState = ModeMove;
         }

         if (mMoveStuckTestCountdown > 0)
            --mMoveStuckTestCountdown;
         else
         {
            // We should check to see if we are stuck...
            F32 locationDelta = (location - mLastLocation).len();
            if (locationDelta < mMoveStuckTolerance && mDamageState == Enabled) 
            {
               // If we are slowing down, then it's likely that our location delta will be less than
               // our move stuck tolerance. Because we can be both slowing and stuck
               // we should TRY to check if we've moved. This could use better detection.
               if ( mMoveState != ModeSlowing || locationDelta == 0 )
               {
                  mMoveState = ModeStuck;
                  onStuck();
               }
            }
         }
      }
   }

   // 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)
   {
      if (checkInLos(mAimObject.getPointer()))
      {
         if (!mTargetInLOS)
         {
            throwCallback( "onTargetEnterLOS" );
            mTargetInLOS = true;
         }
   }
      else if (mTargetInLOS)
      {
            throwCallback( "onTargetExitLOS" );
            mTargetInLOS = false;
         }
      }

   Pose desiredPose = mPose;

   if ( mSwimming )  
      desiredPose = SwimPose;   
   else if ( mAiPose == 1 && canCrouch() )   
      desiredPose = CrouchPose;  
   else if ( mAiPose == 2 && canProne() )  
      desiredPose = PronePose;  
   else if ( mAiPose == 3 && canSprint() )  
      desiredPose = SprintPose;  
   else if ( canStand() )  
      desiredPose = StandPose;  
  
   setPose( desiredPose );
   
   // Replicate the trigger state into the move so that
   // triggers can be controlled from scripts.
   for( U32 i = 0; i < MaxTriggerKeys; i++ )
      movePtr->trigger[ i ] = getImageTriggerState( i );

#ifdef TORQUE_NAVIGATION_ENABLED
   if(mJump == Now)
   {
      movePtr->trigger[2] = true;
      mJump = None;
   }
   else if(mJump == Ledge)
   {
      // If we're not touching the ground, jump!
      RayInfo info;
      if(!getContainer()->castRay(getPosition(), getPosition() - Point3F(0, 0, 0.4f), StaticShapeObjectType, &info))
      {
         movePtr->trigger[2] = true;
         mJump = None;
      }
   }
#endif // TORQUE_NAVIGATION_ENABLED

   mLastLocation = location;

   return true;
}