BVB Source Codes

CRYENGINE Show terrain_compile.cpp Source code

Return Download CRYENGINE: download terrain_compile.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  File name:   terrain_compile.cpp
  5. //  Version:     v1.00
  6. //  Created:     15/04/2005 by Vladimir Kajalin
  7. //  Compilers:   Visual Studio.NET
  8. //  Description: check vis
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #include "StdAfx.h"
  15.  
  16. #include "terrain.h"
  17. #include "StatObj.h"
  18. #include "ObjMan.h"
  19. #include "MatMan.h"
  20. #include "VisAreas.h"
  21. #include "ObjectsTree.h"
  22.  
  23. #define SIGC_ALIGNTOTERRAIN         BIT(0) // Deprecated
  24. #define SIGC_USETERRAINCOLOR        BIT(1)
  25. #define SIGC_HIDEABILITY            BIT(3)
  26. #define SIGC_HIDEABILITYSECONDARY   BIT(4)
  27. #define SIGC_PICKABLE               BIT(5)
  28. #define SIGC_PROCEDURALLYANIMATED   BIT(6)
  29. #define SIGC_CASTSHADOW             BIT(7) // Deprecated
  30. #define SIGC_GI_MODE                BIT(8)
  31. #define SIGC_DYNAMICDISTANCESHADOWS BIT(9)
  32. #define SIGC_USEALPHABLENDING       BIT(10) // not used
  33. #define SIGC_USESPRITES             BIT(11)
  34. #define SIGC_RANDOMROTATION         BIT(12)
  35. #define SIGC_ALLOWINDOOR            BIT(13)
  36.  
  37. // Bits 13-14 reserved for player hideability
  38. #define SIGC_PLAYERHIDEABLE_LOWBIT    (13)
  39. #define SIGC_PLAYERHIDEABLE_MASK      BIT(13) | BIT(14)
  40.  
  41. #define SIGC_CASTSHADOW_MINSPEC_SHIFT (15)
  42. #define SIGC_CASTSHADOW_MINSPEC_MASK  ((END_CONFIG_SPEC_ENUM - 1) << SIGC_CASTSHADOW_MINSPEC_SHIFT)
  43.  
  44. void CTerrain::GetVegetationMaterials(std::vector<IMaterial*>*& pMatTable)
  45. {
  46.         if (!pMatTable)
  47.                 return;
  48.  
  49.         {
  50.                 // get vegetation objects materials
  51.                 PodArray<StatInstGroup>& rTable = GetObjManager()->m_lstStaticTypes[0];
  52.                 int nObjectsCount = rTable.size();
  53.  
  54.                 // init struct values and load cgf's
  55.                 for (uint32 i = 0; i < rTable.size(); i++)
  56.                 {
  57.                         int nMaterialId = -1;
  58.                         if (rTable[i].pMaterial)
  59.                         {
  60.                                 nMaterialId = CObjManager::GetItemId(pMatTable, (IMaterial*)rTable[i].pMaterial, false);
  61.                                 if (nMaterialId < 0)
  62.                                 {
  63.                                         nMaterialId = pMatTable->size();
  64.                                         pMatTable->push_back(rTable[i].pMaterial);
  65.                                 }
  66.                         }
  67.                 }
  68.         }
  69. }
  70.  
  71. int CTerrain::GetTablesSize(SHotUpdateInfo* pExportInfo, int nSID)
  72. {
  73.         int nDataSize = 0;
  74.  
  75.         nDataSize += sizeof(int);
  76.  
  77.         // get brush objects table size
  78.         std::vector<IStatObj*> brushTypes;
  79.         std::vector<IMaterial*> usedMats;
  80.         std::vector<IStatInstGroup*> instGroups;
  81.  
  82.         std::vector<IMaterial*>* pMatTable = &usedMats;
  83.         GetVegetationMaterials(pMatTable);
  84.  
  85.         Get3DEngine()->m_pObjectsTree[nSID]->GenerateStatObjAndMatTables(&brushTypes, &usedMats, &instGroups, pExportInfo);
  86.         GetVisAreaManager()->GenerateStatObjAndMatTables(&brushTypes, &usedMats, &instGroups, pExportInfo);
  87.  
  88.         nDataSize += instGroups.size() * sizeof(StatInstGroupChunk);
  89.  
  90.         nDataSize += sizeof(int);
  91.         nDataSize += brushTypes.size() * sizeof(SNameChunk);
  92.         brushTypes.clear();
  93.  
  94.         // get custom materials table size
  95.         nDataSize += sizeof(int);
  96.         nDataSize += usedMats.size() * sizeof(SNameChunk);
  97.  
  98.         return nDataSize;
  99. }
  100.  
  101. int CTerrain::GetCompiledDataSize(SHotUpdateInfo* pExportInfo, int nSID)
  102. {
  103. #if !ENGINE_ENABLE_COMPILATION
  104.         CryFatalError("serialization code removed, please enable ENGINE_ENABLE_COMPILATION in Cry3DEngine/StdAfx.h");
  105.         return 0;
  106. #else
  107.         int nDataSize = 0;
  108.         byte* pData = NULL;
  109.         Vec3 segmentOffset(0, 0, 0);
  110.  
  111.         bool bHMap(!pExportInfo || pExportInfo->nHeigtmap);
  112.         bool bObjs(!pExportInfo || pExportInfo->nObjTypeMask);
  113.  
  114.         if (bObjs)
  115.         {
  116.                 assert(nSID >= 0 && nSID < Get3DEngine()->m_pObjectsTree.Count() && Get3DEngine()->m_pObjectsTree[nSID]);
  117.                 Get3DEngine()->m_pObjectsTree[nSID]->CleanUpTree();
  118.                 Get3DEngine()->m_pObjectsTree[nSID]->GetData(pData, nDataSize, NULL, NULL, NULL, eLittleEndian, pExportInfo, segmentOffset);
  119.         }
  120.  
  121.         if (bHMap)
  122.                 GetParentNode(nSID)->GetData(pData, nDataSize, GetPlatformEndian(), pExportInfo);
  123.  
  124.         // get header size
  125.         nDataSize += sizeof(STerrainChunkHeader);
  126.  
  127.         // get vegetation objects table size
  128.         if (bObjs)
  129.         {
  130.                 nDataSize += GetTablesSize(pExportInfo, nSID);
  131.         }
  132.  
  133.         return nDataSize;
  134. #endif
  135. }
  136.  
  137. void CTerrain::SaveTables(byte*& pData, int& nDataSize, std::vector<struct IStatObj*>*& pStatObjTable, std::vector<IMaterial*>*& pMatTable, std::vector<IStatInstGroup*>*& pStatInstGroupTable, EEndian eEndian, SHotUpdateInfo* pExportInfo, int nSID)
  138. {
  139.         pMatTable = new std::vector<struct IMaterial*>;
  140.         pStatObjTable = new std::vector<struct IStatObj*>;
  141.         pStatInstGroupTable = new std::vector<struct IStatInstGroup*>;
  142.  
  143.         GetVegetationMaterials(pMatTable);
  144.  
  145.         Get3DEngine()->m_pObjectsTree[nSID]->GenerateStatObjAndMatTables(pStatObjTable, pMatTable, pStatInstGroupTable, pExportInfo);
  146.         GetVisAreaManager()->GenerateStatObjAndMatTables(pStatObjTable, pMatTable, pStatInstGroupTable, pExportInfo);
  147.  
  148.         {
  149.                 {
  150.                         // get vegetation objects count
  151.                         std::vector<IStatInstGroup*>& rTable = *pStatInstGroupTable;
  152.                         int nObjectsCount = rTable.size();
  153.  
  154.                         // prepare temporary chunks array for saving
  155.                         PodArray<StatInstGroupChunk> lstFileChunks;
  156.                         lstFileChunks.PreAllocate(nObjectsCount, nObjectsCount);
  157.  
  158.                         // init struct values and load cgf's
  159.                         for (uint32 i = 0; i < rTable.size(); i++)
  160.                         {
  161.                                 cry_strcpy(lstFileChunks[i].szFileName, rTable[i]->szFileName);
  162.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fBending);
  163.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fSpriteDistRatio);
  164.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fLodDistRatio);
  165.                                 if (lstFileChunks[i].fLodDistRatio < 0.001f) // not allow to export value of 0 because it would mean that variable is not set
  166.                                         lstFileChunks[i].fLodDistRatio = 0.001f;
  167.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fShadowDistRatio);
  168.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fMaxViewDistRatio);
  169.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fBrightness);
  170.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], nRotationRangeToTerrainNormal);
  171.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fAlignToTerrainCoefficient);
  172.  
  173.                                 lstFileChunks[i].nFlags = 0;
  174.                                 if (rTable[i]->bUseTerrainColor)
  175.                                         lstFileChunks[i].nFlags |= SIGC_USETERRAINCOLOR;
  176.                                 if (rTable[i]->bAllowIndoor)
  177.                                         lstFileChunks[i].nFlags |= SIGC_ALLOWINDOOR;
  178.                                 if (rTable[i]->bHideability)
  179.                                         lstFileChunks[i].nFlags |= SIGC_HIDEABILITY;
  180.                                 if (rTable[i]->bHideabilitySecondary)
  181.                                         lstFileChunks[i].nFlags |= SIGC_HIDEABILITYSECONDARY;
  182.                                 if (rTable[i]->bPickable)
  183.                                         lstFileChunks[i].nFlags |= SIGC_PICKABLE;
  184.                                 if (rTable[i]->bAutoMerged)
  185.                                         lstFileChunks[i].nFlags |= SIGC_PROCEDURALLYANIMATED;
  186.                                 if (rTable[i]->bGIMode)
  187.                                         lstFileChunks[i].nFlags |= SIGC_GI_MODE;
  188.                                 if (rTable[i]->bDynamicDistanceShadows)
  189.                                         lstFileChunks[i].nFlags |= SIGC_DYNAMICDISTANCESHADOWS;
  190.                                 if (rTable[i]->bUseSprites)
  191.                                         lstFileChunks[i].nFlags |= SIGC_USESPRITES;
  192.                                 if (rTable[i]->bRandomRotation)
  193.                                         lstFileChunks[i].nFlags |= SIGC_RANDOMROTATION;
  194.  
  195.                                 lstFileChunks[i].nFlags |= ((rTable[i]->nCastShadowMinSpec << SIGC_CASTSHADOW_MINSPEC_SHIFT) & SIGC_CASTSHADOW_MINSPEC_MASK);
  196.                                 lstFileChunks[i].nFlags |= ((rTable[i]->nPlayerHideable << SIGC_PLAYERHIDEABLE_LOWBIT) & SIGC_PLAYERHIDEABLE_MASK);
  197.  
  198.                                 lstFileChunks[i].nMaterialId = -1;
  199.                                 if (rTable[i]->pMaterial)
  200.                                 {
  201.                                         lstFileChunks[i].nMaterialId = CObjManager::GetItemId(pMatTable, (IMaterial*)rTable[i]->pMaterial, false);
  202.                                         if (lstFileChunks[i].nMaterialId < 0)
  203.                                         {
  204.                                                 lstFileChunks[i].nMaterialId = pMatTable->size();
  205.                                                 pMatTable->push_back(rTable[i]->pMaterial);
  206.                                         }
  207.                                 }
  208.  
  209.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], nMaterialLayers);
  210.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fDensity);
  211.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fElevationMax);
  212.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fElevationMin);
  213.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fSize);
  214.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fSizeVar);
  215.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fSlopeMax);
  216.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fSlopeMin);
  217.  
  218.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], m_dwRndFlags);
  219.  
  220.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fStiffness);
  221.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fDamping);
  222.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fVariance);
  223.                                 COPY_MEMBER_SAVE(&lstFileChunks[i], rTable[i], fAirResistance);
  224.  
  225.                                 lstFileChunks[i].nIDPlusOne = rTable[i]->nID + 1;
  226.                         }
  227.  
  228.                         // get count
  229.                         AddToPtr(pData, nDataSize, nObjectsCount, eEndian);
  230.  
  231.                         // get table content
  232.                         for (int i = 0; i < lstFileChunks.Count(); i++)
  233.                                 AddToPtr(pData, nDataSize, lstFileChunks[i], eEndian);
  234.  
  235.                 }
  236.  
  237.                 {
  238.                         // get brush objects count
  239.                         int nObjectsCount = pStatObjTable->size();
  240.                         AddToPtr(pData, nDataSize, nObjectsCount, eEndian);
  241.  
  242.                         PodArray<SNameChunk> lstFileChunks;
  243.                         lstFileChunks.PreAllocate(pStatObjTable->size(), pStatObjTable->size());
  244.  
  245.                         for (uint32 i = 0; i < pStatObjTable->size(); i++)
  246.                         {
  247.                                 if ((*pStatObjTable)[i])
  248.                                         cry_strcpy(lstFileChunks[i].szFileName, (*pStatObjTable)[i]->GetFilePath());
  249.                                 else
  250.                                         lstFileChunks[i].szFileName[0] = 0;
  251.                                 AddToPtr(pData, nDataSize, lstFileChunks[i], eEndian);
  252.                         }
  253.                 }
  254.  
  255.                 {
  256.                         // get brush materials count
  257.                         std::vector<IMaterial*>& rTable = *pMatTable;
  258.                         int nObjectsCount = rTable.size();
  259.  
  260.                         // count
  261.                         AddToPtr(pData, nDataSize, nObjectsCount, eEndian);
  262.  
  263.                         // get table content
  264.                         for (int dwI = 0; dwI < nObjectsCount; ++dwI)
  265.                         {
  266.                                 SNameChunk tmp;
  267.                                 assert(strlen(rTable[dwI] ? rTable[dwI]->GetName() : "") < sizeof(tmp.szFileName));
  268.                                 cry_strcpy(tmp.szFileName, rTable[dwI] ? rTable[dwI]->GetName() : "");
  269.                                 AddToPtr(pData, nDataSize, tmp, eEndian);
  270.                         }
  271.                 }
  272.         }
  273. }
  274.  
  275. bool CTerrain::GetCompiledData(byte* pData, int nDataSize, std::vector<struct IStatObj*>** ppStatObjTable, std::vector<IMaterial*>** ppMatTable, std::vector<struct IStatInstGroup*>** ppStatInstGroupTable, EEndian eEndian, SHotUpdateInfo* pExportInfo, int nSID, const Vec3& segmentOffset)
  276. {
  277. #if !ENGINE_ENABLE_COMPILATION
  278.         CryFatalError("serialization code removed, please enable ENGINE_ENABLE_COMPILATION in Cry3DEngine/StdAfx.h");
  279.         return false;
  280. #else
  281.  
  282.         bool bHMap(!pExportInfo || pExportInfo->nHeigtmap);
  283.         bool bObjs(!pExportInfo || pExportInfo->nObjTypeMask);
  284.  
  285.         //PrintMessage("Exporting terrain data (%s, %.2f MB) ...",
  286.         //  (bHMap && bObjs) ? "Objects and heightmap" : (bHMap ? "Heightmap" : (bObjs ? "Objects" : "Nothing")), ((float)nDataSize)/1024.f/1024.f);
  287.  
  288.         // write header
  289.         STerrainChunkHeader* pTerrainChunkHeader = (STerrainChunkHeader*)pData;
  290.         pTerrainChunkHeader->nVersion = TERRAIN_CHUNK_VERSION;
  291.         pTerrainChunkHeader->nDummy = 0;
  292.  
  293.         pTerrainChunkHeader->nFlags = (eEndian == eBigEndian) ? SERIALIZATION_FLAG_BIG_ENDIAN : 0;
  294.         pTerrainChunkHeader->nFlags |= SERIALIZATION_FLAG_SECTOR_PALETTES | SERIALIZATION_FLAG_INSTANCES_PRESORTED_FOR_STREAMING;
  295.  
  296.         pTerrainChunkHeader->nFlags2 = (Get3DEngine()->m_bAreaActivationInUse ? TCH_FLAG2_AREA_ACTIVATION_IN_USE : 0);
  297.         pTerrainChunkHeader->nChunkSize = nDataSize;
  298.         pTerrainChunkHeader->TerrainInfo.nHeightMapSize_InUnits = m_nSectorSize * GetSectorsTableSize(nSID) / m_nUnitSize;
  299.         pTerrainChunkHeader->TerrainInfo.nUnitSize_InMeters = m_nUnitSize;
  300.         pTerrainChunkHeader->TerrainInfo.nSectorSize_InMeters = m_nSectorSize;
  301.         pTerrainChunkHeader->TerrainInfo.nSectorsTableSize_InSectors = GetSectorsTableSize(nSID);
  302.         pTerrainChunkHeader->TerrainInfo.fHeightmapZRatio = m_fHeightmapZRatio;
  303.         pTerrainChunkHeader->TerrainInfo.fOceanWaterLevel = (m_fOceanWaterLevel > WATER_LEVEL_UNKNOWN) ? m_fOceanWaterLevel : 0;
  304.  
  305.         SwapEndian(*pTerrainChunkHeader, eEndian);
  306.         UPDATE_PTR_AND_SIZE(pData, nDataSize, sizeof(STerrainChunkHeader));
  307.  
  308.         std::vector<struct IStatObj*>* pStatObjTable = NULL;
  309.         std::vector<struct IMaterial*>* pMatTable = NULL;
  310.         std::vector<struct IStatInstGroup*>* pStatInstGroupTable = NULL;
  311.  
  312.         if (bObjs)
  313.         {
  314.                 SaveTables(pData, nDataSize, pStatObjTable, pMatTable, pStatInstGroupTable, eEndian, pExportInfo, nSID);
  315.         }
  316.  
  317.         // get nodes data
  318.         int nNodesLoaded = bHMap ? GetParentNode(nSID)->GetData(pData, nDataSize, eEndian, pExportInfo) : 1;
  319.  
  320.         if (bObjs)
  321.         {
  322.                 Get3DEngine()->m_pObjectsTree[nSID]->CleanUpTree();
  323.  
  324.                 Get3DEngine()->m_pObjectsTree[nSID]->GetData(pData, nDataSize, pStatObjTable, pMatTable, pStatInstGroupTable, eEndian, pExportInfo, segmentOffset);
  325.  
  326.                 if (ppStatObjTable)
  327.                         *ppStatObjTable = pStatObjTable;
  328.                 else
  329.                         SAFE_DELETE(pStatObjTable);
  330.  
  331.                 if (ppMatTable)
  332.                         *ppMatTable = pMatTable;
  333.                 else
  334.                         SAFE_DELETE(pMatTable);
  335.  
  336.                 if (ppStatInstGroupTable)
  337.                         *ppStatInstGroupTable = pStatInstGroupTable;
  338.                 else
  339.                         SAFE_DELETE(pStatInstGroupTable);
  340.         }
  341.  
  342.         //PrintMessagePlus(" done in %.2f sec", GetCurAsyncTimeSec()-fStartTime );
  343.  
  344.         assert(nNodesLoaded && nDataSize == 0);
  345.         return (nNodesLoaded && nDataSize == 0);
  346. #endif
  347. }
  348.  
  349. void CTerrain::GetStatObjAndMatTables(DynArray<IStatObj*>* pStatObjTable, DynArray<IMaterial*>* pMatTable, DynArray<IStatInstGroup*>* pStatInstGroupTable, uint32 nObjTypeMask, int nSID)
  350. {
  351.         SHotUpdateInfo exportInfo;
  352.         exportInfo.nObjTypeMask = nObjTypeMask;
  353.  
  354.         std::vector<IStatObj*> statObjTable;
  355.         std::vector<IMaterial*> matTable;
  356.         std::vector<IStatInstGroup*> statInstGroupTable;
  357.  
  358.         if (Get3DEngine() && Get3DEngine()->m_pObjectsTree[nSID])
  359.                 Get3DEngine()->m_pObjectsTree[nSID]->GenerateStatObjAndMatTables((pStatObjTable != NULL) ? &statObjTable : NULL,
  360.                                                                                  (pMatTable != NULL) ? &matTable : NULL,
  361.                                                                                  (pStatInstGroupTable != NULL) ? &statInstGroupTable : NULL,
  362.                                                                                  &exportInfo);
  363.  
  364.         if (GetVisAreaManager())
  365.                 GetVisAreaManager()->GenerateStatObjAndMatTables((pStatObjTable != NULL) ? &statObjTable : NULL,
  366.                                                                  (pMatTable != NULL) ? &matTable : NULL,
  367.                                                                  (pStatInstGroupTable != NULL) ? &statInstGroupTable : NULL,
  368.                                                                  &exportInfo);
  369.  
  370.         if (pStatObjTable)
  371.         {
  372.                 pStatObjTable->resize(statObjTable.size());
  373.                 for (size_t i = 0; i < statObjTable.size(); ++i)
  374.                 {
  375.                         (*pStatObjTable)[i] = statObjTable[i];
  376.                 }
  377.  
  378.                 statObjTable.clear();
  379.         }
  380.  
  381.         if (pMatTable)
  382.         {
  383.                 pMatTable->resize(matTable.size());
  384.                 for (size_t i = 0; i < matTable.size(); ++i)
  385.                 {
  386.                         (*pMatTable)[i] = matTable[i];
  387.                 }
  388.  
  389.                 matTable.clear();
  390.         }
  391.  
  392.         if (pStatInstGroupTable)
  393.         {
  394.                 pStatInstGroupTable->resize(statInstGroupTable.size());
  395.                 for (size_t i = 0; i < statInstGroupTable.size(); ++i)
  396.                 {
  397.                         (*pStatInstGroupTable)[i] = statInstGroupTable[i];
  398.                 }
  399.  
  400.                 statInstGroupTable.clear();
  401.         }
  402. }
  403.  
  404. void CTerrain::LoadVegetationData(PodArray<StatInstGroup>& rTable, PodArray<StatInstGroupChunk>& lstFileChunks, int i)
  405. {
  406.         cry_strcpy(rTable[i].szFileName, lstFileChunks[i].szFileName);
  407.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fBending);
  408.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fSpriteDistRatio);
  409.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fLodDistRatio);
  410.         if (rTable[i].fLodDistRatio == 0)
  411.                 rTable[i].fLodDistRatio = 1.f; // set default value if it was not exported
  412.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fShadowDistRatio);
  413.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fMaxViewDistRatio);
  414.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fBrightness);
  415.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], nRotationRangeToTerrainNormal);
  416.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fAlignToTerrainCoefficient);
  417.  
  418.         rTable[i].bUseTerrainColor = (lstFileChunks[i].nFlags & SIGC_USETERRAINCOLOR) != 0;
  419.         rTable[i].bAllowIndoor = (lstFileChunks[i].nFlags & SIGC_ALLOWINDOOR) != 0;
  420.         rTable[i].bHideability = (lstFileChunks[i].nFlags & SIGC_HIDEABILITY) != 0;
  421.         rTable[i].bHideabilitySecondary = (lstFileChunks[i].nFlags & SIGC_HIDEABILITYSECONDARY) != 0;
  422.         rTable[i].bPickable = (lstFileChunks[i].nFlags & SIGC_PICKABLE) != 0;
  423.         rTable[i].bAutoMerged = (lstFileChunks[i].nFlags & SIGC_PROCEDURALLYANIMATED) != 0;  // && GetCVars()->e_MergedMeshes;
  424.         rTable[i].bGIMode = (lstFileChunks[i].nFlags & SIGC_GI_MODE) != 0;
  425.         rTable[i].bDynamicDistanceShadows = (lstFileChunks[i].nFlags & SIGC_DYNAMICDISTANCESHADOWS) != 0;
  426.         rTable[i].bUseSprites = (lstFileChunks[i].nFlags & SIGC_USESPRITES) != 0;
  427.         rTable[i].bRandomRotation = (lstFileChunks[i].nFlags & SIGC_RANDOMROTATION) != 0;
  428.  
  429.         int nCastShadowMinSpec = (lstFileChunks[i].nFlags & SIGC_CASTSHADOW_MINSPEC_MASK) >> SIGC_CASTSHADOW_MINSPEC_SHIFT;
  430.  
  431.         bool bCastShadowLegacy = (lstFileChunks[i].nFlags & SIGC_CASTSHADOW) != 0;     // deprecated, should be always false on re-export
  432.         nCastShadowMinSpec = (bCastShadowLegacy && !nCastShadowMinSpec) ? CONFIG_LOW_SPEC : nCastShadowMinSpec;
  433.  
  434.         rTable[i].nCastShadowMinSpec = (nCastShadowMinSpec) ? nCastShadowMinSpec : END_CONFIG_SPEC_ENUM;
  435.  
  436.         rTable[i].nPlayerHideable = ((lstFileChunks[i].nFlags & SIGC_PLAYERHIDEABLE_MASK) >> SIGC_PLAYERHIDEABLE_LOWBIT);
  437.  
  438.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], nMaterialLayers);
  439.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fDensity);
  440.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fElevationMax);
  441.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fElevationMin);
  442.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fSize);
  443.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fSizeVar);
  444.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fSlopeMax);
  445.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fSlopeMin);
  446.  
  447.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fStiffness);
  448.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fDamping);
  449.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fVariance);
  450.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], fAirResistance);
  451.  
  452.         COPY_MEMBER_LOAD(&rTable[i], &lstFileChunks[i], m_dwRndFlags);
  453.         rTable[i].nID = lstFileChunks[i].nIDPlusOne - 1;
  454.  
  455.         int nMinSpec = (rTable[i].m_dwRndFlags & ERF_SPEC_BITS_MASK) >> ERF_SPEC_BITS_SHIFT;
  456.         rTable[i].minConfigSpec = (ESystemConfigSpec)nMinSpec;
  457.  
  458.         if (rTable[i].szFileName[0])
  459.         {
  460.                 rTable[i].pStatObj.ReleaseOwnership();
  461.                 rTable[i].pStatObj = GetObjManager()->LoadStatObj(rTable[i].szFileName, NULL, NULL, !rTable[i].bAutoMerged); //,NULL,NULL,false);
  462.         }
  463.  
  464.         rTable[i].Update(GetCVars(), Get3DEngine()->GetGeomDetailScreenRes());
  465.  
  466. #ifndef SEG_WORLD
  467.         SLICE_AND_SLEEP();
  468. #endif
  469. }
  470.  
  471. template<class T>
  472. bool CTerrain::Load_T(T*& f, int& nDataSize, STerrainChunkHeader* pTerrainChunkHeader, std::vector<struct IStatObj*>** ppStatObjTable, std::vector<IMaterial*>** ppMatTable, bool bHotUpdate, SHotUpdateInfo* pExportInfo, int nSID, Vec3 vSegmentOrigin)
  473. {
  474.         LOADING_TIME_PROFILE_SECTION;
  475.  
  476.         assert(pTerrainChunkHeader->nVersion == TERRAIN_CHUNK_VERSION);
  477.         if (pTerrainChunkHeader->nVersion != TERRAIN_CHUNK_VERSION)
  478.         {
  479.                 Error("CTerrain::SetCompiledData: version of file is %d, expected version is %d", pTerrainChunkHeader->nVersion, (int)TERRAIN_CHUNK_VERSION);
  480.                 return 0;
  481.         }
  482.  
  483.         EEndian eEndian = (pTerrainChunkHeader->nFlags & SERIALIZATION_FLAG_BIG_ENDIAN) ? eBigEndian : eLittleEndian;
  484.         bool bSectorPalettes = (pTerrainChunkHeader->nFlags & SERIALIZATION_FLAG_SECTOR_PALETTES) != 0;
  485.  
  486.         bool bSW = Get3DEngine()->IsSegmentOperationInProgress();
  487.         bool bHMap(!pExportInfo || pExportInfo->nHeigtmap);
  488.         bool bObjs(!pExportInfo || pExportInfo->nObjTypeMask);
  489.         AABB* pBox = (pExportInfo && !pExportInfo->areaBox.IsReset()) ? &pExportInfo->areaBox : NULL;
  490.  
  491.         if (bHotUpdate)
  492.                 PrintMessage("Importing outdoor data (%s, %.2f MB) ...",
  493.                              (bHMap && bObjs) ? "Objects and heightmap" : (bHMap ? "Heightmap" : (bObjs ? "Objects" : "Nothing")), ((float)nDataSize) / 1024.f / 1024.f);
  494.  
  495.         if (pTerrainChunkHeader->nChunkSize != nDataSize + sizeof(STerrainChunkHeader))
  496.                 return 0;
  497.  
  498.         // get terrain settings
  499.         m_nUnitSize = pTerrainChunkHeader->TerrainInfo.nUnitSize_InMeters;
  500.         m_fInvUnitSize = 1.f / m_nUnitSize;
  501.         if (!Get3DEngine()->m_pSegmentsManager)
  502.                 m_nTerrainSize = pTerrainChunkHeader->TerrainInfo.nHeightMapSize_InUnits * pTerrainChunkHeader->TerrainInfo.nUnitSize_InMeters;
  503.  
  504.         m_nTerrainSizeDiv = (m_nTerrainSize >> m_nBitShift) - 1;
  505.         m_nSectorSize = pTerrainChunkHeader->TerrainInfo.nSectorSize_InMeters;
  506. #ifndef SEG_WORLD
  507.         m_nSectorsTableSize = pTerrainChunkHeader->TerrainInfo.nSectorsTableSize_InSectors;
  508. #endif
  509.         m_fHeightmapZRatio = pTerrainChunkHeader->TerrainInfo.fHeightmapZRatio;
  510.         m_fOceanWaterLevel = pTerrainChunkHeader->TerrainInfo.fOceanWaterLevel ? pTerrainChunkHeader->TerrainInfo.fOceanWaterLevel : WATER_LEVEL_UNKNOWN;
  511.  
  512.         if (bHotUpdate)
  513.                 Get3DEngine()->m_bAreaActivationInUse = false;
  514.         else
  515.                 Get3DEngine()->m_bAreaActivationInUse = (pTerrainChunkHeader->nFlags2 & TCH_FLAG2_AREA_ACTIVATION_IN_USE) != 0;
  516.  
  517.         if (Get3DEngine()->IsAreaActivationInUse())
  518.                 PrintMessage("Object layers control in use");
  519.  
  520.         m_nUnitsToSectorBitShift = 0;
  521.         while (m_nSectorSize >> m_nUnitsToSectorBitShift > m_nUnitSize)
  522.                 m_nUnitsToSectorBitShift++;
  523.  
  524.         if (bHMap && !m_pParentNodes[nSID])
  525.         {
  526.                 LOADING_TIME_PROFILE_SECTION_NAMED("BuildSectorsTree");
  527.  
  528.                 m_arrSegmentOrigns[nSID] = vSegmentOrigin;
  529.  
  530.                 // build nodes tree in fast way
  531.                 BuildSectorsTree(false, nSID);
  532.  
  533.                 // pass heightmap to the physics
  534.                 InitHeightfieldPhysics(nSID);
  535.         }
  536.  
  537.         // setup physics grid
  538.         if (!m_bEditor && !bHotUpdate && !bSW)
  539.         {
  540.                 LOADING_TIME_PROFILE_SECTION_NAMED("SetupEntityGrid");
  541.  
  542.                 int nCellSize = CTerrain::GetTerrainSize() > 2048 ? CTerrain::GetTerrainSize() >> 10 : 2;
  543.                 nCellSize = max(nCellSize, GetCVars()->e_PhysMinCellSize);
  544.                 int log2PODGridSize = 0;
  545.                 if (nCellSize == 2)
  546.                         log2PODGridSize = 2;
  547.                 else if (nCellSize == 4)
  548.                         log2PODGridSize = 1;
  549.                 GetPhysicalWorld()->SetupEntityGrid(2, Vec3(0, 0, 0), // this call will destroy all physicalized stuff
  550.                                                     CTerrain::GetTerrainSize() / nCellSize, CTerrain::GetTerrainSize() / nCellSize, (float)nCellSize, (float)nCellSize, log2PODGridSize);
  551.         }
  552.  
  553.         std::vector<IMaterial*>* pMatTable = NULL;
  554.         std::vector<IStatObj*>* pStatObjTable = NULL;
  555.  
  556.         if (bObjs)
  557.         {
  558.                 PodArray<StatInstGroupChunk> lstStatInstGroupChunkFileChunks;
  559.  
  560.                 {
  561.                         // get vegetation objects count
  562.                         MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Terrain, 0, "Vegetation");
  563.                         LOADING_TIME_PROFILE_SECTION_NAMED("Vegetation");
  564.  
  565.                         int nObjectsCount = 0;
  566.                         if (!LoadDataFromFile(&nObjectsCount, 1, f, nDataSize, eEndian))
  567.                                 return 0;
  568.  
  569.                         if (!bHotUpdate)
  570.                                 PrintMessage("===== Loading %d vegetation models =====", nObjectsCount);
  571.  
  572.                         // load chunks into temporary array
  573.                         PodArray<StatInstGroupChunk>& lstFileChunks = lstStatInstGroupChunkFileChunks;
  574.                         lstFileChunks.PreAllocate(nObjectsCount, nObjectsCount);
  575.                         if (!LoadDataFromFile(lstFileChunks.GetElements(), lstFileChunks.Count(), f, nDataSize, eEndian))
  576.                                 return 0;
  577.  
  578.                         // get vegetation objects table
  579.                         if (!m_bEditor || bHotUpdate)
  580.                         {
  581.                                 // preallocate real array
  582.                                 PodArray<StatInstGroup>& rTable = GetObjManager()->m_lstStaticTypes[nSID];
  583.                                 rTable.resize(nObjectsCount);//,nObjectsCount);
  584.  
  585.                                 // init struct values and load cgf's
  586.                                 for (uint32 i = 0; i < rTable.size(); i++)
  587.                                 {
  588.                                         LoadVegetationData(rTable, lstFileChunks, i);
  589.                                 }
  590.                         }
  591.                 }
  592.  
  593.                 pStatObjTable = new std::vector<IStatObj*>;
  594.  
  595.                 {
  596.                         // get brush objects count
  597.                         MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Terrain, 0, "Brushes");
  598.                         LOADING_TIME_PROFILE_SECTION_NAMED("Brushes");
  599.  
  600.                         int nObjectsCount = 0;
  601.                         if (!LoadDataFromFile(&nObjectsCount, 1, f, nDataSize, eEndian))
  602.                                 return 0;
  603.  
  604.                         if (!bHotUpdate)
  605.                                 PrintMessage("===== Loading %d brush models ===== ", nObjectsCount);
  606.  
  607.                         PodArray<SNameChunk> lstFileChunks;
  608.                         lstFileChunks.PreAllocate(nObjectsCount, nObjectsCount);
  609.                         if (!LoadDataFromFile(lstFileChunks.GetElements(), lstFileChunks.Count(), f, nDataSize, eEndian))
  610.                                 return 0;
  611.  
  612.                         // get brush objects table
  613.                         if (!m_bEditor || bHotUpdate)
  614.                         {
  615.                                 pStatObjTable->resize(nObjectsCount);//PreAllocate(nObjectsCount,nObjectsCount);
  616.  
  617.                                 // load cgf's
  618.                                 for (uint32 i = 0; i < pStatObjTable->size(); i++)
  619.                                 {
  620.                                         if (lstFileChunks[i].szFileName[0])
  621.                                         {
  622.                                                 (*pStatObjTable)[i] = GetObjManager()->LoadStatObj(lstFileChunks[i].szFileName);
  623.                                                 (*pStatObjTable)[i]->AddRef();
  624.                                         }
  625.  
  626.                                         SLICE_AND_SLEEP();
  627.                                 }
  628.                         }
  629.                 }
  630.  
  631.                 pMatTable = new std::vector<IMaterial*>;
  632.  
  633.                 {
  634.                         // get brush materials count
  635.                         LOADING_TIME_PROFILE_SECTION_NAMED("BrushMaterials");
  636.  
  637.                         int nObjectsCount = 0;
  638.                         if (!LoadDataFromFile(&nObjectsCount, 1, f, nDataSize, eEndian))
  639.                                 return 0;
  640.  
  641.                         // get vegetation objects table
  642.                         if (!m_bEditor || bHotUpdate)
  643.                         {
  644.                                 if (!bHotUpdate)
  645.                                         PrintMessage("===== Loading %d brush materials ===== ", nObjectsCount);
  646.  
  647.                                 std::vector<IMaterial*>& rTable = *pMatTable;
  648.                                 rTable.clear();
  649.                                 rTable.resize(nObjectsCount);//PreAllocate(nObjectsCount,nObjectsCount);
  650.  
  651.                                 const uint32 cTableCount = rTable.size();
  652.                                 for (uint32 tableIndex = 0; tableIndex < cTableCount; ++tableIndex)
  653.                                 {
  654.                                         SNameChunk matName;
  655.                                         if (!LoadDataFromFile(&matName, 1, f, nDataSize, eEndian))
  656.                                                 return 0;
  657.                                         CryPathString sMtlName = matName.szFileName;
  658.                                         sMtlName = PathUtil::MakeGamePath(sMtlName);
  659.                                         rTable[tableIndex] = matName.szFileName[0] ? GetMatMan()->LoadMaterial(sMtlName) : NULL;
  660.                                         if (rTable[tableIndex])
  661.                                                 rTable[tableIndex]->AddRef();
  662.  
  663.                                         SLICE_AND_SLEEP();
  664.                                 }
  665.  
  666.                                 // assign real material to vegetation group
  667.                                 PodArray<StatInstGroup>& rStaticTypes = GetObjManager()->m_lstStaticTypes[nSID];
  668.                                 for (uint32 i = 0; i < rStaticTypes.size(); i++)
  669.                                 {
  670.                                         if (lstStatInstGroupChunkFileChunks[i].nMaterialId >= 0)
  671.                                                 rStaticTypes[i].pMaterial = rTable[lstStatInstGroupChunkFileChunks[i].nMaterialId];
  672.                                         else
  673.                                                 rStaticTypes[i].pMaterial = NULL;
  674.                                 }
  675.                         }
  676.                         else
  677.                         {
  678.                                 // skip data
  679.                                 SNameChunk matInfoTmp;
  680.                                 for (int tableIndex = 0; tableIndex < nObjectsCount; ++tableIndex)
  681.                                 {
  682.                                         if (!LoadDataFromFile(&matInfoTmp, 1, f, nDataSize, eEndian))
  683.                                                 return 0;
  684.                                 }
  685.                         }
  686.                 }
  687.         }
  688.  
  689.         // set nodes data
  690.         int nNodesLoaded = 0;
  691.         {
  692.                 LOADING_TIME_PROFILE_SECTION_NAMED("TerrainNodes");
  693.  
  694.                 if (!bHotUpdate)
  695.                         PrintMessage("===== Initializing terrain nodes ===== ");
  696.                 nNodesLoaded = bHMap ? GetParentNode(nSID)->Load(f, nDataSize, eEndian, bSectorPalettes, pExportInfo) : 1;
  697.         }
  698.  
  699.         if (bObjs)
  700.         {
  701.                 if (!bHotUpdate)
  702.                         PrintMessage("===== Loading outdoor instances ===== ");
  703.  
  704.                 LOADING_TIME_PROFILE_SECTION_NAMED("ObjectInstances");
  705.  
  706.                 PodArray<IRenderNode*> arrUnregisteredObjects;
  707.                 Get3DEngine()->m_pObjectsTree[nSID]->UnregisterEngineObjectsInArea(pExportInfo, arrUnregisteredObjects, true);
  708.  
  709.                 // load object instances (in case of editor just check input data do no create object instances)
  710.                 int nOcNodesLoaded = 0;
  711.                 if (NULL != pExportInfo && NULL != pExportInfo->pVisibleLayerMask && NULL != pExportInfo->pLayerIdTranslation)
  712.                 {
  713.                         SLayerVisibility visInfo;
  714.                         visInfo.pLayerIdTranslation = pExportInfo->pLayerIdTranslation;
  715.                         visInfo.pLayerVisibilityMask = pExportInfo->pVisibleLayerMask;
  716.                         nOcNodesLoaded = Get3DEngine()->m_pObjectsTree[nSID]->Load(f, nDataSize, pStatObjTable, pMatTable, eEndian, pBox, &visInfo, vSegmentOrigin);
  717.                 }
  718.                 else
  719.                 {
  720.                         nOcNodesLoaded = Get3DEngine()->m_pObjectsTree[nSID]->Load(f, nDataSize, pStatObjTable, pMatTable, eEndian, pBox, NULL, vSegmentOrigin);
  721.                 }
  722.  
  723.                 for (int i = 0; i < arrUnregisteredObjects.Count(); i++)
  724.                         arrUnregisteredObjects[i]->ReleaseNode();
  725.                 arrUnregisteredObjects.Reset();
  726.         }
  727.  
  728.         if (m_bEditor && !bHotUpdate && !bSW && Get3DEngine()->m_pObjectsTree[nSID])
  729.         {
  730.                 // editor will re-insert all objects
  731.                 AABB aabb = Get3DEngine()->m_pObjectsTree[nSID]->GetNodeBox();
  732.                 delete Get3DEngine()->m_pObjectsTree[nSID];
  733.                 Get3DEngine()->m_pObjectsTree[nSID] = COctreeNode::Create(nSID, aabb, 0);
  734.         }
  735.  
  736.         if (bObjs)
  737.         {
  738.                 LOADING_TIME_PROFILE_SECTION_NAMED("PostObj");
  739.  
  740.                 if (ppStatObjTable)
  741.                         *ppStatObjTable = pStatObjTable;
  742.                 else
  743.                         SAFE_DELETE(pStatObjTable);
  744.  
  745.                 if (ppMatTable)
  746.                         *ppMatTable = pMatTable;
  747.                 else
  748.                         SAFE_DELETE(pMatTable);
  749.         }
  750.  
  751.         if (bHMap)
  752.         {
  753.                 LOADING_TIME_PROFILE_SECTION_NAMED("PostTerrain");
  754.  
  755.                 GetParentNode(nSID)->UpdateRangeInfoShift();
  756.                 ResetTerrainVertBuffers(NULL, nSID);
  757.         }
  758.  
  759.         Get3DEngine()->m_bAreaActivationInUse = (pTerrainChunkHeader->nFlags2 & TCH_FLAG2_AREA_ACTIVATION_IN_USE) != 0;
  760.  
  761.         // delete neighbours corner nodes
  762.         //UpdateSectorMeshes();
  763.  
  764.         ReleaseHeightmapGeometryAroundSegment(nSID);
  765.  
  766.         assert(nNodesLoaded && nDataSize == 0);
  767.         return (nNodesLoaded && nDataSize == 0);
  768. }
  769.  
  770. bool CTerrain::SetCompiledData(byte* pData, int nDataSize, std::vector<struct IStatObj*>** ppStatObjTable, std::vector<IMaterial*>** ppMatTable, bool bHotUpdate, SHotUpdateInfo* pExportInfo, int nSID, Vec3 vSegmentOrigin)
  771. {
  772.         STerrainChunkHeader* pTerrainChunkHeader = (STerrainChunkHeader*)pData;
  773.         SwapEndian(*pTerrainChunkHeader, eLittleEndian);
  774.  
  775.         pData += sizeof(STerrainChunkHeader);
  776.         nDataSize -= sizeof(STerrainChunkHeader);
  777.         return Load_T(pData, nDataSize, pTerrainChunkHeader, ppStatObjTable, ppMatTable, bHotUpdate, pExportInfo, nSID, vSegmentOrigin);
  778. }
  779.  
  780. bool CTerrain::Load(FILE* f, int nDataSize, STerrainChunkHeader* pTerrainChunkHeader, std::vector<struct IStatObj*>** ppStatObjTable, std::vector<IMaterial*>** ppMatTable, int nSID, Vec3 vSegmentOrigin)
  781. {
  782.         bool bRes;
  783.  
  784.         // in case of small data amount (console game) load entire file into memory in single operation
  785.         if (nDataSize < 4 * 1024 * 1024 && !GetCVars()->e_StreamInstances)
  786.         {
  787.                 _smart_ptr<IMemoryBlock> pMemBlock = gEnv->pCryPak->PoolAllocMemoryBlock(nDataSize + 8, "LoadTerrain");
  788.                 byte* pPtr = (byte*)pMemBlock->GetData();
  789.                 while (UINT_PTR(pPtr) & 3)
  790.                         pPtr++;
  791.  
  792.                 if (GetPak()->FReadRaw(pPtr, 1, nDataSize, f) != nDataSize)
  793.                         return false;
  794.  
  795.                 bRes = Load_T(pPtr, nDataSize, pTerrainChunkHeader, ppStatObjTable, ppMatTable, 0, 0, nSID, vSegmentOrigin);
  796.         }
  797.         else
  798.         {
  799.                 // in case of big data files - load data in many small blocks
  800.                 bRes = Load_T(f, nDataSize, pTerrainChunkHeader, ppStatObjTable, ppMatTable, 0, 0, nSID, vSegmentOrigin);
  801.         }
  802.  
  803.         if (GetParentNode(nSID))
  804.         {
  805.                 // reopen texture file if needed, texture pack may be randomly closed by editor so automatic reopening used
  806.                 if (!m_arrBaseTexInfos[nSID].m_nDiffTexIndexTableSize)
  807.                         OpenTerrainTextureFile(m_arrBaseTexInfos[nSID].m_hdrDiffTexHdr, m_arrBaseTexInfos[nSID].m_hdrDiffTexInfo,
  808.                                                COMPILED_TERRAIN_TEXTURE_FILE_NAME, m_arrBaseTexInfos[nSID].m_ucpDiffTexTmpBuffer, m_arrBaseTexInfos[nSID].m_nDiffTexIndexTableSize, nSID);
  809.         }
  810.  
  811.         return bRes;
  812. }
  813.  
  814. //////////////////////////////////////////////////////////////////////
  815. // Segmented World
  816. void CTerrain::GetTables(std::vector<struct IStatObj*>*& pStatObjTable, std::vector<IMaterial*>*& pMatTable, std::vector<struct IStatInstGroup*>*& pStatInstGroupTable, int nSID)
  817. {
  818.         SAFE_DELETE(pStatObjTable);
  819.         SAFE_DELETE(pMatTable);
  820.         SAFE_DELETE(pStatInstGroupTable);
  821.  
  822.         pStatObjTable = new std::vector<struct IStatObj*>;
  823.         pMatTable = new std::vector<struct IMaterial*>;
  824.         pStatInstGroupTable = new std::vector<struct IStatInstGroup*>;
  825.  
  826.         if (m_bEditor)
  827.         {
  828.                 if (nSID < 0 || nSID >= Get3DEngine()->m_pObjectsTree.Count())
  829.                 {
  830.                         return;
  831.                 }
  832.  
  833.                 GetVegetationMaterials(pMatTable);
  834.  
  835.                 Get3DEngine()->m_pObjectsTree[nSID]->GenerateStatObjAndMatTables(pStatObjTable, pMatTable, pStatInstGroupTable, NULL);
  836.                 GetVisAreaManager()->GenerateStatObjAndMatTables(pStatObjTable, pMatTable, pStatInstGroupTable, NULL);
  837.         }
  838.         else
  839.         {
  840.                 if (nSID < 0 || nSID >= (int)m_arrLoadStatuses.size())
  841.                 {
  842.                         return;
  843.                 }
  844.  
  845.                 STerrainDataLoadStatus& status = m_arrLoadStatuses[nSID];
  846.                 for (size_t j = 0; j < status.statObjTable.size(); j++)
  847.                         pStatObjTable->push_back(status.statObjTable[j]);
  848.                 for (size_t k = 0; k < status.matTable.size(); k++)
  849.                         pMatTable->push_back(status.matTable[k]);
  850.         }
  851. }
  852.  
  853. void CTerrain::ReleaseTables(std::vector<struct IStatObj*>*& pStatObjTable, std::vector<IMaterial*>*& pMatTable, std::vector<struct IStatInstGroup*>*& pStatInstGroupTable)
  854. {
  855.         SAFE_DELETE(pStatObjTable);
  856.         SAFE_DELETE(pMatTable);
  857.         SAFE_DELETE(pStatInstGroupTable);
  858. }
  859.  
  860. bool CTerrain::StreamCompiledData(byte* pData, int nDataSize, int nSID, const Vec3& vSegmentOrigin)
  861. {
  862.         //SetCompiledData(pData, nDataSize, 0, 0, false, 0, nSID, vSegmentOrigin);
  863.         //return false;
  864.  
  865.         if (nSID < 0 || nSID >= (int)m_arrLoadStatuses.size())
  866.                 return false;
  867.  
  868.         bool result = true;
  869.  
  870.         //Timer timer;
  871.  
  872.         STerrainDataLoadStatus& status = m_arrLoadStatuses[nSID];
  873.         int step = status.loadingStep;
  874.         switch (step)
  875.         {
  876.         case eTDLS_NotStarted:
  877.                 status.loadingStep = eTDLS_Initialize;
  878.                 break;
  879.         case eTDLS_Initialize:
  880.                 StreamStep_Initialize(status, pData, nDataSize, nSID, vSegmentOrigin);
  881.                 break;
  882.         case eTDLS_BuildSectorsTree:
  883.                 StreamStep_BuildSectorsTree(status, pData, nDataSize, nSID, vSegmentOrigin);
  884.                 break;
  885.         case eTDLS_SetupEntityGrid:
  886.                 StreamStep_SetupEntityGrid(status, pData, nDataSize, nSID, vSegmentOrigin);
  887.                 break;
  888.         case eTDLS_ReadTables:
  889.                 StreamStep_ReadTables(status, pData, nDataSize, nSID, vSegmentOrigin);
  890.                 break;
  891.         case eTDLS_LoadTerrainNodes:
  892.                 StreamStep_LoadTerrainNodes(status, pData, nDataSize, nSID, vSegmentOrigin);
  893.                 break;
  894.         case eTDLS_LoadVegetationStatObjs:
  895.                 StreamStep_LoadVegetationStatObjs(status, pData, nDataSize, nSID, vSegmentOrigin);
  896.                 break;
  897.         case eTDLS_LoadBrushStatObjs:
  898.                 StreamStep_LoadBrushStatObjs(status, pData, nDataSize, nSID, vSegmentOrigin);
  899.                 break;
  900.         case eTDLS_LoadMaterials:
  901.                 StreamStep_LoadMaterials(status, pData, nDataSize, nSID, vSegmentOrigin);
  902.                 break;
  903.         case eTDLS_StartLoadObjectTree:
  904.                 StreamStep_StartLoadObjectTree(status, pData, nDataSize, nSID, vSegmentOrigin);
  905.                 break;
  906.         case eTDLS_LoadObjectTree:
  907.                 StreamStep_LoadObjectTree(status, pData, nDataSize, nSID, vSegmentOrigin);
  908.                 break;
  909.         case eTDLS_FinishUp:
  910.                 StreamStep_FinishUp(status, pData, nDataSize, nSID, vSegmentOrigin);
  911.                 break;
  912.         case eTDLS_Complete:
  913.         case eTDLS_Error:
  914.         default:
  915.                 result = false;
  916.                 break;
  917.         }
  918.         //const char* stepNames[] =
  919.         //{
  920.         //      "eTDLS_NotStarted",
  921.         //      "eTDLS_Initialize",
  922.         //      "eTDLS_BuildSectorsTree",
  923.         //      "eTDLS_SetupEntityGrid",
  924.         //      "eTDLS_ReadTables",
  925.         //      "eTDLS_LoadTerrainNodes",
  926.         //      "eTDLS_LoadVegetationStatObjs",
  927.         //      "eTDLS_LoadBrushStatObjs",
  928.         //      "eTDLS_LoadMaterials",
  929.         //      "eTDLS_StartLoadObjectTree",
  930.         //      "eTDLS_LoadObjectTree",
  931.         //      "eTDLS_FinishUp",
  932.         //      "eTDLS_Complete",
  933.         //      "eTDLS_Error"
  934.         //};
  935.  
  936.         //if (timer.TotalElapsed() > 5)
  937.         //      (void)0;//timer.Dumpf("%s", stepNames[step]);
  938.  
  939.         return result;
  940. }
  941.  
  942. void CTerrain::CancelStreamCompiledData(int nSID)
  943. {
  944. }
  945.  
  946. void CTerrain::StreamStep_Initialize(STerrainDataLoadStatus& status, byte* pData, int nDataSize, int nSID, const Vec3& vSegmentOrigin)
  947. {
  948.         byte* pOrigData = pData;
  949.  
  950.         STerrainChunkHeader* pTerrainChunkHeader = (STerrainChunkHeader*)pData;
  951.         pData += sizeof(STerrainChunkHeader);
  952.         nDataSize -= sizeof(STerrainChunkHeader);
  953.  
  954.         assert(pTerrainChunkHeader->nVersion == TERRAIN_CHUNK_VERSION);
  955.         if (pTerrainChunkHeader->nVersion != TERRAIN_CHUNK_VERSION)
  956.         {
  957.                 Error("CTerrain::SetCompiledData: version of file is %d, expected version is %d", pTerrainChunkHeader->nVersion, (int)TERRAIN_CHUNK_VERSION);
  958.                 status.loadingStep = eTDLS_Error;
  959.                 return;
  960.         }
  961.  
  962.         EEndian eEndian = (pTerrainChunkHeader->nFlags & SERIALIZATION_FLAG_BIG_ENDIAN) ? eBigEndian : eLittleEndian;
  963.         bool bSectorPalettes = (pTerrainChunkHeader->nFlags & SERIALIZATION_FLAG_SECTOR_PALETTES) != 0;
  964.  
  965.         if (pTerrainChunkHeader->nChunkSize != nDataSize + sizeof(STerrainChunkHeader))
  966.         {
  967.                 status.loadingStep = eTDLS_Error;
  968.                 return;
  969.         }
  970.  
  971.         // get terrain settings
  972.         m_nUnitSize = pTerrainChunkHeader->TerrainInfo.nUnitSize_InMeters;
  973.         m_fInvUnitSize = 1.f / m_nUnitSize;
  974.         if (!Get3DEngine()->m_pSegmentsManager)
  975.                 m_nTerrainSize = pTerrainChunkHeader->TerrainInfo.nHeightMapSize_InUnits * pTerrainChunkHeader->TerrainInfo.nUnitSize_InMeters;
  976.  
  977.         m_nTerrainSizeDiv = (m_nTerrainSize >> m_nBitShift) - 1;
  978.         m_nSectorSize = pTerrainChunkHeader->TerrainInfo.nSectorSize_InMeters;
  979.         //m_nSectorsTableSize = pTerrainChunkHeader->TerrainInfo.nSectorsTableSize_InSectors;
  980.         m_fHeightmapZRatio = pTerrainChunkHeader->TerrainInfo.fHeightmapZRatio;
  981.         m_fOceanWaterLevel = pTerrainChunkHeader->TerrainInfo.fOceanWaterLevel ? pTerrainChunkHeader->TerrainInfo.fOceanWaterLevel : WATER_LEVEL_UNKNOWN;
  982.  
  983.         Get3DEngine()->m_bAreaActivationInUse = (pTerrainChunkHeader->nFlags2 & TCH_FLAG2_AREA_ACTIVATION_IN_USE) != 0;
  984.  
  985.         if (Get3DEngine()->IsAreaActivationInUse())
  986.                 PrintMessage("Object layers control in use");
  987.  
  988.         m_nUnitsToSectorBitShift = 0;
  989.         while (m_nSectorSize >> m_nUnitsToSectorBitShift > m_nUnitSize)
  990.                 m_nUnitsToSectorBitShift++;
  991.  
  992.         status.loadingStep = eTDLS_BuildSectorsTree;
  993. }
  994. void CTerrain::StreamStep_BuildSectorsTree(STerrainDataLoadStatus& status, byte* pData, int nDataSize, int nSID, const Vec3& vSegmentOrigin)
  995. {
  996.         if (!m_pParentNodes[nSID])
  997.         {
  998.                 LOADING_TIME_PROFILE_SECTION_NAMED("BuildSectorsTree");
  999.  
  1000.                 m_arrSegmentOrigns[nSID] = vSegmentOrigin;
  1001.  
  1002.                 // build nodes tree in fast way
  1003.                 BuildSectorsTree(false, nSID);
  1004.  
  1005.                 // pass heightmap to the physics
  1006.                 SetMaterialMapping(nSID);
  1007.         }
  1008.  
  1009.         status.loadingStep = eTDLS_ReadTables;
  1010. }
  1011. void CTerrain::StreamStep_SetupEntityGrid(STerrainDataLoadStatus& status, byte* pData, int nDataSize, int nSID, const Vec3& vSegmentOrigin)
  1012. {
  1013.         // setup physics grid
  1014.         if (!m_bEditor && !gEnv->p3DEngine->IsSegmentOperationInProgress())
  1015.         {
  1016.                 LOADING_TIME_PROFILE_SECTION_NAMED("SetupEntityGrid");
  1017.  
  1018.                 int nCellSize = CTerrain::GetTerrainSize() > 2048 ? CTerrain::GetTerrainSize() >> 10 : 2;
  1019.                 nCellSize = max(nCellSize, GetCVars()->e_PhysMinCellSize);
  1020.                 int log2PODGridSize = 0;
  1021.                 if (nCellSize == 2)
  1022.                         log2PODGridSize = 2;
  1023.                 else if (nCellSize == 4)
  1024.                         log2PODGridSize = 1;
  1025.                 GetPhysicalWorld()->SetupEntityGrid(2, Vec3(0, 0, 0), // this call will destroy all physicalized stuff
  1026.                                                     CTerrain::GetTerrainSize() / nCellSize, CTerrain::GetTerrainSize() / nCellSize, (float)nCellSize, (float)nCellSize, log2PODGridSize);
  1027.         }
  1028.  
  1029.         status.loadingStep = eTDLS_ReadTables;
  1030. }
  1031. void CTerrain::StreamStep_ReadTables(STerrainDataLoadStatus& status, byte* pData, int nDataSize, int nSID, const Vec3& vSegmentOrigin)
  1032. {
  1033.         STerrainChunkHeader* pTerrainChunkHeader = (STerrainChunkHeader*)pData;
  1034.         pData += sizeof(STerrainChunkHeader);
  1035.         nDataSize -= sizeof(STerrainChunkHeader);
  1036.         EEndian eEndian = (pTerrainChunkHeader->nFlags & SERIALIZATION_FLAG_BIG_ENDIAN) ? eBigEndian : eLittleEndian;
  1037.  
  1038.         byte* pDataStart = pData;
  1039.  
  1040.         // -- load vegetation table
  1041.         int nObjectsCount = 0;
  1042.         if (!LoadDataFromFile(&nObjectsCount, 1, pData, nDataSize, eEndian))
  1043.         {
  1044.                 status.loadingStep = eTDLS_Error;
  1045.                 return;
  1046.         }
  1047.  
  1048.         status.lstVegetation.PreAllocate(nObjectsCount, nObjectsCount);
  1049.         if (!LoadDataFromFile(status.lstVegetation.GetElements(), status.lstVegetation.Count(), pData, nDataSize, eEndian))
  1050.         {
  1051.                 status.loadingStep = eTDLS_Error;
  1052.                 return;
  1053.         }
  1054.         if (nObjectsCount)
  1055.                 GetObjManager()->m_lstStaticTypes[nSID].resize(nObjectsCount);
  1056.  
  1057.         status.vegetationIndex = 0;
  1058.  
  1059.         // -- load brushes table
  1060.         if (!LoadDataFromFile(&nObjectsCount, 1, pData, nDataSize, eEndian))
  1061.         {
  1062.                 status.loadingStep = eTDLS_Error;
  1063.                 return;
  1064.         }
  1065.  
  1066.         status.lstBrushes.PreAllocate(nObjectsCount, nObjectsCount);
  1067.         if (!LoadDataFromFile(status.lstBrushes.GetElements(), status.lstBrushes.Count(), pData, nDataSize, eEndian))
  1068.         {
  1069.                 status.loadingStep = eTDLS_Error;
  1070.                 return;
  1071.         }
  1072.         if (nObjectsCount)
  1073.                 status.statObjTable.resize(nObjectsCount);
  1074.  
  1075.         status.brushesIndex = 0;
  1076.  
  1077.         // -- load materials table
  1078.         if (!LoadDataFromFile(&nObjectsCount, 1, pData, nDataSize, eEndian))
  1079.         {
  1080.                 status.loadingStep = eTDLS_Error;
  1081.                 return;
  1082.         }
  1083.  
  1084.         status.lstMaterials.PreAllocate(nObjectsCount, nObjectsCount);
  1085.         if (!LoadDataFromFile(status.lstMaterials.GetElements(), status.lstMaterials.Count(), pData, nDataSize, eEndian))
  1086.         {
  1087.                 status.loadingStep = eTDLS_Error;
  1088.                 return;
  1089.         }
  1090.         if (nObjectsCount)
  1091.                 status.matTable.resize(nObjectsCount);
  1092.  
  1093.         status.materialsIndex = 0;
  1094.  
  1095.         status.loadingStep = eTDLS_LoadTerrainNodes;
  1096.         status.offset = pData - pDataStart;
  1097. }
  1098. void CTerrain::StreamStep_LoadTerrainNodes(STerrainDataLoadStatus& status, byte* pData, int nDataSize, int nSID, const Vec3& vSegmentOrigin)
  1099. {
  1100.         STerrainChunkHeader* pTerrainChunkHeader = (STerrainChunkHeader*)pData;
  1101.         pData += sizeof(STerrainChunkHeader);
  1102.         nDataSize -= sizeof(STerrainChunkHeader);
  1103.         EEndian eEndian = (pTerrainChunkHeader->nFlags & SERIALIZATION_FLAG_BIG_ENDIAN) ? eBigEndian : eLittleEndian;
  1104.         bool bSectorPalettes = (pTerrainChunkHeader->nFlags & SERIALIZATION_FLAG_SECTOR_PALETTES) != 0;
  1105.  
  1106.         byte* pDataStart = pData;
  1107.         pData += status.offset;
  1108.  
  1109.         ReleaseHeightmapGeometryAroundSegment(nSID);
  1110.  
  1111.         GetParentNode(nSID)->Load(pData, nDataSize, eEndian, bSectorPalettes, 0);
  1112.         GetParentNode(nSID)->UpdateRangeInfoShift();
  1113.         ResetTerrainVertBuffers(NULL, nSID);
  1114.  
  1115.         status.offset = pData - pDataStart;
  1116.         status.loadingStep = eTDLS_LoadVegetationStatObjs;
  1117. }
  1118. void CTerrain::StreamStep_LoadVegetationStatObjs(STerrainDataLoadStatus& status, byte* pData, int nDataSize, int nSID, const Vec3& vSegmentOrigin)
  1119. {
  1120.         if (status.vegetationIndex >= status.lstVegetation.Count())
  1121.         {
  1122.                 status.loadingStep = eTDLS_LoadBrushStatObjs;
  1123.                 return;
  1124.         }
  1125.  
  1126.         int i = status.vegetationIndex;
  1127.         PodArray<StatInstGroup>& rTable = GetObjManager()->m_lstStaticTypes[nSID];
  1128.  
  1129.         LoadVegetationData(rTable, status.lstVegetation, i);
  1130.  
  1131.         ++status.vegetationIndex;
  1132. }
  1133. void CTerrain::StreamStep_LoadBrushStatObjs(STerrainDataLoadStatus& status, byte* pData, int nDataSize, int nSID, const Vec3& vSegmentOrigin)
  1134. {
  1135.         if (status.brushesIndex >= status.lstBrushes.Count())
  1136.         {
  1137.                 status.loadingStep = eTDLS_LoadMaterials;
  1138.                 return;
  1139.         }
  1140.  
  1141.         if (status.lstBrushes[status.brushesIndex].szFileName[0])
  1142.                 status.statObjTable[status.brushesIndex] = GetObjManager()->LoadStatObj(status.lstBrushes[status.brushesIndex].szFileName, NULL, NULL, true, 0, 0, 0, m_arrSegmentPaths[nSID]);
  1143.         ++status.brushesIndex;
  1144. }
  1145. void CTerrain::StreamStep_LoadMaterials(STerrainDataLoadStatus& status, byte* pData, int nDataSize, int nSID, const Vec3& vSegmentOrigin)
  1146. {
  1147.         if (status.materialsIndex >= status.lstMaterials.Count())
  1148.         {
  1149.                 status.loadingStep = eTDLS_StartLoadObjectTree;
  1150.                 return;
  1151.         }
  1152.  
  1153.         SNameChunk& matName = status.lstMaterials[status.materialsIndex];
  1154.         status.matTable[status.materialsIndex] = matName.szFileName[0] ? GetMatMan()->LoadMaterial(matName.szFileName) : NULL;
  1155.         if (status.matTable[status.materialsIndex])
  1156.                 status.matTable[status.materialsIndex]->AddRef();
  1157.         ++status.materialsIndex;
  1158.  
  1159.         if (status.materialsIndex >= status.lstMaterials.Count())
  1160.         {
  1161.                 // assign real material to vegetation group
  1162.                 PodArray<StatInstGroup>& rStaticTypes = GetObjManager()->m_lstStaticTypes[nSID];
  1163.                 for (uint32 i = 0; i < rStaticTypes.size(); i++)
  1164.                 {
  1165.                         if (status.lstVegetation[i].nMaterialId >= 0)
  1166.                                 rStaticTypes[i].pMaterial = status.matTable[status.lstVegetation[i].nMaterialId];
  1167.                         else
  1168.                                 rStaticTypes[i].pMaterial = NULL;
  1169.                 }
  1170.         }
  1171. }
  1172. void CTerrain::StreamStep_StartLoadObjectTree(STerrainDataLoadStatus& status, byte* pData, int nDataSize, int nSID, const Vec3& vSegmentOrigin)
  1173. {
  1174.         Get3DEngine()->m_pObjectsTree[nSID]->UnregisterEngineObjectsInArea(0, status.arrUnregisteredObjects, true);
  1175.         status.loadingStep = eTDLS_LoadObjectTree;
  1176. }
  1177.  
  1178. void CTerrain::StreamStep_LoadObjectTree(STerrainDataLoadStatus& status, byte* pData, int nDataSize, int nSID, const Vec3& vSegmentOrigin)
  1179. {
  1180.         STerrainChunkHeader* pTerrainChunkHeader = (STerrainChunkHeader*)pData;
  1181.         pData += sizeof(STerrainChunkHeader);
  1182.         nDataSize -= sizeof(STerrainChunkHeader);
  1183.         EEndian eEndian = (pTerrainChunkHeader->nFlags & SERIALIZATION_FLAG_BIG_ENDIAN) ? eBigEndian : eLittleEndian;
  1184.         bool bSectorPalettes = (pTerrainChunkHeader->nFlags & SERIALIZATION_FLAG_SECTOR_PALETTES) != 0;
  1185.  
  1186.         byte* pDataStart = pData;
  1187.         pData += status.offset;
  1188.  
  1189.         // load object instances (in case of editor just check input data do no create object instances)
  1190.         bool stillStreaming = Get3DEngine()->m_pObjectsTree[nSID]->StreamLoad(pData, nDataSize, &status.statObjTable, &status.matTable, eEndian, 0);
  1191.  
  1192.         if (!stillStreaming)
  1193.         {
  1194.                 for (int i = 0; i < status.arrUnregisteredObjects.Count(); i++)
  1195.                         status.arrUnregisteredObjects[i]->ReleaseNode();
  1196.                 status.arrUnregisteredObjects.Reset();
  1197.  
  1198.                 for (int i = 0; i < (int)status.matTable.size(); ++i)
  1199.                         if (status.matTable[i])
  1200.                                 status.matTable[i]->Release();
  1201.  
  1202.                 status.loadingStep = eTDLS_FinishUp;
  1203.         }
  1204. }
  1205. void CTerrain::StreamStep_FinishUp(STerrainDataLoadStatus& status, byte* pData, int nDataSize, int nSID, const Vec3& vSegmentOrigin)
  1206. {
  1207.         if (GetParentNode(nSID))
  1208.         {
  1209.                 // reopen texture file if needed, texture pack may be randomly closed by editor so automatic reopening used
  1210.                 if (!m_arrBaseTexInfos[nSID].m_nDiffTexIndexTableSize)
  1211.                         OpenTerrainTextureFile(m_arrBaseTexInfos[nSID].m_hdrDiffTexHdr, m_arrBaseTexInfos[nSID].m_hdrDiffTexInfo,
  1212.                                                m_arrSegmentPaths[nSID] + COMPILED_TERRAIN_TEXTURE_FILE_NAME, m_arrBaseTexInfos[nSID].m_ucpDiffTexTmpBuffer, m_arrBaseTexInfos[nSID].m_nDiffTexIndexTableSize, nSID);
  1213.         }
  1214.  
  1215.         status.Clear();
  1216.         status.loadingStep = eTDLS_Complete;
  1217. }
  1218.  
  1219. #include <CryCore/TypeInfo_impl.h>
  1220. #include "terrain_compile_info.h"
  1221.  
downloadterrain_compile.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top