//////////////////////////////////////////////////////////////////////////// // // 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 #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 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; im_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; im_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; im_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; im_lstBrushContainer.Count(); i++) delete m_pObjManager->m_lstBrushContainer[i]; m_pObjManager->m_lstBrushContainer.Reset(); for(int i=0; im_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 tag char * szMissionXMLStringWithMissionTag = new char [strlen(szMissionXMLString)+256]; strcpy(szMissionXMLStringWithMissionTag, "\n"); strcat(szMissionXMLStringWithMissionTag, szMissionXMLString); strcat(szMissionXMLStringWithMissionTag, ""); 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 ); } }