vivienneanthony

Olsen Noise Algorithm C++ WIP (Working copy).

Feb 18th, 2015
410
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.94 KB | None | 0 0
  1. /*
  2.  * Original Author @author Tat
  3.  * Mod code Vivienne Anthony
  4.  * c++ rewrite vivienne (WIP)
  5.  * verion 1.0 Functional Rewrite
  6.  *
  7.  * Changes
  8.  *  Java to C++ conversion
  9.  *  Memory pointer usage
  10.  */
  11.  
  12. #include <iostream>
  13. #include <vector>
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <png++/png.hpp>
  18.  
  19. using namespace std;
  20.  
  21. void SaveTerrFile(const int * image, int size, char * filename);
  22.  
  23.  
  24. class OlsenNoise2D
  25. {
  26.  
  27. public:
  28.     int * olsennoise(int x, int y, int width, int height);
  29.  
  30. private:
  31.     int hashrandom(std::vector<long long int> elements);
  32.     long long hash(long long v);
  33.  
  34. };
  35.  
  36. int * OlsenNoise2D::olsennoise(int x, int y, int width, int height)
  37. {
  38.     int maxiterations = 7;
  39.     int cx, cy;
  40.     int cxh, cyh;
  41.     int cwidth, cheight;
  42.     int xoff, yoff;
  43.     int nwidth, nheight;
  44.     int nx, ny;
  45.     int nxh, nyh;
  46.     int m=0;
  47.     int n=0;
  48.     int fieldwidth=0;
  49.     int fieldheight=0;
  50.  
  51.     int * field = NULL;
  52.  
  53.     for (int iteration = 0; iteration < maxiterations; iteration++)
  54.     {
  55.         nx = x;
  56.         ny = y;
  57.  
  58.         nxh = x + width;
  59.         nyh = y + height;
  60.  
  61.         for (int i = 1,n = maxiterations - iteration; i < n; i++)
  62.         {
  63.             nx = (nx / 2) - 1;
  64.             ny = (ny / 2) - 1;
  65.             nxh = 1 -(-nxh/2);
  66.             nyh = 1 -(-nyh/2);
  67.         }
  68.  
  69.         xoff = -2*((nx/2)) + nx + 1;
  70.         yoff = -2*((ny/2)) + ny + 1;
  71.  
  72.         cx = (nx / 2) - 1;
  73.         cy = (ny / 2) - 1;
  74.         cxh = 1 -(-nxh/2);
  75.         cyh = 1 -(-nyh/2);
  76.  
  77.         nwidth = nxh - nx;
  78.         nheight = nyh - ny;
  79.  
  80.         cwidth = cxh - cx;
  81.         cheight = cyh - cy;
  82.  
  83.         /// rest
  84.         fieldwidth=cwidth;
  85.         fieldheight=cheight;
  86.  
  87.         /// Only happens once
  88.         if (field==NULL)
  89.         {
  90.             /// allocate memory
  91.             field = new int[cheight * cwidth];
  92.  
  93.             /// blank value
  94.             for (int x = 0; x < cwidth; x++)
  95.             {
  96.                 for (int y = 0; y < cheight; y++)
  97.                 {
  98.                     field[x+(y*cwidth)]=0;
  99.                 }
  100.             }
  101.         }
  102.  
  103.         /// First loop
  104.         for (int j = 0, m=cwidth; j < m; j++)
  105.         {
  106.             for (int k = 0, n=cheight; k < n; k++)
  107.             {
  108.                 field[j+(k*m)] += (hashrandom( {cx + j, cy + k, iteration}) & (1 << (7 - iteration)));
  109.             }
  110.         }
  111.  
  112.         /// Up sampled
  113.         int * upsampled = new int[(fieldwidth*2)*(fieldheight*2)];
  114.         long int upsampledsize=(fieldwidth*2)*(fieldheight*2);
  115.  
  116.         for (int j = 0, m=fieldwidth*2; j < m; j++)
  117.         {
  118.             for (int k = 0,n=fieldheight*2; k < n; k++)
  119.             {
  120.                 upsampled[j+(k*m)] = field[(j / 2)+((k / 2)*fieldwidth)];
  121.             }
  122.         }
  123.  
  124.         /// Allocate upsampled to field
  125.         delete [] field;
  126.         field = upsampled;
  127.  
  128.         /// Copy new fieldwieght and fieldheight
  129.         fieldwidth=fieldwidth*2;
  130.         fieldheight=fieldheight*2;
  131.  
  132.         /// Blur field
  133.         int * blurfield =new int[(fieldwidth-2)*(fieldheight-2)];
  134.         long int blurfieldsize = (fieldwidth-2)*(fieldheight-2);
  135.  
  136.         for (int j = 0,m=fieldwidth-2; j < m; j++)
  137.         {
  138.             for (int k = 0, n=fieldheight-2;  k < n; k++)
  139.             {
  140.                 for (int h = 0; h < 9; h++)
  141.                 {
  142.                     blurfield[j+(k*m)] += field[(j + (h % 3))+((k+(h/ 3))*fieldwidth)];
  143.                 }
  144.                 blurfield[j+(k*m)] /= 9;
  145.             }
  146.         }
  147.  
  148.         /// Allocate blurfield to field
  149.         delete [] field;
  150.         field = blurfield;
  151.  
  152.         /// Copy new fieldwieght and fieldheight
  153.         fieldwidth=fieldwidth-2;
  154.         fieldheight=fieldheight-2;
  155.  
  156.         /// Trim field
  157.         int * trimfield = new int[nwidth*nheight];
  158.         long int trimfieldsize = nwidth*nheight;
  159.  
  160.         for (int j = 0, m=nwidth; j < m; j++)
  161.         {
  162.             for (int k = 0, n=nheight; k < n; k++)
  163.             {
  164.                 trimfield[j+(k*m)] = field[(j + xoff)+((k + yoff)*fieldwidth)];
  165.             }
  166.         }
  167.  
  168.         /// Allocate trimfield to field
  169.         delete [] field;
  170.         field = trimfield;
  171.  
  172.     }
  173.  
  174.     return field;
  175. }
  176.  
  177. int OlsenNoise2D::hashrandom(std::vector<long long int> elements)
  178. {
  179.     long long hashcalc = 0;
  180.  
  181.  
  182.     for (int i = 0; i < elements.size(); i++)
  183.     {
  184.         hashcalc ^= elements[i];
  185.         hashcalc = hash(hashcalc);
  186.     }
  187.     return (int) hashcalc;
  188. };
  189.  
  190. long long OlsenNoise2D::hash(long long v)
  191. {
  192.     long long hash = v;
  193.     long long h = hash;
  194.  
  195.     switch ((int) hash & 3)
  196.     {
  197.     case 3:
  198.         hash += h;
  199.         hash ^= hash << 32;
  200.         hash ^= h << 36;
  201.         hash += hash >> 22;
  202.         break;
  203.     case 2:
  204.         hash += h;
  205.         hash ^= hash << 22;
  206.         hash += hash >> 34;
  207.         break;
  208.     case 1:
  209.         hash += h;
  210.         hash ^= hash << 20;
  211.         hash += hash >> 2;
  212.     }
  213.     hash ^= hash << 6;
  214.     hash += hash >> 10;
  215.     hash ^= hash << 8;
  216.     hash += hash >> 34;
  217.     hash ^= hash << 50;
  218.     hash += hash >> 12;
  219.     return hash;
  220. };
  221.  
  222.  
  223. int main()
  224. {
  225.     /// Test
  226.     int ImageSize=2049;
  227.     int * imageInput = new int[ImageSize*ImageSize];
  228.  
  229.     /// Image
  230.     OlsenNoise2D testingolsen;
  231.     imageInput=testingolsen.olsennoise(0,0,ImageSize,ImageSize);
  232.  
  233.     SaveTerrFile(imageInput, ImageSize, "output.png");
  234.  
  235.     delete imageInput;http://pastebin.com/1i0vwJgv
  236.  
  237.     return 1;
  238. }
  239.  
  240.  
  241. void SaveTerrFile(const int * image, int size, char * filename)
  242. {
  243.     png::image< png::rgb_pixel > newimage(size, size);
  244.  
  245.     for (unsigned int y = 0; y < newimage.get_width(); ++y)
  246.     {
  247.         for (unsigned int x = 0; x < newimage.get_height(); ++x)
  248.         {
  249.             int col = int(image[x+(y*newimage.get_width())]);
  250.             newimage[y][x] = png::rgb_pixel(col,col,col);
  251.             // non-checking equivalent of image.set_pixel(x, y, ...);
  252.         }
  253.     }
  254.  
  255.     newimage.write(filename);
  256. }
Advertisement
Add Comment
Please, Sign In to add comment