Ejemplo n.º 1
0
void Projectile::prepBatchRender( SceneRenderState *state )
{
   if ( !mProjectileShape )
      return;

   GFXTransformSaver saver;

   // Set up our TS render state.
   TSRenderState rdata;
   rdata.setSceneState( state );

   // We might have some forward lit materials
   // so pass down a query to gather lights.
   LightQuery query;
   query.init( getWorldSphere() );
   rdata.setLightQuery( &query );

   MatrixF mat = getRenderTransform();
   mat.scale( mObjScale );
   mat.scale( mDataBlock->scale );
   GFX->setWorldMatrix( mat );

   mProjectileShape->setDetailFromPosAndScale( state, mat.getPosition(), mObjScale );
   mProjectileShape->animate();

   mProjectileShape->render( rdata );
}
Ejemplo n.º 2
0
void TSShapeLoader::generateGroundAnimation(TSShape::Sequence& seq, const AppSequence* appSeq)
{
   seq.firstGroundFrame = shape->groundTranslations.size();
   seq.numGroundFrames = 0;

   if (!boundsNode)
      return;

   // Check if the bounds node is animated by this sequence
   seq.numGroundFrames = (S32)((seq.duration + 0.25f/AppGroundFrameRate) * AppGroundFrameRate);

   seq.flags |= TSShape::MakePath;

   // Get ground transform at the start of the sequence
   MatrixF invStartMat = boundsNode->getNodeTransform(appSeq->getStart());
   zapScale(invStartMat);
   invStartMat.inverse();

   for (int iFrame = 0; iFrame < seq.numGroundFrames; iFrame++)
   {
      F32 time = appSeq->getStart() + seq.duration * iFrame / getMax(1, seq.numGroundFrames - 1);

      // Determine delta bounds node transform at 't'
      MatrixF mat = boundsNode->getNodeTransform(time);
      zapScale(mat);
      mat = invStartMat * mat;

      // Add ground transform
      Quat16 rotation;
      rotation.set(QuatF(mat));
      shape->groundTranslations.push_back(mat.getPosition());
      shape->groundRotations.push_back(rotation);
   }
}
Ejemplo n.º 3
0
MatrixF PlaneReflector::getCameraReflection( const MatrixF &camTrans )
{
   Point3F normal = refplane;

   // Figure out new cam position
   Point3F camPos = camTrans.getPosition();
   F32 dist = refplane.distToPlane( camPos );
   Point3F newCamPos = camPos - normal * dist * 2.0;

   // Figure out new look direction
   Point3F i, j, k;
   camTrans.getColumn( 0, &i );
   camTrans.getColumn( 1, &j );
   camTrans.getColumn( 2, &k );

   i = MathUtils::reflect( i, normal );
   j = MathUtils::reflect( j, normal );
   k = MathUtils::reflect( k, normal );
   //mCross( i, j, &k );


   MatrixF newTrans(true);
   newTrans.setColumn( 0, i );
   newTrans.setColumn( 1, j );
   newTrans.setColumn( 2, k );

   newTrans.setPosition( newCamPos );

   return newTrans;
}
Ejemplo n.º 4
0
void TurretShape::getRenderWeaponMountTransform( F32 delta, S32 mountPoint, const MatrixF &xfm, MatrixF *outMat )
{
   // Returns mount point to world space transform
   if ( mountPoint >= 0 && mountPoint < SceneObject::NumMountPoints) {
      S32 ni = mDataBlock->weaponMountNode[mountPoint];
      if (ni != -1) {
         MatrixF mountTransform = mShapeInstance->mNodeTransforms[ni];
         mountTransform.mul( xfm );
         const Point3F& scale = getScale();

         // The position of the mount point needs to be scaled.
         Point3F position = mountTransform.getPosition();
         position.convolve( scale );
         mountTransform.setPosition( position );

         // Also we would like the object to be scaled to the model.
         mountTransform.scale( scale );
         outMat->mul(getRenderTransform(), mountTransform);
         return;
      }
   }

   // Then let SceneObject handle it.
   GrandParent::getRenderMountTransform( delta, mountPoint, xfm, outMat );   
}
Ejemplo n.º 5
0
Frustum::Frustum( bool isOrtho,
                  F32 nearLeft, 
                  F32 nearRight, 
                  F32 nearTop, 
                  F32 nearBottom, 
                  F32 nearDist,                  
                  F32 farDist,
                  const MatrixF &transform )
{
   mTransform = transform;
   mPosition = transform.getPosition();

   mNearLeft = nearLeft;
   mNearRight = nearRight;
   mNearTop = nearTop;
   mNearBottom = nearBottom;
   mNearDist = nearDist;
   mFarDist = farDist;
   mIsOrtho = isOrtho;

   mNumTiles = 1;
   mCurrTile.set(0,0);
   mTileOverlap.set(0.0f, 0.0f);

   mProjectionOffset.zero();
   mProjectionOffsetMatrix.identity();
}
Ejemplo n.º 6
0
void OrientedBox3F::set( const MatrixF& transform, const Point3F& extents )
{
   mCenter = transform.getPosition();

   mAxes[ RightVector ] = transform.getRightVector();
   mAxes[ ForwardVector ] = transform.getForwardVector();
   mAxes[ UpVector ] = transform.getUpVector();

   mHalfExtents = extents * 0.5f;

   _initPoints();
}
Ejemplo n.º 7
0
bool AIPlayer::onAdd()
{
   if (!Parent::onAdd())
      return false;

   // Use the eye as the current position (see getAIMove)
   MatrixF eye;
   getEyeTransform(&eye);
   mLastLocation = eye.getPosition();

   return true;
}
Ejemplo n.º 8
0
void SkyBox::_renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *mi )
{
   GFXDEBUGEVENT_SCOPE( SkyBox_RenderObject, ColorF::WHITE );

   GFXTransformSaver saver;  
   GFX->setVertexBuffer( mVB );         

   MatrixF worldMat = MatrixF::Identity;
   worldMat.setPosition( state->getCameraPosition() );

   SceneData sgData;
   sgData.init( state );
   sgData.objTrans = &worldMat;

   mMatrixSet->restoreSceneViewProjection();
   mMatrixSet->setWorld( worldMat );
   if ( state->isReflectPass() )
      mMatrixSet->setProjection( state->getSceneManager()->getNonClipProjection() );

   while ( mMatInstance->setupPass( state, sgData ) )
   {         
      mMatInstance->setTransforms( *mMatrixSet, state );
      mMatInstance->setSceneInfo( state, sgData );

      GFX->drawPrimitive( GFXTriangleList, 0, mPrimCount );     
   }

   // Draw render band.
   if ( mFogBandHeight > 0 && mFogBandMatInst )
   {
      const FogData &fog = state->getSceneManager()->getFogData();
      if ( mLastFogColor != fog.color )
      {
         mLastFogColor = fog.color;
         _initRender();
      }

      // Just need it to follow the camera... no rotation.
      MatrixF camPosMat( MatrixF::Identity );
      camPosMat.setPosition( worldMat.getPosition() );
      sgData.objTrans = &camPosMat;
      mMatrixSet->setWorld( *sgData.objTrans );

      while ( mFogBandMatInst->setupPass( state, sgData ) )
      {
         mFogBandMatInst->setTransforms( *mMatrixSet, state );
         mFogBandMatInst->setSceneInfo( state, sgData );

         GFX->setVertexBuffer( mFogBandVB );      
         GFX->drawPrimitive( GFXTriangleList, 0, 16 );
      }
   }
}
Ejemplo n.º 9
0
//----------------------------------------------------------------------------
// Explode
//----------------------------------------------------------------------------
void Splash::spawnExplosion()
{
   if( !mDataBlock->explosion ) return;

   Explosion* pExplosion = new Explosion;
   pExplosion->onNewDataBlock(mDataBlock->explosion, false);

   MatrixF trans = getTransform();
   trans.setPosition( getPosition() );

   pExplosion->setTransform( trans );
   pExplosion->setInitialState( trans.getPosition(), VectorF(0,0,1), 1);
   if (!pExplosion->registerObject())
      delete pExplosion;
}
Ejemplo n.º 10
0
/**
 * Sets the location for the bot to run to
 *
 * @param location Point to run to
 */
void AIPlayer::setMoveDestination( const Point3F &location, bool slowdown )
{
	//.logicking >> hack to avoid stopping right after
	// beginning of the move
	MatrixF eye;
	getEyeTransform(&eye);
	Point3F pos = eye.getPosition();
	mLastLocation = pos;
	mLastLocation.z += mMoveTolerance * 2;
	//.logicking <<
   mMoveDestination = location;
   mMoveState = ModeMove;
   mMoveSlowdown = slowdown;
   mMoveStuckTestCountdown = mMoveStuckTestDelay;
}
Ejemplo n.º 11
0
void SFX3DObject::getReferenceCenter( F32 position[ 3 ] ) const
{
   MatrixF transform;
   getEarTransform( transform );
   Point3F pos = transform.getPosition();
   
   AssertFatal( TypeTraits< F32 >::MIN <= pos.x && pos.x <= TypeTraits< F32 >::MAX,
      "SFX3DObject::getReferenceCenter - invalid float in reference center X position" );
   AssertFatal( TypeTraits< F32 >::MIN <= pos.y && pos.y <= TypeTraits< F32 >::MAX,
      "SFX3DObject::getReferenceCenter - invalid float in reference center Y position" );
   AssertFatal( TypeTraits< F32 >::MIN <= pos.z && pos.z <= TypeTraits< F32 >::MAX,
      "SFX3DObject::getReferenceCenter - invalid float in reference center Z position" );
   
   dMemcpy( position, &pos.x, sizeof( F32 ) * 3 );
}
Ejemplo n.º 12
0
bool TurretShape::getNodeTransform(S32 node, MatrixF& mat)
{
   if (node == -1)
      return false;

   MatrixF nodeTransform = mShapeInstance->mNodeTransforms[node];
   const Point3F& scale = getScale();

   // The position of the node needs to be scaled.
   Point3F position = nodeTransform.getPosition();
   position.convolve( scale );
   nodeTransform.setPosition( position );

   mat.mul(mObjToWorld, nodeTransform);
   return true;
}
Ejemplo n.º 13
0
void RigidBody::setTransform(const MatrixF& newMat)
{
	Parent::setTransform(newMat);
	
	// for GMK editor, when physics simulation is frozen
	//if(gFreezeSim)
	{
		if(mPhysShape) 
			mPhysShape->setTransform(newMat);
		
		mDelta.pos = newMat.getPosition();
		mDelta.rot[0] = QuatF(newMat);
		mDelta.rot[1] = mDelta.rot[0];
		mPhysPosition = mDelta.pos;
		mPhysRotation = mDelta.rot[0];
	}
}
Ejemplo n.º 14
0
void SoftBody::setTransform(const MatrixF& mat)
{

	PhysBody::setTransform(mat);
	if(gFreezeSim || m_stopSimulation)
	{
		m_initTransform = mat;
		if(mPhysShape) 
			mPhysShape->setTransform(mat);

		mDelta.pos = mat.getPosition();
		mDelta.rot[0] = QuatF(mat);
		mDelta.rot[1] = mDelta.rot[0];
		mPhysPosition = mDelta.pos;
		mPhysRotation = mDelta.rot[0];
		mDelta.posVec = VectorF::Zero;
	}
}
Ejemplo n.º 15
0
void PxSingleActor::applyCorrection( const MatrixF& mat, const NxVec3& linVel, const NxVec3& angVel )
{
   // Sometimes the actor hasn't been
   // created yet during the call from unpackUpdate.
   if ( !mActor || !mWorld )
      return;

   mWorld->releaseWriteLock();

   NxVec3 newPos = mat.getPosition();
   NxVec3 currPos = getPosition();

   NxVec3 offset = newPos - currPos;

   // If the difference isn't large enough,
   // just set the new transform, no correction.
   if ( offset.magnitude() > 0.3f )
   {
      // If we're going to set the linear or angular velocity,
      // we do it before we add a corrective force, since it would be overwritten otherwise.
      NxVec3 currLinVel, currAngVel;
      currLinVel = mActor->getLinearVelocity();
      currAngVel = mActor->getAngularVelocity();

      // Scale the corrective force by half,
      // otherwise it will over correct and oscillate.
      NxVec3 massCent = mActor->getCMassGlobalPosition();
      mActor->addForceAtPos( offset, massCent, NX_VELOCITY_CHANGE );

      // If the linear velocity is divergent enough, change to server linear velocity.
      if ( (linVel - currLinVel).magnitude() > 0.3f )
         mActor->setLinearVelocity( linVel );
      // Same for angular.
      if ( (angVel - currAngVel).magnitude() > 0.3f )
         mActor->setAngularVelocity( angVel );   
   }

   Parent::setTransform( mat );
}
Ejemplo n.º 16
0
void Projectile::prepBatchRender( SceneState *state )
{
   GFXTransformSaver saver;

   // Set up our TS render state.
   TSRenderState rdata;
   rdata.setSceneState( state );

   MatrixF mat = getRenderTransform();
   mat.scale( mObjScale );
   mat.scale( mDataBlock->scale );
   GFX->setWorldMatrix( mat );

   if(mProjectileShape)
   {
      AssertFatal(mProjectileShape != NULL,
                  "Projectile::renderObject: Error, projectile shape should always be present in renderObject");
      mProjectileShape->setDetailFromPosAndScale( state, mat.getPosition(), mObjScale );
      mProjectileShape->animate();

      mProjectileShape->render( rdata );
   }
}
Ejemplo n.º 17
0
void BtBody::getState( PhysicsState *outState )
{
   AssertFatal( isDynamic(), "BtBody::getState - This call is only for dynamics!" );

   // TODO: Fix this to do what we intended... to return
   // false so that the caller can early out of the state
   // hasn't changed since the last tick.

   MatrixF trans;
   if ( mInvCenterOfMass )
      trans.mul( btCast<MatrixF>( mActor->getCenterOfMassTransform() ), *mInvCenterOfMass );
   else
      trans = btCast<MatrixF>( mActor->getCenterOfMassTransform() );

   outState->position = trans.getPosition();
   outState->orientation.set( trans );
   outState->linVelocity = btCast<Point3F>( mActor->getLinearVelocity() ); 
   outState->angVelocity = btCast<Point3F>( mActor->getAngularVelocity() ); 
   outState->sleeping = !mActor->isActive();

   // Bullet doesn't keep the momentum... recalc it.
   outState->momentum = ( 1.0f / mActor->getInvMass() ) * outState->linVelocity;
}
Ejemplo n.º 18
0
void WaterPlane::setTransform( const MatrixF &mat )
{
   // We only accept the z value from the new transform.

   MatrixF newMat( true );
   
   Point3F newPos = getPosition();
   newPos.z = mat.getPosition().z;  
   newMat.setPosition( newPos );

   Parent::setTransform( newMat );

   // Parent::setTransforms ends up setting our worldBox to something other than
   // global, so we have to set it back... but we can't actually call setGlobalBounds
   // again because it does extra work adding and removing us from the container.

   mGlobalBounds = true;
   mObjBox.minExtents.set(-1e10, -1e10, -1e10);
   mObjBox.maxExtents.set( 1e10,  1e10,  1e10);

   // Keep mWaterPlane up to date.
   mWaterFogData.plane.set( 0, 0, 1, -getPosition().z );   
}
Ejemplo n.º 19
0
void TurretShape::getWeaponMountTransform( S32 index, const MatrixF &xfm, MatrixF *outMat )
{
   // Returns mount point to world space transform
   if ( index >= 0 && index < SceneObject::NumMountPoints) {
      S32 ni = mDataBlock->weaponMountNode[index];
      if (ni != -1) {
         MatrixF mountTransform = mShapeInstance->mNodeTransforms[ni];
         mountTransform.mul( xfm );
         const Point3F& scale = getScale();

         // The position of the mount point needs to be scaled.
         Point3F position = mountTransform.getPosition();
         position.convolve( scale );
         mountTransform.setPosition( position );

         // Also we would like the object to be scaled to the model.
         outMat->mul(mObjToWorld, mountTransform);
         return;
      }
   }

   // Then let SceneObject handle it.
   GrandParent::getMountTransform( index, xfm, outMat );      
}
Ejemplo n.º 20
0
Point3F	PhysShape::getPosition()
{
    MatrixF res = getTransform();

    return res.getPosition();
}
Ejemplo n.º 21
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();

   // 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;
         throwCallback("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 = 5.0f;
            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;
                  throwCallback("onMoveStuck");
               }
            }
         }
      }
   }

   // 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,
            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);

   mLastLocation = location;

   return true;
}
Ejemplo n.º 22
0
void PxCloth::unpackUpdate( NetConnection *conn, BitStream *stream )
{
   Parent::unpackUpdate( conn, stream );

   // TransformMask
   if ( stream->readFlag() )
   {
      MatrixF mat;
      mathRead( *stream, &mat );
   // start jc
      if(mCloth)
      {
         NxVec3 delta(mat.getPosition() - getTransform().getPosition());

         if(mCloth->isSleeping())
            mCloth->wakeUp();

         if ( mAttachmentMask & BIT( 0 ) )
            mCloth->attachVertexToGlobalPosition( 0, mCloth->getPosition( 0 ) + delta );
         if ( mAttachmentMask & BIT( 1 ) )
            mCloth->attachVertexToGlobalPosition( mPatchVerts.x-1, mCloth->getPosition( mPatchVerts.x-1 ) + delta );   
         if ( mAttachmentMask & BIT( 2 ) )
            mCloth->attachVertexToGlobalPosition( mPatchVerts.x * mPatchVerts.y - mPatchVerts.x, mCloth->getPosition( mPatchVerts.x * mPatchVerts.y - mPatchVerts.x ) + delta );
         if ( mAttachmentMask & BIT( 3 ) )
            mCloth->attachVertexToGlobalPosition( mPatchVerts.x * mPatchVerts.y - 1, mCloth->getPosition( mPatchVerts.x * mPatchVerts.y - 1 ) + delta );   
         if ( mAttachmentMask & BIT( 4 ) )
            mCloth->attachVertexToGlobalPosition( mPatchVerts.x * mPatchVerts.y - (mPatchVerts.x/2), mCloth->getPosition( mPatchVerts.x * mPatchVerts.y - (mPatchVerts.x/2) ) + delta );
         if ( mAttachmentMask & BIT( 5 ) )
            mCloth->attachVertexToGlobalPosition( (mPatchVerts.x/2), mCloth->getPosition( (mPatchVerts.x/2) ) + delta );
         if ( mAttachmentMask & BIT( 6 ) )
            mCloth->attachVertexToGlobalPosition( mPatchVerts.x * (mPatchVerts.y/2), mCloth->getPosition( mPatchVerts.x * (mPatchVerts.y/2) ) + delta );
         if ( mAttachmentMask & BIT( 7 ) )
            mCloth->attachVertexToGlobalPosition( mPatchVerts.x * (mPatchVerts.y/2) + (mPatchVerts.x-1), mCloth->getPosition( mPatchVerts.x * (mPatchVerts.y/2) + (mPatchVerts.x-1) ) + delta );
         
         if ( mAttachmentMask & BIT( 8 ) )
            for ( U32 i = mPatchVerts.x * mPatchVerts.y - mPatchVerts.x; i < mPatchVerts.x * mPatchVerts.y; i++ )
               mCloth->attachVertexToGlobalPosition( i, mCloth->getPosition( i ) + delta );
         
         if ( mAttachmentMask & BIT( 9 ) )
            for ( U32 i = 0; i < mPatchVerts.x; i++ )
               mCloth->attachVertexToGlobalPosition( i, mCloth->getPosition( i ) + delta );

         if ( mAttachmentMask & BIT( 10 ) )
            for ( U32 i = 0; i < mPatchVerts.x * mPatchVerts.y; i+=mPatchVerts.x )
               mCloth->attachVertexToGlobalPosition( i, mCloth->getPosition( i ) + delta );

         if ( mAttachmentMask & BIT( 11 ) )
            for ( U32 i = mPatchVerts.x-1; i < mPatchVerts.x * mPatchVerts.y; i+=mPatchVerts.x )
               mCloth->attachVertexToGlobalPosition( i, mCloth->getPosition( i ) + delta );
      }
   // end jc


      setTransform( mat );
   }

// start jc
   // ScaleAttachmentPointsMask
   if ( stream->readFlag() )
   {
      Point3F attachmentPointScale;
      mathRead( *stream, &attachmentPointScale );

      if(mCloth)
      {
         Point3F scale(Point3F::One);
         scale.convolveInverse(mAttachmentPointScale);
         scale.convolve(attachmentPointScale);
         NxVec3 delta(scale);

         if(mCloth->isSleeping())
            mCloth->wakeUp();

         static NxVec3 delta2;
         if ( mAttachmentMask & BIT( 0 ) )
         {  delta2.arrayMultiply(mCloth->getPosition( 0 ),delta);                                                       mCloth->attachVertexToGlobalPosition( 0, delta2); }
         if ( mAttachmentMask & BIT( 1 ) )
         {  delta2.arrayMultiply(mCloth->getPosition( mPatchVerts.x-1 ), delta);                                        mCloth->attachVertexToGlobalPosition( mPatchVerts.x-1, delta2); } 
         if ( mAttachmentMask & BIT( 2 ) )
         {  delta2.arrayMultiply(mCloth->getPosition( mPatchVerts.x * mPatchVerts.y - mPatchVerts.x ), delta);          mCloth->attachVertexToGlobalPosition( mPatchVerts.x * mPatchVerts.y - mPatchVerts.x, delta2); }
         if ( mAttachmentMask & BIT( 3 ) )
         {  delta2.arrayMultiply(mCloth->getPosition( mPatchVerts.x * mPatchVerts.y - 1 ), delta);                      mCloth->attachVertexToGlobalPosition( mPatchVerts.x * mPatchVerts.y - 1, delta2); }
         if ( mAttachmentMask & BIT( 4 ) )
         {   delta2.arrayMultiply(mCloth->getPosition( mPatchVerts.x * mPatchVerts.y - (mPatchVerts.x/2) ), delta);     mCloth->attachVertexToGlobalPosition( mPatchVerts.x * mPatchVerts.y - (mPatchVerts.x/2), delta2); }
         if ( mAttachmentMask & BIT( 5 ) )
         {  delta2.arrayMultiply(mCloth->getPosition( (mPatchVerts.x/2) ), delta);                                      mCloth->attachVertexToGlobalPosition( (mPatchVerts.x/2), delta2); }
         if ( mAttachmentMask & BIT( 6 ) )
         {  delta2.arrayMultiply(mCloth->getPosition( mPatchVerts.x * (mPatchVerts.y/2) ), delta);                      mCloth->attachVertexToGlobalPosition( mPatchVerts.x * (mPatchVerts.y/2), delta2); }
         if ( mAttachmentMask & BIT( 7 ) )
         {  delta2.arrayMultiply(mCloth->getPosition( mPatchVerts.x * (mPatchVerts.y/2) + (mPatchVerts.x-1) ), delta);  mCloth->attachVertexToGlobalPosition( mPatchVerts.x * (mPatchVerts.y/2) + (mPatchVerts.x-1), delta2); }
         
         if ( mAttachmentMask & BIT( 8 ) )
            for ( U32 i = mPatchVerts.x * mPatchVerts.y - mPatchVerts.x; i < mPatchVerts.x * mPatchVerts.y; i++ )
               {   delta2.arrayMultiply(mCloth->getPosition( i ), delta);     mCloth->attachVertexToGlobalPosition( i, delta2); }
         
         if ( mAttachmentMask & BIT( 9 ) )
            for ( U32 i = 0; i < mPatchVerts.x; i++ )
               {   delta2.arrayMultiply(mCloth->getPosition( i ), delta);     mCloth->attachVertexToGlobalPosition( i, delta2); }

         if ( mAttachmentMask & BIT( 10 ) )
            for ( U32 i = 0; i < mPatchVerts.x * mPatchVerts.y; i+=mPatchVerts.x )
               {   delta2.arrayMultiply(mCloth->getPosition( i ), delta);     mCloth->attachVertexToGlobalPosition( i, delta2); }

         if ( mAttachmentMask & BIT( 11 ) )
            for ( U32 i = mPatchVerts.x-1; i < mPatchVerts.x * mPatchVerts.y; i+=mPatchVerts.x )
               {   delta2.arrayMultiply(mCloth->getPosition( i ), delta);     mCloth->attachVertexToGlobalPosition( i, delta2); }
      }

      mAttachmentPointScale = attachmentPointScale;
   }
// end jc

   // MaterialMask
   if ( stream->readFlag() )
   {
      stream->read( &mMaterialName );
      SAFE_DELETE( mMatInst );
   }

   // ClothMask
   if ( stream->readFlag() )
   {
      Point2I patchVerts;
      Point2F patchSize;
      mathRead( *stream, &patchVerts );
      mathRead( *stream, &patchSize );

      if (  patchVerts != mPatchVerts ||
            !patchSize.equal( mPatchSize ) )
      {
         mPatchVerts = patchVerts;
         mPatchSize = patchSize;
         _releaseMesh();
      }

      U32 attachMask;
      stream->read( &attachMask );
      if ( attachMask != mAttachmentMask )
      {
         mAttachmentMask = attachMask;
         _releaseCloth();
      }

      mBendingEnabled = stream->readFlag();
      mDampingEnabled = stream->readFlag();
      mTriangleCollisionEnabled = stream->readFlag();
      mSelfCollisionEnabled = stream->readFlag();
      stream->read( &mThickness );
      stream->read( &mFriction );
      stream->read( &mBendingStiffness );
      stream->read( &mDampingCoefficient );

      F32 density;
      stream->read( &density );
      if ( density != mDensity )
      {
         mDensity = density;
         _releaseCloth();
      }

      if (  isClientObject() && 
            isProperlyAdded() &&
            mWorld &&
            !mCloth )
      {
         _createClothPatch();
      }

      _updateClothProperties();
   }
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
0
//-----------------------------------------------------------------------------
//
// VActorPhysicsController::postTickUpdate( pDelta );
//
// ...
//
//-----------------------------------------------------------------------------
void VActorPhysicsController::postTickUpdate( const F32 &pDelta )
{
    switch( mControlState )
    {
    case k_PathControlState :
        {
            AssertFatal( isPathing(), "VActorPhysicsController::postTickUpdate() - Invalid Path State." );

            // Fetch Mount Transform.
            MatrixF transform;
            mMountedPath->getMountTransform( mObject->getMountNode(), getTransform(), &transform );
            // Fetch Mount Position.
            const Point3F &mountPosition = transform.getPosition();

            // Update X & Y Position.
            Point3F position = getPosition();
            position.x = mountPosition.x;
            position.y = mountPosition.y;

            // In Water?
            bool underWater = false;
            if ( isInWater() )
            {
                // Fetch Body of Water.
                WaterObject *waterBody = getWaterObject();

                // Fetch Surface Position.
                const F32 &waterSurfacePosition = waterBody->getSurfaceHeight( Point2F( position.x, position.y ) );
                // Fetch Submersion Position.
                const F32 sumbersionPosition = waterSurfacePosition - ( mObject->getWorldBox().len_z() * mObject->getDataBlock()->getSumbergeCoverage() );

                // Choose a Z Value.
                // Note: This is done so that the Actor will either path under the
                //       water, or it will swim along the water's surface.
                position.z = getMin( mountPosition.z, sumbersionPosition );

                // Under Water?
                underWater = ( position.z < sumbersionPosition );
            }

            // Under Water?
            if ( !underWater )
            {
                // Fetch Y Column.
                VectorF forwardVector;
                transform.getColumn( 1, &forwardVector );

                // Determine Angle.
                const F32 &angle = -mAtan2( -forwardVector.x, forwardVector.y );

                // Reset Transform.
                transform.set( EulerF( 0.f, 0.f, angle ) );

                // In the air?
                if ( !isOnGround() )
                {
                    // Apply z-axis force.
                    position.z += ( getVelocity().z * pDelta );
                }
            }

            // Update Transform.
            transform.setPosition( position );

            // Apply Update.
            setTransform( transform );

        } break;

    default :
        {
            // Fetch Transform.
            MatrixF transform = getTransform();

            // Determine the Post-Tick Position.
            Point3F postTickPosition = getPosition() + ( getVelocity() * pDelta );
            // Set the Post Tick Position.
            transform.setPosition( postTickPosition );

            // Apply the Transform.
            setTransform( transform );

        } break;
    }

    // Push Delta.
    mInterpController.pushDelta( getTransform() );
}
Ejemplo n.º 25
0
void PxSingleActor::processTick( const Move *move )
{
   PROFILE_SCOPE( PxSingleActor_ProcessTick );

   if ( !mActor )
      return;

   // Set the last pos/rot to the
   // values of the previous tick for interpolateTick.
   mLastPos = mNextPos;
   mLastRot = mNextRot;

   if ( mActor->isSleeping() || mActor->readBodyFlag( NX_BF_FROZEN ) )
   {
      /*
      if ( !mSleepingLastTick )
      {
         // TODO: We cannot use a warp when we sleep.  The warp
         // can cause interpenetration with other actors which
         // then cause explosions on the next simulation tick.
         //
         // Instead lets have the sleep mask itself send the sleep
         // position and let it set the actor in a safe manner
         // that is specific to sleeping.

         setMaskBits( WarpMask | SleepMask );
      }
      */
      mSleepingLastTick = true;
      
      return;
   }

   mSleepingLastTick = false;

   // Container buoyancy & drag
   _updateContainerForces();      

   // Set the Torque transform to the dynamic actor's transform.
   MatrixF mat;
   mActor->getGlobalPose().getRowMajor44( mat );
   Parent::setTransform( mat );

   // Set the next pos/rot to the current values.
   mNextPos = mat.getPosition();
   mNextRot.set( mat );

   // TODO: We removed passing move updates to the client
   // on every tick because it was a waste of bandwidth.  The
   // client is correct or within limits the vast majority of 
   // the time.
   //
   // Still it can get out of sync.  To correct this when the
   // actor sleeps can cause large ugly jumps in position.  One
   // thought here was to hide the correction by waiting until
   // the object and its new position are offscreen.  Short of
   // that we have to apply corrections gradually over the time
   // of movement if we want corrections to work well.
   //
   // Lets consider some techniques for future improvement.
   //
   // First lets send updates to all non-sleeping actors in some
   // sort of round robin fashion, so that the bandwidth used is
   // limited by the number of actors moving.  If 1 actor is moving
   // it sends updates every tick... if 10 actors are moving each
   // actor gets an update every 10 ticks.  Lets say a really ugly
   // case... 100 moving actors... every actor is updated every 
   // 3.2 seconds... thats probably acceptable.
   //
   // Second lets also consider the idea of sending a velocity only 
   // correction more regularly.  If the actors are in the same start
   // position, a correct velocity would do as much good as a position.
   // Plus the linear velocity can me compressed really well.. less 
   // than 64 bits.  Maybe sending velocity regularly and positions
   // less regular would work?
   //
   // A more radical idea would be to have a special scene object that
   // manages all the packUpdates for all actors.  This object would
   // ensure that the right actors are updated and break up the updates
   // in a way to limit bandwidth usage.

   // Set the MoveMask so this will be updated to the client.
   //setMaskBits( MoveMask );
}
Ejemplo n.º 26
0
void ConvexShape::_renderDebug( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *mat )
{   
   GFXDrawUtil *drawer = GFX->getDrawUtil();

   GFX->setTexture( 0, NULL );

   // Render world box.
   if ( false )
   {
      Box3F wbox( mWorldBox );
      //if ( getServerObject() )      
      //   Box3F wbox = static_cast<ConvexShape*>( getServerObject() )->mWorldBox;      
      GFXStateBlockDesc desc;
      desc.setCullMode( GFXCullNone );
      desc.setFillModeWireframe();
      drawer->drawCube( desc, wbox, ColorI::RED );
   }


   const Vector< Point3F > &pointList = mGeometry.points;
	const Vector< ConvexShape::Face > &faceList = mGeometry.faces;

   // Render Edges.
   if ( false )
   {
      GFXTransformSaver saver;
      //GFXFrustumSaver fsaver;

      MatrixF xfm( getRenderTransform() );
      xfm.scale( getScale() );
      GFX->multWorld( xfm );

      GFXStateBlockDesc desc;
      desc.setZReadWrite( true, false );
      desc.setBlend( true );
      GFX->setStateBlockByDesc( desc );

      //MathUtils::getZBiasProjectionMatrix( 0.01f, state->getFrustum(), )

      const Point3F &camFvec = state->getCameraTransform().getForwardVector();



      for ( S32 i = 0; i < faceList.size(); i++ )
      {         
         const ConvexShape::Face &face = faceList[i];
         
         const Vector< ConvexShape::Edge > &edgeList = face.edges;

         const Vector< U32 > &facePntList = face.points;

         PrimBuild::begin( GFXLineList, edgeList.size() * 2 );
         
         PrimBuild::color( ColorI::WHITE * 0.8f );

         for ( S32 j = 0; j < edgeList.size(); j++ )         
         {
            PrimBuild::vertex3fv( pointList[ facePntList[ edgeList[j].p0 ] ] - camFvec * 0.001f );
            PrimBuild::vertex3fv( pointList[ facePntList[ edgeList[j].p1 ] ] - camFvec * 0.001f );
         }
         
         PrimBuild::end();
      }
   }

   ColorI faceColorsx[4] = 
   {
      ColorI( 255, 0, 0 ),
      ColorI( 0, 255, 0 ),
      ColorI( 0, 0, 255 ),
      ColorI( 255, 0, 255 )
   };

   MatrixF objToWorld( mObjToWorld );
   objToWorld.scale( mObjScale );

   // Render faces centers/colors.
   if ( false )
   {
      GFXStateBlockDesc desc;
      desc.setCullMode( GFXCullNone );
      
      Point3F size( 0.1f );

      for ( S32 i = 0; i < faceList.size(); i++ )
      {
         ColorI color = faceColorsx[ i % 4 ];
         S32 div = ( i / 4 ) * 4;
         if ( div > 0 )
            color /= div;
         color.alpha = 255;
         
         Point3F pnt;
         objToWorld.mulP( faceList[i].centroid, &pnt );
         drawer->drawCube( desc, size, pnt, color, NULL );
      }
   }

   // Render winding order.
   if ( false )
   {
      GFXStateBlockDesc desc;
      desc.setCullMode( GFXCullNone );
      desc.setZReadWrite( true, false );
      GFX->setStateBlockByDesc( desc );  

      U32 pointCount = 0;
      for ( S32 i = 0; i < faceList.size(); i++ )      
         pointCount += faceList[i].winding.size();      

      PrimBuild::begin( GFXLineList, pointCount * 2 );
      
      for ( S32 i = 0; i < faceList.size(); i++ )
      {
         for ( S32 j = 0; j < faceList[i].winding.size(); j++ )
         {
            Point3F p0 = pointList[ faceList[i].points[ faceList[i].winding[j] ] ];
            Point3F p1 = p0 + mSurfaces[ faceList[i].id ].getUpVector() * 0.75f * ( Point3F::One / mObjScale );

            objToWorld.mulP( p0 );
            objToWorld.mulP( p1 );

            ColorI color = faceColorsx[ j % 4 ];
            S32 div = ( j / 4 ) * 4;
            if ( div > 0 )
               color /= div;
            color.alpha = 255;
            
            PrimBuild::color( color );
            PrimBuild::vertex3fv( p0 );            
            PrimBuild::color( color );
            PrimBuild::vertex3fv( p1 );                        
         }
      }

      PrimBuild::end();
   }

   // Render Points.
   if ( false )
   {      
      /*
      GFXTransformSaver saver;

      MatrixF xfm( getRenderTransform() );
      xfm.scale( getScale() );
      GFX->multWorld( xfm );

      GFXStateBlockDesc desc;
      Point3F size( 0.05f );
      */
   }

   // Render surface transforms.
   if ( false )
   {
      GFXStateBlockDesc desc;
      desc.setBlend( false );
      desc.setZReadWrite( true, true );

      Point3F scale(mNormalLength);

      for ( S32 i = 0; i < mSurfaces.size(); i++ )
      {
         MatrixF objToWorld( mObjToWorld );
         objToWorld.scale( mObjScale );

         MatrixF renderMat;
         renderMat.mul( objToWorld, mSurfaces[i] );

         renderMat.setPosition( renderMat.getPosition() + renderMat.getUpVector() * 0.001f );
              
         drawer->drawTransform( desc, renderMat, &scale, NULL );
      }
   }
}
Ejemplo n.º 27
0
void Projectile::emitParticles(const Point3F& from, const Point3F& to, const Point3F& vel, const U32 ms)
{
   if ( mHasExploded )
      return;

   Point3F axis = -vel;

   if( axis.isZero() )
      axis.set( 0.0, 0.0, 1.0 );
   else
      axis.normalize();

   bool fromWater = pointInWater(from);
   bool toWater   = pointInWater(to);

   if (!fromWater && !toWater && bool(mParticleEmitter))                                        // not in water
      mParticleEmitter->emitParticles(from, to, axis, vel, ms);
   else if (fromWater && toWater && bool(mParticleWaterEmitter))                                // in water
      mParticleWaterEmitter->emitParticles(from, to, axis, vel, ms);
   else if (!fromWater && toWater && mDataBlock->splash)     // entering water
   {
      // cast the ray to get the surface point of the water
      RayInfo rInfo;
      if (gClientContainer.castRay(from, to, WaterObjectType, &rInfo))
      {
         MatrixF trans = getTransform();
         trans.setPosition(rInfo.point);

         Splash *splash = new Splash();
         splash->onNewDataBlock(mDataBlock->splash, false);
         splash->setTransform(trans);
         splash->setInitialState(trans.getPosition(), Point3F(0.0, 0.0, 1.0));
         if (!splash->registerObject())
         {
            delete splash;
            splash = NULL;
         }

         // create an emitter for the particles out of water and the particles in water
         if (mParticleEmitter)
            mParticleEmitter->emitParticles(from, rInfo.point, axis, vel, ms);

         if (mParticleWaterEmitter)
            mParticleWaterEmitter->emitParticles(rInfo.point, to, axis, vel, ms);
      }
   }
   else if (fromWater && !toWater && mDataBlock->splash)     // leaving water
   {
      // cast the ray in the opposite direction since that point is out of the water, otherwise
      //  we hit water immediately and wont get the appropriate surface point
      RayInfo rInfo;
      if (gClientContainer.castRay(to, from, WaterObjectType, &rInfo))
      {
         MatrixF trans = getTransform();
         trans.setPosition(rInfo.point);

         Splash *splash = new Splash();
         splash->onNewDataBlock(mDataBlock->splash,false);
         splash->setTransform(trans);
         splash->setInitialState(trans.getPosition(), Point3F(0.0, 0.0, 1.0));
         if (!splash->registerObject())
         {
            delete splash;
            splash = NULL;
         }

         // create an emitter for the particles out of water and the particles in water
         if (mParticleEmitter)
            mParticleEmitter->emitParticles(rInfo.point, to, axis, vel, ms);

         if (mParticleWaterEmitter)
            mParticleWaterEmitter->emitParticles(from, rInfo.point, axis, vel, ms);
      }
   }
}