Files
FC1/Cry3DEngine/3dEngineLoad.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

792 lines
27 KiB
C++

////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
// File name: 3dengineload.cpp
// Version: v1.00
// Created: 28/5/2001 by Vladimir Kajalin
// Compilers: Visual Studio.NET
// Description: Level loading
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "3dEngine.h"
#include "objman.h"
#include "visareas.h"
#include "terrain_water.h"
#include "CryStaticModel.h"
#include "partman.h"
#include "DecalManager.h"
#include "bflyes.h"
#include "detail_grass.h"
#include "rain.h"
#include <IXMLDOM.h>
#include "watervolumes.h"
#include "brush.h"
#include "LMCompStructures.h"
#define LEVEL_DATA_FILE "LevelData.xml"
#define CUSTOM_MATERIALS_FILE "Materials.xml"
#define PARTICLES_FILE "particles.lst"
#define EFFECTS_FOLDER "Effects"
#define SHARED_PARTICLES_EXPLOSIONS "Explosions"
#define SHARED_PARTICLES_WATER "Water"
#define SHARED_PARTICLES_SMOKE "Smoke"
#define SHARED_PARTICLES_BLOOD "Blood"
#define SHARED_PARTICLES_BULLET "Bullet"
#define SHARED_PARTICLES_MISC "Misc"
#define SHARED_PARTICLES_FIRE "Fire"
double C3DEngine::m_dLoadLevelTime = 0;
//////////////////////////////////////////////////////////////////////////
void C3DEngine::ClearRenderResources( bool bEditorMode )
{
// GetLog()->Log("\003*** Clearing render resources ***");
// GetSystem()->GetIAnimationSystem()-> ;
// ShutDown(false);
//if(GetRenderer())
// GetRenderer()->FreeResources(FRR_SHADERS | FRR_TEXTURES | FRR_RESTORE);
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
if(m_pVisAreaManager)
{
UpdateLoadingScreen("Deleting VisAreaManager ...");
delete m_pVisAreaManager;
UpdateLoadingScreenPlus(" Ok");
m_pVisAreaManager=0;
}
if (m_pObjManager)
{
SAFE_DELETE( m_pObjManager->m_pCWaterVolumes );
}
// delete terrain
if(m_pTerrain)
{
UpdateLoadingScreen("Deleting terrain ...");
SAFE_DELETE( m_pTerrain );
UpdateLoadingScreenPlus(" Ok");
}
// free vegetations
if(!bEditorMode)
{
if (m_pObjManager)
m_pObjManager->UnloadVegetations();
}
if (m_pPartManager)
{
m_pPartManager->Reset();
if (!bEditorMode)
{
SAFE_DELETE( m_pPartManager );
}
}
SAFE_DELETE( m_pDecalManager );
// Load Materials Library from LevelData.xml
if (!bEditorMode)
{
SAFE_DELETE( m_pMatMan );
m_pMatMan = new CMatMan();
}
//////////////////////////////////////////////////////////////////////////
// Purge destroyed physics entities.
//////////////////////////////////////////////////////////////////////////
GetSystem()->GetIPhysicalWorld()->PurgeDeletedEntities();
// print warnings
if (m_pObjManager)
m_pObjManager->CheckObjectLeaks();
GetRenderer()->PreLoad();
}
//////////////////////////////////////////////////////////////////////////
void C3DEngine::SetLevelPath( const char * szFolderName )
{
// make folder path
assert(strlen(szFolderName) < 1024);
strcpy( m_szLevelFolder,szFolderName );
if (strlen(m_szLevelFolder) > 0)
{
if (m_szLevelFolder[strlen(m_szLevelFolder)-1] != '/')
strcat( m_szLevelFolder,"/" );
}
}
//////////////////////////////////////////////////////////////////////////
bool C3DEngine::LoadLevel(const char * szFolderName, const char * szMissionName, bool bEditorMode)
{
AUTO_PROFILE_SECTION(GetTimer(), m_dLoadLevelTime);
m_bIgnoreFakeMaterialsInCGF = !bEditorMode;
m_bEditorMode = bEditorMode;
GetRenderer()->MakeCurrent();
if(!szFolderName || !szFolderName[0])
{ Warning( 0,0,"C3DEngine::LoadLevel: Level name is not specified"); return 0; }
if(!szMissionName || !szMissionName[0])
{ Warning( 0,0,"C3DEngine::LoadLevel: Mission name is not specified"); }
char szMissionNameBody[256] = "NoMission";
if(!szMissionName)
szMissionName = szMissionNameBody;
SetLevelPath( szFolderName );
if(!bEditorMode)
{ // check is LevelData.xml file exist
char sMapFileName[_MAX_PATH];
strcpy(sMapFileName,m_szLevelFolder);
strcat(sMapFileName,LEVEL_DATA_FILE);
if(!CXFile::IsFileExist(sMapFileName))
{ UpdateLoadingScreen("Error: Level not found: %s", sMapFileName); return 0; }
}
if(!m_pObjManager)
m_pObjManager = new CObjManager (this);
if(!bEditorMode)
{
if(m_pVisAreaManager)
{
UpdateLoadingScreen("Deleting VisAreaManager ...");
delete m_pVisAreaManager;
UpdateLoadingScreenPlus(" Ok");
m_pVisAreaManager=0;
}
}
if(!m_pVisAreaManager)
m_pVisAreaManager = new CVisAreaManager( );
assert (GetSystem()->GetIAnimationSystem());
if(!bEditorMode)
{
int nCellSize = 4;
GetPhysicalWorld()->SetupEntityGrid(2,vectorf(0,0,0), // this call will destroy all physicalized stuff
CTerrain::GetTerrainSize()/nCellSize,CTerrain::GetTerrainSize()/nCellSize,(float)nCellSize,(float)nCellSize);
}
// cache prev terrain objects
list2<struct IEntityRender*> lstTerrainObjects;
if(bEditorMode && m_pTerrain)
m_pTerrain->GetObjects(&lstTerrainObjects);
// delete terrain
if(m_pTerrain)
{
UpdateLoadingScreen("Deleting terrain ...");
delete m_pTerrain; m_pTerrain=0;
UpdateLoadingScreenPlus(" Ok");
}
// free vegetations
if(!bEditorMode)
m_pObjManager->UnloadVegetations();
// print level name into console
char header[512];
snprintf(header, sizeof(header),
"\001---------------------- Loading level %s, mission %s ------------------------------------",
szFolderName, szMissionName);
header[100]=0;
UpdateLoadingScreen(header);
// print warnings
m_pObjManager->CheckObjectLeaks();
// create terrain
m_pTerrain = new CTerrain( );
m_pObjManager->m_pTerrain = m_pTerrain;
if(m_pTerrain && !m_pTerrain->LoadTerrain(bEditorMode))
{ // terrain not found
delete m_pTerrain;
m_pTerrain = 0;
}
// restore prev terrain objects
for(int i=0; i<lstTerrainObjects.Count(); i++)
{
lstTerrainObjects[i]->m_pSector = 0;
Get3DEngine()->RegisterEntity(lstTerrainObjects[i]);
}
lstTerrainObjects.Reset();
//
m_pObjManager->m_lstVegetContainer.Reset();
m_pObjManager->m_lstBrushContainer.Reset();
//////////////////////////////////////////////////////////////////////////
// Load LevelData.xml File.
XmlNodeRef levelDataRoot = GetSystem()->LoadXmlFile( GetLevelFilePath(LEVEL_DATA_FILE) );
//////////////////////////////////////////////////////////////////////////
// Load Materials Library from LevelData.xml
if (!bEditorMode)
{
delete m_pMatMan;
m_pMatMan = new CMatMan();
m_pMatMan->LoadMaterialsLibrary( GetLevelFilePath(CUSTOM_MATERIALS_FILE),levelDataRoot );
}
{ // recreate particles and decals
if(m_pPartManager)
m_pPartManager->Reset();
else
m_pPartManager = new CPartManager();
delete m_pDecalManager;
m_pDecalManager = new CDecalManager (this);
}
LoadParticleEffects( levelDataRoot,bEditorMode );
// load leveldata.xml
m_pTerrainWaterShader=m_pSunRoadShader=0;
m_nWaterBottomTexId=0;
LoadEnvironmentSettingsFromXML(szMissionName, bEditorMode, 0, true);
// init water if not initialized already (if no mission was found)
if(m_pTerrain && !m_pTerrain->m_pWater)
m_pTerrain->InitTerrainWater(bEditorMode,
m_pTerrainWaterShader, m_nWaterBottomTexId, m_pSunRoadShader,
m_fWaterTranspRatio, m_fWaterReflectRatio,
m_fWaterBumpAmountX, m_fWaterBumpAmountY, m_fWaterBorderTranspRatio);
m_pObjManager->m_pTerrain = m_pTerrain;
/* if (!m_pTerrain)
{
// [marco] Vlad check why it crashes here
CryError("3dengine:Cannot Load terrain - report this to Vladimir Kajalin");
}*/
if(m_pTerrain)
m_pTerrain->SetObjManager(m_pObjManager);
m_pVisAreaManager->SetupFogVolumes(m_pTerrain);
if(m_pObjManager->m_pCWaterVolumes)
m_pObjManager->m_pCWaterVolumes->InitWaterVolumes();
if(!bEditorMode)
{
// load static object bodies
m_pObjManager->LoadVegetationModels(szMissionName,bEditorMode);
// load lsources used for lightmaps
#if !defined(LINUX64)//fails due to different size of CDLight (pointers have 8 bytes)
LoadStaticLightSources(GetLevelFilePath("StatLights.dat"));
#endif
// bushes bodies and instances
m_pObjManager->LoadBrushes();
// merge brushes grouped in the editor
m_pObjManager->MergeBrushes();
// load positions of static objects, update sectors bboxes
m_pTerrain->LoadStatObjInstances();
}
// recreate bugs
/* if(m_pTerrain)
{
delete m_pTerrain->m_pBugsManager;
m_pTerrain->m_pBugsManager = new CBugsManager( );
}*/
// physicalise instances of static objects and buildings
// m_pObjManager->CreatePhysicalEntitys();
for(int i=0; i<m_pObjManager->m_lstBrushContainer.Count(); i++)
{
if (!(m_pObjManager->m_lstBrushContainer[i]->m_dwRndFlags & ERF_MERGED))
{
Get3DEngine()->UnRegisterEntity(m_pObjManager->m_lstBrushContainer[i]);
Get3DEngine()->RegisterEntity(m_pObjManager->m_lstBrushContainer[i]);
}
}
for(int i=0; i<m_pObjManager->m_lstVegetContainer.Count(); i++)
{
Get3DEngine()->UnRegisterEntity(m_pObjManager->m_lstVegetContainer[i]);
Get3DEngine()->RegisterEntity(m_pObjManager->m_lstVegetContainer[i]);
}
if(!bEditorMode)
{
m_pTerrain->SortStaticInstancesBySize();
m_pVisAreaManager->SortStaticInstancesBySize();
}
if(GetCVars()->e_stream_areas)
{ // all data can be streamed from disk now
for(int i=0; i<m_pObjManager->m_lstBrushContainer.Count(); i++)
delete m_pObjManager->m_lstBrushContainer[i];
m_pObjManager->m_lstBrushContainer.Reset();
for(int i=0; i<m_pObjManager->m_lstVegetContainer.Count(); i++)
delete m_pObjManager->m_lstVegetContainer[i];
m_pObjManager->m_lstVegetContainer.Reset();
}
else
{
// from now objects will be stored in the sectors
m_pObjManager->m_lstVegetContainer.Reset();
m_pObjManager->m_lstBrushContainer.Reset();
}
// restore game state
SetRainAmount(0);
EnableOceanRendering(true,true);
SetSkyBoxAlpha(1.f);
m_pObjManager->m_bLockCGFResources = false;
return (true);
}
void C3DEngine::LoadTerrainSurfacesFromXML(void * _pDoc)
{
UpdateLoadingScreen("Loading terrain detail textures ...");
XDOM::IXMLDOMNodeListPtr pDetTexTagList;
XDOM::IXMLDOMNodePtr pDetTexTag;
XDOM::IXMLDOMDocumentPtr pDoc = _pDoc ? *((XDOM::IXMLDOMDocumentPtr*)_pDoc) : (XDOM::IXMLDOMDocumentPtr)0;
if(!_pDoc)
{ // load current LevelData if pDoc not specified
pDoc = GetSystem()->CreateXMLDocument();
if(!pDoc->load(Get3DEngine()->GetLevelFilePath(LEVEL_DATA_FILE)))
return;
}
pDetTexTagList = pDoc->getElementsByTagName("SurfaceTypes");
if (pDetTexTagList)
{
pDetTexTagList->reset();
pDetTexTag = pDetTexTagList->nextNode();
XDOM::IXMLDOMNodeListPtr pDetTexList;
pDetTexList = pDetTexTag->getElementsByTagName("SurfaceType");
if (pDetTexList)
{
pDetTexList->reset();
XDOM::IXMLDOMNodePtr pDetTex;
int nId = 0;
while (pDetTex = pDetTexList->nextNode())
{
XDOM::IXMLDOMNodePtr pDetailTextureName = pDetTex->getAttribute("DetailTexture");
XDOM::IXMLDOMNodePtr pScaleX = pDetTex->getAttribute("DetailScaleX");
XDOM::IXMLDOMNodePtr pScaleY = pDetTex->getAttribute("DetailScaleY");
XDOM::IXMLDOMNodePtr pProjAxis = pDetTex->getAttribute("ProjAxis");
XDOM::IXMLDOMNodePtr pSurfaceName = pDetTex->getAttribute("Name");
if(pDetailTextureName) if(pScaleX) if(pScaleY) if(pSurfaceName)
{
m_pTerrain->SetDetailTextures(nId, pDetailTextureName->getText(),
(float)atof(pScaleX->getText()), (float)atof(pScaleY->getText()),
pProjAxis ? (pProjAxis->getText())[0] : 0, pSurfaceName->getText());
}
nId++;
}
}
// recreate detail objects
delete m_pTerrain->m_pDetailObjects;
m_pTerrain->m_pDetailObjects = new CDetailGrass(pDetTexTagList);
}
m_pTerrain->InitDetailTextureLayers();
UpdateLoadingScreenPlus(" ok");
}
void C3DEngine::LoadFogVolumesFromXML(XDOM::IXMLDOMDocumentPtr pDoc)
{
if(!m_pTerrain)
return;
m_pTerrain->m_lstFogVolumes.Clear();
{ // make hardcoded volume for ocean
VolumeInfo volumeInfo;
volumeInfo.vBoxMax = Vec3d( 1000000, 1000000, m_pTerrain->GetWaterLevel());
volumeInfo.vBoxMin = Vec3d(-1000000, -1000000, -1000000);
// volumeInfo.pShader = 0;
volumeInfo.pShader = GetRenderer()->EF_LoadShader("FogLayer", eSH_World, EF_SYSTEM);
volumeInfo.vColor = m_vUnderWaterFogColor;
volumeInfo.fMaxViewDist = m_fUnderWaterFogDistance;
volumeInfo.bOcean = true;
volumeInfo.m_bCaustics = m_bOceanCaustics;
// add volume to list
m_pTerrain->m_lstFogVolumes.Add(volumeInfo);
}
XDOM::IXMLDOMNodeListPtr pNodeTagList;
XDOM::IXMLDOMNodePtr pNodeTag;
pNodeTagList = pDoc->getElementsByTagName("Objects");
if (pNodeTagList)
{
pNodeTagList->reset();
pNodeTag = pNodeTagList->nextNode();
XDOM::IXMLDOMNodeListPtr pNodeList;
pNodeList = pNodeTag->getElementsByTagName("Object");
if (pNodeList)
{
pNodeList->reset();
XDOM::IXMLDOMNodePtr pNode;
while (pNode = pNodeList->nextNode())
{
XDOM::IXMLDOMNodePtr pName = pNode->getAttribute("Type");
if (pName)
{
if (strstr(pName->getText(),"FogVolume"))
{
XDOM::IXMLDOMNodePtr pAttr;
VolumeInfo volumeInfo;
pAttr = pNode->getAttribute("Pos");
if(pAttr)
{
Vec3d vPos = StringToVector(pAttr->getText());
// get properties
// XDOM::IXMLDOMNodeListPtr pObjectsTagList = pNode->getElementsByTagName("Properties");
// if(pObjectsTagList)
{
XDOM::IXMLDOMNodePtr pAttr1,pAttr2,pAttr3,pAttr4,pAttr5;
pAttr1 = pNode->getAttribute("ViewDistance");
if(pAttr1)
volumeInfo.fMaxViewDist = (float)atof(pAttr1->getText());
pAttr1 = pNode->getAttribute("Width");
pAttr2 = pNode->getAttribute("Length");
pAttr3 = pNode->getAttribute("Height");
pAttr4 = pNode->getAttribute("Shader");
pAttr5 = pNode->getAttribute("Color");
if(pAttr1!=0 && pAttr2!=0 && pAttr3!=0 && pAttr4!=0 && pAttr5!=0)
{
Vec3d vSize((float)atof(pAttr1->getText()), (float)atof(pAttr2->getText()), (float)atof(pAttr3->getText()));
volumeInfo.vBoxMax = vPos + Vec3d(vSize.x*0.5f, vSize.y*0.5f, vSize.z);
volumeInfo.vBoxMin = vPos - Vec3d(vSize.x*0.5f, vSize.y*0.5f, 0);
volumeInfo.pShader = (char*)pAttr4->getText()[0] ? GetRenderer()->EF_LoadShader((char*)pAttr4->getText(), eSH_World, EF_SYSTEM) : GetRenderer()->EF_LoadShader("FogLayer", eSH_World, EF_SYSTEM);
volumeInfo.vColor = StringToVector(pAttr5->getText());
// add volume to list
m_pTerrain->m_lstFogVolumes.Add(volumeInfo);
}
}
}
}
}
}
}
}
}
void C3DEngine::LoadEnvironmentSettingsFromXML(const char * szMissionName, bool bEditorMode, const char * szMissionXMLString, bool bUpdateLightingOnVegetations)
{
if(!m_pTerrain)
{
Warning( 0,0,"Calling C3DEngine::LoadEnvironmentSettingsFromXML while level is not loaded");
return;
}
GetRenderer()->MakeCurrent();
// if xml string specified - load settings just from this string
if(szMissionXMLString)
{
XDOM::IXMLDOMDocumentPtr pMissionDoc;
pMissionDoc=GetSystem()->CreateXMLDocument();
// add empty <Mission> tag
char * szMissionXMLStringWithMissionTag = new char [strlen(szMissionXMLString)+256];
strcpy(szMissionXMLStringWithMissionTag, "<Mission>\n");
strcat(szMissionXMLStringWithMissionTag, szMissionXMLString);
strcat(szMissionXMLStringWithMissionTag, "</Mission>");
if (pMissionDoc->loadXML(szMissionXMLStringWithMissionTag))
{
LoadMissionSettingsFromXML(pMissionDoc, bEditorMode, bUpdateLightingOnVegetations);
// load fog volumes (mission shared data)
// LoadFogVolumesFromXML(pMissionDoc);
// m_pTerrain->InitFogVolumes();
}
delete [] szMissionXMLStringWithMissionTag;
return;
}
// load environment settings
XDOM::IXMLDOMDocumentPtr pDoc = GetSystem()->CreateXMLDocument();
// set default values
m_vFogColor(1,1,1);
m_fDefMaxViewDist = m_fMaxViewDist = 1024;
m_vDefFogColor = m_vFogColor;
m_fDefFogNearDist = m_fFogNearDist=50;
m_fDefFogFarDist = m_fFogFarDist = 1500;
//char buff[128];
// GetCurrentDirectory(128, buff);
if(pDoc->load(Get3DEngine()->GetLevelFilePath(LEVEL_DATA_FILE)))
{
// load detail textures (mission shared data)
LoadTerrainSurfacesFromXML(&pDoc);
// mission environment
if (szMissionName && szMissionName[0])
{
XDOM::IXMLDOMNodeListPtr pMissionTagList;
XDOM::IXMLDOMNodePtr pMissionTag;
pMissionTagList = pDoc->getElementsByTagName("Missions");
if (pMissionTagList)
{
pMissionTagList->reset();
pMissionTag = pMissionTagList->nextNode();
XDOM::IXMLDOMNodeListPtr pMissionList;
pMissionList = pMissionTag->getElementsByTagName("Mission");
if (pMissionList)
{
pMissionList->reset();
XDOM::IXMLDOMNodePtr pMission;
while (pMission = pMissionList->nextNode())
{
XDOM::IXMLDOMNodePtr pName = pMission->getAttribute("Name");
if (pName)
{
if (!stricmp(pName->getText(),szMissionName))
{ // get mission XML file name and open mission file
XDOM::IXMLDOMNodePtr pMissionFileName = pMission->getAttribute("File");
if (pMissionFileName)
{
XDOM::IXMLDOMDocumentPtr pMissionDoc;
pMissionDoc=GetSystem()->CreateXMLDocument();
if (pMissionDoc->load(Get3DEngine()->GetLevelFilePath(pMissionFileName->getText())))
{
LoadMissionSettingsFromXML(pMissionDoc, bEditorMode, bUpdateLightingOnVegetations);
// load fog volumes (mission shared data)
LoadFogVolumesFromXML(pMissionDoc);
m_pTerrain->InitFogVolumes();
if(!bEditorMode)
{
if(!m_pObjManager->m_pCWaterVolumes)
m_pObjManager->m_pCWaterVolumes = new CWaterVolumeManager( );
m_pObjManager->m_pCWaterVolumes->LoadWaterVolumesFromXML(pMissionDoc);
m_pVisAreaManager->LoadVisAreaShapeFromXML(pMissionDoc);
}
m_pVisAreaManager->LoadVisAreaBoxFromXML(pMissionDoc);
}
break;
}
}
}
}
}
}
}
else
Warning(0,0,"C3DEngine::LoadEnvironmentSettingsFromXML: Mission name is not defined");
}
}
char * C3DEngine::GetXMLAttribText(XDOM::IXMLDOMNode * pInputNode, const char * szLevel0,const char * szLevel1,const char * szLevel2,const char * szDefaultValue)
{
static char szResText[128];
strncpy(szResText,szDefaultValue,128);
XDOM::IXMLDOMNodeListPtr pObjectsTagList = pInputNode->getElementsByTagName(szLevel0);
if (!pObjectsTagList)
return szResText;
pObjectsTagList->reset();
XDOM::IXMLDOMNodePtr pObjectsTag = pObjectsTagList->nextNode();
XDOM::IXMLDOMNodeListPtr pNodes = pObjectsTag->getElementsByTagName(szLevel1);
if(pNodes)
{
XDOM::IXMLDOMNodePtr pNode;
pNodes->reset();
while(pNode = pNodes->nextNode())
{
XDOM::IXMLDOMNodePtr pAttr = pNode->getAttribute(szLevel2);
if(pAttr)
strncpy(szResText, pAttr->getText(), sizeof(szResText));
break;
}
}
return szResText;
}
void C3DEngine::LoadMissionSettingsFromXML(XDOM::IXMLDOMNode *pInputNode, bool bEditorMode, bool bUpdateLightingOnVegetations)
{
Vec3d vColor = StringToVector(GetXMLAttribText(pInputNode,"Environment","Fog","Color","255,255,255"));
m_vDefFogColor[0] = m_vFogColor[0] = vColor[0]/255.f;
m_vDefFogColor[1] = m_vFogColor[1] = vColor[1]/255.f;
m_vDefFogColor[2] = m_vFogColor[2] = vColor[2]/255.f;
GetRenderer()->SetClearColor(m_vFogColor);
// fog distance
m_fDefFogNearDist = m_fFogNearDist= (float)atol(GetXMLAttribText(pInputNode,"Environment","Fog","Start","64"));
m_fDefFogFarDist = m_fFogFarDist = (float)atol(GetXMLAttribText(pInputNode,"Environment","Fog","End","1500"));
// max view distance
m_fDefMaxViewDist = m_fMaxViewDist = (float)atol(GetXMLAttribText(pInputNode,"Environment","Fog","ViewDistance","1024"));
// Shaders
char szSkyBoxShaderName[128];
strncpy(szSkyBoxShaderName, GetXMLAttribText(pInputNode, "Environment", "Shaders", "SkyBox", "InfRedGal"), sizeof(szSkyBoxShaderName));
SAFE_RELEASE(m_pSHSky);
m_pSHSky = szSkyBoxShaderName[0] ? GetRenderer()->EF_LoadShader(szSkyBoxShaderName, eSH_World) : NULL;
// set terrain water, sun road and bottom shaders
char szTerrainWaterShaderName[256]="";
strncpy(szTerrainWaterShaderName, GetXMLAttribText(pInputNode,"Environment","Shaders","Water", "terrainwater"), sizeof(szTerrainWaterShaderName));
m_pTerrainWaterShader = szTerrainWaterShaderName[0] ? GetRenderer()->EF_LoadShader(szTerrainWaterShaderName, eSH_World, EF_SYSTEM) : 0;
char szSunRoadShaderName[256]="";
strncpy(szSunRoadShaderName, GetXMLAttribText(pInputNode,"Environment","Shaders","SunWaterRefl", "BumpSunGlow"), sizeof(szSunRoadShaderName));
m_pSunRoadShader = szSunRoadShaderName[0] ? GetRenderer()->EF_LoadShader(szSunRoadShaderName, eSH_World, EF_SYSTEM) : 0;
// load water bottom texture
char szWaterBottomTexName[256]="";
strncpy(szWaterBottomTexName, GetXMLAttribText(pInputNode,"Environment","Ocean","BottomTexture", "terrain/water/oceanfloorcolor.bmp"),sizeof(szWaterBottomTexName));
ITexPic * pPic = GetRenderer()->EF_LoadTexture(szWaterBottomTexName,FT_NOREMOVE,0,eTT_Base);
m_nWaterBottomTexId = pPic->GetTextureID();
// load default zoom texture
char szDefZoomTexName[256]="";
strncpy(szDefZoomTexName, GetXMLAttribText(pInputNode, "Environment", "HeightMap", "DefaultZoomTexture", ""),sizeof(szDefZoomTexName));
if(szDefZoomTexName[0])
{
pPic = GetRenderer()->EF_LoadTexture(szDefZoomTexName,FT_NOREMOVE,0,eTT_Base);
m_pTerrain->m_nDefZoomTexId = pPic->GetTextureID();
}
else
m_pTerrain->m_nDefZoomTexId = 0;
// Ocean
m_pTerrain->m_fShoreSize = (float)atof(GetXMLAttribText(pInputNode,"Environment","Ocean","ShoreSize", "2.0"));
m_fWaterTranspRatio = (float)atof(GetXMLAttribText(pInputNode,"Environment","Ocean","SurfaceTranspRatio", "1.0"));
m_fWaterReflectRatio = (float)atof(GetXMLAttribText(pInputNode,"Environment","Ocean","SurfaceReflectRatio","1.0"));
m_fWaterBumpAmountX = (float)atof(GetXMLAttribText(pInputNode,"Environment","Ocean","SurfaceBumpAmountX", "0.08"));
m_fWaterBumpAmountY = (float)atof(GetXMLAttribText(pInputNode,"Environment","Ocean","SurfaceBumpAmountY", "0.12"));
m_fWaterBorderTranspRatio = (float)atof(GetXMLAttribText(pInputNode,"Environment","Ocean","BorderTranspRatio", "0.5"));
m_vUnderWaterFogColor = StringToVector(GetXMLAttribText(pInputNode,"Environment","Ocean","FogColor","51,90,102"))/255;
m_fUnderWaterFogDistance = (float)atof(GetXMLAttribText(pInputNode,"Environment","Ocean","FogDistance", "8"));
m_bOceanCaustics = atol(GetXMLAttribText(pInputNode,"Environment","Ocean","Caustics", "1"))==1;
m_fSkyBoxAngle = (float)atof(GetXMLAttribText(pInputNode,"Environment","EnvState","SkyBoxAngle","0.0"));
m_fSunHeightScale = (float)atof(GetXMLAttribText(pInputNode,"Environment","EnvState","SunHeightScale","1.0"));
m_fSkyBoxStretching = (float)atof(GetXMLAttribText(pInputNode,"Environment","EnvState","SkyBoxStretching","1.0"));
m_pTerrain->InitTerrainWater(bEditorMode, m_pTerrainWaterShader, m_nWaterBottomTexId, m_pSunRoadShader, m_fWaterTranspRatio, m_fWaterReflectRatio, m_fWaterBumpAmountX, m_fWaterBumpAmountY, m_fWaterBorderTranspRatio);
char szLensFlaresShaderName[128];
strncpy(szLensFlaresShaderName, GetXMLAttribText(pInputNode,"Environment","Shaders","SunLensFlares","CryLight"), sizeof(szLensFlaresShaderName));
if(szLensFlaresShaderName[0])
m_pSHLensFlares = GetRenderer()->EF_LoadShader(szLensFlaresShaderName, eSH_World, EF_SYSTEM);
else
m_pSHLensFlares = NULL;
char szShoreShaderName[128];
strncpy(szShoreShaderName, GetXMLAttribText(pInputNode,"Environment","Shaders","Shore", "terrainwaterbeach"), sizeof(szShoreShaderName));
m_pTerrain->m_pSHShore = szShoreShaderName[0] ? GetRenderer()->EF_LoadShader(szShoreShaderName, eSH_World, EF_SYSTEM) : 0;
// State
vColor = StringToVector(GetXMLAttribText(pInputNode,"Environment","EnvState","EnvColor","128,128,128"));
m_vWorldColorConst = vColor/255.f;
// GetCVars()->e_rain_amount = strstr(GetXMLAttribText(pInputNode,"Environment","EnvState","Rain",""),"True")!=0;
// GetCVars()->e_bflyes = GetCVars()->e_bflyes && strstr(GetXMLAttribText(pInputNode,"Environment","EnvState","BFlyes",""),"True")!=0;
// set sun position
m_vSunPosition = StringToVector(GetXMLAttribText(pInputNode,"Environment","Lighting","SunVector","0,5,-5"));
m_vSunPosition *= -1.0f;
m_vSunPosition.Normalize();
float x=m_vSunPosition.x;
m_vSunPosition.x = m_vSunPosition.y;
m_vSunPosition.y=x;
if(m_vSunPosition.x == 0 && m_vSunPosition.y == 0)
m_vSunPosition = Vec3d(5,5,10000);
else
m_vSunPosition = GetNormalized(m_vSunPosition)*10000;
m_pObjManager->m_vOutdoorAmbientColor =
StringToVector(GetXMLAttribText(pInputNode,"Environment","EnvState","OutdoorAmbientColor","64,64,64"))/255;
m_pObjManager->m_vSunColor =
StringToVector(GetXMLAttribText(pInputNode,"Environment","EnvState","SunColor","128,128,128"))/255;
if(!GetISystem()->IsDedicated())
m_pObjManager->UpdateCustomLighting( GetNormalized(GetSunPosition()) );
// get wind
m_pObjManager->m_fWindForce = (float)atof(GetXMLAttribText(pInputNode,"Environment","EnvState","WindForce","0.15"));
// get terrain lods
float fGeometryLodRatio = (float)atof(GetXMLAttribText(pInputNode,"Environment","HeightMap","GeometryLodRatio","1.0"));
if(GetCVars()->e_cgf_load_lods == 0 && fGeometryLodRatio>1.f) // ised only for very high spec
fGeometryLodRatio = 1.f+(fGeometryLodRatio-1.f)*0.5f;
ICVar * pCVar = GetConsole()->GetCVar("e_terrain_lod_ratio");
if(pCVar)
pCVar->Set(fGeometryLodRatio);
m_pTerrain->m_fTextureLodRatio = (float)atof(GetXMLAttribText(pInputNode,"Environment","HeightMap","TextureLodRatio", "1.0"));
}
//////////////////////////////////////////////////////////////////////////
void C3DEngine::LoadParticleEffects( XmlNodeRef &levelDataRoot,bool bEditorMode )
{
if (!m_pPartManager)
return;
m_pPartManager->LoadSharedParticleLibrary( EFFECTS_FOLDER,SHARED_PARTICLES_EXPLOSIONS );
m_pPartManager->LoadSharedParticleLibrary( EFFECTS_FOLDER,SHARED_PARTICLES_WATER );
m_pPartManager->LoadSharedParticleLibrary( EFFECTS_FOLDER,SHARED_PARTICLES_SMOKE );
m_pPartManager->LoadSharedParticleLibrary( EFFECTS_FOLDER,SHARED_PARTICLES_BLOOD );
m_pPartManager->LoadSharedParticleLibrary( EFFECTS_FOLDER,SHARED_PARTICLES_BULLET );
m_pPartManager->LoadSharedParticleLibrary( EFFECTS_FOLDER,SHARED_PARTICLES_MISC );
m_pPartManager->LoadSharedParticleLibrary( EFFECTS_FOLDER,SHARED_PARTICLES_FIRE );
if (levelDataRoot)
m_pPartManager->LoadParticlesLibs( EFFECTS_FOLDER,levelDataRoot );
CCryFile file;
if (file.Open( GetLevelFilePath(PARTICLES_FILE),"rb" ))
{
m_pPartManager->LoadParticles( file );
}
}