Guest User

Greedy meshing - C++

a guest
Aug 4th, 2014
66
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // in the snippet following variables will be needed:
  2. // chunkSizeX/Y/Z - the size of one chunk in the x/y/z-direction
  3. // sectionHeight - the height of one section inside a chunk, e.g.: sectionHeight = 16 and chunkSizeY=256 makes 16 sections
  4. // currentChunk - reference to a Chunk structure
  5.  
  6.  
  7. enum Face
  8. {
  9.     North   = 1,
  10.     East    = 2,
  11.     South   = 4,
  12.     West    = 8,
  13.     Top = 16,
  14.     Bottom  = 32
  15. };
  16.  
  17. struct Block
  18. {
  19.     int Type;
  20.     Face VisibleFaces;
  21. };
  22.  
  23. struct Chunk
  24. {
  25.     float x, y, z;
  26.     Block blockData[];
  27. };
  28.  
  29.  
  30. int numBlocksPerSection = chunkSizeX * sectionHeight * chunkSizeZ;
  31. bool handled[] = new bool[numBlocksPerSection];
  32. Face activeFace = (Face)1;
  33.  
  34. // iterate over all 6 faces
  35. for (int f = 0; f < 6; ++f)
  36. {
  37.     // reset all blocks not to be handled
  38.     memset(handled, FALSE, numBlocksPerSection);
  39.  
  40.     for(int x = 0; x < chunkSizeX; ++x)
  41.     {
  42.         for(int y = 0; y < sectionHeight; ++y)
  43.         {
  44.             for(int z = 0; z < chunkSizeZ; ++z)
  45.             {
  46.                 // global and relative indices
  47.                 int iGlobal = x + chunkSizeX * ((y + currentSection * sectionHeight) + chunkSizeY * z);
  48.                 int iRelative = x + chunkSizeX * (y + sectionHeight * z);
  49.  
  50.                 Face faces = currentChunk.blockData[iGlobal].VisibleFaces;
  51.  
  52.                 // continue if face is not visible or was handled already
  53.                 if(!(faces & activeFace) || handled[iRelative])
  54.                 {
  55.                     handled[iRelative] = true;
  56.                     continue;
  57.                 }
  58.  
  59.                 int width = 1, height = 1, depth = 1;
  60.  
  61.                 // skip width check if activeFace is East or West -> no width
  62.                 if(!(activeFace & East || activeFace & West))
  63.                 {
  64.                     // calculate width for same faces being adjacent to current block
  65.                     for(; width < chunkSizeX - x &&
  66.                         currentChunk.blockData[SHIFT_INDEX_X(iGlobal, width)].VisibleFaces & tmp &&
  67.                         currentChunk.blockData[iGlobal].Type == currentChunk.blockData[SHIFT_INDEX_X(iGlobal, width)].Type &&
  68.                         && !handled[SHIFT_SECTIONINDEX_X(iRelative, width)]; ++width);
  69.                 }
  70.  
  71.                 bool done = false;
  72.  
  73.                 // skip depth check if activeFace is North or South -> no depth
  74.                 if(!(activeFace & North || activeFace & South))
  75.                 {
  76.                     // calculate depth for same faces being adjacent to current block
  77.                     for(; depth < chunkSizeZ - z; ++depth)
  78.                     {
  79.                         // this time add another loop, to make sure, only increment depth if all blocks inside the width range are same
  80.                         for(int u = 0; u < width; ++u)
  81.                         {
  82.                             int indexGlobal = SHIFT_INDEX_X(SHIFT_INDEX_Z(iGlobal, depth), u);
  83.                             int indexRelative = SHIFT_RELATIVEINDEX_X(SHIFT_RELATIVEINDEX_Z(iRelative, depth), u);
  84.                             if(!(currentChunk.blockData[indexGlobal].VisibleFaces & activeFace &&
  85.                                 currentChunk.blockData[iGlobal].Type == currentChunk.blockData[indexGlobal].Type) ||
  86.                                 handled[indexRelative])
  87.                             {
  88.                                 done = true;
  89.                                 break;
  90.                             }
  91.                         }
  92.                         if(done)
  93.                             break;
  94.                     }
  95.                 }
  96.  
  97.                 done = false;
  98.  
  99.                 // skip height check if activeFace is Top or Bottom -> no height
  100.                 if(!(activeFace & Top || activeFace & Bottom))
  101.                 {
  102.                     // calculate height
  103.                     for(; height < sectionHeight - y; ++height)
  104.                     {
  105.                         // add loops for width and depth
  106.                         for(int u = 0; u < width; ++u)
  107.                         {
  108.                             for(int v = 0; v < depth; ++v)
  109.                             {
  110.                                 int indexGlobal = SHIFT_INDEX_X(SHIFT_INDEX_Y(SHIFT_INDEX_Z(iGlobal, v), height), u);
  111.                                 int indexRelative = SHIFT_RELATIVEINDEX_X(SHIFT_RELATIVEINDEX_Y(SHIFT_RELATIVEINDEX_Z(iRelative, v), height), u);
  112.                                 if(!(currentChunk.blockData[indexGlobal].VisibleFaces & activeFace ||
  113.                                     currentChunk.blockData[iGlobal].Type == currentChunk.blockData[indexGlobal].Type) ||
  114.                                     handled[indexRelative])
  115.                                 {
  116.                                     done = true;
  117.                                     break;
  118.                                 }
  119.                             }
  120.                             if(done)    break;
  121.                         }
  122.                         if(done)    break;
  123.                     }
  124.                 }
  125.  
  126.                 // make sure we add the calculated face range to the handled array
  127.                 for(int a = 0; a < width; ++a)
  128.                     for(int b = 0; b < height; ++b)
  129.                         for(int c = 0; c < depth; ++c)
  130.                             handled[SHIFT_RELATIVEINDEX_X(SHIFT_RELATIVEINDEX_Y(SHIFT_RELATIVEINDEX_Z(iRelative, c), b), a)] = true;
  131.  
  132.                 // add the quad's vertices here, dependent on the activeFace,
  133.                 // e.g. for North and a counter-clockwise ordering:
  134.                 // position1 = vector3(width + x + currentChunk.x, y + currentChunk.y, depth + z + currentChunk.z);
  135.                 // position2 = vector3(width + x + currentChunk.x, y + height + currentChunk.y, depth + z + currentChunk.z);
  136.                 // position3 = vector3(x + currentChunk.x, y + height + currentChunk.y, depth + z + currentChunk.z);
  137.                 // position4 = vector3(x + currentChunk.x, y + currentChunk.y, depth + z + currentChunk.z);
  138.             }
  139.         }
  140.     }
  141.  
  142.     activeFace = (Face)(activeFace * 2);       
  143. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×