mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 23:54:35 +00:00
Merge pull request #229 from Areloch/TerrainAssetFixup
Reworks the terrain loader code to work with the assets.
This commit is contained in:
commit
67dbe4dfe2
15 changed files with 510 additions and 283 deletions
|
|
@ -304,7 +304,7 @@ bool TerrainBlock::_setBaseTexFormat(void *obj, const char *index, const char *d
|
|||
// If the cached base texture is older that the terrain file or
|
||||
// it doesn't exist then generate and cache it.
|
||||
String baseCachePath = terrain->_getBaseTexCacheFileName();
|
||||
if (Platform::compareModifiedTimes(baseCachePath, terrain->mTerrFileName) < 0)
|
||||
if (Platform::compareModifiedTimes(baseCachePath, terrain->mTerrainAsset->getTerrainFilePath()) < 0)
|
||||
terrain->_updateBaseTexture(true);
|
||||
break;
|
||||
}
|
||||
|
|
@ -337,7 +337,7 @@ bool TerrainBlock::_setLightMapSize( void *obj, const char *index, const char *d
|
|||
|
||||
bool TerrainBlock::setFile( const FileName &terrFileName )
|
||||
{
|
||||
if ( terrFileName == mTerrFileName )
|
||||
if ( mTerrainAsset && mTerrainAsset->getTerrainFilePath() == terrFileName )
|
||||
return mFile != NULL;
|
||||
|
||||
Resource<TerrainFile> file = ResourceManager::get().load( terrFileName );
|
||||
|
|
@ -352,27 +352,104 @@ bool TerrainBlock::setFile( const FileName &terrFileName )
|
|||
|
||||
void TerrainBlock::setFile(const Resource<TerrainFile>& terr)
|
||||
{
|
||||
if (mFile)
|
||||
{
|
||||
GFXTextureManager::removeEventDelegate(this, &TerrainBlock::_onTextureEvent);
|
||||
MATMGR->getFlushSignal().remove(this, &TerrainBlock::_onFlushMaterials);
|
||||
}
|
||||
|
||||
mFile = terr;
|
||||
mTerrFileName = terr.getPath();
|
||||
|
||||
if (!mFile)
|
||||
{
|
||||
Con::errorf("TerrainBlock::setFile() - No valid terrain file!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (terr->mNeedsResaving)
|
||||
{
|
||||
if (Platform::messageBox("Update Terrain File", "You appear to have a Terrain file in an older format. Do you want Torque to update it?", MBOkCancel, MIQuestion) == MROk)
|
||||
{
|
||||
mFile->save(terr->mFilePath.getFullPath());
|
||||
mFile->mNeedsResaving = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (terr->mFileVersion != TerrainFile::FILE_VERSION || terr->mNeedsResaving)
|
||||
{
|
||||
Con::errorf(" *********************************************************");
|
||||
Con::errorf(" *********************************************************");
|
||||
Con::errorf(" *********************************************************");
|
||||
Con::errorf(" PLEASE RESAVE THE TERRAIN FILE FOR THIS MISSION! THANKS!");
|
||||
Con::errorf(" *********************************************************");
|
||||
Con::errorf(" *********************************************************");
|
||||
Con::errorf(" *********************************************************");
|
||||
}
|
||||
|
||||
|
||||
_updateBounds();
|
||||
|
||||
resetWorldBox();
|
||||
setRenderTransform(mObjToWorld);
|
||||
|
||||
if (isClientObject())
|
||||
{
|
||||
if (mCRC != terr.getChecksum())
|
||||
{
|
||||
NetConnection::setLastError("Your terrain file doesn't match the version that is running on the server.");
|
||||
return;
|
||||
}
|
||||
|
||||
clearLightMap();
|
||||
|
||||
// Init the detail layer rendering helper.
|
||||
_updateMaterials();
|
||||
_updateLayerTexture();
|
||||
|
||||
// If the cached base texture is older that the terrain file or
|
||||
// it doesn't exist then generate and cache it.
|
||||
String baseCachePath = _getBaseTexCacheFileName();
|
||||
if (Platform::compareModifiedTimes(baseCachePath, mTerrainAsset->getTerrainFilePath()) < 0)
|
||||
_updateBaseTexture(true);
|
||||
|
||||
// The base texture should have been cached by now... so load it.
|
||||
mBaseTex.set(baseCachePath, &GFXStaticTextureSRGBProfile, "TerrainBlock::mBaseTex");
|
||||
|
||||
GFXTextureManager::addEventDelegate(this, &TerrainBlock::_onTextureEvent);
|
||||
MATMGR->getFlushSignal().notify(this, &TerrainBlock::_onFlushMaterials);
|
||||
|
||||
// Build the terrain quadtree.
|
||||
_rebuildQuadtree();
|
||||
|
||||
// Preload all the materials.
|
||||
mCell->preloadMaterials();
|
||||
|
||||
mZoningDirty = true;
|
||||
SceneZoneSpaceManager::getZoningChangedSignal().notify(this, &TerrainBlock::_onZoningChanged);
|
||||
}
|
||||
else
|
||||
mCRC = terr.getChecksum();
|
||||
}
|
||||
|
||||
bool TerrainBlock::setTerrainAsset(const StringTableEntry terrainAssetId)
|
||||
{
|
||||
mTerrainAssetId = terrainAssetId;
|
||||
mTerrainAsset = mTerrainAssetId;
|
||||
|
||||
if (mTerrainAsset.isNull())
|
||||
if (TerrainAsset::getAssetById(terrainAssetId, &mTerrainAsset))
|
||||
{
|
||||
Con::errorf("[TerrainBlock] Failed to load terrain asset.");
|
||||
return false;
|
||||
//Special exception case. If we've defaulted to the 'no shape' mesh, don't save it out, we'll retain the original ids/paths so it doesn't break
|
||||
//the TSStatic
|
||||
if (!mTerrainAsset.isNull())
|
||||
{
|
||||
mTerrFileName = StringTable->EmptyString();
|
||||
}
|
||||
|
||||
setFile(mTerrainAsset->getTerrainResource());
|
||||
|
||||
setMaskBits(-1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Resource<TerrainFile> file = mTerrainAsset->getTerrainResource();
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
setFile(file);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TerrainBlock::save(const char *filename)
|
||||
|
|
@ -425,19 +502,40 @@ bool TerrainBlock::saveAsset()
|
|||
|
||||
bool TerrainBlock::_setTerrainFile( void *obj, const char *index, const char *data )
|
||||
{
|
||||
static_cast<TerrainBlock*>( obj )->setFile( FileName( data ) );
|
||||
return false;
|
||||
//TerrainBlock* terrain = static_cast<TerrainBlock*>( obj )->setFile( FileName( data ) );
|
||||
TerrainBlock* terrain = static_cast<TerrainBlock*>(obj);
|
||||
|
||||
StringTableEntry file = StringTable->insert(data);
|
||||
|
||||
if (file != StringTable->EmptyString())
|
||||
{
|
||||
StringTableEntry assetId = TerrainAsset::getAssetIdByFilename(file);
|
||||
if (assetId != StringTable->EmptyString())
|
||||
{
|
||||
if (terrain->setTerrainAsset(assetId))
|
||||
{
|
||||
terrain->mTerrainAssetId = assetId;
|
||||
terrain->mTerrFileName = StringTable->EmptyString();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
terrain->mTerrainAsset = StringTable->EmptyString();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TerrainBlock::_setTerrainAsset(void* obj, const char* index, const char* data)
|
||||
{
|
||||
TerrainBlock* terr = static_cast<TerrainBlock*>(obj);// ->setFile(FileName(data));
|
||||
|
||||
terr->setTerrainAsset(StringTable->insert(data));
|
||||
|
||||
terr->setMaskBits(FileMask | HeightMapChangeMask);
|
||||
terr->mTerrainAssetId = StringTable->insert(data);
|
||||
|
||||
return false;
|
||||
return terr->setTerrainAsset(terr->mTerrainAssetId);
|
||||
}
|
||||
|
||||
void TerrainBlock::_updateBounds()
|
||||
|
|
@ -870,6 +968,27 @@ void TerrainBlock::addMaterial( const String &name, U32 insertAt )
|
|||
{
|
||||
mFile->mMaterials.push_back( mat );
|
||||
mFile->_initMaterialInstMapping();
|
||||
|
||||
bool isSrv = isServerObject();
|
||||
|
||||
//now we update our asset
|
||||
if (mTerrainAsset)
|
||||
{
|
||||
StringTableEntry terrMatName = StringTable->insert(name.c_str());
|
||||
|
||||
AssetQuery* aq = new AssetQuery();
|
||||
U32 foundCount = AssetDatabase.findAssetType(aq, "TerrainMaterialAsset");
|
||||
|
||||
for (U32 i = 0; i < foundCount; i++)
|
||||
{
|
||||
TerrainMaterialAsset* terrMatAsset = AssetDatabase.acquireAsset<TerrainMaterialAsset>(aq->mAssetList[i]);
|
||||
if (terrMatAsset && terrMatAsset->getMaterialDefinitionName() == terrMatName)
|
||||
{
|
||||
//Do iterative logic to find the next available slot and write to it with our new mat field
|
||||
mTerrainAsset->setDataField(StringTable->insert("terrainMaterialAsset"), nullptr, aq->mAssetList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -993,101 +1112,9 @@ bool TerrainBlock::onAdd()
|
|||
return false;
|
||||
}
|
||||
|
||||
mFile = terr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mTerrFileName.isEmpty())
|
||||
{
|
||||
mTerrFileName = Con::getVariable("$Client::MissionFile");
|
||||
String terrainDirectory(Con::getVariable("$pref::Directories::Terrain"));
|
||||
if (terrainDirectory.isEmpty())
|
||||
{
|
||||
terrainDirectory = "data/terrains/";
|
||||
}
|
||||
mTerrFileName.replace("tools/levels/", terrainDirectory);
|
||||
mTerrFileName.replace("levels/", terrainDirectory);
|
||||
|
||||
Vector<String> materials;
|
||||
materials.push_back("warning_material");
|
||||
TerrainFile::create(&mTerrFileName, 256, materials);
|
||||
}
|
||||
|
||||
terr = ResourceManager::get().load(mTerrFileName);
|
||||
|
||||
if (terr == NULL)
|
||||
{
|
||||
if (isClientObject())
|
||||
NetConnection::setLastError("You are missing a file needed to play this mission: %s", mTerrFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
setFile(terr);
|
||||
}
|
||||
|
||||
if ( terr->mNeedsResaving )
|
||||
{
|
||||
if (Platform::messageBox("Update Terrain File", "You appear to have a Terrain file in an older format. Do you want Torque to update it?", MBOkCancel, MIQuestion) == MROk)
|
||||
{
|
||||
terr->save(terr->mFilePath.getFullPath());
|
||||
terr->mNeedsResaving = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (terr->mFileVersion != TerrainFile::FILE_VERSION || terr->mNeedsResaving)
|
||||
{
|
||||
Con::errorf(" *********************************************************");
|
||||
Con::errorf(" *********************************************************");
|
||||
Con::errorf(" *********************************************************");
|
||||
Con::errorf(" PLEASE RESAVE THE TERRAIN FILE FOR THIS MISSION! THANKS!");
|
||||
Con::errorf(" *********************************************************");
|
||||
Con::errorf(" *********************************************************");
|
||||
Con::errorf(" *********************************************************");
|
||||
}
|
||||
|
||||
_updateBounds();
|
||||
|
||||
resetWorldBox();
|
||||
setRenderTransform(mObjToWorld);
|
||||
|
||||
if (isClientObject())
|
||||
{
|
||||
if ( mCRC != terr.getChecksum() )
|
||||
{
|
||||
NetConnection::setLastError("Your terrain file doesn't match the version that is running on the server.");
|
||||
return false;
|
||||
}
|
||||
|
||||
clearLightMap();
|
||||
|
||||
// Init the detail layer rendering helper.
|
||||
_updateMaterials();
|
||||
_updateLayerTexture();
|
||||
|
||||
// If the cached base texture is older that the terrain file or
|
||||
// it doesn't exist then generate and cache it.
|
||||
String baseCachePath = _getBaseTexCacheFileName();
|
||||
if ( Platform::compareModifiedTimes( baseCachePath, mTerrFileName ) < 0 )
|
||||
_updateBaseTexture( true );
|
||||
|
||||
// The base texture should have been cached by now... so load it.
|
||||
mBaseTex.set( baseCachePath, &GFXStaticTextureSRGBProfile, "TerrainBlock::mBaseTex" );
|
||||
|
||||
GFXTextureManager::addEventDelegate( this, &TerrainBlock::_onTextureEvent );
|
||||
MATMGR->getFlushSignal().notify( this, &TerrainBlock::_onFlushMaterials );
|
||||
|
||||
// Build the terrain quadtree.
|
||||
_rebuildQuadtree();
|
||||
|
||||
// Preload all the materials.
|
||||
mCell->preloadMaterials();
|
||||
|
||||
mZoningDirty = true;
|
||||
SceneZoneSpaceManager::getZoningChangedSignal().notify( this, &TerrainBlock::_onZoningChanged );
|
||||
}
|
||||
else
|
||||
mCRC = terr.getChecksum();
|
||||
|
||||
|
||||
addToScene();
|
||||
|
||||
_updatePhysics();
|
||||
|
|
@ -1097,7 +1124,7 @@ bool TerrainBlock::onAdd()
|
|||
|
||||
String TerrainBlock::_getBaseTexCacheFileName() const
|
||||
{
|
||||
Torque::Path basePath( mTerrFileName );
|
||||
Torque::Path basePath( mTerrainAsset->getTerrainFilePath() );
|
||||
basePath.setFileName( basePath.getFileName() + "_basetex" );
|
||||
basePath.setExtension( formatToExtension(mBaseTexFormat) );
|
||||
return basePath.getFullPath();
|
||||
|
|
@ -1224,7 +1251,7 @@ void TerrainBlock::initPersistFields()
|
|||
{
|
||||
addGroup( "Media" );
|
||||
|
||||
addProtectedField("terrainAsset", TypeTerrainAssetPtr, Offset(mTerrainAsset, TerrainBlock),
|
||||
addProtectedField("terrainAsset", TypeTerrainAssetId, Offset(mTerrainAssetId, TerrainBlock),
|
||||
&TerrainBlock::_setTerrainAsset, &defaultProtectedGetFn,
|
||||
"The source terrain data asset.");
|
||||
|
||||
|
|
@ -1291,8 +1318,9 @@ U32 TerrainBlock::packUpdate(NetConnection* con, U32 mask, BitStream *stream)
|
|||
|
||||
if ( stream->writeFlag( mask & FileMask ) )
|
||||
{
|
||||
stream->write( mTerrFileName );
|
||||
stream->write( mCRC );
|
||||
S32 idasdasdf = getId();
|
||||
stream->write(mCRC);
|
||||
stream->writeString( mTerrainAsset.getAssetId() );
|
||||
}
|
||||
|
||||
if ( stream->writeFlag( mask & SizeMask ) )
|
||||
|
|
@ -1330,14 +1358,11 @@ void TerrainBlock::unpackUpdate(NetConnection* con, BitStream *stream)
|
|||
|
||||
if ( stream->readFlag() ) // FileMask
|
||||
{
|
||||
FileName terrFile;
|
||||
stream->read( &terrFile );
|
||||
stream->read( &mCRC );
|
||||
stream->read(&mCRC);
|
||||
|
||||
if ( isProperlyAdded() )
|
||||
setFile( terrFile );
|
||||
else
|
||||
mTerrFileName = terrFile;
|
||||
char buffer[256];
|
||||
stream->readString(buffer);
|
||||
bool validAsset = setTerrainAsset(StringTable->insert(buffer));
|
||||
}
|
||||
|
||||
if ( stream->readFlag() ) // SizeMask
|
||||
|
|
|
|||
|
|
@ -766,15 +766,15 @@ void TerrainFile::create( String *inOutFilename,
|
|||
U32 newSize,
|
||||
const Vector<String> &materials )
|
||||
{
|
||||
// Determine the path and basename - first try using the input filename (mission name)
|
||||
// Determine the path and basename
|
||||
Torque::Path basePath( *inOutFilename );
|
||||
if ( !basePath.getExtension().equal("mis") )
|
||||
if ( !basePath.getExtension().equal("ter") )
|
||||
{
|
||||
// Use the default path and filename
|
||||
String terrainDirectory( Con::getVariable( "$pref::Directories::Terrain" ) );
|
||||
if ( terrainDirectory.isEmpty() )
|
||||
{
|
||||
terrainDirectory = "art/terrains";
|
||||
terrainDirectory = "data/terrains";
|
||||
}
|
||||
basePath.setPath( terrainDirectory );
|
||||
basePath.setFileName( "terrain" );
|
||||
|
|
|
|||
|
|
@ -46,14 +46,14 @@ DefineEngineStaticMethod( TerrainBlock, createNew, S32, (String terrainName, U32
|
|||
// We create terrains based on level name. If the user wants to rename the terrain names; they have to
|
||||
// rename it themselves in their file browser. The main reason for this is so we can easily increment for ourselves;
|
||||
// and because its too easy to rename the terrain object and forget to take care of the terrain filename afterwards.
|
||||
FileName terrFileName( Con::getVariable("$Client::MissionFile") );
|
||||
|
||||
String terrainDirectory( Con::getVariable( "$pref::Directories::Terrain" ) );
|
||||
if ( terrainDirectory.isEmpty() )
|
||||
{
|
||||
terrainDirectory = "art/terrains/";
|
||||
terrainDirectory = "data/terrains/";
|
||||
}
|
||||
terrFileName.replace("tools/levels/", terrainDirectory);
|
||||
terrFileName.replace("levels/", terrainDirectory);
|
||||
|
||||
String terrFileName = terrainDirectory + "/" + terrainName + ".ter";
|
||||
|
||||
TerrainFile::create( &terrFileName, resolution, materials );
|
||||
|
||||
|
|
@ -273,18 +273,32 @@ bool TerrainBlock::import( const GBitmap &heightMap,
|
|||
{
|
||||
// Get a unique file name for the terrain.
|
||||
String fileName( getName() );
|
||||
if ( fileName.isEmpty() )
|
||||
fileName = "terrain";
|
||||
mTerrFileName = FS::MakeUniquePath( "levels", fileName, "ter" );
|
||||
if (fileName.isEmpty())
|
||||
{
|
||||
fileName = Torque::Path(Con::getVariable("$Client::MissionFile")).getFileName();
|
||||
|
||||
// TODO: We have to save and reload the file to get
|
||||
if (fileName.isEmpty())
|
||||
fileName = "terrain";
|
||||
}
|
||||
String terrainFileName = FS::MakeUniquePath( "levels", fileName, "ter" );
|
||||
|
||||
if (!TerrainAsset::getAssetByFilename(terrainFileName, &mTerrainAsset))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mFile = mTerrainAsset->getTerrainResource();
|
||||
}
|
||||
|
||||
/*// TODO: We have to save and reload the file to get
|
||||
// it into the resource system. This creates lots
|
||||
// of temporary unused files when the terrain is
|
||||
// discarded because of undo or quit.
|
||||
TerrainFile *file = new TerrainFile;
|
||||
file->save( mTerrFileName );
|
||||
delete file;
|
||||
mFile = ResourceManager::get().load( mTerrFileName );
|
||||
mFile = ResourceManager::get().load( mTerrFileName );*/
|
||||
}
|
||||
|
||||
// The file does a bunch of the work.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
#include "gfx/gfxTextureManager.h"
|
||||
#include "gfx/bitmap/gBitmap.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
IMPLEMENT_CONOBJECT( TerrainMaterial );
|
||||
|
||||
|
|
@ -77,7 +79,9 @@ TerrainMaterial::~TerrainMaterial()
|
|||
|
||||
void TerrainMaterial::initPersistFields()
|
||||
{
|
||||
addField( "diffuseMap", TypeStringFilename, Offset( mDiffuseMap, TerrainMaterial ), "Base texture for the material" );
|
||||
scriptBindMapSlot(DiffuseMap, TerrainMaterial);
|
||||
|
||||
//addField( "diffuseMap", TypeStringFilename, Offset( mDiffuseMap, TerrainMaterial ), "Base texture for the material" );
|
||||
addField( "diffuseSize", TypeF32, Offset( mDiffuseSize, TerrainMaterial ), "Used to scale the diffuse map to the material square" );
|
||||
|
||||
addField( "normalMap", TypeStringFilename, Offset( mNormalMap, TerrainMaterial ), "Bump map for the material" );
|
||||
|
|
@ -154,7 +158,7 @@ TerrainMaterial* TerrainMaterial::findOrCreate( const char *nameOrPath )
|
|||
{
|
||||
mat = new TerrainMaterial();
|
||||
mat->setInternalName( nameOrPath );
|
||||
mat->mDiffuseMap = nameOrPath;
|
||||
mat->mDiffuseMapFilename = nameOrPath;
|
||||
mat->registerObject();
|
||||
Sim::getRootGroup()->addObject( mat );
|
||||
return mat;
|
||||
|
|
@ -169,7 +173,7 @@ TerrainMaterial* TerrainMaterial::findOrCreate( const char *nameOrPath )
|
|||
// fallback here just in case it gets "lost".
|
||||
mat = new TerrainMaterial();
|
||||
mat->setInternalName( "warning_material" );
|
||||
mat->mDiffuseMap = GFXTextureManager::getWarningTexturePath();
|
||||
mat->mDiffuseMapFilename = GFXTextureManager::getWarningTexturePath();
|
||||
mat->mDiffuseSize = 500;
|
||||
mat->mDetailMap = GFXTextureManager::getWarningTexturePath();
|
||||
mat->mDetailSize = 5;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "console/simBase.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ImageAsset.h"
|
||||
|
||||
/// The TerrainMaterial class orginizes the material settings
|
||||
/// for a single terrain material layer.
|
||||
|
|
@ -37,7 +38,11 @@ class TerrainMaterial : public SimObject
|
|||
protected:
|
||||
|
||||
///
|
||||
FileName mDiffuseMap;
|
||||
//FileName mDiffuseMap;
|
||||
|
||||
//AssetPtr<ImageAsset> mDiffuseAsset;
|
||||
|
||||
DECLARE_TEXTUREMAP(DiffuseMap);
|
||||
|
||||
/// The size of the diffuse base map in meters
|
||||
/// used to generate its texture coordinates.
|
||||
|
|
@ -99,7 +104,7 @@ public:
|
|||
/// a material is not found or defined.
|
||||
static TerrainMaterial* getWarningMaterial();
|
||||
|
||||
const String& getDiffuseMap() const { return mDiffuseMap; }
|
||||
const String& getDiffuseMap() const { return mDiffuseMapFilename; }
|
||||
|
||||
F32 getDiffuseSize() const { return mDiffuseSize; }
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,10 @@ void TerrainBlock::_onFlushMaterials()
|
|||
}
|
||||
|
||||
void TerrainBlock::_updateMaterials()
|
||||
{
|
||||
{
|
||||
if (!mFile)
|
||||
return;
|
||||
|
||||
mBaseTextures.setSize( mFile->mMaterials.size() );
|
||||
|
||||
mMaxDetailDistance = 0.0f;
|
||||
|
|
@ -363,6 +366,9 @@ void TerrainBlock::_renderBlock( SceneRenderState *state )
|
|||
{
|
||||
PROFILE_SCOPE( TerrainBlock_RenderBlock );
|
||||
|
||||
if (!mFile)
|
||||
return;
|
||||
|
||||
// Prevent rendering shadows if feature is disabled
|
||||
if ( !mCastShadows && state->isShadowPass() )
|
||||
return;
|
||||
|
|
@ -529,4 +535,4 @@ void TerrainBlock::_renderDebug( ObjectRenderInst *ri,
|
|||
mDebugCells[i]->renderBounds();
|
||||
|
||||
mDebugCells.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue