BVB Source Codes

CRYENGINE Show StatObjStream.cpp Source code

Return Download CRYENGINE: download StatObjStream.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:   statobjconstr.cpp
  5. //  Version:     v1.00
  6. //  Created:     28/5/2001 by Vladimir Kajalin
  7. //  Compilers:   Visual Studio.NET
  8. //  Description: loading
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #include "StdAfx.h"
  15.  
  16. #include "StatObj.h"
  17. #include "IndexedMesh.h"
  18. #include "../RenderDll/Common/Shadow_Renderer.h"
  19. #include <CryRenderer/IRenderer.h>
  20. #include <CryMemory/CrySizer.h>
  21.  
  22. #include "CGF/CGFLoader.h"
  23. #include "CGF/CGFSaver.h"
  24. #include "CGF/ReadOnlyChunkFile.h"
  25.  
  26. #define GEOM_INFO_FILE_EXT "ginfo"
  27. #define MESH_NAME_FOR_MAIN "main"
  28.  
  29. extern const char* stristr(const char* szString, const char* szSubstring);
  30.  
  31. extern void        TransformMesh(CMesh& mesh, Matrix34 tm);
  32.  
  33. #if !defined (_RELEASE) || defined(ENABLE_STATOSCOPE_RELEASE)
  34. float CStatObj::s_fStreamingTime = 0.0f;
  35. int CStatObj::s_nBandwidth = 0;
  36. #endif
  37.  
  38. void CStatObj::StreamAsyncOnComplete(IReadStream* pStream, unsigned nError)
  39. {
  40.         FUNCTION_PROFILER_3DENGINE;
  41.  
  42.         if (nError == ERROR_CANT_OPEN_FILE && m_bHasStreamOnlyCGF)
  43.         {
  44.                 // Deliberately ignore
  45.         }
  46.         else if (pStream->IsError())
  47.         {
  48.                 // file was not loaded successfully
  49.                 m_eStreamingStatus = ecss_Ready;
  50.                 if (pStream->GetError() != ERROR_USER_ABORT && pStream->GetError() != ERROR_ABORTED_ON_SHUTDOWN)
  51.                         Error("CStatObj::StreamAsyncOnComplete: Error loading CGF: %s Error: %s", m_szFileName.c_str(), pStream->GetErrorName());
  52.         }
  53.         else
  54.         {
  55. #if !defined (_RELEASE)
  56.                 float timeinseconds = (gEnv->pTimer->GetCurrTime() - m_fStreamingStart);
  57.                 s_nBandwidth += pStream->GetBytesRead();
  58.                 s_fStreamingTime += timeinseconds;
  59.                 m_fStreamingStart = 0.0f;
  60. #endif
  61.  
  62.                 if (!LoadStreamRenderMeshes(0, pStream->GetBuffer(), pStream->GetBytesRead(), strstr(m_szFileName.c_str(), "_lod") != NULL))
  63.                 {
  64.                         Error("CStatObj::StreamOnComplete_LoadCGF_FromMemBlock, filename=%s", m_szFileName.c_str());
  65.                 }
  66.         }
  67.  
  68.         pStream->FreeTemporaryMemory(); // We dont need internal stream loaded buffer anymore.
  69. }
  70.  
  71. //////////////////////////////////////////////////////////////////////////
  72. void CStatObj::StreamOnComplete(IReadStream* pStream, unsigned nError)
  73. {
  74.         FUNCTION_PROFILER_3DENGINE;
  75.  
  76.         // Synchronous callback.
  77.  
  78.         if (nError == ERROR_CANT_OPEN_FILE && m_bHasStreamOnlyCGF)
  79.         {
  80.                 m_bHasStreamOnlyCGF = 0;
  81.                 m_eStreamingStatus = ecss_NotLoaded;
  82.         }
  83.         else if (pStream->IsError())
  84.         {
  85.                 // file was not loaded successfully
  86.                 if (pStream->GetError() != ERROR_USER_ABORT && pStream->GetError() != ERROR_ABORTED_ON_SHUTDOWN)
  87.                         Error("CStatObj::StreamOnComplete: Error loading CGF: %s Error: %s", m_szFileName.c_str(), pStream->GetErrorName());
  88.  
  89.                 m_eStreamingStatus = ecss_Ready;
  90.         }
  91.         else
  92.         {
  93.                 CommitStreamRenderMeshes();
  94.  
  95.                 //////////////////////////////////////////////////////////////////////////
  96.                 // Forces vegetation sprites to be marked for regeneration from new mesh.
  97.                 //////////////////////////////////////////////////////////////////////////
  98.                 for (int nSID = 0; nSID < m_pObjManager->m_lstStaticTypes.Count(); nSID++)
  99.                 {
  100.                         PodArray<StatInstGroup>& rGroupTable = m_pObjManager->m_lstStaticTypes[nSID];
  101.                         for (int nGroupId = 0, nGroups = rGroupTable.Count(); nGroupId < nGroups; nGroupId++)
  102.                         {
  103.                                 StatInstGroup& rGroup = rGroupTable[nGroupId];
  104.                                 if (rGroup.pStatObj == this)
  105.                                 {
  106.                                         rGroup.Update(GetCVars(), Get3DEngine()->GetGeomDetailScreenRes());
  107.                                 }
  108.                         }
  109.                 }
  110.                 //////////////////////////////////////////////////////////////////////////
  111.  
  112. #ifdef OBJMAN_STREAM_STATS
  113.                 if (m_pStreamListener)
  114.                         m_pStreamListener->OnReceivedStreamedObject(static_cast<IStreamable*>(this));
  115. #endif
  116.  
  117.                 m_eStreamingStatus = ecss_Ready;
  118.         }
  119.  
  120.         m_pReadStream = 0;
  121. }
  122.  
  123. void CStatObj::IncrementModificationId()
  124. {
  125.         m_nModificationId++;
  126.  
  127.         if (m_pParentObject)
  128.                 m_pParentObject->IncrementModificationId();
  129.  
  130.         if (m_pLod0)
  131.                 m_pLod0->IncrementModificationId();
  132. }
  133.  
  134. void CStatObj::GetStreamFilePath(stack_string& strOut)
  135. {
  136.         strOut = m_szFileName.c_str();
  137.         strOut.append("m");
  138. }
  139.  
  140. //////////////////////////////////////////////////////////////////////////
  141. void CStatObj::StartStreaming(bool bFinishNow, IReadStream_AutoPtr* ppStream)
  142. {
  143.         assert(!m_pParentObject);
  144.  
  145.         assert(m_eStreamingStatus == ecss_NotLoaded);
  146.  
  147.         if (m_eStreamingStatus != ecss_NotLoaded)
  148.                 return;
  149.  
  150.         // start streaming
  151.         StreamReadParams params;
  152.         params.dwUserData = 0;
  153.         params.nSize = 0;
  154.         params.pBuffer = NULL;
  155.         params.nLoadTime = 10000;
  156.         params.nMaxLoadTime = 10000;
  157.         if (bFinishNow)
  158.         {
  159.                 params.ePriority = estpUrgent;
  160.         }
  161.  
  162.         if (m_szFileName.empty())
  163.         {
  164.                 assert(!"CStatObj::StartStreaming: CGF name is empty");
  165.                 m_eStreamingStatus = ecss_Ready;
  166.                 if (ppStream) *ppStream = NULL;
  167.                 return;
  168.         }
  169.  
  170. #if !defined (_RELEASE)
  171.         m_fStreamingStart = gEnv->pTimer->GetCurrTime();
  172. #endif //!defined (_RELEASE)
  173.         const char* path = m_szFileName.c_str();
  174.  
  175.         stack_string streamPath;
  176.         if (m_bHasStreamOnlyCGF)
  177.         {
  178.                 GetStreamFilePath(streamPath);
  179.                 path = streamPath.c_str();
  180.         }
  181.  
  182.         m_pReadStream = GetSystem()->GetStreamEngine()->StartRead(eStreamTaskTypeGeometry, path, this, &params);
  183.  
  184.         if (ppStream)
  185.                 (*ppStream) = m_pReadStream;
  186.         if (!bFinishNow)
  187.                 m_eStreamingStatus = ecss_InProgress;
  188.         else if (!ppStream)
  189.                 m_pReadStream->Wait();
  190. }
  191.  
  192. void CStatObj::ReleaseStreamableContent()
  193. {
  194.         assert(!m_pParentObject);
  195.         assert(!m_pClonedSourceObject);
  196.         assert(!m_bSharesChildren);
  197.  
  198.         bool bLodsAreLoadedFromSeparateFile = (m_pLod0 != 0) ? m_pLod0->m_bLodsAreLoadedFromSeparateFile : m_bLodsAreLoadedFromSeparateFile;
  199.  
  200.         if (!bLodsAreLoadedFromSeparateFile)
  201.         {
  202.                 for (int nLod = 0; nLod < MAX_STATOBJ_LODS_NUM; nLod++)
  203.                 {
  204.                         CStatObj* pLod = (CStatObj*)GetLodObject(nLod);
  205.  
  206.                         if (!pLod)
  207.                                 continue;
  208.  
  209.                         pLod->SetRenderMesh(0);
  210.                         pLod->FreeFoliageData();
  211.                         pLod->m_eStreamingStatus = ecss_NotLoaded;
  212.  
  213.                         if (pLod->m_pParentObject)
  214.                         {
  215.                                 pLod->m_pParentObject->SetRenderMesh(0);
  216.                                 pLod->m_pParentObject->FreeFoliageData();
  217.                                 pLod->m_pParentObject->m_eStreamingStatus = ecss_NotLoaded;
  218.                         }
  219.                 }
  220.         }
  221.  
  222.         for (int s = 0; s < GetSubObjectCount(); s++)
  223.         {
  224.                 SSubObject& sub = *GetSubObject(s);
  225.                 if (!sub.pStatObj)
  226.                         continue;
  227.  
  228.                 if (bLodsAreLoadedFromSeparateFile)
  229.                 {
  230.                         CStatObj* pSubLod = (CStatObj*)sub.pStatObj;
  231.  
  232.                         if (!pSubLod)
  233.                                 continue;
  234.  
  235.                         pSubLod->SetRenderMesh(0);
  236.                         pSubLod->FreeFoliageData();
  237.                         pSubLod->m_eStreamingStatus = ecss_NotLoaded;
  238.  
  239.                         if (pSubLod->m_pParentObject)
  240.                         {
  241.                                 pSubLod->m_pParentObject->SetRenderMesh(0);
  242.                                 pSubLod->m_pParentObject->FreeFoliageData();
  243.                                 pSubLod->m_pParentObject->m_eStreamingStatus = ecss_NotLoaded;
  244.                         }
  245.                 }
  246.                 else
  247.                 {
  248.                         for (int nLod = 0; nLod < MAX_STATOBJ_LODS_NUM; nLod++)
  249.                         {
  250.                                 CStatObj* pSubLod = (CStatObj*)sub.pStatObj->GetLodObject(nLod);
  251.  
  252.                                 if (!pSubLod)
  253.                                         continue;
  254.  
  255.                                 pSubLod->SetRenderMesh(0);
  256.                                 pSubLod->FreeFoliageData();
  257.                                 pSubLod->m_eStreamingStatus = ecss_NotLoaded;
  258.  
  259.                                 if (pSubLod->m_pParentObject)
  260.                                 {
  261.                                         pSubLod->m_pParentObject->SetRenderMesh(0);
  262.                                         pSubLod->m_pParentObject->FreeFoliageData();
  263.                                         pSubLod->m_pParentObject->m_eStreamingStatus = ecss_NotLoaded;
  264.                                 }
  265.                         }
  266.                 }
  267.         }
  268.  
  269.         SetRenderMesh(0);
  270.         FreeFoliageData();
  271.  
  272.         m_pMergedRenderMesh = 0;
  273.  
  274.         m_eStreamingStatus = ecss_NotLoaded;
  275. }
  276.  
  277. int CStatObj::GetStreamableContentMemoryUsage(bool bJustForDebug)
  278. {
  279.         assert(!m_pParentObject || bJustForDebug); // only parents allowed to be registered for streaming
  280.  
  281.         bool bLodsAreLoadedFromSeparateFile = (m_pLod0 != 0) ? m_pLod0->m_bLodsAreLoadedFromSeparateFile : m_bLodsAreLoadedFromSeparateFile;
  282.         bool bCountLods = !bLodsAreLoadedFromSeparateFile;
  283.  
  284.         if (m_arrRenderMeshesPotentialMemoryUsage[bCountLods] < 0)
  285.         {
  286.                 int nCount = 0;
  287.  
  288.                 if (bCountLods)
  289.                 {
  290.                         if (m_pLODs)
  291.                                 for (int nLod = 1; nLod < MAX_STATOBJ_LODS_NUM; nLod++)
  292.                                 {
  293.                                         CStatObj* pLod = (CStatObj*)m_pLODs[nLod];
  294.  
  295.                                         if (!pLod)
  296.                                                 continue;
  297.  
  298.                                         nCount += pLod->m_nRenderMeshMemoryUsage;
  299.                                 }
  300.                 }
  301.  
  302.                 nCount += m_nRenderMeshMemoryUsage;
  303.  
  304.                 for (int s = 0; s < GetSubObjectCount(); s++)
  305.                 {
  306.                         SSubObject& sub = *GetSubObject(s);
  307.  
  308.                         if (!sub.pStatObj)
  309.                                 continue;
  310.  
  311.                         if (bCountLods)
  312.                         {
  313.                                 CStatObj* pSubStatObj = (CStatObj*)sub.pStatObj;
  314.                                 if (pSubStatObj->m_pLODs)
  315.                                 {
  316.                                         for (int nLod = 1; nLod < MAX_STATOBJ_LODS_NUM; nLod++)
  317.                                         {
  318.                                                 CStatObj* pSubLod = pSubStatObj->m_pLODs[nLod];
  319.  
  320.                                                 if (!pSubLod)
  321.                                                         continue;
  322.  
  323.                                                 nCount += pSubLod->m_nRenderMeshMemoryUsage;
  324.                                         }
  325.                                 }
  326.                         }
  327.  
  328.                         nCount += ((CStatObj*)sub.pStatObj)->m_nRenderMeshMemoryUsage;
  329.                 }
  330.  
  331.                 m_arrRenderMeshesPotentialMemoryUsage[bCountLods] = nCount;
  332.         }
  333.  
  334.         if (m_pMergedRenderMesh)
  335.         {
  336.                 //TODO: Need to have a function to calculate memory usage.
  337.                 //m_nMergedMemoryUsage = m_pMergedRenderMesh->GetAllocatedBytes(true);
  338.                 m_nMergedMemoryUsage = m_pMergedRenderMesh->GetVerticesCount() * (sizeof(SPipTangents) + sizeof(SVF_P3S_C4B_T2S)) + m_pMergedRenderMesh->GetIndicesCount() * sizeof(uint16);
  339.         }
  340.         else if (!GetCVars()->e_StatObjMerge)
  341.         {
  342.                 m_nMergedMemoryUsage = 0;
  343.         }
  344.  
  345.         return m_nMergedMemoryUsage + m_arrRenderMeshesPotentialMemoryUsage[bCountLods];
  346. }
  347.  
  348. void CStatObj::UpdateStreamingPrioriryInternal(const Matrix34A& objMatrix, float fImportance, bool bFullUpdate)
  349. {
  350.         int nRoundId = GetObjManager()->m_nUpdateStreamingPrioriryRoundId;
  351.  
  352.         if (m_pParentObject && m_bSubObject)
  353.         {
  354.                 // stream parent for sub-objects
  355.                 m_pParentObject->UpdateStreamingPrioriryInternal(objMatrix, fImportance, bFullUpdate);
  356.         }
  357.         else if (!m_bSubObject)
  358.         {
  359.                 // stream object itself
  360.                 if (m_bCanUnload)
  361.                 {
  362.                         if (UpdateStreamingPrioriryLowLevel(fImportance, nRoundId, bFullUpdate))
  363.                                 GetObjManager()->RegisterForStreaming(this);
  364.                 }
  365.         }
  366.         else if (m_pLod0)
  367.         {
  368.                 // sub-object lod without parent
  369.                 m_pLod0->UpdateStreamingPrioriryInternal(objMatrix, fImportance, bFullUpdate);
  370.                 assert(!m_pLod0->m_bLodsAreLoadedFromSeparateFile);
  371.         }
  372.         else if (m_bCanUnload)
  373.                 assert(!"Invalid CGF hierarchy");
  374. }
  375.  
  376. bool CStatObj::UpdateStreamableComponents(float fImportance, const Matrix34A& objMatrix, bool bFullUpdate, int nNewLod)
  377. {
  378.         if (m_pLod0) // redirect to lod0, otherwise we fail to pre-cache neighbor LODs
  379.                 return m_pLod0->UpdateStreamableComponents(fImportance, objMatrix, bFullUpdate, nNewLod);
  380.  
  381. #ifndef _RELEASE
  382.         if (GetCVars()->e_StreamCgfDebug && strlen(GetCVars()->e_StreamCgfDebugFilter->GetString()) && strstr(m_szFileName, GetCVars()->e_StreamCgfDebugFilter->GetString()))
  383.                 PrintMessage(__FUNCTION__);
  384. #endif
  385.  
  386.         //  FUNCTION_PROFILER_3DENGINE;
  387.  
  388.         if (m_nFlags & STATIC_OBJECT_HIDDEN)
  389.                 return false;
  390.  
  391.         nNewLod = min(nNewLod, MAX_STATOBJ_LODS_NUM - 1);
  392.  
  393.         if ((m_nFlags & STATIC_OBJECT_COMPOUND) && SubObjectCount())
  394.         {
  395.                 for (int s = 0, num = SubObjectCount(); s < num; s++)
  396.                 {
  397.                         IStatObj::SSubObject& subObj = SubObject(s);
  398.  
  399.                         if (subObj.pStatObj && subObj.nType == STATIC_SUB_OBJECT_MESH && !subObj.bShadowProxy)
  400.                         {
  401.                                 Matrix34 subObjMatrix = objMatrix * subObj.tm;
  402.  
  403.                                 CStatObj* pSubStatObj = ((CStatObj*)subObj.pStatObj);
  404.  
  405.                                 if (pSubStatObj->m_nLoadedTrisCount < 1)
  406.                                         continue;
  407.  
  408.                                 for (int l = nNewLod; l <= (nNewLod + 1) && l < MAX_STATOBJ_LODS_NUM; l++)
  409.                                 {
  410.                                         if (CStatObj* pLod = (CStatObj*)pSubStatObj->GetLodObject(l, true))
  411.                                         {
  412.                                                 pLod->UpdateStreamingPrioriryInternal(objMatrix, fImportance, bFullUpdate);
  413.  
  414.                                                 if (!(CStatObj*)pSubStatObj->m_pLODs)
  415.                                                         break;
  416.                                         }
  417.                                 }
  418.                         }
  419.                 }
  420.         }
  421.         else if (m_nLoadedTrisCount >= 1)
  422.         {
  423.                 for (int l = nNewLod; l <= (nNewLod + 1) && l < MAX_STATOBJ_LODS_NUM; l++)
  424.                 {
  425.                         if (CStatObj* pLod = (CStatObj*)GetLodObject(l, true))
  426.                         {
  427.                                 pLod->UpdateStreamingPrioriryInternal(objMatrix, fImportance, bFullUpdate);
  428.  
  429.                                 if (!m_pLODs)
  430.                                         break;
  431.                         }
  432.                 }
  433.         }
  434.  
  435.         // update also next state CGF
  436.         if (!m_szStreamingDependencyFilePath.empty())
  437.                 if (CStatObj* pNextState = (CStatObj*)GetObjManager()->FindStaticObjectByFilename(m_szStreamingDependencyFilePath))
  438.                         pNextState->UpdateStreamableComponents(fImportance, objMatrix, bFullUpdate, nNewLod);
  439.  
  440.         if (m_pParentObject && !m_pParentObject->m_szStreamingDependencyFilePath.empty())
  441.                 if (CStatObj* pNextState = (CStatObj*)GetObjManager()->FindStaticObjectByFilename(m_pParentObject->m_szStreamingDependencyFilePath))
  442.                         pNextState->UpdateStreamableComponents(fImportance, objMatrix, bFullUpdate, nNewLod);
  443.  
  444.         return true;
  445. }
  446.  
  447. void CStatObj::DisableStreaming()
  448. {
  449.         for (int nLodLevel = 0; nLodLevel < MAX_STATOBJ_LODS_NUM; nLodLevel++)
  450.         {
  451.                 if (CStatObj* pLodObj = (CStatObj*)GetLodObject(nLodLevel))
  452.                 {
  453.                         pLodObj->m_nLastDrawMainFrameId = gEnv->nMainFrameID + 1000;
  454.                         pLodObj->UpdateStreamingPrioriryLowLevel(1.f, GetObjManager()->m_nUpdateStreamingPrioriryRoundId, true);
  455.                         pLodObj->m_bCanUnload = false;
  456.  
  457.                         // only register the parent object for streaming, it will stream in all subobject + lods
  458.                         if (pLodObj->m_pParentObject)
  459.                                 GetObjManager()->RegisterForStreaming(pLodObj->m_pParentObject);
  460.                         else
  461.                                 GetObjManager()->RegisterForStreaming(pLodObj);
  462.                 }
  463.         }
  464. }
  465.  
  466. bool CStatObj::CheckForStreamingDependencyLoop(const char* szFilenameDependancy) const
  467. {
  468.         CObjManager* pObjManager = GetObjManager();
  469.         while (szFilenameDependancy)
  470.         {
  471.                 const CStatObj* pStatObjDependency = static_cast<const CStatObj*>(pObjManager->FindStaticObjectByFilename(szFilenameDependancy));
  472.                 if (!pStatObjDependency)
  473.                         return false;
  474.  
  475.                 if (this == pStatObjDependency)
  476.                         return true;
  477.  
  478.                 szFilenameDependancy = pStatObjDependency->m_szStreamingDependencyFilePath.c_str();
  479.         }
  480.  
  481.         return false;
  482. }
  483.  
downloadStatObjStream.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