Beispiel #1
0
void Item::setTransform(const MatrixF& mat)
{
   Point3F pos;
   mat.getColumn(3,&pos);
   MatrixF tmat;
   if (!mRotate) {
      // Forces all rotation to be around the z axis
      VectorF vec;
      mat.getColumn(1,&vec);
      tmat.set(EulerF(0,0,-mAtan2(-vec.x,vec.y)));
   }
   else
      tmat.identity();
   tmat.setColumn(3,pos);
   Parent::setTransform(tmat);
   if (!mStatic)
   {
      mAtRest = false;
      mAtRestCounter = 0;
   }

   if ( mPhysicsRep )
      mPhysicsRep->setTransform( getTransform() );

   setMaskBits(RotationMask | PositionMask | NoWarpMask);
}
Beispiel #2
0
void FlyingVehicle::updateEmitter(bool active,F32 dt,ParticleEmitterData *emitter,S32 idx,S32 count)
{
   if (!emitter)
      return;
   for (S32 j = idx; j < idx + count; j++)
      if (active) {
         if (mDataBlock->jetNode[j] != -1) {
            if (!bool(mJetEmitter[j])) {
               mJetEmitter[j] = new ParticleEmitter;
               mJetEmitter[j]->onNewDataBlock(emitter,false);
               mJetEmitter[j]->registerObject();
            }
            MatrixF mat;
            Point3F pos,axis;
            mat.mul(getRenderTransform(),
                    mShapeInstance->mNodeTransforms[mDataBlock->jetNode[j]]);
            mat.getColumn(1,&axis);
            mat.getColumn(3,&pos);
            mJetEmitter[j]->emitParticles(pos,true,axis,getVelocity(),(U32)(dt * 1000));
         }
      }
      else {
         for (S32 j = idx; j < idx + count; j++)
            if (bool(mJetEmitter[j])) {
               mJetEmitter[j]->deleteWhenEmpty();
               mJetEmitter[j] = 0;
            }
      }
}
Beispiel #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;
}
void SFXXAudioVoice::setTransform( const MatrixF& transform )
{
   transform.getColumn( 3, (Point3F*)&mEmitter.Position );
   transform.getColumn( 1, (Point3F*)&mEmitter.OrientFront );
   transform.getColumn( 2, (Point3F*)&mEmitter.OrientTop );

   // XAudio and Torque use opposite handedness, so
   // flip the z coord to account for that.
   mEmitter.Position.z     *= -1.0f;
   mEmitter.OrientFront.z  *= -1.0f;
   mEmitter.OrientTop.z    *= -1.0f;
}
Beispiel #5
0
void BoxConvex::emitFace(S32 fi,const MatrixF& mat,ConvexFeature* cf)
{
   Face& face = sFace[fi];

   // Emit vertices
   S32 vc = cf->mVertexList.size();
   cf->mVertexList.increment(4);
   Point3F *vp = cf->mVertexList.begin();
   for (S32 v = 0; v < 4; v++)
      mat.mulP(getVertex(face.vertex[v]),&vp[vc + v]);

   // Emit edges
   cf->mEdgeList.increment(4);
   ConvexFeature::Edge* edge = cf->mEdgeList.end() - 4;
   for (S32 e = 0; e < 4; e++) {
      edge[e].vertex[0] = vc + e;
      edge[e].vertex[1] = vc + ((e + 1) & 3);
   }

   // Emit 2 triangle faces
   cf->mFaceList.increment(2);
   ConvexFeature::Face* ef = cf->mFaceList.end() - 2;
   mat.getColumn(face.axis,&ef->normal);
   if (face.flip)
      ef[0].normal.neg();
   ef[1].normal = ef[0].normal;
   ef[1].vertex[0] = ef[0].vertex[0] = vc;
   ef[1].vertex[1] = ef[0].vertex[2] = vc + 2;
   ef[0].vertex[1] = vc + 1;
   ef[1].vertex[2] = vc + 3;
}
void WorldEditorSelection::offset( const Point3F& offset, F32 gridSnap )
{
   for( iterator iter = begin(); iter != end(); ++ iter )
   {
      SceneObject* obj = dynamic_cast<SceneObject*>( *iter );
      if( !obj )
         continue;

      MatrixF mat = obj->getTransform();
      Point3F wPos;
      mat.getColumn(3, &wPos);

      // adjust
      wPos += offset;
      
      if( gridSnap != 0.f )
      {
         wPos.x -= mFmod( wPos.x, gridSnap );
         wPos.y -= mFmod( wPos.y, gridSnap );
         wPos.z -= mFmod( wPos.z, gridSnap );
      }
      
      mat.setColumn(3, wPos);
      obj->setTransform(mat);
   }

   mCentroidValid = false;
}
Beispiel #7
0
void Rigid::setTransform(const MatrixF& mat)
{
   angPosition.set(mat);
   mat.getColumn(3,&linPosition);

   // Update center of mass
   angPosition.mulP(centerOfMass,&worldCenterOfMass);
   worldCenterOfMass += linPosition;
}
Beispiel #8
0
void Item::processTick(const Move* move)
{
   Parent::processTick(move);

   //
   if (mCollisionObject && !--mCollisionTimeout)
      mCollisionObject = 0;

   // Warp to catch up to server
   if (delta.warpTicks > 0)
   {
      delta.warpTicks--;

      // Set new pos.
      MatrixF mat = mObjToWorld;
      mat.getColumn(3,&delta.pos);
      delta.pos += delta.warpOffset;
      mat.setColumn(3,delta.pos);
      Parent::setTransform(mat);

      // Backstepping
      delta.posVec.x = -delta.warpOffset.x;
      delta.posVec.y = -delta.warpOffset.y;
      delta.posVec.z = -delta.warpOffset.z;
   }
   else
   {
      if (isServerObject() && mAtRest && (mStatic == false && mDataBlock->sticky == false))
      {
         if (++mAtRestCounter > csmAtRestTimer)
         {
            mAtRest = false;
            mAtRestCounter = 0;
            setMaskBits(PositionMask);
         }
      }

      if (!mStatic && !mAtRest && isHidden() == false)
      {
         updateVelocity(TickSec);
         updateWorkingCollisionSet(isGhost() ? sClientCollisionMask : sServerCollisionMask, TickSec);
         updatePos(isGhost() ? sClientCollisionMask : sServerCollisionMask, TickSec);
      }
      else
      {
         // Need to clear out last updatePos or warp interpolation
         delta.posVec.set(0,0,0);
      }
   }
}
Beispiel #9
0
void SFXDSVoice::setTransform( const MatrixF& transform )
{
   if ( !mDSBuffer3D )
      return;

   Point3F pos, dir;
   transform.getColumn( 3, &pos );
   transform.getColumn( 1, &dir );
   DSAssert( mDSBuffer3D->SetPosition( pos.x, pos.z, pos.y, DS3D_DEFERRED ), 
      "SFXDSVoice::setTransform - couldn't set position of the buffer." );

   DSAssert( mDSBuffer3D->SetConeOrientation( dir.x, dir.z, dir.y, DS3D_DEFERRED ), 
      "SFXDSVoice::setTransform - couldn't set cone orientation of the buffer." );
}
void WorldEditorSelection::setRotate(const EulerF & rot)
{
   for( iterator iter = begin(); iter != end(); ++ iter )
   {
      SceneObject* object = dynamic_cast< SceneObject* >( *iter );
      if( !object )
         continue;

      MatrixF mat = object->getTransform();
      Point3F pos;
      mat.getColumn(3, &pos);

      MatrixF rmat(rot);
      rmat.setPosition(pos);

      object->setTransform(rmat);
   }
}
Beispiel #11
0
void GameTSCtrl::onMouseMove(const GuiEvent &evt)
{ 
   if(gSnapLine)
      return;
   
   MatrixF mat;
   Point3F vel;
   if ( GameGetCameraTransform(&mat, &vel) )
   {
      Point3F pos;
      mat.getColumn(3,&pos);
      Point3F screenPoint((F32)evt.mousePoint.x, (F32)evt.mousePoint.y, 1.0f);
      Point3F worldPoint;
      if (unproject(screenPoint, &worldPoint)) 
	  {
         Point3F vec = worldPoint - pos;
         lineTestStart = pos;
         vec.normalizeSafe();
         lineTestEnd = pos + vec * 500;
       
		 static U32 losMask = VehicleObjectType | StaticShapeObjectType;  
		 RayInfo ri;  
         bool hit = gClientContainer.castRay( lineTestStart, lineTestEnd, losMask, &ri);  

		 	 
		 if (!hit)
		 {
		    //Con::printf("no hit!");
			if (mCursorObject != NULL)
			   mCursorObject->setHighlighted(false);
			mCursorObject = NULL;		 
		 }
		 else
		 {	    
			if (ri.object != mCursorObject && mCursorObject != NULL)
			   mCursorObject->setHighlighted(false);
			mCursorObject = (ShapeBase*)ri.object;	
			mCursorObject->setHighlighted(true);
		 }
	  }
   }
}
void WorldEditorSelection::setScale(const VectorF & scale, const Point3F & center)
{
   for( iterator iter = begin(); iter != end(); ++ iter )
   {
      SceneObject* object = dynamic_cast< SceneObject* >( *iter );
      if( !object )
         continue;
         
      MatrixF mat = object->getTransform();

      Point3F pos;
      mat.getColumn(3, &pos);

      Point3F offset = pos - center;
      offset *= scale;

      object->setPosition(offset + center);
      object->setScale(scale);
   }
}
Beispiel #13
0
/**
 * Sets the correct aim for the bot to the target
 */
void AIPlayer::getMuzzleVector(U32 imageSlot,VectorF* vec)
{
   MatrixF mat;
   getMuzzleTransform(imageSlot,&mat);

   MountedImage& image = mMountedImageList[imageSlot];

   if (image.dataBlock->correctMuzzleVector)
   {
      disableHeadZCalc();
      if (getCorrectedAim(mat, vec))
      {
         enableHeadZCalc();
         return;
      }
      enableHeadZCalc();

   }
   mat.getColumn(1,vec);
}
Beispiel #14
0
void GameTSCtrl::onMouseMove(const GuiEvent &evt)
{
   if(gSnapLine)
      return;

   MatrixF mat;
   Point3F vel;
   if ( GameGetCameraTransform(&mat, &vel) )
   {
      Point3F pos;
      mat.getColumn(3,&pos);
      Point3F screenPoint((F32)evt.mousePoint.x, (F32)evt.mousePoint.y, -1.0f);
      Point3F worldPoint;
      if (unproject(screenPoint, &worldPoint)) {
         Point3F vec = worldPoint - pos;
         lineTestStart = pos;
         vec.normalizeSafe();
         lineTestEnd = pos + vec * 1000;
      }
   }
}
void WorldEditorSelection::scale(const VectorF & scale, const Point3F & center)
{
   for( iterator iter = begin(); iter != end(); ++ iter )
   {
      SceneObject* object = dynamic_cast< SceneObject* >( *iter );
      if( !object )
         continue;

      VectorF current = object->getScale();
      current.convolve(scale);

      // clamp scale to sensible limits
      current.setMax( Point3F( 0.01f ) );
      current.setMin( Point3F( 1000.0f ) );

      // Apply the scale first.  If the object's scale doesn't change with
      // this operation then this object doesn't scale.  In this case
      // we don't want to continue with the offset operation.
      VectorF prevScale = object->getScale();
      object->setScale(current);
      if( !object->getScale().equal(current) )
         continue;

      // determine the actual scale factor to apply to the object offset
      // need to account for the scale limiting above to prevent offsets
      // being reduced to 0 which then cannot be restored by unscaling
      VectorF adjustedScale = current / prevScale;

      MatrixF mat = object->getTransform();

      Point3F pos;
      mat.getColumn(3, &pos);

      Point3F offset = pos - center;
      offset *= adjustedScale;

      object->setPosition(offset + center);
   }
}
void Lightning::scheduleThunder(Strike* newStrike)
{
   AssertFatal(isClientObject(), "Lightning::scheduleThunder: server objects should not enter this version of the function");

   // If no thunder sounds, don't schedule anything!
   if (mDataBlock->numThunders == 0)
      return;

   GameConnection* connection = GameConnection::getConnectionToServer();
   if (connection) {
      MatrixF cameraMatrix;

      if (connection->getControlCameraTransform(0, &cameraMatrix)) {
         Point3F worldPos;
         cameraMatrix.getColumn(3, &worldPos);

         worldPos.x -= newStrike->xVal;
         worldPos.y -= newStrike->yVal;
         worldPos.z  = 0.0f;

         F32 dist = worldPos.len();
         F32 t    = dist / 330.0f;

         // Ok, we need to schedule a random strike sound t secs in the future...
         //
         if (t <= 0.03f) {
            // If it's really close, just play it...
            U32 thunder = sgLightningRand.randI(0, mDataBlock->numThunders - 1);
            SFX->playOnce(mDataBlock->thunderSounds[thunder]);
         } else {
            Thunder* pThunder = new Thunder;
            pThunder->tRemaining = t;
            pThunder->next       = mThunderListHead;
            mThunderListHead     = pThunder;
         }
      }
   }
}
Beispiel #17
0
void AITurretShape::_renderScanner( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat )
{
   GFXStateBlockDesc desc;
   desc.setBlend(false, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
   desc.setZReadWrite(false,true);
   desc.fillMode = GFXFillWireframe;

   // Render the scan box
   GFX->getDrawUtil()->drawCube(desc, mTransformedScanBox.getExtents(), mTransformedScanBox.getCenter(), ColorI(255, 0, 0));

   // Render a line from the scan node to the max scan distance
   MatrixF nodeMat;
   if (getNodeTransform(mDataBlock->scanNode, nodeMat))
   {
      Point3F start;
      nodeMat.getColumn(3, &start);

      Point3F end(0.0f, mScanDistance, 0.0f);
      nodeMat.mulP(end);

      GFX->getDrawUtil()->drawLine(start, end, ColorI(255, 255, 0));
   }
}
Beispiel #18
0
void Etherform::updateTrailEmitter(F32 dt)
{
	if(mDamageState == Destroyed)
		return;

	if(!mDataBlock->jetEmitter[EtherformData::TrailEmitter])
		return;

	ParticleEmitter* emitter = mJetEmitter[EtherformData::TrailEmitter];

	// Particle trail emitter
   F32 speed = this->getVelocity().len();
	if(speed > mDataBlock->minTrailSpeed)
	{
		if(!bool(emitter))
		{
			emitter = new ParticleEmitter;
			emitter->onNewDataBlock(mDataBlock->jetEmitter[EtherformData::TrailEmitter], false);
			emitter->registerObject();
			mJetEmitter[EtherformData::TrailEmitter] = emitter;
		}
		MatrixF mat = this->getRenderTransform();
		Point3F pos,axis;
		//mat.getColumn(1,&axis);
		axis = this->getVelocity(); axis.normalize();
		mat.getColumn(3,&pos);
		emitter->emitParticles(pos,true,axis,getVelocity(),(U32)(dt * 1000));
   }
	else
	{
		if(bool(emitter))
		{
			emitter->deleteWhenEmpty();
			mJetEmitter[EtherformData::TrailEmitter] = 0;
		}
	}
}
Beispiel #19
0
void SFXSource::_updateVolume( const MatrixF& listener )
{
   const F32 volume = mVolume * mModulativeVolume;

   if ( !mIs3D ) 
   {
      mDistToListener = 0.0f;
      mAttenuatedVolume = volume; 
      return;
	}

   Point3F pos, lpos;
   mTransform.getColumn( 3, &pos );
   listener.getColumn( 3, &lpos );

   mDistToListener = ( pos - lpos ).len();
   mAttenuatedVolume = SFXDistanceAttenuation(
      SFX->getDistanceModel(),
      mMinDistance,
      mMaxDistance,
      mDistToListener,
      volume,
      SFX->getRolloffFactor() );
}
void WorldEditorSelection::rotate(const EulerF & rot, const Point3F & center)
{
   // single selections will rotate around own axis, multiple about world
   if(size() == 1)
   {
      SceneObject* object = dynamic_cast< SceneObject* >( at( 0 ) );
      if( object )
      {
         MatrixF mat = object->getTransform();

         Point3F pos;
         mat.getColumn(3, &pos);

         // get offset in obj space
         Point3F offset = pos - center;
         MatrixF wMat = object->getWorldTransform();
         wMat.mulV(offset);

         //
         MatrixF transform(EulerF(0,0,0), -offset);
         transform.mul(MatrixF(rot));
         transform.mul(MatrixF(EulerF(0,0,0), offset));
         mat.mul(transform);

         object->setTransform(mat);
      }
   }
   else
   {
      for( iterator iter = begin(); iter != end(); ++ iter )
      {
         SceneObject* object = dynamic_cast< SceneObject* >( *iter );
         if( !object )
            continue;
            
         MatrixF mat = object->getTransform();

         Point3F pos;
         mat.getColumn(3, &pos);

         // get offset in obj space
         Point3F offset = pos - center;

         MatrixF transform(rot);
         Point3F wOffset;
         transform.mulV(offset, &wOffset);

         MatrixF wMat = object->getWorldTransform();
         wMat.mulV(offset);

         //
         transform.set(EulerF(0,0,0), -offset);

         mat.setColumn(3, Point3F(0,0,0));
         wMat.setColumn(3, Point3F(0,0,0));

         transform.mul(wMat);
         transform.mul(MatrixF(rot));
         transform.mul(mat);
         mat.mul(transform);

         mat.normalize();
         mat.setColumn(3, wOffset + center);

         object->setTransform(mat);
      }
   }

   mCentroidValid = false;
}
Beispiel #21
0
void TurretShape::getCameraTransform(F32* pos,MatrixF* mat)
{
   // Returns camera to world space transform
   // Handles first person / third person camera position
   if (isServerObject() && mShapeInstance)
      mShapeInstance->animateNodeSubtrees(true);

   if (*pos == 0) {
      getRenderEyeTransform(mat);
      return;
   }

   // Get the shape's camera parameters.
   F32 min,max;
   MatrixF rot;
   Point3F offset;
   getCameraParameters(&min,&max,&offset,&rot);

   // Start with the current eye position
   MatrixF eye;
   getRenderEyeTransform(&eye);

   // Build a transform that points along the eye axis
   // but where the Z axis is always up.
   {
      MatrixF cam(1);
      VectorF x,y,z(0,0,1);
      eye.getColumn(1, &y);
      mCross(y, z, &x);
      x.normalize();
      mCross(x, y, &z);
      z.normalize();
      cam.setColumn(0,x);
      cam.setColumn(1,y);
      cam.setColumn(2,z);
      mat->mul(cam,rot);
   }

   // Camera is positioned straight back along the eye's -Y axis.
   // A ray is cast to make sure the camera doesn't go through
   // anything solid.
   VectorF vp,vec;
   vp.x = vp.z = 0;
   vp.y = -(max - min) * *pos;
   eye.mulV(vp,&vec);

   // Use the camera node as the starting position if it exists.
   Point3F osp,sp;
   if (mDataBlock->cameraNode != -1) 
   {
      mShapeInstance->mNodeTransforms[mDataBlock->cameraNode].getColumn(3,&osp);
      getRenderTransform().mulP(osp,&sp);
   }
   else
      eye.getColumn(3,&sp);

   // Make sure we don't hit ourself...
   disableCollision();
   if (isMounted())
      getObjectMount()->disableCollision();

   // Cast the ray into the container database to see if we're going
   // to hit anything.
   RayInfo collision;
   Point3F ep = sp + vec + offset;
   if (mContainer->castRay(sp, ep,
         ~(WaterObjectType | GameBaseObjectType | DefaultObjectType | sTriggerMask),
         &collision) == true) {

      // Shift the collision point back a little to try and
      // avoid clipping against the front camera plane.
      F32 t = collision.t - (-mDot(vec, collision.normal) / vec.len()) * 0.1;
      if (t > 0.0f)
         ep = sp + offset + (vec * t);
      else
         eye.getColumn(3,&ep);
   }
   mat->setColumn(3,ep);

   // Re-enable our collision.
   if (isMounted())
      getObjectMount()->enableCollision();
   enableCollision();

   // Apply Camera FX.
   mat->mul( gCamFXMgr.getTrans() );
}
//-----------------------------------------------------------------------------
//
// 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() );
}
Beispiel #23
0
void FlyingVehicle::updateForces(F32 /*dt*/)
{
   PROFILE_SCOPE( FlyingVehicle_UpdateForces );

   MatrixF currPosMat;
   mRigid.getTransform(&currPosMat);
   mRigid.atRest = false;

   Point3F massCenter;
   currPosMat.mulP(mDataBlock->massCenter,&massCenter);

   Point3F xv,yv,zv;
   currPosMat.getColumn(0,&xv);
   currPosMat.getColumn(1,&yv);
   currPosMat.getColumn(2,&zv);
   F32 speed = mRigid.linVelocity.len();

   Point3F force  = Point3F(0, 0, sFlyingVehicleGravity * mRigid.mass * mGravityMod);
   Point3F torque = Point3F(0, 0, 0);

   // Drag at any speed
   force  -= mRigid.linVelocity * mDataBlock->minDrag;
   torque -= mRigid.angMomentum * mDataBlock->rotationalDrag;

   // Auto-stop at low speeds
   if (speed < mDataBlock->maxAutoSpeed) {
      F32 autoScale = 1 - speed / mDataBlock->maxAutoSpeed;

      // Gyroscope
      F32 gf = mDataBlock->autoAngularForce * autoScale;
      torque -= xv * gf * mDot(yv,Point3F(0,0,1));

      // Manuevering jets
      F32 sf = mDataBlock->autoLinearForce * autoScale;
      force -= yv * sf * mDot(yv, mRigid.linVelocity);
      force -= xv * sf * mDot(xv, mRigid.linVelocity);
   }

   // Hovering Jet
   F32 vf = -sFlyingVehicleGravity * mRigid.mass * mGravityMod;
   F32 h  = getHeight();
   if (h <= 1) {
      if (h > 0) {
         vf -= vf * h * 0.1;
      } else {
         vf += mDataBlock->jetForce * -h;
      }
   }
   force += zv * vf;

   // Damping "surfaces"
   force -= xv * mDot(xv,mRigid.linVelocity) * mDataBlock->horizontalSurfaceForce;
   force -= zv * mDot(zv,mRigid.linVelocity) * mDataBlock->verticalSurfaceForce;

   // Turbo Jet
   if (mJetting) {
      if (mThrustDirection == ThrustForward)
         force += yv * mDataBlock->jetForce * mCeilingFactor;
      else if (mThrustDirection == ThrustBackward)
         force -= yv * mDataBlock->jetForce * mCeilingFactor;
      else
         force += zv * mDataBlock->jetForce * mDataBlock->vertThrustMultiple * mCeilingFactor;
   }

   // Maneuvering jets
   force += yv * (mThrust.y * mDataBlock->maneuveringForce * mCeilingFactor);
   force += xv * (mThrust.x * mDataBlock->maneuveringForce * mCeilingFactor);

   // Steering
   Point2F steering;
   steering.x = mSteering.x / mDataBlock->maxSteeringAngle;
   steering.x *= mFabs(steering.x);
   steering.y = mSteering.y / mDataBlock->maxSteeringAngle;
   steering.y *= mFabs(steering.y);
   torque -= xv * steering.y * mDataBlock->steeringForce;
   torque -= zv * steering.x * mDataBlock->steeringForce;

   // Roll
   torque += yv * steering.x * mDataBlock->steeringRollForce;
   F32 ar = mDataBlock->autoAngularForce * mDot(xv,Point3F(0,0,1));
   ar -= mDataBlock->rollForce * mDot(xv, mRigid.linVelocity);
   torque += yv * ar;

   // Add in force from physical zones...
   force += mAppliedForce;

   // Container buoyancy & drag
   force -= Point3F(0, 0, 1) * (mBuoyancy * sFlyingVehicleGravity * mRigid.mass * mGravityMod);
   force -= mRigid.linVelocity * mDrag;

   //
   mRigid.force  = force;
   mRigid.torque = torque;
}
void GuiRiverEditorCtrl::renderScene(const RectI & updateRect)
{
   //GFXDrawUtil *drawer = GFX->getDrawUtil();            

   GFX->setStateBlock( mZDisableSB );

   // get the projected size...
   GameConnection* connection = GameConnection::getConnectionToServer();
   if(!connection)
      return;

   // Grab the camera's transform
   MatrixF mat;
   connection->getControlCameraTransform(0, &mat);

   // Get the camera position
   Point3F camPos;
   mat.getColumn(3,&camPos);

   if ( mHoverRiver && mHoverRiver != mSelRiver )
   {
      _drawRiverSpline( mHoverRiver, mHoverSplineColor );
   }

   if ( mSelRiver )
   {
      _drawRiverSpline( mSelRiver, mSelectedSplineColor );            

      // Render Gizmo for selected node if were in either of the three transform modes
      if ( mSelNode != -1 && ( mMode == mMovePointMode || mMode == mScalePointMode || mMode == mRotatePointMode ) )
      {
			if( mMode == mMovePointMode )
			{
				mGizmo->getProfile()->mode = MoveMode;
			}
			else if( mMode == mScalePointMode )
			{
				mGizmo->getProfile()->mode = ScaleMode;
			}
			else if( mMode == mRotatePointMode )
			{
				mGizmo->getProfile()->mode = RotateMode;
			}

         const RiverNode &node = mSelRiver->mNodes[mSelNode];

         MatrixF objMat = mSelRiver->getNodeTransform(mSelNode);      
         Point3F objScale( node.width, 1.0f, node.depth );
         Point3F worldPos = node.point;

         mGizmo->set( objMat, worldPos, objScale );

         mGizmo->renderGizmo(mLastCameraQuery.cameraMatrix);
      }    
   }

   // Now draw all the 2d stuff!
   GFX->setClipRect(updateRect); 

   // Render Gizmo text
   if ( mSelRiver && mSelNode != -1 )
   {
      // mGizmo->setPosition(mSelRiver->mNodes[mSelNode].point);
      // mGizmo->renderText( mSaveViewport, mSaveModelview, mSaveProjection );      
   }
   
   // Draw Control nodes for selecting and highlighted rivers
   if ( mHoverRiver )
      _drawRiverControlNodes( mHoverRiver, mHoverSplineColor );
   if ( mSelRiver )
      _drawRiverControlNodes( mSelRiver, mSelectedSplineColor );
} 
/**
 * 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;
}
Beispiel #26
0
void Polytope::buildBox(const MatrixF& transform,const Box3F& box)
{
   // Box is assumed to be axis aligned in the source space.
   // Transform into geometry space
   Point3F xvec,yvec,zvec,min;
   transform.getColumn(0,&xvec);
   xvec *= box.len_x();
   transform.getColumn(1,&yvec);
   yvec *= box.len_y();
   transform.getColumn(2,&zvec);
   zvec *= box.len_z();
   transform.mulP(box.minExtents,&min);

   // Initial vertices
   mVertexList.setSize(8);
   mVertexList[0].point = min;
   mVertexList[1].point = min + yvec;
   mVertexList[2].point = min + xvec + yvec;
   mVertexList[3].point = min + xvec;
   mVertexList[4].point = mVertexList[0].point + zvec;
   mVertexList[5].point = mVertexList[1].point + zvec;
   mVertexList[6].point = mVertexList[2].point + zvec;
   mVertexList[7].point = mVertexList[3].point + zvec;
   S32 i;
   for (i = 0; i < 8; i++)
      mVertexList[i].side = 0;

   // Initial faces
   mFaceList.setSize(6);
   for (S32 f = 0; f < 6; f++) {
      Face& face = mFaceList[f];
      face.original = true;
      face.vertex = 0;
   }

   mFaceList[0].plane.set(mVertexList[0].point,xvec);
   mFaceList[0].plane.invert();
   mFaceList[1].plane.set(mVertexList[2].point,yvec);
   mFaceList[2].plane.set(mVertexList[2].point,xvec);
   mFaceList[3].plane.set(mVertexList[0].point,yvec);
   mFaceList[3].plane.invert();
   mFaceList[4].plane.set(mVertexList[0].point,zvec);
   mFaceList[4].plane.invert();
   mFaceList[5].plane.set(mVertexList[4].point,zvec);

   // Initial edges
   mEdgeList.setSize(12);
   Edge* edge = mEdgeList.begin();
   S32 nextEdge = 0;
   for (i = 0; i < 4; i++) {
      S32 n = (i == 3)? 0: i + 1;
      S32 p = (i == 0)? 3: i - 1;
      edge->vertex[0] = i;
      edge->vertex[1] = n;
      edge->face[0] = i;
      edge->face[1] = 4;
      edge->next = ++nextEdge;
      edge++;
      edge->vertex[0] = 4 + i;
      edge->vertex[1] = 4 + n;
      edge->face[0] = i;
      edge->face[1] = 5;
      edge->next = ++nextEdge;
      edge++;
      edge->vertex[0] = i;
      edge->vertex[1] = 4 + i;
      edge->face[0] = i;
      edge->face[1] = p;
      edge->next = ++nextEdge;
      edge++;
   }
   edge[-1].next = -1;

   // Volume
   mVolumeList.setSize(1);
   Volume& volume = mVolumeList.last();
   volume.edgeList = 0;
   volume.material = -1;
   volume.object = 0;
   sideCount = 0;
}
Beispiel #27
0
void GuiObjectView::renderWorld( const RectI& updateRect )
{
   if( !mModel )
      return;
      
   GFXTransformSaver _saveTransforms;

   // Determine the camera position, and store off render state.
   
   MatrixF modelview;
   MatrixF mv;
   Point3F cp;

   modelview = GFX->getWorldMatrix();

   mv = modelview;
   mv.inverse();
   mv.getColumn( 3, &cp );

   RenderPassManager* renderPass = gClientSceneGraph->getDefaultRenderPass();

   S32 time = Platform::getVirtualMilliseconds();
   S32 dt = time - mLastRenderTime;
   mLastRenderTime = time;

   LIGHTMGR->unregisterAllLights();
   LIGHTMGR->setSpecialLight( LightManager::slSunLightType, mLight );
  
   GFX->setStateBlock( mDefaultGuiSB );

   F32 left, right, top, bottom, nearPlane, farPlane;
   bool isOrtho;
   GFX->getFrustum( &left, &right, &bottom, &top, &nearPlane, &farPlane, &isOrtho );

   Frustum frust( false, left, right, top, bottom, nearPlane, farPlane, MatrixF::Identity );

   SceneRenderState state
   (
      gClientSceneGraph,
      SPT_Diffuse,
      SceneCameraState( GFX->getViewport(), frust, GFX->getWorldMatrix(), GFX->getProjectionMatrix() ),
      renderPass,
      false
   );

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

   // We might have some forward lit materials
   // so pass down a query to gather lights.
   LightQuery query;
   query.init( SphereF( Point3F::Zero, 1.0f ) );
   rdata.setLightQuery( &query );

   // Render primary model.

   if( mModel )
   {
      if( mRunThread )
      {
         mModel->advanceTime( dt / 1000.f, mRunThread );
         mModel->animate();
      }
      
      mModel->render( rdata );
   }
   
   // Render mounted model.

   if( mMountedModel && mMountNode != -1 )
   {
      GFX->pushWorldMatrix();
      GFX->multWorld( mModel->mNodeTransforms[ mMountNode ] );
      GFX->multWorld( mMountTransform );
      
      mMountedModel->render( rdata );

      GFX->popWorldMatrix();
   }

   renderPass->renderPass( &state );

   // Make sure to remove our fake sun.
   LIGHTMGR->unregisterAllLights();
}
void EditTSCtrl::renderCameraAxis()
{
   GFXDEBUGEVENT_SCOPE( Editor_renderCameraAxis, ColorI::WHITE );

   static MatrixF sRotMat(EulerF( (M_PI_F / -2.0f), 0.0f, 0.0f));

   MatrixF camMat = mLastCameraQuery.cameraMatrix;
   camMat.mul(sRotMat);
   camMat.inverse();

   MatrixF axis;
   axis.setColumn(0, Point3F(1, 0, 0));
   axis.setColumn(1, Point3F(0, 0, 1));
   axis.setColumn(2, Point3F(0, -1, 0));
   axis.mul(camMat);

   Point3F forwardVec, upVec, rightVec;
	axis.getColumn( 2, &forwardVec );
	axis.getColumn( 1, &upVec );
	axis.getColumn( 0, &rightVec );

   Point2I pos = getPosition();
	F32 offsetx = pos.x + 20.0;
	F32 offsety = pos.y + getExtent().y - 42.0; // Take the status bar into account
	F32 scale = 15.0;

   // Generate correct drawing order
   ColorI c1(255,0,0);
   ColorI c2(0,255,0);
   ColorI c3(0,0,255);
	ColorI tc;
	Point3F *p1, *p2, *p3, *tp;
	p1 = &rightVec;
	p2 = &upVec;
	p3 = &forwardVec;
	if(p3->y > p2->y)
	{
		tp = p2; tc = c2;
		p2 = p3; c2 = c3;
		p3 = tp; c3 = tc;
	}
	if(p2->y > p1->y)
	{
		tp = p1; tc = c1;
		p1 = p2; c1 = c2;
		p2 = tp; c2 = tc;
	}

   PrimBuild::begin( GFXLineList, 6 );
		//*** Axis 1
		PrimBuild::color(c1);
		PrimBuild::vertex3f(offsetx, offsety, 0);
		PrimBuild::vertex3f(offsetx+p1->x*scale, offsety-p1->z*scale, 0);

		//*** Axis 2
		PrimBuild::color(c2);
		PrimBuild::vertex3f(offsetx, offsety, 0);
		PrimBuild::vertex3f(offsetx+p2->x*scale, offsety-p2->z*scale, 0);

		//*** Axis 3
		PrimBuild::color(c3);
		PrimBuild::vertex3f(offsetx, offsety, 0);
		PrimBuild::vertex3f(offsetx+p3->x*scale, offsety-p3->z*scale, 0);
   PrimBuild::end();
}
Beispiel #29
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);
}
Beispiel #30
0
bool Box3F::collideOrientedBox(const Point3F & bRadii, const MatrixF & toA) const
{
   Point3F p;
   toA.getColumn(3,&p);
   Point3F aCenter = minExtents + maxExtents;
   aCenter *= 0.5f;
   p -= aCenter; // this essentially puts origin of toA target space on the center of the current box
   Point3F aRadii = maxExtents - minExtents;
   aRadii *= 0.5f;

	F32 absXX,absXY,absXZ;
	F32 absYX,absYY,absYZ;
	F32 absZX,absZY,absZZ;

   const F32 * f = toA;

   absXX = mFabs(f[0]);
   absYX = mFabs(f[1]);
   absZX = mFabs(f[2]);

	if (aRadii.x + bRadii.x * absXX + bRadii.y * absYX + bRadii.z * absZX - mFabs(p.x)<0.0f)
		return false;

   absXY = mFabs(f[4]);
   absYY = mFabs(f[5]);
   absZY = mFabs(f[6]);
	if (aRadii.y + bRadii.x * absXY +	bRadii.y * absYY +	bRadii.z * absZY - mFabs(p.y)<0.0f)
		return false;
	
   absXZ = mFabs(f[8]);
   absYZ = mFabs(f[9]);
   absZZ = mFabs(f[10]);
	if (aRadii.z + bRadii.x * absXZ + bRadii.y * absYZ +	bRadii.z * absZZ - mFabs(p.z)<0.0f)
		return false;

	if (aRadii.x*absXX + aRadii.y*absXY + aRadii.z*absXZ + bRadii.x - mFabs(p.x*f[0] + p.y*f[4] + p.z*f[8])<0.0f)
		return false;

	if (aRadii.x*absYX + aRadii.y*absYY + aRadii.z*absYZ + bRadii.y - mFabs(p.x*f[1] + p.y*f[5] + p.z*f[9])<0.0f)
		return false;		
	
	if (aRadii.x*absZX + aRadii.y*absZY + aRadii.z*absZZ + bRadii.z - mFabs(p.x*f[2] + p.y*f[6] + p.z*f[10])<0.0f)
		return false;		
	
	if (mFabs(p.z*f[4] - p.y*f[8]) >
				aRadii.y * absXZ + aRadii.z * absXY +
				bRadii.y * absZX + bRadii.z * absYX)
		return false;
	
	if (mFabs(p.z*f[5] - p.y*f[9]) >
				aRadii.y * absYZ + aRadii.z * absYY +
				bRadii.x * absZX + bRadii.z * absXX)
		return false;
	
	if (mFabs(p.z*f[6] - p.y*f[10]) >
				aRadii.y * absZZ + aRadii.z * absZY +
				bRadii.x * absYX + bRadii.y * absXX)
		return false;
	
	if (mFabs(p.x*f[8] - p.z*f[0]) >
				aRadii.x * absXZ + aRadii.z * absXX +
				bRadii.y * absZY + bRadii.z * absYY)
		return false;
	
	if (mFabs(p.x*f[9] - p.z*f[1]) >
				aRadii.x * absYZ + aRadii.z * absYX +
				bRadii.x * absZY + bRadii.z * absXY)
		return false;
	
	if (mFabs(p.x*f[10] - p.z*f[2]) >
				aRadii.x * absZZ + aRadii.z * absZX +
				bRadii.x * absYY + bRadii.y * absXY)
		return false;
	
	if (mFabs(p.y*f[0] - p.x*f[4]) >
				aRadii.x * absXY + aRadii.y * absXX +
				bRadii.y * absZZ + bRadii.z * absYZ)
		return false;
	
	if (mFabs(p.y*f[1] - p.x*f[5]) >
				aRadii.x * absYY + aRadii.y * absYX +
				bRadii.x * absZZ + bRadii.z * absXZ)
		return false;
	
	if (mFabs(p.y*f[2] - p.x*f[6]) >
				aRadii.x * absZY + aRadii.y * absZX +
				bRadii.x * absYZ + bRadii.y * absXZ)
		return false;
	
	return true;
}