CUgopEntity

xrVis.cpp

Jun 14th, 2020
175
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "stdafx.h"
  2. #include "build.h"
  3. #include "math.h"
  4. #include "ffileops.h"
  5.  
  6. // from xrPVS
  7. typedef xr_vector<u16>  vecW;
  8. typedef vecW::iterator  vecW_IT;
  9.  
  10. extern xr_vector<vecW>      g_pvs;
  11. extern u32          g_pvs_X,g_pvs_Y,g_pvs_Z;
  12.  
  13. struct V_Header {
  14.     u32 nX,nY,nZ;
  15.     float   relevance;
  16.     Fvector min;
  17. };
  18.  
  19. u32 PlaceData(xr_vector<vecW> &C, vecW &P)
  20. {
  21.     if (P.size()>1) {
  22.         std::sort   (P.begin(),P.end());
  23.         vecW::iterator I = std::unique  (P.begin(),P.end());
  24.         P.erase(I,P.end());
  25.     }
  26.  
  27.     // Search placeholder
  28.     u32 sz  = P.size();
  29.     u32 pos = 0;
  30.     for (xr_vector<vecW>::iterator it=C.begin(); it!=C.end(); it++)
  31.     {
  32.         u32 S = it->size();
  33.         if (S!=sz) { pos+=S+1; continue; }
  34.         if (0!=memcmp(it->begin(),P.begin(),S*sizeof(u16))) { pos+=S+1; continue; }
  35.  
  36.         // Ok-Ob :)
  37.         goto exit;
  38.     }
  39.  
  40.     // If we get here - need to register _new set of data
  41.     C.push_back(P);
  42.  
  43. exit:
  44.     P.clear();
  45.     return pos*sizeof(u16);
  46. }
  47.  
  48. void SaveDATA(IWriter &fs, xr_vector<vecW> &C)
  49. {
  50.     for (xr_vector<vecW>::iterator it=C.begin(); it!=C.end(); it++)
  51.     {
  52.         fs.Wword(it->size());
  53.         fs.write(it->begin(),it->size()*sizeof(u16));
  54.     }
  55. }
  56.  
  57. int*    g_pvs_map_vm = 0;
  58. void CalculateRelSet(Fvector &pos, vecW &rel_set)
  59. {
  60.     // calculate volume in local level space
  61.     Fbox    Volume;
  62.     Volume.set(pos,pos);
  63.     float   Vsize = (g_params.m_relevance+g_params.m_sample_step)/2.f;
  64.     Volume.min.sub(Vsize);
  65.     Volume.max.add(Vsize);
  66.     Volume.min.sub(g_TREE_ROOT->bbox.min);
  67.     Volume.max.sub(g_TREE_ROOT->bbox.min);
  68.  
  69.     // scale it to sample grid space
  70.     Volume.min.div(g_params.m_sample_step);
  71.     Volume.max.div(g_params.m_sample_step);
  72.  
  73.     // calc volume in grid-space
  74.     int minX,minY,minZ;
  75.     int maxX,maxY,maxZ;
  76.  
  77.     minX = iROUND(floorf(Volume.min.x));    clamp(minX, 0, int(g_pvs_X)-1);
  78.     minY = iROUND(floorf(Volume.min.y));    clamp(minY, 0, int(g_pvs_Y)-1);
  79.     minZ = iROUND(floorf(Volume.min.z));    clamp(minZ, 0, int(g_pvs_Z)-1);
  80.  
  81.     maxX = iROUND(ceilf(Volume.max.x));     clamp(maxX, 0, int(g_pvs_X)-1);
  82.     maxY = iROUND(ceilf(Volume.max.y));     clamp(maxY, 0, int(g_pvs_Y)-1);
  83.     maxZ = iROUND(ceilf(Volume.max.z));     clamp(maxZ, 0, int(g_pvs_Z)-1);
  84.  
  85.     /*
  86.     clMsg("- Selected BB: [%d,%d,%d]-[%d,%d,%d]",
  87.         minX,minY,minZ,
  88.         maxX,maxY,maxZ
  89.         );
  90.     */
  91.  
  92.     // merge data
  93.     for (int z=minZ; z<=maxZ; z++) {
  94.         for (int x=minX; x<=maxX; x++) {
  95.             for (int y=minY; y<=maxY; y++)
  96.             {
  97.                 u32 cell    = z*g_pvs_X*g_pvs_Y + x*g_pvs_Y + y;
  98. //              clMsg("* Sample #%d",cell);
  99.                 int     ptr     = g_pvs_map_vm[cell];
  100.                 if (ptr>=0)
  101.                 {
  102.                     rel_set.insert(rel_set.end(),g_pvs[ptr].begin(),g_pvs[ptr].end());
  103.                 }
  104.             }
  105.         }
  106.     }
  107.     if (rel_set.size()>1)
  108.     {
  109.         std::sort(rel_set.begin(),rel_set.end());
  110.         vecW_IT I = std::unique(rel_set.begin(),rel_set.end());
  111.         rel_set.erase(I,rel_set.end());
  112.     }
  113. }
  114.  
  115. void CBuild::BuildRelevance(IWriter &fs)
  116. {
  117.     static Fvector size;
  118.     static u32  nx,ny,nz;
  119.  
  120.     Status("Preparing...");
  121.     R_ASSERT(g_TREE_ROOT);
  122.     g_TREE_ROOT->bbox.getsize(size);
  123.     clMsg("Level dimensions: [%3.1f,%3.1f,%3.1f]",size.x,size.y,size.z);
  124.     nx = iROUND(ceilf(size.x/g_params.m_relevance));
  125.     ny = iROUND(ceilf(size.y/g_params.m_relevance));
  126.     nz = iROUND(ceilf(size.z/g_params.m_relevance));
  127.     clMsg("Ceiling dimensions: [%3d,%3d,%3d]",nx, ny, nz);
  128.  
  129.     fs.open_chunk(fsL_VISIBILITY);
  130.  
  131.     fs.open_chunk(fsV_HEADER);
  132.     V_Header        H;
  133.     H.nX            = nx;
  134.     H.nY            = ny;
  135.     H.nZ            = nz;
  136.     H.relevance     = g_params.m_relevance;
  137.     H.min.set       (g_TREE_ROOT->bbox.min);
  138.     fs.write        (&H,sizeof(H));
  139.     fs.close_chunk  ();
  140.  
  141.     // Build Visibility
  142.     static xr_vector< u32 >     slots;
  143.     static xr_vector< vecW >        vis_nodes;
  144.     static xr_vector< vecW >        vis_lights;
  145.     static xr_vector< vecW >        vis_glows;
  146.     static xr_vector< vecW >        vis_occluders;
  147.     static vecW                 rel_set;
  148.     static vecW                 unroll;
  149.  
  150.     CVirtualFileStream*         pvs_map_stream=0;
  151.     if (g_params.m_bTestOcclusion)
  152.     {
  153.         pvs_map_stream  = xr_new<CVirtualFileStream> ("pvs.temp");
  154.         g_pvs_map_vm    = (int *)pvs_map_stream->Pointer();
  155.     }
  156.  
  157.     static u32              dwSlot = 0;
  158.     for (int z=0; z<nz; z++) {
  159.         for (int x=0; x<nx; x++) {
  160.             for (int y=0; y<ny; y++)
  161.             {
  162.                 Status("Volume #%d...",dwSlot);
  163.                 static Fvector pos;
  164.                 pos.set(x,y,z);
  165.                 pos.add(.5f);
  166.                 pos.mul(g_params.m_relevance);
  167.                 pos.add(g_TREE_ROOT->bbox.min);
  168.  
  169.                 // ******* Nodes relevance
  170.                 if (g_params.m_bTestOcclusion)
  171.                 {
  172.                     CalculateRelSet(pos,unroll);
  173.                     if (unroll.empty() || g_TREE_ROOT->VisCapture(unroll,rel_set))
  174.                         rel_set.push_back(g_tree.size()-1);
  175.                     unroll.clear();
  176.                     slots.push_back(PlaceData(vis_nodes,rel_set));
  177.                 } else {
  178.                     // Unroll hierrarhy
  179.                     VERIFY(g_TREE_ROOT);
  180.                     g_TREE_ROOT->VisUnroll(pos,unroll);
  181.                     if (unroll.size()>1)
  182.                         std::sort(unroll.begin(),unroll.end());
  183.                     // Capture results
  184.                     if (g_TREE_ROOT->VisCapture(unroll,rel_set))
  185.                         rel_set.push_back(g_tree.size()-1);
  186.                     unroll.clear();
  187.                     // Register in container
  188.                     slots.push_back(PlaceData(vis_nodes,rel_set));
  189.                 }
  190.  
  191.                 // Lights relevance
  192.                 for (int i=0; i<lights.size(); i++)
  193.                 {
  194.                     if ((pos.distance_to(lights[i].position) - lights[i].range) < g_params.m_viewdist) {
  195.                         rel_set.push_back(i);
  196.                     }
  197.                 }
  198.                 slots.push_back(PlaceData(vis_lights,rel_set));
  199.  
  200.                 // Glows relevance
  201.                 for (i=0; i<glows.size(); i++)
  202.                 {
  203.                     if ((pos.distance_to(glows[i].P) - glows[i].size) < g_params.m_viewdist) {
  204.                         rel_set.push_back(i);
  205.                     }
  206.                 }
  207.                 slots.push_back(PlaceData(vis_glows,rel_set));
  208.  
  209.                 // Occluders relevance
  210.                 for (i=0; i<occluders.size(); i++)
  211.                 {
  212.                     Fvector P; float R=-1; float T;
  213.                     P.add(occluders[i].V2,occluders[i].V4);
  214.                     P.mul(.5f);
  215.                     T = P.distance_to(occluders[i].V1); if (T>R) R=T;
  216.                     T = P.distance_to(occluders[i].V2); if (T>R) R=T;
  217.                     T = P.distance_to(occluders[i].V4); if (T>R) R=T;
  218.                     if ((pos.distance_to(P) - R) < g_params.m_viewdist*g_params.m_occluder_rel_scale) {
  219.                         rel_set.push_back(i);
  220.                     }
  221.                 }
  222.                 slots.push_back(PlaceData(vis_occluders,rel_set));
  223.  
  224.                 dwSlot++;
  225.                 Progress(float(dwSlot)/float(nz*nx*ny));
  226.             }
  227.         }
  228.     }
  229.  
  230.  
  231.     xr_delete       (pvs_map_stream);
  232.  
  233.     fs.open_chunk   (fsV_NODES);
  234.     SaveDATA        (fs,vis_nodes);
  235.     fs.close_chunk  ();
  236.  
  237.     fs.open_chunk(fsV_LIGHTS);
  238.     SaveDATA(fs,vis_lights);
  239.     fs.close_chunk();
  240.  
  241.     fs.open_chunk(fsV_GLOWS);
  242.     SaveDATA(fs,vis_glows);
  243.     fs.close_chunk();
  244.  
  245.     fs.open_chunk(fsV_OCCLUDERS);
  246.     SaveDATA(fs,vis_occluders);
  247.     fs.close_chunk();
  248.  
  249.     fs.open_chunk(fsV_MAP);
  250.     fs.write(slots.begin(),slots.size()*sizeof(u32));
  251.     fs.close_chunk();
  252.  
  253.     fs.close_chunk();
  254. }
RAW Paste Data