BVB Source Codes

CRYENGINE Show BlockPacker.cpp Source code

Return Download CRYENGINE: download BlockPacker.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:   BlockPacker.cpp
  5. //  Created:     2012 by Vladimir Kajalin.
  6. //  Description: 3D block atlas
  7. // -------------------------------------------------------------------------
  8. //  History:
  9. //
  10. ////////////////////////////////////////////////////////////////////////////
  11.  
  12. #include "StdAfx.h"
  13.  
  14. #if defined(FEATURE_SVO_GI)
  15.  
  16.         #include "BlockPacker.h"
  17.  
  18. const int nHS = 4;
  19.  
  20. CBlockPacker3D::CBlockPacker3D(const uint32 dwLogWidth, const uint32 dwLogHeight, const uint32 dwLogDepth, const bool bNonPow)
  21.         : m_fLastUsed(0.0f)
  22.         , m_nUsedBlocks(0)
  23. {
  24.         if (bNonPow)
  25.         {
  26.                 m_dwWidth = dwLogWidth;
  27.                 m_dwHeight = dwLogHeight;
  28.                 m_dwDepth = dwLogDepth;
  29.         }
  30.         else
  31.         {
  32.                 m_dwWidth = 1 << dwLogWidth;
  33.                 m_dwHeight = 1 << dwLogHeight;
  34.                 m_dwDepth = 1 << dwLogDepth;
  35.         }
  36.  
  37.         m_BlockBitmap.resize(m_dwWidth * m_dwHeight * m_dwDepth, 0xffffffff);
  38.         m_BlockUsageGrid.resize(m_dwWidth * m_dwHeight * m_dwDepth / nHS / nHS / nHS, 0);
  39.         m_Blocks.reserve(m_dwWidth * m_dwHeight * m_dwDepth);
  40. }
  41.  
  42. SBlockMinMax* CBlockPacker3D::GetBlockInfo(const uint32 dwBlockID)
  43. {
  44.         uint32 dwSize = (uint32)m_Blocks.size();
  45.  
  46.         assert(dwBlockID < dwSize);
  47.         if (dwBlockID >= dwSize)
  48.                 return NULL;
  49.  
  50.         SBlockMinMax& ref = m_Blocks[dwBlockID];
  51.  
  52.         if (ref.IsFree())
  53.                 return NULL;
  54.  
  55.         return &m_Blocks[dwBlockID];
  56. }
  57.  
  58. void CBlockPacker3D::UpdateSize(int nW, int nH, int nD)
  59. {
  60.         assert(m_nUsedBlocks == 0);
  61.  
  62.         m_dwWidth = nW;
  63.         m_dwHeight = nH;
  64.         m_dwDepth = nD;
  65.  
  66.         m_nUsedBlocks = 0;
  67.  
  68.         m_BlockBitmap.resize(m_dwWidth * m_dwHeight * m_dwDepth, 0xffffffff);
  69. }
  70.  
  71. void CBlockPacker3D::RemoveBlock(const uint32 dwBlockID)
  72. {
  73.         uint32 dwSize = (uint32)m_Blocks.size();
  74.  
  75.         assert(dwBlockID < dwSize);
  76.         if (dwBlockID >= dwSize)
  77.                 return;     // to avoid crash
  78.  
  79.         SBlockMinMax& ref = m_Blocks[dwBlockID];
  80.  
  81.         assert(!ref.IsFree());
  82.  
  83.         FillRect(ref, 0xffffffff);
  84.         m_nUsedBlocks -= (ref.m_dwMaxX - ref.m_dwMinX) * (ref.m_dwMaxY - ref.m_dwMinY) * (ref.m_dwMaxZ - ref.m_dwMinZ);
  85.  
  86.         ref.MarkFree();
  87.  
  88.         //      m_BlocksList.remove(&ref);
  89. }
  90.  
  91. void CBlockPacker3D::RemoveBlock(SBlockMinMax* pInfo)
  92. {
  93.         SBlockMinMax& ref = *pInfo;
  94.  
  95.         assert(!ref.IsFree());
  96.  
  97.         FillRect(ref, 0xffffffff);
  98.         m_nUsedBlocks -= (ref.m_dwMaxX - ref.m_dwMinX) * (ref.m_dwMaxY - ref.m_dwMinY) * (ref.m_dwMaxZ - ref.m_dwMinZ);
  99.  
  100.         ref.MarkFree();
  101.  
  102.         //      m_BlocksList.remove(&ref);
  103. }
  104.  
  105. SBlockMinMax* CBlockPacker3D::AddBlock(const uint32 dwLogWidth, const uint32 dwLogHeight, const uint32 dwLogDepth, void* pUserData, uint32 nCreateFrameId, uint32 nDataSize)
  106. {
  107.         if (!dwLogWidth || !dwLogHeight || !dwLogDepth)
  108.                 assert(!"Empty block");
  109.  
  110.         uint32 dwLocalWidth = dwLogWidth;
  111.         uint32 dwLocalHeight = dwLogHeight;
  112.         uint32 dwLocalDepth = dwLogDepth;
  113.  
  114.         int nCountNeeded = dwLocalWidth * dwLocalHeight * dwLocalDepth;
  115.  
  116.         int dwW = m_dwWidth / nHS;
  117.         int dwH = m_dwHeight / nHS;
  118.         int dwD = m_dwDepth / nHS;
  119.  
  120.         for (int nZ = 0; nZ < dwD; nZ++)
  121.                 for (int nY = 0; nY < dwH; nY++)
  122.                         for (int nX = 0; nX < dwW; nX++)
  123.                         {
  124.                                 uint32 dwMinX = nX * nHS;
  125.                                 uint32 dwMinY = nY * nHS;
  126.                                 uint32 dwMinZ = nZ * nHS;
  127.  
  128.                                 uint32 dwMaxX = (nX + 1) * nHS;
  129.                                 uint32 dwMaxY = (nY + 1) * nHS;
  130.                                 uint32 dwMaxZ = (nZ + 1) * nHS;
  131.  
  132.                                 int nCountFree = nHS * nHS * nHS - m_BlockUsageGrid[nX + nY * dwW + nZ * dwW * dwH];
  133.  
  134.                                 if (nCountNeeded <= nCountFree)
  135.                                 {
  136.                                         SBlockMinMax testblock;
  137.                                         testblock.m_pUserData = pUserData;
  138.                                         testblock.m_nLastVisFrameId = nCreateFrameId;
  139.                                         testblock.m_nDataSize = nDataSize;
  140.  
  141.                                         for (uint32 dwZ = dwMinZ; dwZ < dwMaxZ; dwZ += dwLocalDepth)
  142.                                         {
  143.                                                 for (uint32 dwY = dwMinY; dwY < dwMaxY; dwY += dwLocalHeight)
  144.                                                 {
  145.                                                         for (uint32 dwX = dwMinX; dwX < dwMaxX; dwX += dwLocalWidth)
  146.                                                         {
  147.                                                                 testblock.m_dwMinX = dwX;
  148.                                                                 testblock.m_dwMaxX = dwX + dwLocalWidth;
  149.                                                                 testblock.m_dwMinY = dwY;
  150.                                                                 testblock.m_dwMaxY = dwY + dwLocalHeight;
  151.                                                                 testblock.m_dwMinZ = dwZ;
  152.                                                                 testblock.m_dwMaxZ = dwZ + dwLocalDepth;
  153.  
  154.                                                                 if (IsFree(testblock))
  155.                                                                 {
  156.                                                                         uint32 dwBlockID = FindFreeBlockIDOrCreateNew();
  157.  
  158.                                                                         m_Blocks[dwBlockID] = testblock;
  159.  
  160.                                                                         FillRect(testblock, dwBlockID);
  161.  
  162.                                                                         m_nUsedBlocks += dwLocalWidth * dwLocalHeight * dwLocalDepth;
  163.  
  164.                                                                         //                                                      m_BlocksList.insertBeginning(&m_Blocks[dwBlockID]);
  165.  
  166.                                                                         return &m_Blocks[dwBlockID];
  167.                                                                 }
  168.                                                         }
  169.                                                 }
  170.                                         }
  171.                                 }
  172.                         }
  173.  
  174.         return NULL;  // no space left to this block
  175. }
  176.  
  177. void CBlockPacker3D::UpdateUsageGrid(const SBlockMinMax& rectIn)
  178. {
  179.         SBlockMinMax rectUM;
  180.  
  181.         rectUM.m_dwMinX = rectIn.m_dwMinX / nHS;
  182.         rectUM.m_dwMinY = rectIn.m_dwMinY / nHS;
  183.         rectUM.m_dwMinZ = rectIn.m_dwMinZ / nHS;
  184.  
  185.         rectUM.m_dwMaxX = (rectIn.m_dwMaxX - 1) / nHS + 1;
  186.         rectUM.m_dwMaxY = (rectIn.m_dwMaxY - 1) / nHS + 1;
  187.         rectUM.m_dwMaxZ = (rectIn.m_dwMaxZ - 1) / nHS + 1;
  188.  
  189.         int dwW = m_dwWidth / nHS;
  190.         int dwH = m_dwHeight / nHS;
  191.         int dwD = m_dwDepth / nHS;
  192.  
  193.         for (uint32 dwZ = rectUM.m_dwMinZ; dwZ < rectUM.m_dwMaxZ; ++dwZ)
  194.         {
  195.                 for (uint32 dwY = rectUM.m_dwMinY; dwY < rectUM.m_dwMaxY; ++dwY)
  196.                 {
  197.                         for (uint32 dwX = rectUM.m_dwMinX; dwX < rectUM.m_dwMaxX; ++dwX)
  198.                         {
  199.                                 SBlockMinMax rectTest = rectUM;
  200.  
  201.                                 rectTest.m_dwMinX = dwX * nHS;
  202.                                 rectTest.m_dwMinY = dwY * nHS;
  203.                                 rectTest.m_dwMinZ = dwZ * nHS;
  204.  
  205.                                 rectTest.m_dwMaxX = (dwX + 1) * nHS;
  206.                                 rectTest.m_dwMaxY = (dwY + 1) * nHS;
  207.                                 rectTest.m_dwMaxZ = (dwZ + 1) * nHS;
  208.  
  209.                                 m_BlockUsageGrid[dwX + dwY * dwW + dwZ * dwW * dwH] = GetUsedSlotsCount(rectTest);
  210.                         }
  211.                 }
  212.         }
  213. }
  214.  
  215. void CBlockPacker3D::FillRect(const SBlockMinMax& rect, uint32 dwValue)
  216. {
  217.         for (uint32 dwZ = rect.m_dwMinZ; dwZ < rect.m_dwMaxZ; ++dwZ)
  218.                 for (uint32 dwY = rect.m_dwMinY; dwY < rect.m_dwMaxY; ++dwY)
  219.                         for (uint32 dwX = rect.m_dwMinX; dwX < rect.m_dwMaxX; ++dwX)
  220.                                 m_BlockBitmap[dwX + dwY * m_dwWidth + dwZ * m_dwWidth * m_dwHeight] = dwValue;
  221.  
  222.         UpdateUsageGrid(rect);
  223. }
  224.  
  225. int CBlockPacker3D::GetUsedSlotsCount(const SBlockMinMax& rect)
  226. {
  227.         int nCount = 0;
  228.  
  229.         for (uint32 dwZ = rect.m_dwMinZ; dwZ < rect.m_dwMaxZ; ++dwZ)
  230.                 for (uint32 dwY = rect.m_dwMinY; dwY < rect.m_dwMaxY; ++dwY)
  231.                         for (uint32 dwX = rect.m_dwMinX; dwX < rect.m_dwMaxX; ++dwX)
  232.                                 if (m_BlockBitmap[dwX + dwY * m_dwWidth + dwZ * m_dwWidth * m_dwHeight] != 0xffffffff)
  233.                                         nCount++;
  234.  
  235.         return nCount;
  236. }
  237.  
  238. bool CBlockPacker3D::IsFree(const SBlockMinMax& rect)
  239. {
  240.         for (uint32 dwZ = rect.m_dwMinZ; dwZ < rect.m_dwMaxZ; ++dwZ)
  241.                 for (uint32 dwY = rect.m_dwMinY; dwY < rect.m_dwMaxY; ++dwY)
  242.                         for (uint32 dwX = rect.m_dwMinX; dwX < rect.m_dwMaxX; ++dwX)
  243.                                 if (m_BlockBitmap[dwX + dwY * m_dwWidth + dwZ * m_dwWidth * m_dwHeight] != 0xffffffff)
  244.                                         return false;
  245.  
  246.         return true;
  247. }
  248.  
  249. uint32 CBlockPacker3D::FindFreeBlockIDOrCreateNew()
  250. {
  251.         std::vector<SBlockMinMax>::const_iterator it, end = m_Blocks.end();
  252.         uint32 dwI = 0;
  253.  
  254.         for (it = m_Blocks.begin(); it != end; ++it, ++dwI)
  255.         {
  256.                 const SBlockMinMax& ref = *it;
  257.  
  258.                 if (ref.IsFree())
  259.                         return dwI;
  260.         }
  261.  
  262.         m_Blocks.push_back(SBlockMinMax());
  263.  
  264.         return (uint32)m_Blocks.size() - 1;
  265. }
  266.  
  267. #endif
  268.  
downloadBlockPacker.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