2
0
Эх сурвалжийг харах

Merge pull request #528 from DavidWyand-GG/OculusRiftUpdate2

SceneCullingState with culling and camera frustum
David Wyand 11 жил өмнө
parent
commit
8c98aad0b3

+ 2 - 2
Engine/source/T3D/decal/decalManager.cpp

@@ -1004,7 +1004,7 @@ void DecalManager::prepRenderImage( SceneRenderState* state )
 
    PROFILE_START( DecalManager_RenderDecals_SphereTreeCull );
 
-   const Frustum& rootFrustum = state->getFrustum();
+   const Frustum& rootFrustum = state->getCameraFrustum();
 
    // Populate vector of decal instances to be rendered with all
    // decals from visible decal spheres.
@@ -1448,7 +1448,7 @@ void DecalManager::_renderDecalSpheres( ObjectRenderInst* ri, SceneRenderState*
       DecalSphere *decalSphere = grid[i];
       const SphereF &worldSphere = decalSphere->mWorldSphere;
 
-      if( state->getFrustum().isCulled( worldSphere ) )
+      if( state->getCullingFrustum().isCulled( worldSphere ) )
          continue;
 
       drawUtil->drawSphere( desc, worldSphere.radius, worldSphere.center, sphereColor );

+ 1 - 1
Engine/source/T3D/fx/fxFoliageReplicator.cpp

@@ -146,7 +146,7 @@ void fxFoliageRenderList::SetupClipPlanes( SceneRenderState* state, const F32 fa
    const F32 nearPlane = state->getNearPlane();
    const F32 farPlane = farClipPlane;
 
-   const Frustum& frustum = state->getFrustum();
+   const Frustum& frustum = state->getCullingFrustum();
 
    // [rene, 23-Feb-11] Why isn't this preserving the ortho state of the original frustum?
 

+ 1 - 1
Engine/source/T3D/fx/groundCover.cpp

@@ -1539,7 +1539,7 @@ void GroundCover::prepRenderImage( SceneRenderState *state )
 
    // Setup the frustum culler.
    if ( ( mCuller.getPosition().isZero() || !mDebugLockFrustum ) && !state->isShadowPass() )
-      mCuller = state->getFrustum();
+      mCuller = state->getCullingFrustum();
 
    // Update the cells, but only during the diffuse pass. 
    // We don't want cell generation to thrash when the reflection camera 

+ 1 - 1
Engine/source/T3D/groundPlane.cpp

@@ -352,7 +352,7 @@ void GroundPlane::prepRenderImage( SceneRenderState* state )
    PROFILE_SCOPE( GroundPlane_prepRender );
 
    // Update the geometry.
-   createGeometry( state->getFrustum() );
+   createGeometry( state->getCullingFrustum() );
    if( mVertexBuffer.isNull() )
       return;
 

+ 2 - 2
Engine/source/T3D/lightFlareData.cpp

@@ -279,7 +279,7 @@ bool LightFlareData::_testVisibility(const SceneRenderState *state, LightFlareSt
    const Point3F &lightPos = flareState->lightMat.getPosition();  
    const RectI &viewport = GFX->getViewport();
    MatrixF projMatrix;
-   state->getFrustum().getProjectionMatrix(&projMatrix);
+   state->getCameraFrustum().getProjectionMatrix(&projMatrix);
    if( state->isReflectPass() )
       projMatrix = state->getSceneManager()->getNonClipProjection();
    bool onScreen = MathUtils::mProjectWorldToScreen( lightPos, outLightPosSS, viewport, GFX->getWorldMatrix(), projMatrix );
@@ -465,7 +465,7 @@ void LightFlareData::prepRender( SceneRenderState *state, LightFlareState *flare
 
    // Take any projection offset into account so that the point where the flare's
    // elements converge is at the 'eye' point rather than the center of the viewport.
-   const Point2F& projOffset = state->getFrustum().getProjectionOffset();
+   const Point2F& projOffset = state->getCameraFrustum().getProjectionOffset();
    Point3F flareVec( -lightPosSS + Point3F(projOffset.x, projOffset.y, 0.0f) );
    const F32 flareLength = flareVec.len();
    if ( flareLength > 0.0f )

+ 1 - 1
Engine/source/T3D/tsStatic.cpp

@@ -525,7 +525,7 @@ void TSStatic::prepRenderImage( SceneRenderState* state )
    Frustum culler;
    if ( mMeshCulling )
    {
-      culler = state->getFrustum();
+      culler = state->getCullingFrustum();
       MatrixF xfm( true );
       xfm.scale( Point3F::One / getScale() );
       xfm.mul( getRenderWorldTransform() );

+ 1 - 1
Engine/source/environment/decalRoad.cpp

@@ -721,7 +721,7 @@ void DecalRoad::prepRenderImage( SceneRenderState* state )
    if ( !smShowRoad && smEditorOpen )
       return;
 
-   const Frustum &frustum = state->getFrustum();
+   const Frustum &frustum = state->getCameraFrustum();
 
    MeshRenderInst coreRI;
    coreRI.clear();

+ 1 - 1
Engine/source/environment/scatterSky.cpp

@@ -930,7 +930,7 @@ void ScatterSky::_render( ObjectRenderInst *ri, SceneRenderState *state, BaseMat
    Point3F camPos( 0, 0, smViewerHeight );
    Point4F miscParams( camPos.z, camPos.z * camPos.z, mScale, mScale / mRayleighScaleDepth );
 
-   Frustum frust = state->getFrustum();
+   Frustum frust = state->getCameraFrustum();
    frust.setFarDist( smEarthRadius + smAtmosphereRadius );
    MatrixF proj( true );
    frust.getProjectionMatrix( &proj );

+ 2 - 2
Engine/source/environment/waterPlane.cpp

@@ -173,7 +173,7 @@ void WaterPlane::unpackUpdate(NetConnection* con, BitStream* stream)
 
 void WaterPlane::setupVBIB( SceneRenderState *state )
 {
-   const Frustum &frustum = state->getFrustum();
+   const Frustum &frustum = state->getCullingFrustum();
    
    // Water base-color, assigned as color for all verts.
    const GFXVertexColor vertCol(mWaterFogData.color);
@@ -708,7 +708,7 @@ void WaterPlane::prepRenderImage( SceneRenderState *state )
 
    mMatrixSet->setSceneView(GFX->getWorldMatrix());
    
-   const Frustum &frustum = state->getFrustum();
+   const Frustum &frustum = state->getCameraFrustum();
 
    if ( mPrimBuff.isNull() || 
         mGenerateVB ||         

+ 1 - 1
Engine/source/forest/forestRender.cpp

@@ -110,7 +110,7 @@ void Forest::prepRenderImage( SceneRenderState *state )
    // the forest, so pass down a LightQuery for it.
    LightQuery lightQuery;
    rdata.setLightQuery( &lightQuery );
-   Frustum culler = state->getFrustum();
+   Frustum culler = state->getCullingFrustum();
 
    // Adjust the far distance if the cull scale has changed.
    if ( !mIsEqual( cullScale, 1.0f ) )

+ 1 - 1
Engine/source/lighting/advanced/advancedLightBinManager.cpp

@@ -444,7 +444,7 @@ void AdvancedLightBinManager::_deleteLightMaterials()
 void AdvancedLightBinManager::_setupPerFrameParameters( const SceneRenderState *state )
 {
    PROFILE_SCOPE( AdvancedLightBinManager_SetupPerFrameParameters );
-   const Frustum &frustum = state->getFrustum();
+   const Frustum &frustum = state->getCameraFrustum();
 
    MatrixF invCam( frustum.getTransform() );
    invCam.inverse();

+ 1 - 1
Engine/source/lighting/common/projectedShadow.cpp

@@ -324,7 +324,7 @@ bool ProjectedShadow::_updateDecal( const SceneRenderState *state )
    bool shouldClip = lightDirChanged || hasMoved || hasScaled;
 
    // Now, check and see if the object is visible.
-   const Frustum &frust = state->getFrustum();
+   const Frustum &frust = state->getCullingFrustum();
    if ( frust.isCulled( SphereF( mDecalInstance->mPosition, mDecalInstance->mSize * mDecalInstance->mSize ) ) && !shouldClip )
       return false;
 

+ 2 - 2
Engine/source/lighting/shadowMap/pssmLightShadowMap.cpp

@@ -207,7 +207,7 @@ void PSSMLightShadowMap::_render(   RenderPassManager* renderPass,
       _setNumSplits( params->numSplits, texSize );
    mLogWeight = params->logWeight;
 
-   Frustum fullFrustum( diffuseState->getFrustum() );
+   Frustum fullFrustum( diffuseState->getCameraFrustum() );
    fullFrustum.cropNearFar(fullFrustum.getNearDist(), params->shadowDistance);
 
    GFXFrustumSaver frustSaver;
@@ -223,7 +223,7 @@ void PSSMLightShadowMap::_render(   RenderPassManager* renderPass,
 
    // Calculate our standard light matrices
    MatrixF lightMatrix;
-   calcLightMatrices( lightMatrix, diffuseState->getFrustum() );
+   calcLightMatrices( lightMatrix, diffuseState->getCameraFrustum() );
    lightMatrix.inverse();
    MatrixF lightViewProj = GFX->getProjectionMatrix() * lightMatrix;
 

+ 1 - 1
Engine/source/lighting/shadowMap/singleLightShadowMap.cpp

@@ -67,7 +67,7 @@ void SingleLightShadowMap::_render( RenderPassManager* renderPass,
    GFXTransformSaver saver;
 
    MatrixF lightMatrix;
-   calcLightMatrices( lightMatrix, diffuseState->getFrustum() );
+   calcLightMatrices( lightMatrix, diffuseState->getCameraFrustum() );
    lightMatrix.inverse();
    GFX->setWorldMatrix(lightMatrix);
 

+ 94 - 0
Engine/source/math/util/frustum.cpp

@@ -228,6 +228,100 @@ void Frustum::cropNearFar(F32 newNearDist, F32 newFarDist)
 
 //-----------------------------------------------------------------------------
 
+bool Frustum::bakeProjectionOffset()
+{
+   // Nothing to bake if ortho
+   if( mIsOrtho )
+      return false;
+
+   // Nothing to bake if no offset
+   if( mProjectionOffset.isZero() )
+      return false;
+
+   // Near plane points in camera space
+   Point3F np[4];
+   np[0].set( mNearLeft, mNearDist, mNearTop );       // NearTopLeft
+   np[1].set( mNearRight, mNearDist, mNearTop );      // NearTopRight
+   np[2].set( mNearLeft, mNearDist, mNearBottom );    // NearBottomLeft
+   np[3].set( mNearRight, mNearDist, mNearBottom );   // NearBottomRight
+
+   // Generate the near plane
+   PlaneF nearPlane( np[0], np[1], np[3] );
+
+   // Far plane points in camera space
+   const F32 farOverNear = mFarDist / mNearDist;
+   Point3F fp0( mNearLeft * farOverNear, mFarDist, mNearTop * farOverNear );     // FarTopLeft
+   Point3F fp1( mNearRight * farOverNear, mFarDist, mNearTop * farOverNear );    // FarTopRight
+   Point3F fp2( mNearLeft * farOverNear, mFarDist, mNearBottom * farOverNear );  // FarBottomLeft
+   Point3F fp3( mNearRight * farOverNear, mFarDist, mNearBottom * farOverNear ); // FarBottomRight
+
+   // Generate the far plane
+   PlaneF farPlane( fp0, fp1, fp3 );
+
+   // The offset camera point
+   Point3F offsetCamera( mProjectionOffset.x, 0.0f, mProjectionOffset.y );
+
+   // The near plane point we'll be using for our calculations below
+   U32 nIndex = 0;
+   if( mProjectionOffset.x < 0.0 )
+   {
+      // Offset to the left so we'll need to use the near plane point on the right
+      nIndex = 1;
+   }
+   if( mProjectionOffset.y > 0.0 )
+   {
+      // Offset to the top so we'll need to use the near plane point at the bottom
+      nIndex += 2;
+   }
+
+   // Begin by calculating the offset point on the far plane as it goes
+   // from the offset camera to the edge of the near plane.
+   Point3F farPoint;
+   Point3F fdir = np[nIndex] - offsetCamera;
+   fdir.normalize();
+   if( farPlane.intersect(offsetCamera, fdir, &farPoint) )
+   {
+      // Calculate the new near plane edge from the non-offset camera position
+      // to the far plane point from above.
+      Point3F nearPoint;
+      Point3F ndir = farPoint;
+      ndir.normalize();
+      if( nearPlane.intersect( Point3F::Zero, ndir, &nearPoint) )
+      {
+         // Handle a x offset
+         if( mProjectionOffset.x < 0.0 )
+         {
+            // The new near plane right side
+            mNearRight = nearPoint.x;
+         }
+         else if( mProjectionOffset.x > 0.0 )
+         {
+            // The new near plane left side
+            mNearLeft = nearPoint.x;
+         }
+
+         // Handle a y offset
+         if( mProjectionOffset.y < 0.0 )
+         {
+            // The new near plane top side
+            mNearTop = nearPoint.y;
+         }
+         else if( mProjectionOffset.y > 0.0 )
+         {
+            // The new near plane bottom side
+            mNearBottom = nearPoint.y;
+         }
+      }
+   }
+
+   mDirty = true;
+
+   // Indicate that we've modified the frustum
+   return true;
+}
+
+//-----------------------------------------------------------------------------
+
 void FrustumData::_update() const
 {
    if( !mDirty )

+ 7 - 0
Engine/source/math/util/frustum.h

@@ -412,6 +412,9 @@ class Frustum : public PolyhedronImpl< FrustumData >
       /// points typically used for early rejection.
       const Box3F& getBounds() const { _update(); return mBounds; }
 
+      // Does the frustum have a projection offset?
+      bool hasProjectionOffset() const { return !mProjectionOffset.isZero(); }
+
       /// Get the offset used when calculating the projection matrix
       const Point2F& getProjectionOffset() const { return mProjectionOffset; }
 
@@ -424,6 +427,10 @@ class Frustum : public PolyhedronImpl< FrustumData >
       /// Clear any offset used when calculating the projection matrix
       void clearProjectionOffset() { mProjectionOffset.zero(); mProjectionOffsetMatrix.identity(); }
 
+      /// Enlarges the frustum to contain the planes generated by a project offset, if any.
+      /// Used by scene culling to ensure that all object are contained within the asymetrical frustum.
+      bool bakeProjectionOffset();
+
       /// Generates a projection matrix from the frustum.
       void getProjectionMatrix( MatrixF *proj, bool gfxRotate=true ) const;
 

+ 3 - 3
Engine/source/postFx/postEffect.cpp

@@ -719,7 +719,7 @@ void PostEffect::_setupConstants( const SceneRenderState *state )
       mShaderConsts->setSafe( mNearFarSC, Point2F( state->getNearPlane(), state->getFarPlane() ) );
       mShaderConsts->setSafe( mInvNearFarSC, Point2F( 1.0f / state->getNearPlane(), 1.0f / state->getFarPlane() ) );
       mShaderConsts->setSafe( mWorldToScreenScaleSC, state->getWorldToScreenScale() );
-      mShaderConsts->setSafe( mProjectionOffsetSC, state->getFrustum().getProjectionOffset() );
+      mShaderConsts->setSafe( mProjectionOffsetSC, state->getCameraFrustum().getProjectionOffset() );
       mShaderConsts->setSafe( mFogColorSC, state->getSceneManager()->getFogData().color );
 
       if ( mWaterColorSC->isValid() )
@@ -750,7 +750,7 @@ void PostEffect::_setupConstants( const SceneRenderState *state )
       {
          // Grab our projection matrix
          // from the frustum.
-         Frustum frust = state->getFrustum();
+         Frustum frust = state->getCameraFrustum();
          MatrixF proj( true );
          frust.getProjectionMatrix( &proj );
 
@@ -1219,7 +1219,7 @@ void PostEffect::process(  const SceneRenderState *state,
 
    Frustum frustum;
    if ( state )
-      frustum = state->getFrustum();
+      frustum = state->getCameraFrustum();
    else
    {
       // If we don't have a scene state then setup

+ 20 - 16
Engine/source/scene/culling/sceneCullingState.cpp

@@ -68,17 +68,21 @@ SceneCullingState::SceneCullingState( SceneManager* sceneManager, const SceneCam
    mZoneVisibilityFlags.setSize( numZones );
    mZoneVisibilityFlags.clear();
 
+   // Culling frustum
+
+   mCullingFrustum = mCameraState.getFrustum();
+   mCullingFrustum.bakeProjectionOffset();
+
    // Construct the root culling volume from
-   // the camera's view frustum.  Omit the frustum's
+   // the culling frustum.  Omit the frustum's
    // near and far plane so we don't test it repeatedly.
 
-   const Frustum& frustum = mCameraState.getFrustum();
    PlaneF* planes = allocateData< PlaneF >( 4 );
 
-   planes[ 0 ] = frustum.getPlanes()[ Frustum::PlaneLeft ];
-   planes[ 1 ] = frustum.getPlanes()[ Frustum::PlaneRight ];
-   planes[ 2 ] = frustum.getPlanes()[ Frustum::PlaneTop];
-   planes[ 3 ] = frustum.getPlanes()[ Frustum::PlaneBottom ];
+   planes[ 0 ] = mCullingFrustum.getPlanes()[ Frustum::PlaneLeft ];
+   planes[ 1 ] = mCullingFrustum.getPlanes()[ Frustum::PlaneRight ];
+   planes[ 2 ] = mCullingFrustum.getPlanes()[ Frustum::PlaneTop];
+   planes[ 3 ] = mCullingFrustum.getPlanes()[ Frustum::PlaneBottom ];
 
    mRootVolume = SceneCullingVolume(
       SceneCullingVolume::Includer,
@@ -219,7 +223,7 @@ bool SceneCullingState::createCullingVolume( const Point3F* vertices, U32 numVer
 {
    const Point3F& viewPos = getCameraState().getViewPosition();
    const Point3F& viewDir = getCameraState().getViewDirection();
-   const bool isOrtho = getFrustum().isOrtho();
+   const bool isOrtho = getCullingFrustum().isOrtho();
 
    //TODO: check if we need to handle penetration of the near plane for occluders specially
 
@@ -440,8 +444,8 @@ bool SceneCullingState::createCullingVolume( const Point3F* vertices, U32 numVer
 
    if( type == SceneCullingVolume::Occluder )
    {
-      const F32 widthEstimatePercentage = widthEstimate / getFrustum().getWidth();
-      const F32 heightEstimatePercentage = heightEstimate / getFrustum().getHeight();
+      const F32 widthEstimatePercentage = widthEstimate / getCullingFrustum().getWidth();
+      const F32 heightEstimatePercentage = heightEstimate / getCullingFrustum().getHeight();
 
       if( widthEstimatePercentage < smOccluderMinWidthPercentage ||
           heightEstimatePercentage < smOccluderMinHeightPercentage )
@@ -614,7 +618,7 @@ inline SceneZoneCullingState::CullingTestResult SceneCullingState::_test( const
 
    if( disableZoneCulling() )
    {
-      if( !OCCLUDERS_ONLY && !getFrustum().isCulled( bounds ) )
+      if( !OCCLUDERS_ONLY && !getCullingFrustum().isCulled( bounds ) )
          return SceneZoneCullingState::CullingTestPositiveByInclusion;
 
       return SceneZoneCullingState::CullingTestNegative;
@@ -631,7 +635,7 @@ inline SceneZoneCullingState::CullingTestResult SceneCullingState::_test( const
    }
    else
    {
-      const PlaneF* frustumPlanes = getFrustum().getPlanes();
+      const PlaneF* frustumPlanes = getCullingFrustum().getPlanes();
 
       return _test(
          bounds,
@@ -715,8 +719,8 @@ U32 SceneCullingState::cullObjects( SceneObject** objects, U32 numObjects, U32 c
 
    // We test near and far planes separately in order to not do the tests
    // repeatedly, so fetch the planes now.
-   const PlaneF& nearPlane = getFrustum().getPlanes()[ Frustum::PlaneNear ];
-   const PlaneF& farPlane = getFrustum().getPlanes()[ Frustum::PlaneFar ];
+   const PlaneF& nearPlane = getCullingFrustum().getPlanes()[ Frustum::PlaneNear ];
+   const PlaneF& farPlane = getCullingFrustum().getPlanes()[ Frustum::PlaneFar ];
 
    for( U32 i = 0; i < numObjects; ++ i )
    {
@@ -766,7 +770,7 @@ U32 SceneCullingState::cullObjects( SceneObject** objects, U32 numObjects, U32 c
                ( object->getTypeMask() & CULLING_EXCLUDE_TYPEMASK ) ||
                disableZoneCulling() )
       {
-         isCulled = getFrustum().isCulled( object->getWorldBox() );
+         isCulled = getCullingFrustum().isCulled( object->getWorldBox() );
       }
 
       // Go through the zones that the object is assigned to and
@@ -881,8 +885,8 @@ void SceneCullingState::debugRenderCullingVolumes() const
    const ColorI occluderColor( 255, 0, 0, 255 );
    const ColorI includerColor( 0, 255, 0, 255 );
 
-   const PlaneF& nearPlane = getFrustum().getPlanes()[ Frustum::PlaneNear ];
-   const PlaneF& farPlane = getFrustum().getPlanes()[ Frustum::PlaneFar ];
+   const PlaneF& nearPlane = getCullingFrustum().getPlanes()[ Frustum::PlaneNear ];
+   const PlaneF& farPlane = getCullingFrustum().getPlanes()[ Frustum::PlaneFar ];
 
    DebugDrawer* drawer = DebugDrawer::get();
    const SceneZoneSpaceManager* zoneManager = mSceneManager->getZoneManager();

+ 8 - 2
Engine/source/scene/culling/sceneCullingState.h

@@ -100,9 +100,12 @@ class SceneCullingState
       /// The viewing state that defines how the scene is being viewed.
       SceneCameraState mCameraState;
 
-      /// The root culling volume corresponding to the camera frustum.
+      /// The root culling volume corresponding to the culling frustum.
       SceneCullingVolume mRootVolume;
 
+      /// The root culling frustum, which may be different from the camera frustum
+      Frustum mCullingFrustum;
+
       /// Occluders that have been added to this render state.  Adding an occluder does not
       /// necessarily result in an occluder volume being added.  To not repeatedly try to
       /// process the same occluder object, all objects that are added are recorded here.
@@ -136,7 +139,10 @@ class SceneCullingState
       SceneManager* getSceneManager() const { return mSceneManager; }
 
       /// Return the root frustum which is used to set up scene visibility.
-      const Frustum& getFrustum() const { return getCameraState().getFrustum(); }
+      const Frustum& getCullingFrustum() const { return mCullingFrustum; }
+
+      /// Return the root frustum which is used to set up scene visibility.
+      const Frustum& getCameraFrustum() const { return getCameraState().getFrustum(); }
 
       /// Return the viewing state that defines how the scene is being viewed.
       const SceneCameraState& getCameraState() const { return mCameraState; }

+ 1 - 1
Engine/source/scene/reflector.cpp

@@ -420,7 +420,7 @@ void CubeReflector::updateFace( const ReflectParams &params, U32 faceidx )
    reflectRenderState.disableAdvancedLightingBins(true);
 
    // render scene
-   LIGHTMGR->registerGlobalLights( &reflectRenderState.getFrustum(), false );
+   LIGHTMGR->registerGlobalLights( &reflectRenderState.getCullingFrustum(), false );
    gClientSceneGraph->renderSceneNoLights( &reflectRenderState, mDesc->objectTypeMask );
    LIGHTMGR->unregisterAllLights();
 

+ 3 - 3
Engine/source/scene/sceneManager.cpp

@@ -191,7 +191,7 @@ void SceneManager::renderScene( SceneRenderState* renderState, U32 objectMask, S
    // Get the lights for rendering the scene.
 
    PROFILE_START( SceneGraph_registerLights );
-      LIGHTMGR->registerGlobalLights( &renderState->getFrustum(), false );
+      LIGHTMGR->registerGlobalLights( &renderState->getCullingFrustum(), false );
    PROFILE_END();
 
    // If its a diffuse pass, update the current ambient light level.
@@ -404,7 +404,7 @@ void SceneManager::_renderScene( SceneRenderState* state, U32 objectMask, SceneZ
    // the opportunity to render editor visualizations even if
    // they are otherwise not in view.
 
-   if( !state->getFrustum().getBounds().isOverlapped( state->getRenderArea() ) )
+   if( !state->getCullingFrustum().getBounds().isOverlapped( state->getRenderArea() ) )
    {
       // This handles fringe cases like flying backwards into a zone where you
       // end up pretty much standing on a zone border and looking directly into
@@ -415,7 +415,7 @@ void SceneManager::_renderScene( SceneRenderState* state, U32 objectMask, SceneZ
       return;
    }
 
-   Box3F queryBox = state->getFrustum().getBounds();
+   Box3F queryBox = state->getCullingFrustum().getBounds();
    if( !gEditingMission )
    {
       queryBox.minExtents.setMax( state->getRenderArea().minExtents );

+ 7 - 4
Engine/source/scene/sceneRenderState.h

@@ -145,8 +145,11 @@ class SceneRenderState
       const SceneCullingState& getCullingState() const { return mCullingState; }
       SceneCullingState& getCullingState() { return mCullingState; }
 
-      /// Returns the root frustum.
-      const Frustum& getFrustum() const { return getCullingState().getFrustum(); }
+      /// Returns the root culling frustum.
+      const Frustum& getCullingFrustum() const { return getCullingState().getCullingFrustum(); }
+
+      /// Returns the root camera frustum.
+      const Frustum& getCameraFrustum() const { return getCullingState().getCameraFrustum(); }
 
       /// @}
 
@@ -262,10 +265,10 @@ class SceneRenderState
       const MatrixF& getCameraTransform() const { return getCullingState().getCameraState().getViewWorldMatrix(); }
 
       /// Returns the minimum distance something must be from the camera to not be culled.
-      F32 getNearPlane() const { return getFrustum().getNearDist();   }
+      F32 getNearPlane() const { return getCullingFrustum().getNearDist();   }
 
       /// Returns the maximum distance something can be from the camera to not be culled.
-      F32 getFarPlane() const { return getFrustum().getFarDist();    }
+      F32 getFarPlane() const { return getCullingFrustum().getFarDist();    }
 
       /// Returns the camera vector normalized to 1 / far distance.
       const Point3F& getVectorEye() const { return mVectorEye; }