123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "platform/platform.h"
- #include "scene/sceneManager.h"
- #include "scene/sceneObject.h"
- #include "scene/zones/sceneTraversalState.h"
- #include "scene/sceneRenderState.h"
- #include "scene/zones/sceneRootZone.h"
- #include "scene/zones/sceneZoneSpace.h"
- #include "lighting/lightManager.h"
- #include "renderInstance/renderPassManager.h"
- #include "gfx/gfxDevice.h"
- #include "gfx/gfxDrawUtil.h"
- #include "gfx/gfxDebugEvent.h"
- #include "console/engineAPI.h"
- #include "sim/netConnection.h"
- #include "T3D/gameBase/gameConnection.h"
- #include "math/mathUtils.h"
- // For player object bounds workaround.
- #include "T3D/player.h"
- #include "postFx/postEffectManager.h"
- extern bool gEditingMission;
- MODULE_BEGIN( Scene )
- MODULE_INIT_AFTER( Sim )
- MODULE_SHUTDOWN_AFTER( Sim )
- MODULE_SHUTDOWN_AFTER( VolumetricFogRTManager )
-
- MODULE_INIT
- {
- // Client scene.
- gClientSceneGraph = new SceneManager( true );
- // Server scene.
- gServerSceneGraph = new SceneManager( false );
- Con::addVariable( "$Scene::lockCull", TypeBool, &SceneManager::smLockDiffuseFrustum,
- "Debug tool which locks the frustum culling to the current camera location.\n"
- "@ingroup Rendering\n" );
- Con::addVariable( "$Scene::disableTerrainOcclusion", TypeBool, &SceneCullingState::smDisableTerrainOcclusion,
- "Used to disable the somewhat expensive terrain occlusion testing.\n"
- "@ingroup Rendering\n" );
- Con::addVariable( "$Scene::disableZoneCulling", TypeBool, &SceneCullingState::smDisableZoneCulling,
- "If true, zone culling will be disabled and the scene contents will only be culled against the root frustum.\n\n"
- "@ingroup Rendering\n" );
- Con::addVariable( "$Scene::renderBoundingBoxes", TypeBool, &SceneManager::smRenderBoundingBoxes,
- "If true, the bounding boxes of objects will be displayed.\n\n"
- "@ingroup Rendering" );
- Con::addVariable( "$Scene::maxOccludersPerZone", TypeS32, &SceneCullingState::smMaxOccludersPerZone,
- "Maximum number of occluders that will be concurrently allowed into the scene culling state of any given zone.\n\n"
- "@ingroup Rendering" );
- Con::addVariable( "$Scene::occluderMinWidthPercentage", TypeF32, &SceneCullingState::smOccluderMinWidthPercentage,
- "TODO\n\n"
- "@ingroup Rendering" );
- Con::addVariable( "$Scene::occluderMinHeightPercentage", TypeF32, &SceneCullingState::smOccluderMinHeightPercentage,
- "TODO\n\n"
- "@ingroup Rendering" );
- }
-
- MODULE_SHUTDOWN
- {
- SAFE_DELETE( gClientSceneGraph );
- SAFE_DELETE( gServerSceneGraph );
- }
- MODULE_END;
- bool SceneManager::smRenderBoundingBoxes;
- bool SceneManager::smLockDiffuseFrustum = false;
- SceneCameraState SceneManager::smLockedDiffuseCamera = SceneCameraState( RectI(), Frustum(), MatrixF(), MatrixF() );
- SceneManager* gClientSceneGraph = NULL;
- SceneManager* gServerSceneGraph = NULL;
- //-----------------------------------------------------------------------------
- SceneManager::SceneManager( bool isClient )
- : mIsClient( isClient ),
- mZoneManager( NULL ),
- mUsePostEffectFog( true ),
- mDisplayTargetResolution( 0, 0 ),
- mCurrentRenderState( NULL ),
- mVisibleDistance( 500.f ),
- mVisibleGhostDistance( 0 ),
- mNearClip( 0.1f ),
- mLightManager( NULL ),
- mAmbientLightColor( LinearColorF( 0.1f, 0.1f, 0.1f, 1.0f ) ),
- mDefaultRenderPass( NULL )
- {
- VECTOR_SET_ASSOCIATION( mBatchQueryList );
- // For the client, create a zone manager.
- if( isClient )
- {
- mZoneManager = new SceneZoneSpaceManager( getContainer() );
- // Add the root zone to the scene.
- addObjectToScene( mZoneManager->getRootZone() );
- }
- }
- //-----------------------------------------------------------------------------
- SceneManager::~SceneManager()
- {
- SAFE_DELETE( mZoneManager );
- if( mLightManager )
- mLightManager->deactivate();
- }
- //-----------------------------------------------------------------------------
- void SceneManager::renderScene( ScenePassType passType, U32 objectMask )
- {
- SceneCameraState cameraState = SceneCameraState::fromGFX();
-
- // Handle frustum locking.
- const bool lockedFrustum = ( smLockDiffuseFrustum && passType == SPT_Diffuse );
- if( lockedFrustum )
- cameraState = smLockedDiffuseCamera;
- else if( passType == SPT_Diffuse )
- {
- // Store the camera state so if we lock, this will become the
- // locked state.
- smLockedDiffuseCamera = cameraState;
- }
-
- // Create the render state.
- SceneRenderState renderState( this, passType, cameraState );
- // If we have locked the frustum, reset the view transform
- // on the render pass which the render state has just set
- // to the view matrix corresponding to the locked frustum. For
- // rendering, however, we need the true view matrix from the
- // GFX state.
- if( lockedFrustum )
- {
- RenderPassManager* rpm = renderState.getRenderPass();
- rpm->assignSharedXform( RenderPassManager::View, GFX->getWorldMatrix() );
- }
- // Render.
- renderScene( &renderState, objectMask );
- }
- //-----------------------------------------------------------------------------
- void SceneManager::renderScene( SceneRenderState* renderState, U32 objectMask, SceneZoneSpace* baseObject, U32 baseZone )
- {
- PROFILE_SCOPE( SceneGraph_renderScene );
- // Get the lights for rendering the scene.
- PROFILE_START( SceneGraph_registerLights );
- LIGHTMGR->registerGlobalLights( &renderState->getCullingFrustum(), false, renderState->isDiffusePass());
- PROFILE_END();
- // If its a diffuse pass, update the current ambient light level.
- // To do that find the starting zone and determine whether it has a custom
- // ambient light color. If so, pass it on to the ambient light manager.
- // If not, use the ambient light color of the sunlight.
- //
- // Note that we retain the starting zone information here and pass it
- // on to renderSceneNoLights so that we don't need to look it up twice.
- if( renderState->isDiffusePass() )
- {
- if( !baseObject && getZoneManager() )
- {
- getZoneManager()->findZone( renderState->getCameraPosition(), baseObject, baseZone );
- AssertFatal( baseObject != NULL, "SceneManager::renderScene - findZone() did not return an object" );
- }
- LinearColorF zoneAmbient;
- if( baseObject && baseObject->getZoneAmbientLightColor( baseZone, zoneAmbient ) )
- mAmbientLightColor.setTargetValue( zoneAmbient );
- else
- {
- const LightInfo* sunlight = LIGHTMGR->getSpecialLight( LightManager::slSunLightType );
- if( sunlight )
- mAmbientLightColor.setTargetValue( sunlight->getAmbient() );
- }
- renderState->setAmbientLightColor( mAmbientLightColor.getCurrentValue() );
- }
- // Trigger the pre-render signal.
- PROFILE_START( SceneGraph_preRenderSignal);
- mCurrentRenderState = renderState;
- getPreRenderSignal().trigger( this, renderState );
- mCurrentRenderState = NULL;
- PROFILE_END();
- // Render the scene.
- if(GFX->getCurrentRenderStyle() == GFXDevice::RS_StereoSideBySide)
- {
- // Store previous values
- RectI originalVP = GFX->getViewport();
- MatrixF originalWorld = GFX->getWorldMatrix();
- Frustum originalFrustum = GFX->getFrustum();
- // Save PFX & SceneManager projections
- MatrixF origNonClipProjection = renderState->getSceneManager()->getNonClipProjection();
- PFXFrameState origPFXState = PFXMGR->getFrameState();
- const FovPort *currentFovPort = GFX->getStereoFovPort();
- const MatrixF *worldEyeTransforms = GFX->getInverseStereoEyeTransforms();
- // Render left half of display
- GFX->activateStereoTarget(0);
- GFX->beginField();
- GFX->setWorldMatrix(worldEyeTransforms[0]);
- Frustum gfxFrustum = originalFrustum;
- MathUtils::makeFovPortFrustum(&gfxFrustum, gfxFrustum.isOrtho(), gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[0]);
- GFX->setFrustum(gfxFrustum);
- SceneCameraState cameraStateLeft = SceneCameraState::fromGFX();
- SceneRenderState renderStateLeft( this, renderState->getScenePassType(), cameraStateLeft );
- renderStateLeft.getSceneManager()->setNonClipProjection(GFX->getProjectionMatrix());
- renderStateLeft.setSceneRenderStyle(SRS_SideBySide);
- PFXMGR->setFrameMatrices(GFX->getWorldMatrix(), GFX->getProjectionMatrix());
- renderSceneNoLights( &renderStateLeft, objectMask, baseObject, baseZone ); // left
- // Indicate that we've just finished a field
- //GFX->clear(GFXClearTarget | GFXClearZBuffer | GFXClearStencil, ColorI(255,0,0), 1.0f, 0);
- GFX->endField();
-
- // Render right half of display
- GFX->activateStereoTarget(1);
- GFX->beginField();
- GFX->setWorldMatrix(worldEyeTransforms[1]);
- gfxFrustum = originalFrustum;
- MathUtils::makeFovPortFrustum(&gfxFrustum, gfxFrustum.isOrtho(), gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[1]);
- GFX->setFrustum(gfxFrustum);
- SceneCameraState cameraStateRight = SceneCameraState::fromGFX();
- SceneRenderState renderStateRight( this, renderState->getScenePassType(), cameraStateRight );
- renderStateRight.getSceneManager()->setNonClipProjection(GFX->getProjectionMatrix());
- renderStateRight.setSceneRenderStyle(SRS_SideBySide);
- PFXMGR->setFrameMatrices(GFX->getWorldMatrix(), GFX->getProjectionMatrix());
- renderSceneNoLights( &renderStateRight, objectMask, baseObject, baseZone ); // right
- // Indicate that we've just finished a field
- //GFX->clear(GFXClearTarget | GFXClearZBuffer | GFXClearStencil, ColorI(0,255,0), 1.0f, 0);
- GFX->endField();
- // Restore previous values
- renderState->getSceneManager()->setNonClipProjection(origNonClipProjection);
- PFXMGR->setFrameState(origPFXState);
- GFX->setWorldMatrix(originalWorld);
- GFX->setFrustum(originalFrustum);
- GFX->setViewport(originalVP);
- }
- else
- {
- renderSceneNoLights( renderState, objectMask, baseObject, baseZone );
- }
- // Trigger the post-render signal.
- PROFILE_START( SceneGraphRender_postRenderSignal );
- mCurrentRenderState = renderState;
- getPostRenderSignal().trigger( this, renderState );
- mCurrentRenderState = NULL;
- PROFILE_END();
- // Remove the previously registered lights.
- PROFILE_START( SceneGraph_unregisterLights);
- LIGHTMGR->unregisterAllLights();
- PROFILE_END();
- }
- //-----------------------------------------------------------------------------
- void SceneManager::renderSceneNoLights( SceneRenderState* renderState, U32 objectMask, SceneZoneSpace* baseObject, U32 baseZone )
- {
- // Set the current state.
- mCurrentRenderState = renderState;
- // Render.
- _renderScene( mCurrentRenderState, objectMask, baseObject, baseZone );
- #ifdef TORQUE_DEBUG
- // If frustum is locked and this is a diffuse pass, render the culling volumes of
- // zones that are selected (or the volumes of the outdoor zone if no zone is
- // selected).
- if( gEditingMission && renderState->isDiffusePass() && smLockDiffuseFrustum )
- renderState->getCullingState().debugRenderCullingVolumes();
-
- #endif
- mCurrentRenderState = NULL;
- }
- //-----------------------------------------------------------------------------
- void SceneManager::_renderScene( SceneRenderState* state, U32 objectMask, SceneZoneSpace* baseObject, U32 baseZone )
- {
- AssertFatal( this == gClientSceneGraph, "SceneManager::_buildSceneGraph - Only the client scenegraph can support this call!" );
- PROFILE_SCOPE( SceneGraph_batchRenderImages );
- // In the editor, override the type mask for diffuse passes.
- if( gEditingMission && state->isDiffusePass() )
- objectMask = EDITOR_RENDER_TYPEMASK;
- // Update the zoning state and traverse zones.
- if( getZoneManager() )
- {
- // Update.
- getZoneManager()->updateZoningState();
- // If zone culling isn't disabled, traverse the
- // zones now.
- if( !state->getCullingState().disableZoneCulling() )
- {
- // Find the start zone if we haven't already.
- if( !baseObject )
- {
- getZoneManager()->findZone( state->getCameraPosition(), baseObject, baseZone );
- AssertFatal( baseObject != NULL, "SceneManager::_renderScene - findZone() did not return an object" );
- }
- // Traverse zones starting in base object.
- SceneTraversalState traversalState( &state->getCullingState() );
- PROFILE_START( Scene_traverseZones );
- baseObject->traverseZones( &traversalState, baseZone );
- PROFILE_END();
- // Set the scene render box to the area we have traversed.
- state->setRenderArea( traversalState.getTraversedArea() );
- }
- }
- // Set the query box for the container query. Never
- // make it larger than the frustum's AABB. In the editor,
- // always query the full frustum as that gives objects
- // the opportunity to render editor visualizations even if
- // they are otherwise not in view.
- 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
- // its "walls". In that case the traversal area will be behind the frustum
- // (remember that the camera isn't where visibility starts, it's the near
- // distance).
- return;
- }
- Box3F queryBox = state->getCullingFrustum().getBounds();
- if( !gEditingMission )
- {
- queryBox.minExtents.setMax( state->getRenderArea().minExtents );
- queryBox.maxExtents.setMin( state->getRenderArea().maxExtents );
- }
- PROFILE_START( Scene_cullObjects );
- //TODO: We should split the codepaths here based on whether the outdoor zone has visible space.
- // If it has, we should use the container query-based path.
- // If it hasn't, we should fill the object list directly from the zone lists which will usually
- // include way fewer objects.
-
- // Gather all objects that intersect the scene render box.
- mBatchQueryList.clear();
- getContainer()->findObjectList( queryBox, objectMask, &mBatchQueryList );
- // Cull the list.
- U32 numRenderObjects = state->getCullingState().cullObjects(
- mBatchQueryList.address(),
- mBatchQueryList.size(),
- !state->isDiffusePass() ? SceneCullingState::CullEditorOverrides : 0 // Keep forced editor stuff out of non-diffuse passes.
- );
- //HACK: If the control object is a Player and it is not in the render list, force
- // it into it. This really should be solved by collision bounds being separate from
- // object bounds; only because the Player class is using bounds not encompassing
- // the actual player object is it that we have this problem in the first place.
- // Note that we are forcing the player object into ALL passes here but such
- // is the power of proliferation of things done wrong.
- GameConnection* connection = GameConnection::getConnectionToServer();
- if( connection )
- {
- Player* player = dynamic_cast< Player* >( connection->getControlObject() );
- if( player )
- {
- mBatchQueryList.setSize( numRenderObjects );
- if( !mBatchQueryList.contains( player ) )
- {
- mBatchQueryList.push_back( player );
- numRenderObjects ++;
- }
- }
- }
- PROFILE_END();
- //store our rendered objects into a list we can easily look up against later if required
- mRenderedObjectsList.clear();
- for (U32 i = 0; i < numRenderObjects; ++i)
- {
- mRenderedObjectsList.push_back(mBatchQueryList[i]);
- }
- // Render the remaining objects.
- PROFILE_START( Scene_renderObjects );
- state->renderObjects( mBatchQueryList.address(), numRenderObjects );
- PROFILE_END();
- // Render bounding boxes, if enabled.
- if( smRenderBoundingBoxes && state->isDiffusePass() )
- {
- GFXDEBUGEVENT_SCOPE( Scene_renderBoundingBoxes, ColorI::WHITE );
- GameBase* cameraObject = 0;
- if( connection )
- cameraObject = connection->getCameraObject();
- GFXStateBlockDesc desc;
- desc.setFillModeWireframe();
- desc.setZReadWrite( true, false );
- for( U32 i = 0; i < numRenderObjects; ++ i )
- {
- SceneObject* object = mBatchQueryList[ i ];
- // Skip global bounds object.
- if( object->isGlobalBounds() )
- continue;
- // Skip camera object as we're viewing the scene from it.
- if( object == cameraObject )
- continue;
- const Box3F& worldBox = object->getWorldBox();
- GFX->getDrawUtil()->drawObjectBox(
- desc,
- Point3F( worldBox.len_x() / 2, worldBox.len_y() / 2, worldBox.len_z() / 2),
- worldBox.getCenter(),
- MatrixF::Identity,
- ColorI::WHITE
- );
- }
- }
- }
- //-----------------------------------------------------------------------------
- struct ScopingInfo
- {
- Point3F scopePoint;
- F32 scopeDist;
- F32 scopeDistSquared;
- NetConnection* connection;
- };
- static void _scopeCallback( SceneObject* object, void* data )
- {
- if( !object->isScopeable() )
- return;
- ScopingInfo* info = reinterpret_cast< ScopingInfo* >( data );
- NetConnection* connection = info->connection;
- F32 difSq = ( object->getWorldSphere().center - info->scopePoint ).lenSquared();
- if( difSq < info->scopeDistSquared )
- {
- // Not even close, it's in...
- connection->objectInScope( object );
- }
- else
- {
- // Check a little more closely...
- F32 realDif = mSqrt( difSq );
- if( realDif - object->getWorldSphere().radius < info->scopeDist)
- connection->objectInScope( object );
- }
- }
- void SceneManager::scopeScene( CameraScopeQuery* query, NetConnection* netConnection )
- {
- PROFILE_SCOPE( SceneGraph_scopeScene );
- // Note that this method does not use the zoning information in the scene
- // to scope objects. The reason is that with the way that scoping is implemented
- // in the networking layer--i.e. by killing off ghosts of objects that are out
- // of scope--, it doesn't make sense to let, for example, all objects in the outdoor
- // zone go out of scope, just because there is no exterior portal that is visible from
- // the current camera viewpoint (in any direction).
- //
- // So, we perform a simple box query on the area covered by the camera query
- // and then scope in everything that is in range.
-
- // Set up scoping info.
- ScopingInfo info;
- info.scopePoint = query->pos;
- info.scopeDist = query->visibleDistance;
- info.scopeDistSquared = info.scopeDist * info.scopeDist;
- info.connection = netConnection;
- // Scope all objects in the query area.
- Box3F area( query->visibleDistance );
- area.setCenter( query->pos );
- getContainer()->findObjects( area, 0xFFFFFFFF, _scopeCallback, &info );
- }
- //-----------------------------------------------------------------------------
- bool SceneManager::addObjectToScene( SceneObject* object )
- {
- AssertFatal( !object->mSceneManager, "SceneManager::addObjectToScene - Object already part of a scene" );
- // Mark the object as belonging to us.
- object->mSceneManager = this;
- // Register with managers except its the root zone.
- if( !dynamic_cast< SceneRootZone* >( object ) )
- {
- // Add to container.
- getContainer()->addObject( object );
- // Register the object with the zone manager.
- if( getZoneManager() )
- getZoneManager()->registerObject( object );
- }
- // Notify the object.
- return object->onSceneAdd();
- }
- //-----------------------------------------------------------------------------
- void SceneManager::removeObjectFromScene( SceneObject* obj )
- {
- AssertFatal( obj, "SceneManager::removeObjectFromScene - Object is not declared" );
- AssertFatal( obj->getSceneManager() == this, "SceneManager::removeObjectFromScene - Object not part of SceneManager" );
- // Notify the object.
- obj->onSceneRemove();
- // Remove the object from the container.
- if( getContainer() )
- getContainer()->removeObject( obj );
- // Remove the object from the zoning system.
- if( getZoneManager() )
- getZoneManager()->unregisterObject( obj );
- // Clear out the reference to us.
- obj->mSceneManager = NULL;
- }
- //-----------------------------------------------------------------------------
- void SceneManager::notifyObjectDirty( SceneObject* object )
- {
- // Update container state.
- if( object->mContainer )
- object->mContainer->checkBins( object );
- // Mark zoning state as dirty.
- if( getZoneManager() )
- getZoneManager()->notifyObjectChanged( object );
- }
- //-----------------------------------------------------------------------------
- void SceneManager::setDisplayTargetResolution( const Point2I &size )
- {
- mDisplayTargetResolution = size;
- }
- //-----------------------------------------------------------------------------
- const Point2I & SceneManager::getDisplayTargetResolution() const
- {
- return mDisplayTargetResolution;
- }
- //-----------------------------------------------------------------------------
- bool SceneManager::setLightManager( const char* lmName )
- {
- LightManager *lm = LightManager::findByName( lmName );
- if ( !lm )
- return false;
- return _setLightManager( lm );
- }
- //-----------------------------------------------------------------------------
- bool SceneManager::_setLightManager( LightManager* lm )
- {
- // Avoid unnecessary work reinitializing materials.
- if ( lm == mLightManager )
- return true;
- // Make sure its valid... else fail!
- if ( !lm->isCompatible() )
- return false;
- // We only deactivate it... all light managers are singletons
- // and will manager their own lifetime.
- if ( mLightManager )
- mLightManager->deactivate();
- mLightManager = lm;
- if ( mLightManager )
- mLightManager->activate( this );
- return true;
- }
- //-----------------------------------------------------------------------------
- RenderPassManager* SceneManager::getDefaultRenderPass() const
- {
- if( !mDefaultRenderPass )
- {
- Sim::findObject( "DiffuseRenderPassManager", mDefaultRenderPass );
- AssertISV( mDefaultRenderPass, "SceneManager::_setDefaultRenderPass - No DiffuseRenderPassManager defined! Must be set up in script!" );
- }
- return mDefaultRenderPass;
- }
- //=============================================================================
- // Console API.
- //=============================================================================
- // MARK: ---- Console API ----
- //-----------------------------------------------------------------------------
- DefineEngineFunction( sceneDumpZoneStates, void, ( bool updateFirst ), ( true ),
- "Dump the current zoning states of all zone spaces in the scene to the console.\n\n"
- "@param updateFirst If true, zoning states are brought up to date first; if false, the zoning states "
- "are dumped as is.\n\n"
- "@note Only valid on the client.\n"
- "@ingroup Game" )
- {
- if( !gClientSceneGraph )
- {
- Con::errorf( "sceneDumpZoneStates - Only valid on client!" );
- return;
- }
- SceneZoneSpaceManager* manager = gClientSceneGraph->getZoneManager();
- if( !manager )
- {
- Con::errorf( "sceneDumpZoneStates - Scene is not using zones!" );
- return;
- }
- manager->dumpZoneStates( updateFirst );
- }
- //-----------------------------------------------------------------------------
- DefineEngineFunction( sceneGetZoneOwner, SceneObject*, ( U32 zoneId ),,
- "Return the SceneObject that contains the given zone.\n\n"
- "@param zoneId ID of zone.\n"
- "@return A SceneObject or NULL if the given @a zoneId is invalid.\n\n"
- "@note Only valid on the client.\n"
- "@ingroup Game" )
- {
- if( !gClientSceneGraph )
- {
- Con::errorf( "sceneGetZoneOwner - Only valid on client!" );
- return NULL;
- }
- SceneZoneSpaceManager* manager = gClientSceneGraph->getZoneManager();
- if( !manager )
- {
- Con::errorf( "sceneGetZoneOwner - Scene is not using zones!" );
- return NULL;
- }
- if( !manager->isValidZoneId( zoneId ) )
- {
- Con::errorf( "sceneGetZoneOwner - Invalid zone ID: %i", zoneId );
- return NULL;
- }
- return manager->getZoneOwner( zoneId );
- }
|