Ejemplo n.º 1
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;
                }
        }
}
Ejemplo n.º 2
0
GLint gluProject( GLdouble objx, GLdouble objy, GLdouble objz, const F64 *model, const F64 * proj, const GLint * vp, F64 * winx, F64 * winy, F64 * winz )
{
    Vector4F v = Vector4F( objx, objy, objz, 1.0f );
    MatrixF pmat = MatrixF( false );
        for (int i=0; i<16; i++) { ((F32*)pmat)[i] = (float)proj[i]; }
    MatrixF mmat = MatrixF( false );
        for (int i=0; i<16; i++) { ((F32*)mmat)[i] = (float)model[i]; }
        
    //Luma:	Projection fix
    mmat.transpose();
    pmat.transpose();
    (pmat.mul(mmat)).mul(v);
    
    //Luma:	Projection fix
    if(v.w == 0.0f)
    {
        return GL_FALSE;
    }
    F32		invW = 1.0f / v.w;
    v.x *= invW;
    v.y *= invW;
    v.z *= invW;
        
    *winx = (GLfloat)vp[0] + (GLfloat)vp[2] * (v.x + 1.0f) * 0.5f;
    *winy = (GLfloat)vp[1] + (GLfloat)vp[3] * (v.y + 1.0f) * 0.5f;
    *winz = (v.z + 1.0f) * 0.5f;
    int glError;
    glError = TEST_FOR_OPENGL_ERRORS
    return GL_TRUE;
}
Ejemplo n.º 3
0
void T3DSceneComponent::_ComputeObjectBox()
{
   _objectBox->set(Box3F(10E30f, 10E30f, 10E30f, -10E30f, -10E30f, -10E30f));
   bool gotone = false;
   for (T3DSceneClient * walk = _sceneClientList; walk != NULL; walk = walk->getNextSceneClient())
   {
      ISolid3D * solid = dynamic_cast<ISolid3D*>(walk);
      if (solid == NULL)
         continue;

      Box3F box = solid->getObjectBox();
      if (solid->getTransform3D() != NULL)
      {
         MatrixF mat;
         solid->getTransform3D()->getObjectMatrix(mat, true);
         mat.mul(box);
      }
      box.extend(_objectBox->get().min);
      box.extend(_objectBox->get().max);
      _objectBox->set(box);
      gotone = true;
   }
   if (!gotone)
      _objectBox->set(Box3F());

   setDirtyObjectBox(false);
   setDirtyWorldBox(true);
}
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 );   
}
Box3F PSSMLightShadowMap::_calcClipSpaceAABB(const Frustum& f, const MatrixF& transform, F32 farDist)
{
   // Calculate frustum center
   Point3F center(0,0,0);
   for (U32 i = 0; i < 8; i++)   
   {
      const Point3F& pt = f.getPoints()[i];      
      center += pt;
   }
   center /= 8;

   // Calculate frustum bounding sphere radius
   F32 radius = 0.0f;
   for (U32 i = 0; i < 8; i++)      
      radius = getMax(radius, (f.getPoints()[i] - center).lenSquared());
   radius = mFloor( mSqrt(radius) );
      
   // Now build box for sphere
   Box3F result;
   Point3F radiusBox(radius, radius, radius);
   result.minExtents = center - radiusBox;
   result.maxExtents = center + radiusBox;

   // Transform to light projection space
   transform.mul(result);
   
   return result;   
}
Ejemplo n.º 6
0
void AITurretShape::_setScanBox()
{
   mTransformedScanBox = mScanBox;
   MatrixF mat;
   getScanTransform(mat);
   mat.mul(mTransformedScanBox);
}
// This "rounds" the projection matrix to remove subtexel movement during shadow map
// rasterization.  This is here to reduce shadow shimmering.
void PSSMLightShadowMap::_roundProjection(const MatrixF& lightMat, const MatrixF& cropMatrix, Point3F &offset, U32 splitNum)
{
   // Round to the nearest shadowmap texel, this helps reduce shimmering
   MatrixF currentProj = GFX->getProjectionMatrix();
   currentProj = cropMatrix * currentProj * lightMat;

   // Project origin to screen.
   Point4F originShadow4F(0,0,0,1);
   currentProj.mul(originShadow4F);
   Point2F originShadow(originShadow4F.x / originShadow4F.w, originShadow4F.y / originShadow4F.w);   

   // Convert to texture space (0..shadowMapSize)
   F32 t = mNumSplits < 4 ? mShadowMapTex->getWidth() / mNumSplits : mShadowMapTex->getWidth() / 2;
   Point2F texelsToTexture(t / 2.0f, mShadowMapTex->getHeight() / 2.0f);
   if (mNumSplits >= 4) texelsToTexture.y *= 0.5f;
   originShadow.convolve(texelsToTexture);

   // Clamp to texel boundary
   Point2F originRounded;
   originRounded.x = mFloor(originShadow.x + 0.5f);
   originRounded.y = mFloor(originShadow.y + 0.5f);

   // Subtract origin to get an offset to recenter everything on texel boundaries
   originRounded -= originShadow;

   // Convert back to texels (0..1) and offset
   originRounded.convolveInverse(texelsToTexture);
   offset.x += originRounded.x;
   offset.y += originRounded.y;
}
Ejemplo n.º 8
0
void T3DSceneComponent::AddSceneClient(T3DSceneClient * sceneClient)
{
   AssertFatal(sceneClient,"Cannot add a NULL scene client");

   // add to the front of the list
   sceneClient->setNextSceneClient(_sceneClientList);
   _sceneClientList = sceneClient;

   // extend object box
   ISolid3D * solid = dynamic_cast<ISolid3D*>(sceneClient);
   if (solid != NULL)
   {
      if (isObjectBoxLocked())
         setDirtyObjectBox(true);
      else
      {
         Box3F box = solid->getObjectBox();
         if (solid->getTransform3D() != NULL)
         {
            MatrixF mat;
            solid->getTransform3D()->getObjectMatrix(mat, true);
            mat.mul(box);
         }
         box.extend(_objectBox->get().min);
         box.extend(_objectBox->get().max);
         _objectBox->set(box);
      }

      // policy is that we become parent transform
      if (solid->getTransform3D() != NULL && solid->getTransform3D()->isChildOf(_transform, true))
         solid->getTransform3D()->setParentTransform(_transform);
   }
}
Ejemplo n.º 9
0
void TurretShape::getRenderImageTransform(U32 imageSlot,S32 node,MatrixF* mat)
{
   // Same as ShapeBase::getRenderImageTransform() other than getRenderWeaponMountTransform() below

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

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

         if ( data.useEyeNode && isFirstPerson() && data.eyeMountNode[shapeIndex] != -1 )
         {
            MatrixF emat;
            getRenderEyeBaseTransform(&emat, mDataBlock->mountedImagesBank);

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

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

         mat->mul(mmat, nmat);
      }
      else
         getRenderImageTransform(imageSlot,mat);
   }
   else
      *mat = getRenderTransform();
}
Ejemplo n.º 10
0
Box3F ForestConvex::getBoundingBox(const MatrixF& mat, const Point3F& scale) const
{
   Box3F newBox = box;
   newBox.minExtents.convolve(scale);
   newBox.maxExtents.convolve(scale);
   mat.mul(newBox);
   return newBox;
}
Ejemplo n.º 11
0
Box3F Convex::getBoundingBox(const MatrixF& mat, const Point3F& scale) const
{
   Box3F wBox;//TOFIX = mObject->getObjBox();
   wBox.minExtents.convolve(scale);
   wBox.maxExtents.convolve(scale);
   mat.mul(wBox);
   return wBox;
}
Ejemplo n.º 12
0
GLint gluUnProject( GLdouble winx, GLdouble winy, GLdouble winz, const F64 *model, const F64 * proj, const GLint * vp, F64 * x, F64 * y, F64 * z )
{
    Vector4F v = Vector4F( 2.0f*(winx-vp[0])/vp[2] - 1.0f, 2.0f*(winy-vp[1])/vp[2] - 1.0f, 2.0f*vp[2] - 1.0f, 1.0f );
    MatrixF pmat = MatrixF( false );
    for (int i=0; i<16; i++) { ((F32*)pmat)[i] = (float)proj[i]; }
    MatrixF mmat = MatrixF( false );
    for (int i=0; i<16; i++) { ((F32*)mmat)[i] = (float)model[i]; }
    mmat = pmat.mul(mmat);

    mmat = mmat.inverse();
    mmat.mul( v );
    *x = v.x;
    *y = v.y;
    *z = v.z;
    int glError;
    glError = TEST_FOR_OPENGL_ERRORS
    return GL_TRUE;
}
Ejemplo n.º 13
0
void Etherform::setRenderPosition(const Point3F& pos, const Point3F& rot, F32 dt)
{
   MatrixF xRot, zRot;
   xRot.set(EulerF(rot.x, 0, 0));
   zRot.set(EulerF(0, 0, rot.z));
   MatrixF temp;
   temp.mul(zRot, xRot);
   temp.setColumn(3, pos);
   Parent::setRenderTransform(temp);
}
Box3F T3DSceneComponent::getWorldBox()
{
   if (DirtyWorldBox && !LockWorldBox)
      _UpdateWorldBox();

   MatrixF mat = getTransform3D()->getWorldMatrix();
   Box3F box = getObjectBox();

   mat.mul(box);
   return box;
}
Ejemplo n.º 15
0
void TSShapeInstance::addPath(TSThread *gt, F32 start, F32 end, MatrixF *mat)
{
   // never get here while in transition...
   AssertFatal(!gt->transitionData.inTransition,"TSShapeInstance::addPath");

   if (!mat)
      mat = &mGroundTransform;

   MatrixF startInvM;
   gt->getGround(start,&startInvM);
   startInvM.inverse();

   MatrixF endM;
   gt->getGround(end,&endM);

   MatrixF addM;
   addM.mul(startInvM,endM);
   endM.mul(*mat,addM);
   *mat = endM;
}
Ejemplo n.º 16
0
void BtBody::applyCorrection( const MatrixF &transform )
{
   AssertFatal( mActor, "BtBody::applyCorrection - The actor is null!" );
   AssertFatal( isDynamic(), "BtBody::applyCorrection - This call is only for dynamics!" );

   if ( mCenterOfMass )
   {
      MatrixF xfm;
      xfm.mul( transform, *mCenterOfMass );
      mActor->setCenterOfMassTransform( btCast<btTransform>( xfm ) ); 
   }
   else
      mActor->setCenterOfMassTransform( btCast<btTransform>( transform ) ); 
}
Ejemplo n.º 17
0
MatrixF ConvexShape::getSurfaceWorldMat( S32 surfId, bool scaled ) const
{
   if ( surfId < 0 || surfId >= mSurfaces.size() )
      return MatrixF::Identity;      

   MatrixF objToWorld( mObjToWorld );

   if ( scaled )
      objToWorld.scale( mObjScale );

   MatrixF surfMat;
   surfMat.mul( objToWorld, mSurfaces[surfId] );   

   return surfMat;
}
void WorldEditorSelection::rotate(const EulerF &rot)
{
   for( iterator iter = begin(); iter != end(); ++ iter )
   {
      SceneObject* object = dynamic_cast< SceneObject* >( *iter );
      if( !object )
         continue;

         MatrixF mat = object->getTransform();

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

         object->setTransform(mat);
   }
}
Ejemplo n.º 19
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.º 20
0
void Etherform::interpolateTick(F32 dt)
{
	Parent::interpolateTick(dt);

	if(dt != 0.0f)
	{
		Point3F pos = delta.pos + delta.posVec * dt;
		Point3F rot = delta.rot + delta.rotVec * dt;

		this->setRenderPosition(pos, rot, dt);

		// update laser trails...
		for( S32 i=0; i < NUM_ETHERFORM_LASERTRAILS; i++ )
		{
			if(mLaserTrailList[i])
				mLaserTrailList[i]->setLastNodePos(pos);
		}

		// apply camera effects - is this the best place? - bramage
		GameConnection* connection = GameConnection::getConnectionToServer();
		if(connection->isFirstPerson())
		{
			GameBase* obj = connection->getControlObject();
			if( obj == this )
			{
				MatrixF curTrans = this->getRenderTransform();
				curTrans.mul( gCamFXMgr.getTrans() );
				Parent::setRenderTransform( curTrans );
			}
		}
	}
	else
	{
		this->setRenderPosition(delta.pos, delta.rot, 0);
	}

	// Save last interpolation delta value.
	delta.dt = dt;
}
Ejemplo n.º 21
0
void BtBody::setTransform( const MatrixF &transform )
{
   AssertFatal( mActor, "BtBody::setTransform - The actor is null!" );

   if ( mCenterOfMass )
   {
      MatrixF xfm;
      xfm.mul( transform, *mCenterOfMass );
      mActor->setCenterOfMassTransform( btCast<btTransform>( xfm ) ); 
   }
   else
      mActor->setCenterOfMassTransform( btCast<btTransform>( transform ) ); 

   // If its dynamic we have more to do.
   if ( isDynamic() )
   {
      // Clear any velocity and forces... this is a warp.
      mActor->clearForces();
      mActor->setLinearVelocity( btVector3( 0, 0, 0 ) );
      mActor->setAngularVelocity( btVector3( 0, 0, 0 ) );
      mActor->activate();
   }
}
Ejemplo n.º 22
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.º 23
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 );      
}
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;
}
//-----------------------------------------------------------------------------
// Object Rendering
//-----------------------------------------------------------------------------
void MetaShapeRenderer::createGeometry()
{
	Point3F scale = this->getScale();
	Box3F box = this->getObjBox();
   box.minExtents.convolve(scale);
   box.maxExtents.convolve(scale);
	MatrixF mat = this->getTransform();
	mat.mul(box);

	mPolyList.clear();
   this->getContainer()->buildPolyList(
		PLC_Collision,
		box,
		ShapeBaseObjectType,
		&mPolyList
	);

	mUpdatePolyList = false;

   static const Point3F cubePoints[8] = 
   {
      Point3F( 1.0f, -1.0f, -1.0f), Point3F( 1.0f, -1.0f,  1.0f),
      Point3F( 1.0f,  1.0f, -1.0f), Point3F( 1.0f,  1.0f,  1.0f),
      Point3F(-1.0f, -1.0f, -1.0f), Point3F(-1.0f,  1.0f, -1.0f),
      Point3F(-1.0f, -1.0f,  1.0f), Point3F(-1.0f,  1.0f,  1.0f)
   };

   static const Point3F cubeNormals[6] = 
   {
      Point3F( 1.0f,  0.0f,  0.0f), Point3F(-1.0f,  0.0f,  0.0f),
      Point3F( 0.0f,  1.0f,  0.0f), Point3F( 0.0f, -1.0f,  0.0f),
      Point3F( 0.0f,  0.0f,  1.0f), Point3F( 0.0f,  0.0f, -1.0f)
   };

   static const ColorI cubeColors[3] = 
   {
      ColorI( 0, 0, 100, 100),
      ColorI( 0, 0, 100, 100),
      ColorI( 0, 0, 100, 100)
   };

   static const U32 cubeFaces[36][3] = 
   {
      { 3, 0, 0 }, { 0, 0, 0 }, { 1, 0, 0 },
      { 2, 0, 0 }, { 0, 0, 0 }, { 3, 0, 0 },
      { 7, 1, 0 }, { 4, 1, 0 }, { 5, 1, 0 },
      { 6, 1, 0 }, { 4, 1, 0 }, { 7, 1, 0 },
      { 3, 2, 1 }, { 5, 2, 1 }, { 2, 2, 1 },
      { 7, 2, 1 }, { 5, 2, 1 }, { 3, 2, 1 },
      { 1, 3, 1 }, { 4, 3, 1 }, { 6, 3, 1 },
      { 0, 3, 1 }, { 4, 3, 1 }, { 1, 3, 1 },
      { 3, 4, 2 }, { 6, 4, 2 }, { 7, 4, 2 },
      { 1, 4, 2 }, { 6, 4, 2 }, { 3, 4, 2 },
      { 2, 5, 2 }, { 4, 5, 2 }, { 0, 5, 2 },
      { 5, 5, 2 }, { 4, 5, 2 }, { 2, 5, 2 }
   };

   // Fill the vertex buffer
   VertexType *pVert = NULL;

   mVertexBuffer.set( GFX, 36, GFXBufferTypeStatic );
   pVert = mVertexBuffer.lock();

   Point3F halfSize = getObjBox().getExtents() * 0.5f;

   for (U32 i = 0; i < 36; i++)
   {
      const U32& vdx = cubeFaces[i][0];
      const U32& ndx = cubeFaces[i][1];
      const U32& cdx = cubeFaces[i][2];

      pVert[i].point  = cubePoints[vdx] * halfSize;
      pVert[i].normal = cubeNormals[ndx];
      pVert[i].color  = cubeColors[cdx];
   }

   mVertexBuffer.unlock();

   // Set up our normal and reflection StateBlocks
   GFXStateBlockDesc desc;

   // The normal StateBlock only needs a default StateBlock
   mNormalSB = GFX->createStateBlock( desc );

   // The reflection needs its culling reversed
   desc.cullDefined = true;
   desc.cullMode = GFXCullCW;
   mReflectSB = GFX->createStateBlock( desc );
}
Ejemplo n.º 26
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);
}
Ejemplo n.º 27
0
void TerrainBlock::_renderBlock( SceneRenderState *state )
{
   PROFILE_SCOPE( TerrainBlock_RenderBlock );

   // Prevent rendering shadows if feature is disabled
   if ( !mCastShadows && state->isShadowPass() ) 
      return;
	  
   MatrixF worldViewXfm = state->getWorldViewMatrix();
   worldViewXfm.mul( getRenderTransform() );

   MatrixF worldViewProjXfm = state->getProjectionMatrix();
   worldViewProjXfm.mul( worldViewXfm );

   const MatrixF &objectXfm = getRenderWorldTransform();

   Point3F objCamPos = state->getDiffuseCameraPosition();
   objectXfm.mulP( objCamPos );

   // Get the shadow material.
   if ( !mDefaultMatInst )
      mDefaultMatInst = TerrainCellMaterial::getShadowMat();

   // Make sure we have a base material.
   if ( !mBaseMaterial )
   {
      mBaseMaterial = new TerrainCellMaterial();
      mBaseMaterial->init( this, 0, false, false, true );
   }

   // Did the detail layers change?
   if ( mDetailsDirty )
   {   
      _updateMaterials();
      mDetailsDirty = false;
   }

   // If the layer texture has been cleared or is 
   // dirty then update it.
   if ( mLayerTex.isNull() || mLayerTexDirty )
      _updateLayerTexture();

   // If the layer texture is dirty or we lost the base
   // texture then regenerate it.
   if ( mLayerTexDirty || mBaseTex.isNull() )
   {
      _updateBaseTexture( false );
      mLayerTexDirty = false;
   }   

   static Vector<TerrCell*> renderCells;
   renderCells.clear();

   mCell->cullCells( state,
                     objCamPos,
                     &renderCells );

   RenderPassManager *renderPass = state->getRenderPass();

   MatrixF *riObjectToWorldXfm = renderPass->allocUniqueXform( getRenderTransform() );

   const bool isColorDrawPass = state->isDiffusePass() || state->isReflectPass();

   // This is here for shadows mostly... it allows the
   // proper shadow material to be generated.
   BaseMatInstance *defaultMatInst = state->getOverrideMaterial( mDefaultMatInst );

   // Only pass and use the light manager if this is not a shadow pass.
   LightManager *lm = NULL;
   if ( isColorDrawPass )
      lm = LIGHTMGR;

   for ( U32 i=0; i < renderCells.size(); i++ )
   {
      TerrCell *cell = renderCells[i];

      // Ok this cell is fit to render.
      TerrainRenderInst *inst = renderPass->allocInst<TerrainRenderInst>();

      // Setup lights for this cell.
      if ( lm )
      {
         SphereF bounds = cell->getSphereBounds();
         getRenderTransform().mulP( bounds.center );

         LightQuery query;
         query.init( bounds );
		   query.getLights( inst->lights, 8 );
      }

      GFXVertexBufferHandleBase vertBuff;
      GFXPrimitiveBufferHandle  primBuff;

      cell->getRenderPrimitive( &inst->prim, &vertBuff, &primBuff );

      inst->mat = defaultMatInst;
      inst->vertBuff = vertBuff.getPointer();

      if ( primBuff.isValid() )
      {
         // Use the cell's custom primitive buffer
         inst->primBuff = primBuff.getPointer();
      }
      else
      {
         // Use the standard primitive buffer for this cell
         inst->primBuff = mPrimBuffer.getPointer();
      }

      inst->objectToWorldXfm = riObjectToWorldXfm;

      // If we're not drawing to the shadow map then we need
      // to include the normal rendering materials. 
      if ( isColorDrawPass )
      {         
         const SphereF &bounds = cell->getSphereBounds();         

         F32 sqDist = ( bounds.center - objCamPos ).lenSquared();         

         F32 radiusSq = mSquared( ( mMaxDetailDistance + bounds.radius ) * smDetailScale );

         // If this cell is near enough to get detail textures then
         // use the full detail mapping material.  Else we use the
         // simple base only material.
         if ( !state->isReflectPass() && sqDist < radiusSq )
            inst->cellMat = cell->getMaterial();
         else if ( state->isReflectPass() )
            inst->cellMat = mBaseMaterial->getReflectMat();
         else
            inst->cellMat = mBaseMaterial;
      }

      inst->defaultKey = (U32)cell->getMaterials();

      // Submit it for rendering.
      renderPass->addInst( inst );
   }

   // Trigger the debug rendering.
   if (  state->isDiffusePass() && 
         !renderCells.empty() && 
         smDebugRender )
   {      
      // Store the render cells for later.
      mDebugCells = renderCells;

      ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
      ri->renderDelegate.bind( this, &TerrainBlock::_renderDebug );
      ri->type = RenderPassManager::RIT_Editor;
      state->getRenderPass()->addInst( ri );
   }
}
void TSLastDetail::_update()
{
   // We're gonna render... make sure we can.
   bool sceneBegun = GFX->canCurrentlyRender();
   if ( !sceneBegun )
      GFX->beginScene();

   _validateDim();

   Vector<GBitmap*> bitmaps;
   Vector<GBitmap*> normalmaps;

   // We need to create our own instance to render with.
   TSShapeInstance *shape = new TSShapeInstance( mShape, true );

   // Animate the shape once.
   shape->animate( mDl );

   // So we don't have to change it everywhere.
   const GFXFormat format = GFXFormatR8G8B8A8;  

   S32 imposterCount = ( ((2*mNumPolarSteps) + 1 ) * mNumEquatorSteps ) + ( mIncludePoles ? 2 : 0 );

   // Figure out the optimal texture size.
   Point2I texSize( smMaxTexSize, smMaxTexSize );
   while ( true )
   {
      Point2I halfSize( texSize.x / 2, texSize.y / 2 );
      U32 count = ( halfSize.x / mDim ) * ( halfSize.y / mDim );
      if ( count < imposterCount )
      {
         // Try half of the height.
         count = ( texSize.x / mDim ) * ( halfSize.y / mDim );
         if ( count >= imposterCount )
            texSize.y = halfSize.y;
         break;
      }

      texSize = halfSize;
   }

   GBitmap *imposter = NULL;
   GBitmap *normalmap = NULL;
   GBitmap destBmp( texSize.x, texSize.y, true, format );
   GBitmap destNormal( texSize.x, texSize.y, true, format );

   U32 mipLevels = destBmp.getNumMipLevels();

   ImposterCapture *imposterCap = new ImposterCapture();

   F32 equatorStepSize = M_2PI_F / (F32)mNumEquatorSteps;

   static const MatrixF topXfm( EulerF( -M_PI_F / 2.0f, 0, 0 ) );
   static const MatrixF bottomXfm( EulerF( M_PI_F / 2.0f, 0, 0 ) );

   MatrixF angMat;

   F32 polarStepSize = 0.0f;
   if ( mNumPolarSteps > 0 )
      polarStepSize = -( 0.5f * M_PI_F - mDegToRad( mPolarAngle ) ) / (F32)mNumPolarSteps;

   PROFILE_START(TSLastDetail_snapshots);

   S32 currDim = mDim;
   for ( S32 mip = 0; mip < mipLevels; mip++ )
   {
      if ( currDim < 1 )
         currDim = 1;
      
      dMemset( destBmp.getWritableBits(mip), 0, destBmp.getWidth(mip) * destBmp.getHeight(mip) * GFXFormat_getByteSize( format ) );
      dMemset( destNormal.getWritableBits(mip), 0, destNormal.getWidth(mip) * destNormal.getHeight(mip) * GFXFormat_getByteSize( format ) );

      bitmaps.clear();
      normalmaps.clear();

      F32 rotX = 0.0f;
      if ( mNumPolarSteps > 0 )
         rotX = -( mDegToRad( mPolarAngle ) - 0.5f * M_PI_F );

      // We capture the images in a particular order which must
      // match the order expected by the imposter renderer.

      imposterCap->begin( shape, mDl, currDim, mRadius, mCenter );

      for ( U32 j=0; j < (2 * mNumPolarSteps + 1); j++ )
      {
         F32 rotZ = -M_PI_F / 2.0f;

         for ( U32 k=0; k < mNumEquatorSteps; k++ )
         {            
            angMat.mul( MatrixF( EulerF( rotX, 0, 0 ) ),
                        MatrixF( EulerF( 0, 0, rotZ ) ) );

            imposterCap->capture( angMat, &imposter, &normalmap );

            bitmaps.push_back( imposter );
            normalmaps.push_back( normalmap );

            rotZ += equatorStepSize;
         }

         rotX += polarStepSize;

         if ( mIncludePoles )
         {
            imposterCap->capture( topXfm, &imposter, &normalmap );

            bitmaps.push_back(imposter);
            normalmaps.push_back( normalmap );

            imposterCap->capture( bottomXfm, &imposter, &normalmap );

            bitmaps.push_back( imposter );
            normalmaps.push_back( normalmap );
         }         
      }

      imposterCap->end();

      Point2I texSize( destBmp.getWidth(mip), destBmp.getHeight(mip) );

      // Ok... pack in bitmaps till we run out.
      for ( S32 y=0; y+currDim <= texSize.y; )
      {
         for ( S32 x=0; x+currDim <= texSize.x; )
         {
            // Copy the next bitmap to the dest texture.
            GBitmap* bmp = bitmaps.first();
            bitmaps.pop_front();
            destBmp.copyRect( bmp, RectI( 0, 0, currDim, currDim ), Point2I( x, y ), 0, mip );
            delete bmp;

            // Copy the next normal to the dest texture.
            GBitmap* normalmap = normalmaps.first();
            normalmaps.pop_front();
            destNormal.copyRect( normalmap, RectI( 0, 0, currDim, currDim ), Point2I( x, y ), 0, mip );
            delete normalmap;

            // Did we finish?
            if ( bitmaps.empty() )
               break;

            x += currDim;
         }

         // Did we finish?
         if ( bitmaps.empty() )
            break;

         y += currDim;
      }

      // Next mip...
      currDim /= 2;
   }

   PROFILE_END(); // TSLastDetail_snapshots

   delete imposterCap;
   delete shape;   
   
   
   // Should we dump the images?
   if ( Con::getBoolVariable( "$TSLastDetail::dumpImposters", false ) )
   {
      String imposterPath = mCachePath + ".imposter.png";
      String normalsPath = mCachePath + ".imposter_normals.png";

      FileStream stream;
      if ( stream.open( imposterPath, Torque::FS::File::Write  ) )
         destBmp.writeBitmap( "png", stream );
      stream.close();

      if ( stream.open( normalsPath, Torque::FS::File::Write ) )
         destNormal.writeBitmap( "png", stream );
      stream.close();
   }

   // DEBUG: Some code to force usage of a test image.
   //GBitmap* tempMap = GBitmap::load( "./forest/data/test1234.png" );
   //tempMap->extrudeMipLevels();
   //mTexture.set( tempMap, &GFXDefaultStaticDiffuseProfile, false );
   //delete tempMap;

   DDSFile *ddsDest = DDSFile::createDDSFileFromGBitmap( &destBmp );
   DDSUtil::squishDDS( ddsDest, GFXFormatDXT3 );

   DDSFile *ddsNormals = DDSFile::createDDSFileFromGBitmap( &destNormal );
   DDSUtil::squishDDS( ddsNormals, GFXFormatDXT5 );

   // Finally save the imposters to disk.
   FileStream fs;
   if ( fs.open( _getDiffuseMapPath(), Torque::FS::File::Write ) )
   {
      ddsDest->write( fs );
      fs.close();
   }
   if ( fs.open( _getNormalMapPath(), Torque::FS::File::Write ) )
   {
      ddsNormals->write( fs );
      fs.close();
   }

   delete ddsDest;
   delete ddsNormals;

   // If we did a begin then end it now.
   if ( !sceneBegun )
      GFX->endScene();
}
Ejemplo n.º 29
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.º 30
0
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();
}