SceneObject::SceneObject()
{
   mContainer = 0;
   mTypeMask = DefaultObjectType;
   mCollisionMask = 0xFF;
   mCollisionCount = 0;
   mGlobalBounds = false;

   mObjScale.set(1,1,1);
   mObjToWorld.identity();
   mWorldToObj.identity();

   mObjBox      = Box3F(Point3F(0, 0, 0), Point3F(0, 0, 0));
   mWorldBox    = Box3F(Point3F(0, 0, 0), Point3F(0, 0, 0));
   mWorldSphere = SphereF(Point3F(0, 0, 0), 0);

   mRenderObjToWorld.identity();
   mRenderWorldToObj.identity();
   mRenderWorldBox = Box3F(Point3F(0, 0, 0), Point3F(0, 0, 0));
   mRenderWorldSphere = SphereF(Point3F(0, 0, 0), 0);

   mContainerSeqKey = 0;

   mBinRefHead = NULL;

   mSceneManager = NULL;

   mNumCurrZones = 0;
   mZoneRefHead = NULL;
   mZoneRefDirty = false;

   mBinMinX = 0xFFFFFFFF;
   mBinMaxX = 0xFFFFFFFF;
   mBinMinY = 0xFFFFFFFF;
   mBinMaxY = 0xFFFFFFFF;
   mLightPlugin = NULL;

   mMount.object = NULL;
   mMount.link = NULL;
   mMount.list = NULL;
   mMount.node = -1;
   mMount.xfm = MatrixF::Identity;
   mMountPID = NULL;

   mSceneObjectLinks = NULL;

   for(U32 i = 0; i < Palette::NumSlots; i++)
      mPalette.colors[i] = Palette::defaultColor;
   mFlickerTime = 0;

   mObjectFlags.set( RenderEnabledFlag | SelectionEnabledFlag );
   mIsScopeAlways = false;
}
Exemple #2
0
SceneObject::SceneObject()
{
   mContainer = 0;
   mTypeMask = DefaultObjectType;
   mCollisionCount = 0;
   mGlobalBounds = false;

   mObjScale.set(1,1,1);
   mObjToWorld.identity();
   mWorldToObj.identity();

   mObjBox      = Box3F(Point3F(0, 0, 0), Point3F(0, 0, 0));
   mWorldBox    = Box3F(Point3F(0, 0, 0), Point3F(0, 0, 0));
   mWorldSphere = SphereF(Point3F(0, 0, 0), 0);

   mRenderObjToWorld.identity();
   mRenderWorldToObj.identity();
   mRenderWorldBox = Box3F(Point3F(0, 0, 0), Point3F(0, 0, 0));
   mRenderWorldSphere = SphereF(Point3F(0, 0, 0), 0);

   mContainerSeqKey = 0;

   mBinRefHead = NULL;

   mSceneManager = NULL;

   mNumCurrZones = 0;
   mZoneRefHead = NULL;
   mZoneRefDirty = false;

   mBinMinX = 0xFFFFFFFF;
   mBinMaxX = 0xFFFFFFFF;
   mBinMinY = 0xFFFFFFFF;
   mBinMaxY = 0xFFFFFFFF;
   mLightPlugin = NULL;

   mMount.object = NULL;
   mMount.link = NULL;
   mMount.list = NULL;
   mMount.node = -1;
   mMount.xfm = MatrixF::Identity;
   mMountPID = NULL;

   mSceneObjectLinks = NULL;

   mObjectFlags.set( RenderEnabledFlag | SelectionEnabledFlag );
   mIsScopeAlways = false;
   //.logicking guidebot >>
   m_worldObject = NULL;
   //.logicking guidebot <<
}
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 BaseShadowRenderImage::preRenderShadow(TSRenderContext & rc, float curTime)
{
   if (!castShadow)
      return;
      
	// do visibility check for shadow
   Point3F center;
   m_mul(shape->getShape().fCenter,transform,&center);
	SphereF shadowSphere = SphereF(center,shape->getShape().fRadius);
	int shadowVis = rc.getCamera()->testVisibility(shadowSphere);
	if ( shadowVis==TS::ClipNoneVis )
   {
      shadowSettings.shadowDetail = -1;
      return;
   }

   // shape detail to use for shadows
   if (!shadowOwnDetail)
   {
      projSize = rc.getCamera()->transformProjectRadius( center, shape->getShape().fRadius );
      float adjustedSize = shadowDetailScale * projSize;
                           
      shadowSettings.shadowDetail = shape->getShape().selectDetail( adjustedSize );

      if (shadowSettings.shadowDetail==-1)
         return;
   }

   // first pass at shadow details
   setShadowDetailsA(rc);

   // set shadow details may veto shadow
   if (shadowSettings.shadowDetail==-1)
      return;

   // set light direction, but only if different than before
   Point3F * pLight = &lightDirection;
   Point3F tempDirection;
   if (swingDown != 0.0f)
   {
      tempDirection = (lightDirection * (1.0f - swingDown)) + (Point3F(0, 0, -1) * swingDown);
      tempDirection.normalize();
      pLight = &tempDirection;
   }
   if (m_dot(*pLight,lastLight) < 0.999)
   {
      shadow.setLight( *pLight, shape);
      lastLight = *pLight;
      nextShadowUpdateTime = -1;
   }

   // set position of shadow
   shadow.setPosition(transform.p);

   if (shadowSettings.cacheProjection)
   {
      if (shadowSettings.recacheProjection)
      {
         shadow.calcSourceWindow(shape,transform);
         getPolys();
         shadow.cachePolys();
         shadowSettings.recacheProjection = false;
      }
   }
   else
   {
      shadow.calcSourceWindow(shape,transform);
      getPolys();
      Point3F cc = rc.getCamera()->getTCW().p;
      Point3F camY = transform.p-cc;
      camY.normalize();
      shadow.getPlanes(cc,camY);
   }
   
   setShadowDetails(rc);
   
   // set shadow details may veto shadow
   if (shadowSettings.shadowDetail==-1)
      return;

   if (shadowSettings.shadowDetail < shadowSettings.hiShadowDetail)
      shadowSettings.shadowDetail = shadowSettings.hiShadowDetail;

   // adjust next update time...
   nextShadowUpdateTime += shadowSettings.updateDelta - prevShadowUpdateDelta;
   prevShadowUpdateDelta = shadowSettings.updateDelta;

   // adjust bmp dim...
   int newBmpDim = shadowSettings.bmpDim;
   if (newBmpDim != prevBmpDim)
   {
      prevBmpDim = newBmpDim;
      shadow.setBitmapSize(deviceManager.getGFXDeviceManager(),newBmpDim,rc.getSurface());
      nextShadowUpdateTime = -1;
   }

   shadow.setAlphaLevel(alphaLevel);

   // create the shadow bitmap if needed
   if (curTime > nextShadowUpdateTime)
   {
      if (shadowSettings.useFloor)
      {
         SimContainerQuery query;
         Box3F & box = query.box;
         box.fMin    = box.fMax = center;
         box.fMin.z += shape->getShape().fRadius;
         box.fMax.z -= shape->getShape().fRadius * 1.5f;
         query.id = -1;
         query.type = -1;
         query.mask = shadowSettings.projectTerrainOnly ? SimTerrainObjectType : projectionMask;
         SimCollisionInfo collision;
         if (root->findLOS(query,&collision))
         {
            Point3F n,p;
            m_mul(collision.surfaces[0].position,collision.surfaces.tWorld,&p);
            m_mul(collision.surfaces[0].normal,(RMat3F&)collision.surfaces.tWorld,&n);
            p -= transform.p;
            Point3F lift = n;
            lift *= shadowSettings.liftFloor;
            p += lift;
            shadow.setFloor(p,n);
         }
         else
            shadow.clearFloor();
      }
      else
         shadow.clearFloor();

      shape->setDetailLevel(shadowSettings.shadowDetail);
      shape->animate();
      GFXPalette * pal = SimGame::get()->getWorld(SimGame::CLIENT)->getPalette();
      AssertFatal(pal, "invalid palette");
      // getShadowBitmap assumes calcSourceWindow already called...
      // ...but that's ok because we called it above
      shadow.getShadowBitmap(shape,pal,transform,shadowSettings.blurMethod);
      nextShadowUpdateTime = curTime + shadowSettings.updateDelta;
   }

	AssertFatal(root,
		"shadowRenderImage::preRenderShadow:  cannot cast shadow before \'root\' container set");

   // this'll keep track of how many shadows are out there
   if (shadowNum < 0)
      shadowNum=1; // first preRender this render cycle
   else
      shadowNum++;
}
Exemple #5
0
SphereF Box3F::getBoundingSphere() const
{
   return SphereF( getCenter(), getGreatestDiagonalLength() / 2.f );
}
void GuiMaterialPreview::renderWorld(const RectI &updateRect)
{
   // nothing to render, punt
   if ( !mModel && !mMountedModel )
      return;

   S32 time = Platform::getVirtualMilliseconds();
   //S32 dt = time - lastRenderTime;
   lastRenderTime = time;

   

   F32 left, right, top, bottom, nearPlane, farPlane;
   bool isOrtho;
   GFX->getFrustum( &left, &right, &bottom, &top, &nearPlane, &farPlane, &isOrtho);
   Frustum frust( isOrtho, left, right, bottom, top, nearPlane, farPlane, MatrixF::Identity );

   FogData savedFogData = gClientSceneGraph->getFogData();
   gClientSceneGraph->setFogData( FogData() );  // no fog in preview window

   RenderPassManager* renderPass = gClientSceneGraph->getDefaultRenderPass();
   SceneRenderState state
   (
      gClientSceneGraph,
      SPT_Diffuse,
      SceneCameraState( GFX->getViewport(), frust, GFX->getWorldMatrix(), GFX->getProjectionMatrix() ),
      renderPass,
      true
   );

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

   // Set up pass transforms
   renderPass->assignSharedXform(RenderPassManager::View, MatrixF::Identity);
   renderPass->assignSharedXform(RenderPassManager::Projection, GFX->getProjectionMatrix());

   LIGHTMGR->unregisterAllLights();
   LIGHTMGR->setSpecialLight( LightManager::slSunLightType, mFakeSun );

   if ( mModel )
      mModel->render( rdata );

   if ( mMountedModel )
   {
      // render a weapon
	   /*
      MatrixF mat;

      GFX->pushWorldMatrix();
      GFX->multWorld( mat );

      GFX->popWorldMatrix();
	  */
   }

   renderPass->renderPass( &state );

   gClientSceneGraph->setFogData( savedFogData );         // restore fog setting

   // Make sure to remove our fake sun
   LIGHTMGR->unregisterAllLights();
}
bool ProjectedShadow::_updateDecal( const SceneRenderState *state )
{
    PROFILE_SCOPE( ProjectedShadow_UpdateDecal );

    if ( !LIGHTMGR )
        return false;

    // Get the position of the decal first.
    const Box3F &objBox = mParentObject->getObjBox();
    const Point3F boxCenter = objBox.getCenter();
    Point3F decalPos = boxCenter;
    const MatrixF &renderTransform = mParentObject->getRenderTransform();
    {
        // Set up the decal position.
        // We use the object space box center
        // multiplied by the render transform
        // of the object to ensure we benefit
        // from interpolation.
        MatrixF t( renderTransform );
        t.setColumn(2,Point3F::UnitZ);
        t.mulP( decalPos );
    }

    if ( mDecalInstance )
    {
        mDecalInstance->mPosition = decalPos;
        if ( !shouldRender( state ) )
            return false;
    }

    // Get the sunlight for the shadow projection.
    // We want the LightManager to return NULL if it can't
    // get the "real" sun, so we specify false for the useDefault parameter.
    LightInfo *lights[4] = {0};
    LightQuery query;
    query.init( mParentObject->getWorldSphere() );
    query.getLights( lights, 4 );

    Point3F pos = renderTransform.getPosition();

    Point3F lightDir( 0, 0, 0 );
    Point3F tmp( 0, 0, 0 );
    F32 weight = 0;
    F32 range = 0;
    U32 lightCount = 0;
    F32 dist = 0;
    F32 fade = 0;
    for ( U32 i = 0; i < 4; i++ )
    {
        // If we got a NULL light,
        // we're at the end of the list.
        if ( !lights[i] )
            break;

        if ( !lights[i]->getCastShadows() )
            continue;

        if ( lights[i]->getType() != LightInfo::Point )
            tmp = lights[i]->getDirection();
        else
            tmp = pos - lights[i]->getPosition();

        range = lights[i]->getRange().x;
        dist = ( (tmp.lenSquared()) / ((range * range) * 0.5f));
        weight = mClampF( 1.0f - ( tmp.lenSquared() / (range * range)), 0.00001f, 1.0f );

        if ( lights[i]->getType() == LightInfo::Vector )
            fade = getMax( fade, 1.0f );
        else
            fade = getMax( fade, mClampF( 1.0f - dist, 0.00001f, 1.0f ) );

        lightDir += tmp * weight;
        lightCount++;
    }

    lightDir.normalize();

    // No light... no shadow.
    if ( !lights[0] )
        return false;

    // Has the light direction
    // changed since last update?
    bool lightDirChanged = !mLastLightDir.equal( lightDir );

    // Has the parent object moved
    // or scaled since the last update?
    bool hasMoved = !mLastObjectPosition.equal( mParentObject->getRenderPosition() );
    bool hasScaled = !mLastObjectScale.equal( mParentObject->getScale() );

    // Set the last light direction
    // to the current light direction.
    mLastLightDir = lightDir;
    mLastObjectPosition = mParentObject->getRenderPosition();
    mLastObjectScale = mParentObject->getScale();


    // Temps used to generate
    // tangent vector for DecalInstance below.
    VectorF right( 0, 0, 0 );
    VectorF fwd( 0, 0, 0 );
    VectorF tmpFwd( 0, 0, 0 );

    U32 idx = lightDir.getLeastComponentIndex();

    tmpFwd[idx] = 1.0f;

    right = mCross( tmpFwd, lightDir );
    fwd = mCross( lightDir, right );
    right = mCross( fwd, lightDir );

    right.normalize();

    // Set up the world to light space
    // matrix, along with proper position
    // and rotation to be used as the world
    // matrix for the render to texture later on.
    static MatrixF sRotMat(EulerF( 0.0f, -(M_PI_F/2.0f), 0.0f));
    mWorldToLight.identity();
    MathUtils::getMatrixFromForwardVector( lightDir, &mWorldToLight );
    mWorldToLight.setPosition( ( pos + boxCenter ) - ( ( (mRadius * smDepthAdjust) + 0.001f ) * lightDir ) );
    mWorldToLight.mul( sRotMat );
    mWorldToLight.inverse();

    // Get the shapebase datablock if we have one.
    ShapeBaseData *data = NULL;
    if ( mShapeBase )
        data = static_cast<ShapeBaseData*>( mShapeBase->getDataBlock() );

    // We use the object box's extents multiplied
    // by the object's scale divided by 2 for the radius
    // because the object's worldsphere radius is not
    // rotationally invariant.
    mRadius = (objBox.getExtents() * mParentObject->getScale()).len() * 0.5f;

    if ( data )
        mRadius *= data->shadowSphereAdjust;

    // Create the decal if we don't have one yet.
    if ( !mDecalInstance )
        mDecalInstance = gDecalManager->addDecal( decalPos,
                         lightDir,
                         right,
                         mDecalData,
                         1.0f,
                         0,
                         PermanentDecal | ClipDecal | CustomDecal );

    if ( !mDecalInstance )
        return false;

    mDecalInstance->mVisibility = fade;

    // Setup decal parameters.
    mDecalInstance->mSize = mRadius * 2.0f;
    mDecalInstance->mNormal = -lightDir;
    mDecalInstance->mTangent = -right;
    mDecalInstance->mRotAroundNormal = 0;
    mDecalInstance->mPosition = decalPos;
    mDecalInstance->mDataBlock = mDecalData;

    // If the position of the world
    // space box center is the same
    // as the decal's position, and
    // the light direction has not
    // changed, we don't need to clip.
    bool shouldClip = lightDirChanged || hasMoved || hasScaled;

    // Now, check and see if the object is visible.
    const Frustum &frust = state->getCullingFrustum();
    if ( frust.isCulled( SphereF( mDecalInstance->mPosition, mDecalInstance->mSize * mDecalInstance->mSize ) ) && !shouldClip )
        return false;

    F32 shadowLen = 10.0f;
    if ( data )
        shadowLen = data->shadowProjectionDistance;

    const Point3F &boxExtents = objBox.getExtents();


    mShadowLength = shadowLen * mParentObject->getScale().z;

    // Set up clip depth, and box half
    // offset for decal clipping.
    Point2F clipParams(  mShadowLength, (boxExtents.x + boxExtents.y) * 0.25f );

    bool render = false;
    bool clipSucceeded = true;

    // Clip!
    if ( shouldClip )
    {
        clipSucceeded = gDecalManager->clipDecal( mDecalInstance,
                        NULL,
                        &clipParams );
    }

    // If the clip failed,
    // we'll return false in
    // order to keep from
    // unnecessarily rendering
    // into the texture.  If
    // there was no reason to clip
    // on this update, we'll assume we
    // should update the texture.
    render = clipSucceeded;

    // Tell the DecalManager we've changed this decal.
    gDecalManager->notifyDecalModified( mDecalInstance );

    return render;
}