Got an iPhone or iPad? We have a brand new Pastebin App for both devices, and it's totally free! Click here to download the new Pastebin App for iOS.
Guest

Untitled

By: a guest on Feb 22nd, 2012  |  syntax: C++  |  size: 4.00 KB  |  hits: 19  |  expires: Never
download  |  raw  |  embed  |  report abuse
Copied
  1. //topogen.cpp
  2. //makes a big heightmap
  3. //betopp 2011
  4.  
  5. //uploaded to freenode #vidyadev, public domain
  6.  
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <math.h>
  11. #include <ImfChannelList.h>
  12. #include <ImfTiledOutputFile.h>
  13. #include <half.h>
  14.  
  15. #define MAPSIZE 16385
  16.  
  17. #define CELLSIZE 256
  18.  
  19. #define HM(hmx,hmy) heightmap[((hmy)*MAPSIZE)+(hmx)]
  20.  
  21. #define VARDECAY 0.3f
  22.  
  23.  
  24. void squarestep(float *heightmap, int xmin, int ymin, int xmax, int ymax, float var)
  25. {
  26.         if(xmin >= (xmax))
  27.                 return;
  28.        
  29.         if(ymin >= (ymax))
  30.                 return;
  31.        
  32.        
  33.        
  34.        
  35.         int xmiddle = (xmin + xmax) / 2;
  36.         int ymiddle = (ymin + ymax) / 2;
  37.                
  38.  
  39.  
  40.         HM( xmiddle, ymiddle ) = (HM(xmax, ymax) + HM(xmax, ymin) + HM(xmin, ymax) + HM(xmin, ymin)) / 4.0f;           
  41.         HM( xmiddle, ymiddle ) += 2.0f * (((float)random() / (float)RAND_MAX) - 0.5f) * var;   
  42. }
  43.  
  44.  
  45. void squarestep_for_offset(float *heightmap, int offset, int stepsize, float var)
  46. {
  47.        
  48.        
  49.         int cx;
  50.         int cy;
  51.  
  52.                
  53.        
  54.         for(cy=offset;cy<(MAPSIZE-stepsize);cy+=stepsize)
  55.         {
  56.        
  57.                 for(cx=offset;cx<(MAPSIZE-stepsize);cx+=stepsize)
  58.                 {
  59.                         squarestep(heightmap, cx, cy, cx+stepsize, cy+stepsize, var);
  60.                 }
  61.                
  62.         }
  63. }
  64.  
  65.  
  66.  
  67. void diamonds(float *heightmap, float var)
  68. {
  69.         int cy, cx;
  70.         for(cy=1;cy<MAPSIZE-1;cy++)
  71.         {
  72.                 for(cx=1;cx<MAPSIZE-1;cx++)
  73.                 {
  74.                         if( ((cx+cy)%2) )
  75.                         {
  76.                        
  77.                                         HM(cx, cy) = ((HM((cx+1), cy)) + (HM((cx-1), cy)) + (HM(cx, (cy+1))) + (HM(cx, (cy-1)))) / 4.0f;
  78.                                
  79.                                
  80.                                         HM( cx, cy) += 2.0f * (((float)random() / (float)RAND_MAX) - 0.5f) * var;      
  81.                                
  82.                         }
  83.                 }
  84.         }
  85. }
  86.  
  87. void writeexr(half *heightmap)
  88. {
  89. /*      int cellx, celly;
  90.         for(celly = 0; celly < (MAPSIZE-1)/CELLSIZE; celly++)
  91.         {
  92.                 for(cellx = 0; cellx < (MAPSIZE-1)/CELLSIZE; cellx++)
  93.                 {
  94.                        
  95.                 }
  96.                
  97.        
  98.         }*/
  99.        
  100.         /*          float pixelAspectRatio = 1,
  101.             const Imath::V2f &screenWindowCenter = Imath::V2f (0, 0),
  102.             float screenWindowWidth = 1,
  103.             LineOrder lineOrder = INCREASING_Y,
  104.             Compression = ZIP_COMPRESSION);*/
  105.        
  106.        
  107.         Imf::Header imfH(MAPSIZE-1, MAPSIZE-1, 1, Imath::V2f (0, 0), 1, Imf::INCREASING_Y, Imf::B44A_COMPRESSION);
  108.        
  109.         imfH.channels().insert("Z", Imf::Channel(Imf::HALF));
  110.        
  111.         imfH.setTileDescription(Imf::TileDescription(CELLSIZE, CELLSIZE, Imf::MIPMAP_LEVELS));
  112.        
  113.         Imf::TiledOutputFile imfOut("heightmap.exr", imfH);
  114.        
  115.         Imf::FrameBuffer imfFB;
  116.        
  117.         imfFB.insert("Z", Imf::Slice(Imf::HALF, (char*)heightmap, sizeof(half), sizeof(half)*MAPSIZE));
  118.        
  119.         imfOut.setFrameBuffer(imfFB);
  120.        
  121.        
  122.         int lsize = MAPSIZE-1;
  123.        
  124.         int level;
  125.         for(level=0;level<imfOut.numLevels();++level)
  126.         {
  127.                
  128.                 imfOut.writeTiles(0, imfOut.numXTiles(level)-1, 0, imfOut.numYTiles(level)-1, level);
  129.                
  130.                 lsize = lsize / 2;
  131.        
  132.                 int cx, cy;
  133.                 for(cy=0;cy<lsize;cy++)
  134.                 {
  135.                         for(cx=0;cx<lsize;cx++)
  136.                         {
  137.                                 int lowx = 2*cx;
  138.                                 int highx = lowx + 1;
  139.                                
  140.                                 int lowy = 2*cy*MAPSIZE;
  141.                                 int highy = lowy + MAPSIZE;
  142.                                
  143.                                 heightmap[(cy*MAPSIZE)+cx] = (heightmap[lowx+lowy] + heightmap[lowx+highy] + heightmap[highx+lowy] + heightmap[highx+highy]) / 4.0f;
  144.                         }
  145.                 }
  146.                
  147.                
  148.         }
  149. }
  150.  
  151. int main(int argc, const char **argv)
  152. {
  153.         int count;
  154.         int squaresize;
  155.         float var = 100.0f;
  156.        
  157.         //allocate and initialize the map
  158.         float *heightmap = (float*)malloc(sizeof(float)*MAPSIZE*MAPSIZE);
  159.        
  160.         for(count=0;count<MAPSIZE*MAPSIZE;count++)
  161.         {
  162.                 heightmap[count] = 0.0f;
  163.         }
  164.        
  165.         for(squaresize=(MAPSIZE-1);squaresize>1;squaresize = squaresize/2)
  166.         {
  167.                 squarestep_for_offset(heightmap, 0, squaresize, var);
  168.                
  169.                 squarestep_for_offset(heightmap, squaresize/2, squaresize, var);
  170.        
  171.                 var *= VARDECAY;
  172.                
  173.         }
  174.        
  175.         diamonds(heightmap, var);
  176.        
  177.        
  178.         float min = 999999.0f;
  179.         float max = -999999.0f;
  180.        
  181.         for(count=0;count<MAPSIZE*MAPSIZE;count++)
  182.         {
  183.                 if(heightmap[count] < min)
  184.                         min = heightmap[count];
  185.                 if(heightmap[count] > max)
  186.                         max = heightmap[count];
  187.         }
  188.         printf("min max %f %f\n", min, max);
  189.        
  190.  
  191.         half *halfbuf = (half*)heightmap;
  192.        
  193.        
  194.         for(count=0;count<MAPSIZE*MAPSIZE;count++)
  195.         {
  196.                 halfbuf[count] = half((heightmap[count] - min) / (max - min));
  197.         }
  198.        
  199.         //write chunky map
  200.         writeexr(halfbuf);
  201.  
  202.         return 0;
  203. }