Beispiel #1
0
bool TurretShape::getWorldNodeTransform(S32 node, MatrixF& mat)
{
   MatrixF nodeMat;
   if (!getNodeTransform(node, nodeMat))
      return false;

   nodeMat.affineInverse();
   mat = nodeMat;
   return true;
}
Beispiel #2
0
void TurretShape::getImageTransform(U32 imageSlot,S32 node,MatrixF* mat)
{
   // Same as ShapeBase::getImageTransform() other than getRenderWeaponMountTransform() below

   // Image transform in world space
   MountedImage& image = mMountedImageList[imageSlot];
   if (image.dataBlock)
   {
      if (node != -1)
      {
         ShapeBaseImageData& data = *image.dataBlock;
         U32 shapeIndex = getImageShapeIndex(image);

         MatrixF nmat = image.shapeInstance[shapeIndex]->mNodeTransforms[node];
         MatrixF mmat;

         if (data.useEyeNode && isFirstPerson() && data.eyeMountNode[shapeIndex] != -1)
         {
            // We need to animate, even on the server, to make sure the nodes are in the correct location.
            image.shapeInstance[shapeIndex]->animate();

            MatrixF emat;
            getEyeBaseTransform(&emat, mDataBlock->mountedImagesBank);

            MatrixF mountTransform = image.shapeInstance[shapeIndex]->mNodeTransforms[data.eyeMountNode[shapeIndex]];
            mountTransform.affineInverse();

            mmat.mul(emat, mountTransform);
         }
         else if (data.useEyeOffset && isFirstPerson())
         {
            MatrixF emat;
            getEyeTransform(&emat);
            mmat.mul(emat,data.eyeOffset);
         }
         else
         {
            MatrixF emat;
            getWeaponMountTransform( imageSlot, MatrixF::Identity, &emat );
            mmat.mul(emat,data.mountTransform[shapeIndex]);
         }

         mat->mul(mmat, nmat);
      }
      else
         getImageTransform(imageSlot,mat);
   }
   else
      *mat = mObjToWorld;
}
Beispiel #3
0
void TerrainCellMaterial::setTransformAndEye(   const MatrixF &modelXfm, 
                                                const MatrixF &viewXfm,
                                                const MatrixF &projectXfm,
                                                F32 farPlane )
{
   PROFILE_SCOPE( TerrainCellMaterial_SetTransformAndEye );

   MatrixF modelViewProj = projectXfm * viewXfm * modelXfm;
  
   MatrixF invViewXfm( viewXfm );
   invViewXfm.inverse();
   Point3F eyePos = invViewXfm.getPosition();
   
   MatrixF invModelXfm( modelXfm );
   invModelXfm.inverse();

   Point3F objEyePos = eyePos;
   invModelXfm.mulP( objEyePos );
   
   VectorF vEye = invViewXfm.getForwardVector();
   vEye.normalize( 1.0f / farPlane );

   for ( U32 i=0; i < mPasses.size(); i++ )
   {
      Pass &pass = mPasses[i];

      pass.consts->setSafe( pass.modelViewProjConst, modelViewProj );

      if( pass.viewToObj->isValid() || pass.worldViewOnly->isValid() )
      {
         MatrixF worldViewOnly = viewXfm * modelXfm;

         pass.consts->setSafe( pass.worldViewOnly, worldViewOnly );

         if( pass.viewToObj->isValid() )
         {
            worldViewOnly.affineInverse();
            pass.consts->set( pass.viewToObj, worldViewOnly);
         } 
      }

      pass.consts->setSafe( pass.eyePosWorldConst, eyePos );
      pass.consts->setSafe( pass.eyePosConst, objEyePos );
      pass.consts->setSafe( pass.objTransConst, modelXfm );
      pass.consts->setSafe( pass.worldToObjConst, invModelXfm );
      pass.consts->setSafe( pass.vEyeConst, vEye );
   }
}
Beispiel #4
0
void AITurretShape::_trackTarget(F32 dt)
{
   // Only on server
   if (isClientObject())
      return;

   // We can only track a target if we have one
   if (!mTarget.isValid())
      return;

   Point3F targetPos = mTarget.target->getBoxCenter();

   // Can we see the target?
   MatrixF aimMat;
   getAimTransform(aimMat);
   Point3F start;
   aimMat.getColumn(3, &start);
   RayInfo ri;

   Point3F sightPoint;

   disableCollision();
   bool los = _testTargetLineOfSight(start, mTarget.target, sightPoint);
   enableCollision();

   if (!los)
   {
      // Target is blocked.  Should we try to track from its last
      // known position and velocity?
      SimTime curTime = Sim::getCurrentTime();
      if ( (curTime - mTarget.lastSightTime) > (mDataBlock->trackLostTargetTime * 1000.0f) )
      {
         // Time's up.  Stop tracking.
         _cleanupTargetAndTurret();
         return;
      }
      
      // Use last known information to attempt to
      // continue to track target for a while.
      targetPos = mTarget.lastPos + mTarget.lastVel * F32(curTime - mTarget.lastSightTime) / 1000.0f;
   }
   else
   {
      // Target is visible

      // We only track targets that are alive
      if (mTarget.target->getDamageState() != Enabled)
      {
         // We can't track any more
         _cleanupTargetAndTurret();
         return;
      }

      targetPos = sightPoint;

      // Store latest target info
      mTarget.lastPos = targetPos;
      mTarget.lastVel = mTarget.target->getVelocity();
      mTarget.lastSightTime = Sim::getCurrentTime();
   }

   // Calculate angles to face the target, specifically the part that we can see
   VectorF toTarget;
   MatrixF mat;
   S32 node = mDataBlock->aimNode;
   if (node != -1)
   {
      // Get the current position of our node
      MatrixF* nodeTrans = &mShapeInstance->mNodeTransforms[node];
      Point3F currentPos;
      nodeTrans->getColumn(3, &currentPos);

      // Turn this into a matrix we can use to put the target
      // position into our space.
      MatrixF nodeMat(true);
      nodeMat.setColumn(3, currentPos);
      mat.mul(mObjToWorld, nodeMat);
      mat.affineInverse();
   }
   else
   {
      mat = mWorldToObj;
   }
   mat.mulP(targetPos, &toTarget);

   // lead the target
   F32 timeToTargetSquared = (mWeaponLeadVelocitySquared > 0) ? toTarget.lenSquared() / mWeaponLeadVelocitySquared : 0;
   if (timeToTargetSquared > 1.0)
   {
      targetPos = targetPos + (mTarget.lastVel * mSqrt(timeToTargetSquared));
      mat.mulP(targetPos, &toTarget);
   }

   F32 yaw, pitch;
   MathUtils::getAnglesFromVector(toTarget, yaw, pitch);
   if (yaw > M_PI_F)
      yaw = yaw - M_2PI_F;
   //if (pitch > M_PI_F)
   //   pitch = -(pitch - M_2PI_F);

   Point3F rot(-pitch, 0.0f, yaw);

   // If we have a rotation rate make sure we follow it
   if (mHeadingRate > 0)
   {
      F32 rate = mHeadingRate * dt;
      F32 rateCheck = mFabs(rot.z - mRot.z);
      if (rateCheck > rate)
      {
         // This will clamp the new value to the rate regardless if it
         // is increasing or decreasing.
         rot.z = mClampF(rot.z, mRot.z-rate, mRot.z+rate);
      }
   }
   if (mPitchRate > 0)
   {
      F32 rate = mPitchRate * dt;
      F32 rateCheck = mFabs(rot.x - mRot.x);
      if (rateCheck > rate)
      {
         // This will clamp the new value to the rate regardless if it
         // is increasing or decreasing.
         rot.x = mClampF(rot.x, mRot.x-rate, mRot.x+rate);
      }
   }

   // Test if the rotation to the target is outside of our limits
   if (_outsideLimits(rot))
   {
      // We can't track any more
      _cleanupTargetAndTurret();
      return;
   }

   // Test if the target is out of weapons range
   if (toTarget.lenSquared() > mWeaponRangeSquared)
   {
      // We can't track any more
      _cleanupTargetAndTurret();
      return;
   }

   mRot = rot;

   _setRotation( mRot );
   setMaskBits(TurretUpdateMask);
}