BVB Source Codes

CRYENGINE Show GeomCache.cpp Source code

Return Download CRYENGINE: download GeomCache.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:   GeomCache.cpp
  5. //  Created:     19/7/2012 by Axel Gneiting
  6. //  Description: Manages geometry cache data
  7. // -------------------------------------------------------------------------
  8. ////////////////////////////////////////////////////////////////////////////
  9.  
  10. #include "StdAfx.h"
  11.  
  12. #if defined(USE_GEOM_CACHES)
  13.  
  14.         #include "GeomCache.h"
  15.         #include "GeomCacheManager.h"
  16.         #include "GeomCacheDecoder.h"
  17.         #include <CryString/StringUtils.h>
  18.         #include "MatMan.h"
  19.  
  20. CGeomCache::CGeomCache(const char* pFileName)
  21.         : m_bValid(false)
  22.         , m_bLoaded(false)
  23.         , m_refCount(0)
  24.         , m_fileName(pFileName)
  25.         , m_lastDrawMainFrameId(0)
  26.         , m_bPlaybackFromMemory(false)
  27.         , m_numFrames(0)
  28.         , m_compressedAnimationDataSize(0)
  29.         , m_totalUncompressedAnimationSize(0)
  30.         , m_numStreams(0)
  31.         , m_staticMeshDataOffset(0)
  32.         , m_aabb(0.0f)
  33. {
  34.         m_bUseStreaming = GetCVars()->e_StreamCgf > 0;
  35.         m_staticDataHeader.m_compressedSize = 0;
  36.         m_staticDataHeader.m_uncompressedSize = 0;
  37.  
  38.         string materialPath = PathUtil::ReplaceExtension(m_fileName, "mtl");
  39.         m_pMaterial = GetMatMan()->LoadMaterial(materialPath);
  40.  
  41.         if (!LoadGeomCache())
  42.         {
  43.                 FileWarning(0, m_fileName.c_str(), "Failed to load geometry cache: %s", m_lastError.c_str());
  44.                 stl::free_container(m_lastError);
  45.         }
  46. }
  47.  
  48. CGeomCache::~CGeomCache()
  49. {
  50.         Shutdown();
  51. }
  52.  
  53. int CGeomCache::AddRef()
  54. {
  55.         ++m_refCount;
  56.         return m_refCount;
  57. }
  58.  
  59. int CGeomCache::Release()
  60. {
  61.         assert(m_refCount >= 0);
  62.  
  63.         --m_refCount;
  64.         int refCount = m_refCount;
  65.         if (m_refCount <= 0)
  66.         {
  67.                 GetGeomCacheManager()->DeleteGeomCache(this);
  68.         }
  69.  
  70.         return refCount;
  71. }
  72.  
  73. void CGeomCache::SetMaterial(IMaterial* pMaterial)
  74. {
  75.         m_pMaterial = pMaterial;
  76. }
  77.  
  78. _smart_ptr<IMaterial> CGeomCache::GetMaterial()
  79. {
  80.         return m_pMaterial;
  81. }
  82.  
  83. const _smart_ptr<IMaterial> CGeomCache::GetMaterial() const
  84. {
  85.         return m_pMaterial;
  86. }
  87.  
  88. const char* CGeomCache::GetFilePath() const
  89. {
  90.         return m_fileName;
  91. }
  92.  
  93. class CScopedFileHandle
  94. {
  95. public:
  96.         CScopedFileHandle(const string& fileName, const char* mode)
  97.         {
  98.                 m_pHandle = gEnv->pCryPak->FOpen(fileName, mode);
  99.         }
  100.  
  101.         ~CScopedFileHandle()
  102.         {
  103.                 if (m_pHandle)
  104.                 {
  105.                         gEnv->pCryPak->FClose(m_pHandle);
  106.                 }
  107.         }
  108.  
  109.         operator FILE*()
  110.         {
  111.                 return m_pHandle;
  112.         }
  113.  
  114.         bool IsValid() const
  115.         {
  116.                 return m_pHandle != NULL;
  117.         }
  118.  
  119. private:
  120.         FILE* m_pHandle;
  121. };
  122.  
  123. bool CGeomCache::LoadGeomCache()
  124. {
  125.         using namespace GeomCacheFile;
  126.  
  127.         FUNCTION_PROFILER_3DENGINE;
  128.  
  129.         CRY_DEFINE_ASSET_SCOPE("GeomCache", m_fileName);
  130.  
  131.         #if INCLUDE_MEMSTAT_CONTEXTS
  132.         MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_GeomCache, EMemStatContextFlags::MSF_Instance, "%s", m_fileName.c_str());
  133.         #endif
  134.  
  135.         CScopedFileHandle geomCacheFileHandle(m_fileName, "rb");
  136.         if (!geomCacheFileHandle.IsValid())
  137.         {
  138.                 return false;
  139.         }
  140.  
  141.         size_t bytesRead = 0;
  142.  
  143.         // Read header and check signature
  144.         SHeader header;
  145.         bytesRead = gEnv->pCryPak->FReadRaw((void*)&header, 1, sizeof(SHeader), geomCacheFileHandle);
  146.         if (bytesRead != sizeof(SHeader))
  147.         {
  148.                 m_lastError = "Could not read header";
  149.                 return false;
  150.         }
  151.  
  152.         if (header.m_signature != kFileSignature)
  153.         {
  154.                 m_lastError = "Bad file signature";
  155.                 return false;
  156.         }
  157.  
  158.         if (header.m_version != kCurrentVersion)
  159.         {
  160.                 m_lastError = "Bad file version";
  161.                 return false;
  162.         }
  163.  
  164.         const bool bFileHas32BitIndexFormat = (header.m_flags & eFileHeaderFlags_32BitIndices) != 0;
  165.         if (((sizeof(vtx_idx) == sizeof(uint16)) && bFileHas32BitIndexFormat) || ((sizeof(vtx_idx) == sizeof(uint32)) && !bFileHas32BitIndexFormat))
  166.         {
  167.                 m_lastError = "Index format mismatch";
  168.                 return false;
  169.         }
  170.  
  171.         if (header.m_blockCompressionFormat != eBlockCompressionFormat_None &&
  172.             header.m_blockCompressionFormat != eBlockCompressionFormat_Deflate &&
  173.             header.m_blockCompressionFormat != eBlockCompressionFormat_LZ4HC)
  174.         {
  175.                 m_lastError = "Bad block compression format";
  176.                 return false;
  177.         }
  178.  
  179.         m_bPlaybackFromMemory = (header.m_flags & GeomCacheFile::eFileHeaderFlags_PlaybackFromMemory) != 0;
  180.         m_blockCompressionFormat = static_cast<EBlockCompressionFormat>(header.m_blockCompressionFormat);
  181.         m_totalUncompressedAnimationSize = header.m_totalUncompressedAnimationSize;
  182.         m_numFrames = header.m_numFrames;
  183.         m_aabb.min = Vec3(header.m_aabbMin[0], header.m_aabbMin[1], header.m_aabbMin[2]);
  184.         m_aabb.max = Vec3(header.m_aabbMax[0], header.m_aabbMax[1], header.m_aabbMax[2]);
  185.  
  186.         // Read frame times and frame offsets.
  187.         if (!ReadFrameInfos(geomCacheFileHandle, header.m_numFrames))
  188.         {
  189.                 return false;
  190.         }
  191.  
  192.         const int maxPlaybackFromMemorySize = std::max(0, GetCVars()->e_GeomCacheMaxPlaybackFromMemorySize);
  193.         if (m_bPlaybackFromMemory && m_compressedAnimationDataSize > uint(maxPlaybackFromMemorySize * 1024 * 1024))
  194.         {
  195.                 GetLog()->LogWarning("Animated data size of geometry cache '%s' is over memory playback limit "
  196.                                      "of %d MiB. Reverting to stream playback.", m_fileName.c_str(), maxPlaybackFromMemorySize);
  197.                 m_bPlaybackFromMemory = false;
  198.         }
  199.  
  200.         // Load static node data and physics geometries
  201.         {
  202.                 std::vector<char> compressedData;
  203.                 std::vector<char> decompressedData;
  204.  
  205.                 if (!ReadStaticBlock(geomCacheFileHandle, (EBlockCompressionFormat)(header.m_blockCompressionFormat), compressedData)
  206.                     || !DecompressStaticBlock((EBlockCompressionFormat)(header.m_blockCompressionFormat), &compressedData[0], decompressedData))
  207.                 {
  208.                         if (m_lastError.empty())
  209.                         {
  210.                                 m_lastError = "Could not read or decompress static block";
  211.                         }
  212.  
  213.                         return false;
  214.                 }
  215.  
  216.                 CGeomCacheStreamReader reader(&decompressedData[0], decompressedData.size());
  217.                 if (!ReadNodesStaticDataRec(reader))
  218.                 {
  219.                         if (m_lastError.empty())
  220.                         {
  221.                                 m_lastError = "Could not read node static data";
  222.                         }
  223.  
  224.                         return false;
  225.                 }
  226.         }
  227.  
  228.         m_staticMeshDataOffset = gEnv->pCryPak->FTell(geomCacheFileHandle);
  229.  
  230.         if (!m_bUseStreaming)
  231.         {
  232.                 std::vector<char> compressedData;
  233.                 std::vector<char> decompressedData;
  234.  
  235.                 if (!ReadStaticBlock(geomCacheFileHandle, (EBlockCompressionFormat)(header.m_blockCompressionFormat), compressedData)
  236.                     || !DecompressStaticBlock((EBlockCompressionFormat)(header.m_blockCompressionFormat), &compressedData[0], decompressedData))
  237.                 {
  238.                         if (m_lastError.empty())
  239.                         {
  240.                                 m_lastError = "Could not read or decompress static block";
  241.                         }
  242.  
  243.                         return false;
  244.                 }
  245.  
  246.                 CGeomCacheStreamReader reader(&decompressedData[0], decompressedData.size());
  247.                 if (!ReadMeshesStaticData(reader, m_fileName.c_str()))
  248.                 {
  249.                         if (m_lastError.empty())
  250.                         {
  251.                                 m_lastError = "Could not read mesh static data";
  252.                         }
  253.  
  254.                         return false;
  255.                 }
  256.  
  257.                 if (m_bPlaybackFromMemory && m_frameInfos.size() > 0)
  258.                 {
  259.                         std::vector<char> animationData;
  260.                         animationData.resize(static_cast<size_t>(m_compressedAnimationDataSize));
  261.                         bytesRead = gEnv->pCryPak->FReadRaw((void*)&animationData[0], 1, static_cast<uint>(m_compressedAnimationDataSize), geomCacheFileHandle);
  262.  
  263.                         if (!LoadAnimatedData(&animationData[0], 0))
  264.                         {
  265.                                 return false;
  266.                         }
  267.                 }
  268.  
  269.                 m_bLoaded = true;
  270.         }
  271.         else
  272.         {
  273.                 bytesRead = gEnv->pCryPak->FReadRaw((void*)&m_staticDataHeader, 1, sizeof(GeomCacheFile::SCompressedBlockHeader), geomCacheFileHandle);
  274.                 if (bytesRead != sizeof(GeomCacheFile::SCompressedBlockHeader))
  275.                 {
  276.                         m_lastError = "Bad data";
  277.                         return false;
  278.                 }
  279.         }
  280.  
  281.         m_bValid = true;
  282.         return true;
  283. }
  284.  
  285. bool CGeomCache::ReadStaticBlock(FILE* pFile, GeomCacheFile::EBlockCompressionFormat compressionFormat, std::vector<char>& compressedData)
  286. {
  287.         compressedData.resize(sizeof(GeomCacheFile::SCompressedBlockHeader));
  288.  
  289.         size_t bytesRead = 0;
  290.         bytesRead = gEnv->pCryPak->FReadRaw((void*)&compressedData[0], 1, sizeof(GeomCacheFile::SCompressedBlockHeader), pFile);
  291.         if (bytesRead != sizeof(GeomCacheFile::SCompressedBlockHeader))
  292.         {
  293.                 return false;
  294.         }
  295.  
  296.         m_staticDataHeader = *reinterpret_cast<GeomCacheFile::SCompressedBlockHeader*>(&compressedData[0]);
  297.         compressedData.resize(sizeof(GeomCacheFile::SCompressedBlockHeader) + m_staticDataHeader.m_compressedSize);
  298.  
  299.         bytesRead = gEnv->pCryPak->FReadRaw(&compressedData[sizeof(GeomCacheFile::SCompressedBlockHeader)], 1, m_staticDataHeader.m_compressedSize, pFile);
  300.         if (bytesRead != m_staticDataHeader.m_compressedSize)
  301.         {
  302.                 return false;
  303.         }
  304.  
  305.         return true;
  306. }
  307.  
  308. bool CGeomCache::DecompressStaticBlock(GeomCacheFile::EBlockCompressionFormat compressionFormat, const char* pCompressedData, std::vector<char>& decompressedData)
  309. {
  310.         const GeomCacheFile::SCompressedBlockHeader staticBlockHeader = *reinterpret_cast<const GeomCacheFile::SCompressedBlockHeader*>(pCompressedData);
  311.         decompressedData.resize(staticBlockHeader.m_uncompressedSize);
  312.  
  313.         if (!GeomCacheDecoder::DecompressBlock(compressionFormat, &decompressedData[0], pCompressedData))
  314.         {
  315.                 m_lastError = "Could not decompress static data";
  316.                 return false;
  317.         }
  318.  
  319.         return true;
  320. }
  321.  
  322. bool CGeomCache::ReadFrameInfos(FILE* pFile, const uint32 numFrames)
  323. {
  324.         FUNCTION_PROFILER_3DENGINE;
  325.  
  326.         size_t bytesRead;
  327.  
  328.         std::vector<GeomCacheFile::SFrameInfo> fileFrameInfos;
  329.  
  330.         fileFrameInfos.resize(numFrames);
  331.         bytesRead = gEnv->pCryPak->FReadRaw((void*)&fileFrameInfos[0], 1, numFrames * sizeof(GeomCacheFile::SFrameInfo), pFile);
  332.         if (bytesRead != (numFrames * sizeof(GeomCacheFile::SFrameInfo)))
  333.         {
  334.                 return false;
  335.         }
  336.  
  337.         m_frameInfos.resize(numFrames);
  338.         for (uint i = 0; i < numFrames; ++i)
  339.         {
  340.                 m_frameInfos[i].m_frameTime = fileFrameInfos[i].m_frameTime;
  341.                 m_frameInfos[i].m_frameType = fileFrameInfos[i].m_frameType;
  342.                 m_frameInfos[i].m_frameSize = fileFrameInfos[i].m_frameSize;
  343.                 m_frameInfos[i].m_frameOffset = fileFrameInfos[i].m_frameOffset;
  344.                 m_compressedAnimationDataSize += m_frameInfos[i].m_frameSize;
  345.         }
  346.  
  347.         if (m_frameInfos.front().m_frameType != GeomCacheFile::eFrameType_IFrame
  348.             || m_frameInfos.back().m_frameType != GeomCacheFile::eFrameType_IFrame)
  349.         {
  350.                 return false;
  351.         }
  352.  
  353.         // Assign prev/next index frames and count total data size
  354.         uint prevIFrame = 0;
  355.         for (uint i = 0; i < numFrames; ++i)
  356.         {
  357.                 m_frameInfos[i].m_prevIFrame = prevIFrame;
  358.  
  359.                 if (m_frameInfos[i].m_frameType == GeomCacheFile::eFrameType_IFrame)
  360.                 {
  361.                         prevIFrame = i;
  362.                 }
  363.         }
  364.  
  365.         uint nextIFrame = numFrames - 1;
  366.         for (int i = numFrames - 1; i >= 0; --i)
  367.         {
  368.                 m_frameInfos[i].m_nextIFrame = nextIFrame;
  369.  
  370.                 if (m_frameInfos[i].m_frameType == GeomCacheFile::eFrameType_IFrame)
  371.                 {
  372.                         nextIFrame = i;
  373.                 }
  374.         }
  375.  
  376.         return true;
  377. }
  378.  
  379. bool CGeomCache::ReadMeshesStaticData(CGeomCacheStreamReader& reader, const char* pFileName)
  380. {
  381.         FUNCTION_PROFILER_3DENGINE;
  382.  
  383.         uint32 numMeshes;
  384.         if (!reader.Read(&numMeshes))
  385.         {
  386.                 return false;
  387.         }
  388.  
  389.         std::vector<GeomCacheFile::SMeshInfo> meshInfos;
  390.         meshInfos.reserve(numMeshes);
  391.  
  392.         for (uint32 i = 0; i < numMeshes; ++i)
  393.         {
  394.                 GeomCacheFile::SMeshInfo meshInfo;
  395.                 m_staticMeshData.push_back(SGeomCacheStaticMeshData());
  396.                 SGeomCacheStaticMeshData& staticMeshData = m_staticMeshData.back();
  397.  
  398.                 if (!reader.Read(&meshInfo))
  399.                 {
  400.                         return false;
  401.                 }
  402.  
  403.                 staticMeshData.m_bUsePredictor = (meshInfo.m_flags & GeomCacheFile::eMeshIFrameFlags_UsePredictor) != 0;
  404.                 staticMeshData.m_positionPrecision[0] = meshInfo.m_positionPrecision[0];
  405.                 staticMeshData.m_positionPrecision[1] = meshInfo.m_positionPrecision[1];
  406.                 staticMeshData.m_positionPrecision[2] = meshInfo.m_positionPrecision[2];
  407.                 staticMeshData.m_constantStreams = static_cast<GeomCacheFile::EStreams>(meshInfo.m_constantStreams);
  408.                 staticMeshData.m_animatedStreams = static_cast<GeomCacheFile::EStreams>(meshInfo.m_animatedStreams);
  409.                 staticMeshData.m_numVertices = meshInfo.m_numVertices;
  410.                 staticMeshData.m_aabb.min = Vec3(meshInfo.m_aabbMin[0], meshInfo.m_aabbMin[1], meshInfo.m_aabbMin[2]);
  411.                 staticMeshData.m_aabb.max = Vec3(meshInfo.m_aabbMax[0], meshInfo.m_aabbMax[1], meshInfo.m_aabbMax[2]);
  412.                 staticMeshData.m_hash = meshInfo.m_hash;
  413.  
  414.                 std::vector<char> tempName(meshInfo.m_nameLength);
  415.                 if (!reader.Read(&tempName[0], meshInfo.m_nameLength))
  416.                 {
  417.                         return false;
  418.                 }
  419.  
  420.                 if (gEnv->IsEditor())
  421.                 {
  422.                         staticMeshData.m_name = &tempName[0];
  423.                 }
  424.  
  425.                 // Read material IDs
  426.                 staticMeshData.m_materialIds.resize(meshInfo.m_numMaterials);
  427.  
  428.                 if (!reader.Read(&staticMeshData.m_materialIds[0], meshInfo.m_numMaterials))
  429.                 {
  430.                         return false;
  431.                 }
  432.  
  433.                 meshInfos.push_back(meshInfo);
  434.         }
  435.  
  436.         m_staticMeshData.reserve(numMeshes);
  437.         for (uint32 i = 0; i < numMeshes; ++i)
  438.         {
  439.                 if (!ReadMeshStaticData(reader, meshInfos[i], m_staticMeshData[i], pFileName))
  440.                 {
  441.                         return false;
  442.                 }
  443.         }
  444.  
  445.         return true;
  446. }
  447.  
  448. bool CGeomCache::ReadMeshStaticData(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo,
  449.                                     SGeomCacheStaticMeshData& staticMeshData, const char* pFileName)
  450. {
  451.         CGeomCacheMeshManager& meshManager = GetGeomCacheManager()->GetMeshManager();
  452.  
  453.         if (meshInfo.m_animatedStreams == 0)
  454.         {
  455.                 // If we don't need the static data to fill dynamic meshes, just construct a static mesh
  456.                 _smart_ptr<IRenderMesh> pRenderMesh = meshManager.ConstructStaticRenderMesh(reader, meshInfo, staticMeshData, pFileName);
  457.  
  458.                 if (!pRenderMesh)
  459.                 {
  460.                         return false;
  461.                 }
  462.  
  463.                 m_staticRenderMeshes.push_back(pRenderMesh);
  464.         }
  465.         else
  466.         {
  467.                 // Otherwise we need the static data for filling the dynamic mesh later and read it to the vertex array in staticMeshData
  468.                 if (!meshManager.ReadMeshStaticData(reader, meshInfo, staticMeshData))
  469.                 {
  470.                         return false;
  471.                 }
  472.         }
  473.  
  474.         return true;
  475. }
  476.  
  477. bool CGeomCache::ReadNodesStaticDataRec(CGeomCacheStreamReader& reader)
  478. {
  479.         FUNCTION_PROFILER_3DENGINE;
  480.  
  481.         GeomCacheFile::SNodeInfo nodeInfo;
  482.         if (!reader.Read(&nodeInfo))
  483.         {
  484.                 return false;
  485.         }
  486.  
  487.         SGeomCacheStaticNodeData staticNodeData;
  488.         staticNodeData.m_meshOrGeometryIndex = nodeInfo.m_meshIndex;
  489.         staticNodeData.m_numChildren = nodeInfo.m_numChildren;
  490.         staticNodeData.m_type = static_cast<GeomCacheFile::ENodeType>(nodeInfo.m_type);
  491.         staticNodeData.m_transformType = static_cast<GeomCacheFile::ETransformType>(nodeInfo.m_transformType);
  492.  
  493.         std::vector<char> tempName(nodeInfo.m_nameLength);
  494.         if (!reader.Read(&tempName[0], nodeInfo.m_nameLength))
  495.         {
  496.                 return false;
  497.         }
  498.  
  499.         if (gEnv->IsEditor())
  500.         {
  501.                 staticNodeData.m_name = &tempName[0];
  502.         }
  503.  
  504.         staticNodeData.m_nameHash = CryStringUtils::HashString(&tempName[0]);
  505.  
  506.         if (!reader.Read(&staticNodeData.m_localTransform))
  507.         {
  508.                 return false;
  509.         }
  510.  
  511.         if (staticNodeData.m_type == GeomCacheFile::eNodeType_PhysicsGeometry)
  512.         {
  513.                 uint32 geometrySize;
  514.                 if (!reader.Read(&geometrySize))
  515.                 {
  516.                         return false;
  517.                 }
  518.  
  519.                 std::vector<char> geometryData(geometrySize);
  520.                 if (!reader.Read(&geometryData[0], geometrySize))
  521.                 {
  522.                         return false;
  523.                 }
  524.  
  525.                 CMemStream memStream(&geometryData[0], geometrySize, false);
  526.                 phys_geometry* pGeometry = GetPhysicalWorld()->GetGeomManager()->LoadPhysGeometry(memStream, 0, 0, 0);
  527.                 m_physicsGeometries.push_back(pGeometry);
  528.  
  529.                 staticNodeData.m_meshOrGeometryIndex = (uint32)(m_physicsGeometries.size() - 1);
  530.         }
  531.  
  532.         m_staticNodeData.push_back(staticNodeData);
  533.  
  534.         for (uint32 i = 0; i < nodeInfo.m_numChildren; ++i)
  535.         {
  536.                 if (!ReadNodesStaticDataRec(reader))
  537.                 {
  538.                         return false;
  539.                 }
  540.         }
  541.  
  542.         return true;
  543. }
  544.  
  545. float CGeomCache::GetDuration() const
  546. {
  547.         if (m_frameInfos.empty())
  548.         {
  549.                 return 0.0f;
  550.         }
  551.         else
  552.         {
  553.                 return m_frameInfos.back().m_frameTime - m_frameInfos.front().m_frameTime;
  554.         }
  555. }
  556.  
  557. IGeomCache::SStatistics CGeomCache::GetStatistics() const
  558. {
  559.         IGeomCache::SStatistics stats;
  560.         memset(&stats, 0, sizeof(stats));
  561.  
  562.         std::set<uint16> materialIds;
  563.  
  564.         CGeomCacheMeshManager& meshManager = GetGeomCacheManager()->GetMeshManager();
  565.  
  566.         const uint numMeshes = m_staticMeshData.size();
  567.         for (uint i = 0; i < numMeshes; ++i)
  568.         {
  569.                 const SGeomCacheStaticMeshData& meshData = m_staticMeshData[i];
  570.                 materialIds.insert(meshData.m_materialIds.begin(), meshData.m_materialIds.end());
  571.  
  572.                 stats.m_staticDataSize += static_cast<uint>(sizeof(SGeomCacheStaticMeshData));
  573.                 stats.m_staticDataSize += static_cast<uint>(sizeof(vtx_idx) * meshData.m_indices.size());
  574.                 stats.m_staticDataSize += static_cast<uint>(sizeof(uint32) * meshData.m_numIndices.size());
  575.                 stats.m_staticDataSize += static_cast<uint>(sizeof(Vec3) * meshData.m_positions.size());
  576.                 stats.m_staticDataSize += static_cast<uint>(sizeof(UCol) * meshData.m_colors.size());
  577.                 stats.m_staticDataSize += static_cast<uint>(sizeof(Vec2) * meshData.m_texcoords.size());
  578.                 stats.m_staticDataSize += static_cast<uint>(sizeof(SPipTangents) * meshData.m_tangents.size());
  579.                 stats.m_staticDataSize += static_cast<uint>(sizeof(uint16) * meshData.m_materialIds.size());
  580.                 stats.m_staticDataSize += static_cast<uint>(sizeof(uint16) * meshData.m_predictorData.size());
  581.  
  582.                 uint numIndices = 0;
  583.                 const uint numMaterials = meshData.m_numIndices.size();
  584.                 for (uint j = 0; j < numMaterials; ++j)
  585.                 {
  586.                         numIndices += meshData.m_numIndices[j];
  587.                 }
  588.  
  589.                 if (meshData.m_animatedStreams == 0)
  590.                 {
  591.                         ++stats.m_numStaticMeshes;
  592.                         stats.m_numStaticVertices += meshData.m_numVertices;
  593.                         stats.m_numStaticTriangles += numIndices / 3;
  594.                 }
  595.                 else
  596.                 {
  597.                         ++stats.m_numAnimatedMeshes;
  598.                         stats.m_numAnimatedVertices += meshData.m_numVertices;
  599.                         stats.m_numAnimatedTriangles += numIndices / 3;
  600.                 }
  601.         }
  602.  
  603.         stats.m_staticDataSize += static_cast<uint>(m_staticNodeData.size() * sizeof(SGeomCacheStaticNodeData));
  604.         stats.m_staticDataSize += static_cast<uint>(m_frameInfos.size() * sizeof(SFrameInfo));
  605.  
  606.         stats.m_bPlaybackFromMemory = m_bPlaybackFromMemory;
  607.         stats.m_averageAnimationDataRate = (float(m_compressedAnimationDataSize) / 1024.0f / 1024.0f) / float(GetDuration());
  608.         stats.m_numMaterials = static_cast<uint>(materialIds.size());
  609.         stats.m_diskAnimationDataSize = static_cast<uint>(m_compressedAnimationDataSize);
  610.         stats.m_memoryAnimationDataSize = static_cast<uint>(m_animationData.size());
  611.  
  612.         return stats;
  613. }
  614.  
  615. void CGeomCache::Shutdown()
  616. {
  617.         uint numPhysicsGeometries = m_physicsGeometries.size();
  618.         for (uint i = 0; i < numPhysicsGeometries; ++i)
  619.         {
  620.                 phys_geometry* pGeometry = m_physicsGeometries[i];
  621.                 if (pGeometry)
  622.                 {
  623.                         GetPhysicalWorld()->GetGeomManager()->UnregisterGeometry(pGeometry);
  624.                 }
  625.         }
  626.  
  627.         if (m_pStaticDataReadStream)
  628.         {
  629.                 m_pStaticDataReadStream->Abort();
  630.                 m_pStaticDataReadStream = NULL;
  631.         }
  632.  
  633.         GetObjManager()->UnregisterForStreaming(this);
  634.         GetGeomCacheManager()->StopCacheStreamsAndWait(this);
  635.  
  636.         const uint numListeners = m_listeners.size();
  637.         for (uint i = 0; i < numListeners; ++i)
  638.         {
  639.                 m_listeners[i]->OnGeomCacheStaticDataUnloaded();
  640.         }
  641.  
  642.         m_eStreamingStatus = ecss_NotLoaded;
  643.  
  644.         stl::free_container(m_frameInfos);
  645.         stl::free_container(m_staticMeshData);
  646.         stl::free_container(m_staticNodeData);
  647.         stl::free_container(m_physicsGeometries);
  648.         stl::free_container(m_animationData);
  649. }
  650.  
  651. void CGeomCache::Reload()
  652. {
  653.         Shutdown();
  654.  
  655.         const bool bUseStreaming = m_bUseStreaming;
  656.         m_bUseStreaming = false;
  657.         m_bValid = false;
  658.         m_bLoaded = false;
  659.         LoadGeomCache();
  660.         m_bUseStreaming = bUseStreaming;
  661.  
  662.         if (m_bLoaded)
  663.         {
  664.                 const uint numListeners = m_listeners.size();
  665.                 for (uint i = 0; i < numListeners; ++i)
  666.                 {
  667.                         m_listeners[i]->OnGeomCacheStaticDataLoaded();
  668.                 }
  669.         }
  670.         else
  671.         {
  672.                 FileWarning(0, m_fileName.c_str(), "Failed to load geometry cache: %s", m_lastError.c_str());
  673.                 stl::free_container(m_lastError);
  674.         }
  675. }
  676.  
  677. uint CGeomCache::GetNumFrames() const
  678. {
  679.         return m_frameInfos.size();
  680. }
  681.  
  682. bool CGeomCache::PlaybackFromMemory() const
  683. {
  684.         return m_bPlaybackFromMemory;
  685. }
  686.  
  687. uint64 CGeomCache::GetCompressedAnimationDataSize() const
  688. {
  689.         return m_compressedAnimationDataSize;
  690. }
  691.  
  692. char* CGeomCache::GetFrameData(const uint frameIndex)
  693. {
  694.         assert(m_bPlaybackFromMemory);
  695.  
  696.         char* pAnimationData = &m_animationData[0];
  697.  
  698.         SGeomCacheFrameHeader* pFrameHeader = reinterpret_cast<SGeomCacheFrameHeader*>(
  699.           pAnimationData + (frameIndex * sizeof(SGeomCacheFrameHeader)));
  700.  
  701.         return pAnimationData + pFrameHeader->m_offset;
  702. }
  703.  
  704. const char* CGeomCache::GetFrameData(const uint frameIndex) const
  705. {
  706.         assert(m_bPlaybackFromMemory);
  707.  
  708.         const char* pAnimationData = &m_animationData[0];
  709.  
  710.         const SGeomCacheFrameHeader* pFrameHeader = reinterpret_cast<const SGeomCacheFrameHeader*>(
  711.           pAnimationData + (frameIndex * sizeof(SGeomCacheFrameHeader)));
  712.  
  713.         return pAnimationData + pFrameHeader->m_offset;
  714. }
  715.  
  716. AABB CGeomCache::GetAABB() const
  717. {
  718.         return m_aabb;
  719. }
  720.  
  721. uint CGeomCache::GetFloorFrameIndex(const float time) const
  722. {
  723.         if (m_frameInfos.empty())
  724.         {
  725.                 return 0;
  726.         }
  727.  
  728.         const float duration = GetDuration();
  729.         float timeInCycle = fmod(time, duration);
  730.         uint numLoops = static_cast<uint>(floor(time / duration));
  731.  
  732.         // Make sure that exactly at wrap around we still refer to last frame
  733.         if (timeInCycle == 0.0f && time > 0.0f)
  734.         {
  735.                 timeInCycle = duration;
  736.                 numLoops -= 1;
  737.         }
  738.  
  739.         const uint numFrames = m_frameInfos.size();
  740.         const uint numPreviousCycleFrames = numLoops * numFrames;
  741.         uint frameInCycle;
  742.  
  743.         // upper_bound = first value greater than time
  744.         SFrameInfo value = { timeInCycle };
  745.         std::vector<SFrameInfo>::const_iterator findIter =
  746.           std::upper_bound(m_frameInfos.begin(), m_frameInfos.end(), value, CompareFrameTimes);
  747.         if (findIter == m_frameInfos.begin())
  748.         {
  749.                 frameInCycle = 0;
  750.         }
  751.         else if (findIter == m_frameInfos.end())
  752.         {
  753.                 frameInCycle = static_cast<uint>(m_frameInfos.size() - 1);
  754.         }
  755.         else
  756.         {
  757.                 frameInCycle = static_cast<uint>(findIter - m_frameInfos.begin() - 1);
  758.         }
  759.  
  760.         return frameInCycle + numPreviousCycleFrames;
  761. }
  762.  
  763. uint CGeomCache::GetCeilFrameIndex(const float time) const
  764. {
  765.         if (m_frameInfos.empty())
  766.         {
  767.                 return 0;
  768.         }
  769.  
  770.         const float duration = GetDuration();
  771.         float timeInCycle = fmod(time, duration);
  772.         uint numLoops = static_cast<uint>(floor(time / duration));
  773.  
  774.         // Make sure that exactly at wrap around we still refer to last frame
  775.         if (timeInCycle == 0.0f && time > 0.0f)
  776.         {
  777.                 timeInCycle = duration;
  778.                 numLoops -= 1;
  779.         }
  780.  
  781.         const uint numFrames = m_frameInfos.size();
  782.         const uint numPreviousCycleFrames = numLoops * numFrames;
  783.         uint frameInCycle;
  784.  
  785.         // lower_bound = first value greater than or equal to time
  786.         SFrameInfo value = { timeInCycle };
  787.         std::vector<SFrameInfo>::const_iterator findIter =
  788.           std::lower_bound(m_frameInfos.begin(), m_frameInfos.end(), value, CompareFrameTimes);
  789.         if (findIter == m_frameInfos.end())
  790.         {
  791.                 frameInCycle = static_cast<uint>(m_frameInfos.size() - 1);
  792.         }
  793.         else
  794.         {
  795.                 frameInCycle = static_cast<uint>(findIter - m_frameInfos.begin());
  796.         }
  797.  
  798.         return frameInCycle + numPreviousCycleFrames;
  799. }
  800.  
  801. GeomCacheFile::EFrameType CGeomCache::GetFrameType(const uint frameIndex) const
  802. {
  803.         const uint numFrames = m_frameInfos.size();
  804.         return (GeomCacheFile::EFrameType)m_frameInfos[frameIndex % numFrames].m_frameType;
  805. }
  806.  
  807. uint64 CGeomCache::GetFrameOffset(const uint frameIndex) const
  808. {
  809.         const uint numFrames = m_frameInfos.size();
  810.         return m_frameInfos[frameIndex % numFrames].m_frameOffset;
  811. }
  812.  
  813. uint32 CGeomCache::GetFrameSize(const uint frameIndex) const
  814. {
  815.         const uint numFrames = m_frameInfos.size();
  816.         return m_frameInfos[frameIndex % numFrames].m_frameSize;
  817. }
  818.  
  819. float CGeomCache::GetFrameTime(const uint frameIndex) const
  820. {
  821.         const uint numFrames = m_frameInfos.size();
  822.         const uint numLoops = frameIndex / numFrames;
  823.         const float duration = GetDuration();
  824.         return (duration * numLoops) + m_frameInfos[frameIndex % numFrames].m_frameTime;
  825. }
  826.  
  827. uint CGeomCache::GetPrevIFrame(const uint frameIndex) const
  828. {
  829.         const uint numFrames = m_frameInfos.size();
  830.         const uint numLoops = frameIndex / numFrames;
  831.         return (numFrames * numLoops) + m_frameInfos[frameIndex % numFrames].m_prevIFrame;
  832. }
  833.  
  834. uint CGeomCache::GetNextIFrame(const uint frameIndex) const
  835. {
  836.         const uint numFrames = m_frameInfos.size();
  837.         const uint numLoops = frameIndex / numFrames;
  838.         return (numFrames * numLoops) + m_frameInfos[frameIndex % numFrames].m_nextIFrame;
  839. }
  840.  
  841. bool CGeomCache::NeedsPrevFrames(const uint frameIndex) const
  842. {
  843.         if (GetFrameType(frameIndex) == GeomCacheFile::eFrameType_IFrame
  844.             || GetFrameType(frameIndex - 1) == GeomCacheFile::eFrameType_IFrame)
  845.         {
  846.                 return false;
  847.         }
  848.  
  849.         return true;
  850. }
  851.  
  852. void CGeomCache::ValidateReadRange(const uint start, uint& end) const
  853. {
  854.         const uint numFrames = m_frameInfos.size();
  855.         uint startMod = start % numFrames;
  856.         uint endMod = end % numFrames;
  857.  
  858.         if (endMod < startMod)
  859.         {
  860.                 end = start + (numFrames - 1 - startMod);
  861.         }
  862. }
  863.  
  864. GeomCacheFile::EBlockCompressionFormat CGeomCache::GetBlockCompressionFormat() const
  865. {
  866.         return m_blockCompressionFormat;
  867. }
  868.  
  869. void CGeomCache::UpdateStreamableComponents(float importance, const Matrix34A& objMatrix, IRenderNode* pRenderNode, bool bFullUpdate)
  870. {
  871.         if (!m_bUseStreaming)
  872.         {
  873.                 return;
  874.         }
  875.  
  876.         const int nRoundId = GetObjManager()->m_nUpdateStreamingPrioriryRoundId;
  877.  
  878.         if (UpdateStreamingPrioriryLowLevel(importance, nRoundId, bFullUpdate))
  879.         {
  880.                 GetObjManager()->RegisterForStreaming(this);
  881.         }
  882. }
  883.  
  884. void CGeomCache::StartStreaming(bool bFinishNow, IReadStream_AutoPtr* ppStream)
  885. {
  886.         m_bValid = false;
  887.  
  888.         assert(m_eStreamingStatus == ecss_NotLoaded);
  889.         if (m_eStreamingStatus != ecss_NotLoaded)
  890.         {
  891.                 return;
  892.         }
  893.  
  894.         if (m_bLoaded)
  895.         {
  896.                 const uint numListeners = m_listeners.size();
  897.                 for (uint i = 0; i < numListeners; ++i)
  898.                 {
  899.                         m_listeners[i]->OnGeomCacheStaticDataLoaded();
  900.                 }
  901.  
  902.                 m_eStreamingStatus = ecss_Ready;
  903.                 return;
  904.         }
  905.  
  906.         // start streaming
  907.         StreamReadParams params;
  908.         params.dwUserData = 0;
  909.         params.nOffset = static_cast<uint>(m_staticMeshDataOffset);
  910.         params.nSize = sizeof(GeomCacheFile::SCompressedBlockHeader) + m_staticDataHeader.m_compressedSize;
  911.         params.pBuffer = NULL;
  912.         params.nLoadTime = 10000;
  913.         params.nMaxLoadTime = 10000;
  914.  
  915.         if (m_bPlaybackFromMemory)
  916.         {
  917.                 params.nSize += static_cast<uint>(m_compressedAnimationDataSize);
  918.         }
  919.  
  920.         if (bFinishNow)
  921.         {
  922.                 params.ePriority = estpUrgent;
  923.         }
  924.  
  925.         if (m_fileName.empty())
  926.         {
  927.                 m_eStreamingStatus = ecss_Ready;
  928.                 if (ppStream) *ppStream = NULL;
  929.                 return;
  930.         }
  931.  
  932.         m_pStaticDataReadStream = GetSystem()->GetStreamEngine()->StartRead(eStreamTaskTypeGeometry, m_fileName, this, &params);
  933.  
  934.         if (ppStream)
  935.         {
  936.                 (*ppStream) = m_pStaticDataReadStream;
  937.         }
  938.  
  939.         if (!bFinishNow)
  940.         {
  941.                 m_eStreamingStatus = ecss_InProgress;
  942.         }
  943.         else if (!ppStream)
  944.         {
  945.                 m_pStaticDataReadStream->Wait();
  946.         }
  947. }
  948.  
  949. void CGeomCache::StreamOnComplete(IReadStream* pStream, unsigned nError)
  950. {
  951.         if (nError != 0 || !m_bValid)
  952.         {
  953.                 return;
  954.         }
  955.  
  956.         const uint numListeners = m_listeners.size();
  957.         for (uint i = 0; i < numListeners; ++i)
  958.         {
  959.                 m_listeners[i]->OnGeomCacheStaticDataLoaded();
  960.         }
  961.  
  962.         m_eStreamingStatus = ecss_Ready;
  963.  
  964.         m_pStaticDataReadStream = NULL;
  965. }
  966.  
  967. void CGeomCache::StreamAsyncOnComplete(IReadStream* pStream, unsigned nError)
  968. {
  969.         if (nError != 0)
  970.         {
  971.                 return;
  972.         }
  973.  
  974.         const char* pData = (char*)pStream->GetBuffer();
  975.  
  976.         std::vector<char> decompressedData;
  977.         if (!DecompressStaticBlock((GeomCacheFile::EBlockCompressionFormat)(m_blockCompressionFormat), pData, decompressedData))
  978.         {
  979.                 if (m_lastError.empty())
  980.                 {
  981.                         m_lastError = "Could not decompress static block";
  982.                         return;
  983.                 }
  984.         }
  985.  
  986.         CGeomCacheStreamReader reader(&decompressedData[0], decompressedData.size());
  987.         if (!ReadMeshesStaticData(reader, m_fileName.c_str()))
  988.         {
  989.                 if (m_lastError.empty())
  990.                 {
  991.                         m_lastError = "Could not read mesh static data";
  992.                         return;
  993.                 }
  994.         }
  995.  
  996.         if (m_bPlaybackFromMemory && m_frameInfos.size() > 0)
  997.         {
  998.                 if (!LoadAnimatedData(pData, sizeof(GeomCacheFile::SCompressedBlockHeader) + m_staticDataHeader.m_compressedSize))
  999.                 {
  1000.                         return;
  1001.                 }
  1002.         }
  1003.  
  1004.         m_bValid = true;
  1005.         m_bLoaded = true;
  1006.  
  1007.         pStream->FreeTemporaryMemory();
  1008. }
  1009.  
  1010. bool CGeomCache::LoadAnimatedData(const char* pData, const size_t bufferOffset)
  1011. {
  1012.         const uint numFrames = m_frameInfos.size();
  1013.  
  1014.         // First get size necessary for decompressing animation data
  1015.         uint32 totalDecompressedAnimatedDataSize = GeomCacheDecoder::GetDecompressBufferSize(pData + bufferOffset, numFrames);
  1016.  
  1017.         // Allocate memory and decompress blocks into it
  1018.         m_animationData.resize(totalDecompressedAnimatedDataSize);
  1019.         if (!GeomCacheDecoder::DecompressBlocks(m_blockCompressionFormat, &m_animationData[0], pData + bufferOffset, 0, numFrames, numFrames))
  1020.         {
  1021.                 m_lastError = "Could not decompress animation data";
  1022.                 return false;
  1023.         }
  1024.  
  1025.         // Decode index frames
  1026.         for (uint i = 0; i < numFrames; ++i)
  1027.         {
  1028.                 if (m_frameInfos[i].m_frameType == GeomCacheFile::eFrameType_IFrame)
  1029.                 {
  1030.                         GeomCacheDecoder::DecodeIFrame(this, GetFrameData(i));
  1031.                 }
  1032.         }
  1033.  
  1034.         // Decode b-frames
  1035.         for (uint i = 0; i < numFrames; ++i)
  1036.         {
  1037.                 if (m_frameInfos[i].m_frameType == GeomCacheFile::eFrameType_BFrame)
  1038.                 {
  1039.                         char* pFrameData = GetFrameData(i);
  1040.                         char* pPrevFrameData[2] = { pFrameData, pFrameData };
  1041.  
  1042.                         if (NeedsPrevFrames(i))
  1043.                         {
  1044.                                 pPrevFrameData[0] = GetFrameData(i - 2);
  1045.                                 pPrevFrameData[1] = GetFrameData(i - 1);
  1046.                         }
  1047.  
  1048.                         char* pFloorIndexFrameData = GetFrameData(GetPrevIFrame(i));
  1049.                         char* pCeilIndexFrameData = GetFrameData(GetNextIFrame(i));
  1050.  
  1051.                         GeomCacheDecoder::DecodeBFrame(this, pFrameData, pPrevFrameData, pFloorIndexFrameData, pCeilIndexFrameData);
  1052.                 }
  1053.         }
  1054.  
  1055.         return true;
  1056. }
  1057.  
  1058. int CGeomCache::GetStreamableContentMemoryUsage(bool bJustForDebug)
  1059. {
  1060.         return 0;
  1061. }
  1062.  
  1063. void CGeomCache::ReleaseStreamableContent()
  1064. {
  1065.         const uint numListeners = m_listeners.size();
  1066.         for (uint i = 0; i < numListeners; ++i)
  1067.         {
  1068.                 m_listeners[i]->OnGeomCacheStaticDataUnloaded();
  1069.         }
  1070.  
  1071.         // Data cannot be unloaded right away, because stream could still be active,
  1072.         // so we need to wait for a UnloadData callback from the geom cache managers
  1073.         m_eStreamingStatus = ecss_NotLoaded;
  1074. }
  1075.  
  1076. void CGeomCache::GetStreamableName(string& sName)
  1077. {
  1078.         sName = m_fileName;
  1079. }
  1080.  
  1081. uint32 CGeomCache::GetLastDrawMainFrameId()
  1082. {
  1083.         return m_lastDrawMainFrameId;
  1084. }
  1085.  
  1086. bool CGeomCache::IsUnloadable() const
  1087. {
  1088.         return m_bUseStreaming;
  1089. }
  1090.  
  1091. void CGeomCache::AddListener(IGeomCacheListener* pListener)
  1092. {
  1093.         stl::push_back_unique(m_listeners, pListener);
  1094. }
  1095.  
  1096. void CGeomCache::RemoveListener(IGeomCacheListener* pListener)
  1097. {
  1098.         stl::find_and_erase(m_listeners, pListener);
  1099. }
  1100.  
  1101. void CGeomCache::UnloadData()
  1102. {
  1103.         if (m_eStreamingStatus == ecss_NotLoaded)
  1104.         {
  1105.                 CGeomCacheMeshManager& meshManager = GetGeomCacheManager()->GetMeshManager();
  1106.  
  1107.                 uint numStaticMesh = m_staticMeshData.size();
  1108.                 for (uint i = 0; i < numStaticMesh; ++i)
  1109.                 {
  1110.                         if (m_staticMeshData[i].m_animatedStreams == 0)
  1111.                         {
  1112.                                 meshManager.RemoveReference(m_staticMeshData[i]);
  1113.                         }
  1114.                 }
  1115.  
  1116.                 stl::free_container(m_staticRenderMeshes);
  1117.                 stl::free_container(m_staticMeshData);
  1118.                 stl::free_container(m_animationData);
  1119.                 m_bLoaded = false;
  1120.         }
  1121. }
  1122.  
  1123. #endif
  1124.  
downloadGeomCache.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