CUgopEntity

xrPVS.cpp

Jun 14th, 2020
1,106
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "stdafx.h"
  2. #include "build.h"
  3. #include "xrOcclusion.h"
  4.  
  5. #pragma comment(lib,"xrOcclusion.lib")
  6. #pragma comment(lib,"winmm.lib")
  7.  
  8. typedef xr_vector<u16>  vecW;
  9. typedef vecW::iterator  vecW_IT;
  10.  
  11. typedef xr_vector<BOOL> vecB;
  12. typedef vecB::iterator  vecB_IT;
  13.  
  14. typedef xr_multimap<u32,u32>                    treeCompress;
  15. typedef treeCompress::iterator                      treeCompressIt;
  16. typedef treeCompress::value_type                    treeCompressType;
  17. typedef std::pair<treeCompressIt,treeCompressIt>    treeCompressPair;
  18.  
  19. xr_vector<vecW> g_pvs;
  20.  
  21. treeCompress    g_compress_tree;
  22.  
  23. vecW            g_selected;
  24. vecB            g_result;
  25.  
  26. u32         g_pvs_X,g_pvs_Y,g_pvs_Z;
  27.  
  28. int CompressSelected()
  29. {
  30.     if (g_selected.size()>1)
  31.     {
  32.         std::sort   (g_selected.begin(),g_selected.end());
  33.         vecW_IT I = std::unique (g_selected.begin(),g_selected.end());
  34.         g_selected.erase(I,g_selected.end());
  35.     }
  36.  
  37.     // Search placeholder
  38.     u32 sz                  = g_selected.size();
  39.     u32 sz_bytes                = sz*sizeof(u16);
  40.     treeCompressPair    Range   = g_compress_tree.equal_range(sz);
  41.  
  42.     for (treeCompressIt it=Range.first; it!=Range.second; it++)
  43.     {
  44.         treeCompressType    &= *it;
  45.         u32 entry           = V.second;
  46.         vecW    &entry_data     = g_pvs[entry];
  47.         if (0!=memcmp(entry_data.begin(),g_selected.begin(),sz_bytes)) continue;
  48.  
  49.         // Ok-Ob :)
  50.         return entry;
  51.     }
  52.  
  53.     // If we get here - need to register _new set of data
  54.     u32 entry = g_pvs.size();
  55.     g_pvs.push_back(g_selected);
  56.     g_compress_tree.insert(mk_pair(sz,entry));
  57.     return entry;
  58. }
  59.  
  60. void CBuild::BuildPVS()
  61. {
  62.     Fvector size;
  63.     Fvector pos;
  64.     Fvector ground_dir;
  65.  
  66.     Status("Preparing...");
  67.  
  68.     g_TREE_ROOT->bbox.getsize(size);
  69.     g_pvs_X = iROUND(ceilf(size.x/g_params.m_sample_step))+1;
  70.     g_pvs_Y = iROUND(ceilf(size.y/g_params.m_sample_step))+1;
  71.     g_pvs_Z = iROUND(ceilf(size.z/g_params.m_sample_step))+1;
  72.     clMsg("Ceiling dimensions: [%3d,%3d,%3d]",g_pvs_X, g_pvs_Y, g_pvs_Z);
  73.  
  74.     // ground pick setup
  75.     XRC.RayMode         (RAY_ONLYFIRST|RAY_CULL);
  76.     ground_dir.set      (0,-1,0);
  77.  
  78.     // reserve memory
  79.     CFS_File            pvs_map     ("pvs.temp");
  80.     u32             dwSlot      = 0;
  81.     u32             dwSlotsTotal= g_pvs_X*g_pvs_Y*g_pvs_Z;
  82.     u32 pvs_reserve = dwSlotsTotal/1024 + 512;
  83.     clMsg("PVS: %d M"(pvs_reserve*sizeof(vecW))/(1024*1024));
  84.     g_pvs.reserve       (pvs_reserve);
  85.  
  86.     // begin!
  87.     Status("Processing...");
  88.     u32             dwStartTime = timeGetTime();
  89.     for (int z=0; z<g_pvs_Z; z++) {
  90.         for (int x=0; x<g_pvs_X; x++) {
  91.             for (int y=0; y<g_pvs_Y; y++)
  92.             {
  93.                 pos.set(x,y,z);
  94.                 pos.mul(g_params.m_sample_step);
  95.                 pos.add(g_TREE_ROOT->bbox.min);
  96.                 dwSlot++;
  97.                
  98.                 // ground pick
  99.                 XRC.RayPick(precalc_identity,1.f,&RCAST_Model,pos,ground_dir,g_params.m_sample_break);
  100.                 if (XRC.GetRayContactCount()==0)
  101.                 {
  102.                     // don't calculate PVS for this point
  103.                     int tmp = -1;
  104.                     pvs_map.write(&tmp,4);
  105.                     continue;
  106.                 }
  107.  
  108.                 // Sample PVS data
  109.                 g_TREE_ROOT->VisUnroll(pos,g_selected);
  110.                 if (!g_selected.empty()) {
  111.                     g_result.resize(g_selected.size());
  112.                     ZeroMemory(g_result.begin(),g_result.size()*sizeof(BOOL));
  113.                     ORM_Process(g_selected.size(),pos,g_selected.begin(),g_result.begin());
  114.                    
  115.                     // Exclude invisible
  116.                     for (int i=0; i<g_selected.size(); i++)
  117.                     {
  118.                         if (!g_result[i]) {
  119.                             if (g_tree[g_selected[i]]->isPatch) continue;
  120.                             g_selected.erase(g_selected.begin()+i);
  121.                             g_result.erase(g_result.begin()+i);
  122.                             i--;
  123.                         }
  124.                     }
  125.                 }
  126.                
  127.                 // Compress and record PVS sample
  128.                 pvs_map.w_u32(CompressSelected());
  129.                 g_selected.clear();
  130.  
  131.                 // Statistic
  132.                 if (dwSlot%64 == 63)
  133.                 {
  134.                     Progress(float(dwSlot)/float(dwSlotsTotal));
  135.                     u32 dwCurrentTime = timeGetTime();
  136.                     Status("Sample #%d\nSpeed %3.1f samples per second\nPVS entrys: %d",
  137.                         dwSlot,1000.f*float(dwSlot)/float(dwCurrentTime-dwStartTime),
  138.                         g_pvs.size()
  139.                         );
  140.  
  141.                 }
  142.             }
  143.         }
  144.     }
  145.     ORM_Destroy();
  146.     clMsg("* PVS entrys:  %d",  g_pvs.size());
  147.     clMsg("* Aver. Speed: %3.1f",   1000.f*float(dwSlot)/float(timeGetTime()-dwStartTime));
  148. }
RAW Paste Data