Sunday, December 7, 2014

Perlin Generator Class

 #include "Perlin.cpp"  

 #include <vector>
 using namespace std;
 class PerlinGenerator{
      public:
           //PerlinGenerator(void);
           PerlinGenerator(float size, float scale);
           PerlinGenerator(float size, float scale, float zdepth);
           vector<vector<float> > getNoisevalues(void);
           vector<vector<vector<float> > > getNoisevalues3d(void);
      private:  
           float cscale;
           // 513 x 513  
           float csize;
           //Perlin* perlina;
           float zdepth;
           vector<vector<float> > cnoisevals;
           vector<vector<vector<float> > > cnoisevals3d;
           vector<vector<vector<vector<float> > > > cnoisepartials;                    
 };
 PerlinGenerator::PerlinGenerator(float size, float scale){
      //default size = 513
 //     Ogre::Log* tlog = Ogre::LogManager::getSingleton().getLog("Perlin.log");
      csize = size;
      cscale = scale;
      int maxnode = ((int)size)/scale + 2;
      Perlin* perlina = new Perlin(maxnode, maxnode);
 /*
      std::ostringstream ss5;
      ss5<< "Test2" << "\n";
      ss5<< "Scale: "<< scale<<"\n";
      ss5<< "Size: " << size<< "\n";
      ss5<< "MaxNode: "<< maxnode << "\n";
      tlog->logMessage(ss5.str());
 */
      float maxval = 0.0f, minval = 0.0f;
      vector<vector<float> > noiseval((int)size);  
      for (int i = 0; i < size; i++){
           noiseval[i].resize(size);
           for(int j = 0; j < size; j++){
                float x = i/scale;
                float y = j/scale;
 /*
                ss5.str(std::string());
                ss5<< "Test3: " << i<< ","<< j<< "\n";
                ss5<< "pos: " << x << ","<< y <<"\n";
                tlog->logMessage(ss5.str());
 */
                float val = perlina->getNoiseValue(x,y);
                if (val < minval){
                     minval = val;
                }
                if (val > maxval){
                     maxval = val;
                }
                noiseval[i][j] = val;
           }
      }
      //std::ostringstream ss5;
 /*
      ss5.str(std::string());
      ss5<< "Test4" << "\n";
      tlog->logMessage(ss5.str());
 */
      //we assume that at least one value will be inclose proximity to  
      //a ceiling range of possible noise values here...
      //we can however limits the ceiling of values on greyscale returns further.
      //rescale values...we don't know what the possible range  
      //is formally on the set of returned noise values
      //so we test the min and max values for which ever
      //has the greatest magnitude  
      float scaleceiling;
      if (abs(minval)< abs(maxval)){
      //floor maxval to an int and then add 1 for ceiling.
           if ((int)maxval == abs(maxval)){
                scaleceiling = abs(maxval);
           }
           else{
                scaleceiling = (int)abs(maxval)+1;
           }
      }
      else{
           if (abs((int)minval) == abs(minval)){
                scaleceiling = abs(minval);
           }
           else{
                scaleceiling = (int)abs(minval)+1;
           }
      }
      //now we reiterate all noise points and divide by scaleceiling  
      //to ensure all points are within the range [-1,1]
      // divide this value by 1/2 to put it within range [-1/2, 1/2]
      // and then translate the value by +1/2 to put it within range  
      // [0,1]
      for (int i = 0; i < size; i++){      
           for(int j = 0; j < size; j++){
                noiseval[i][j] = (noiseval[i][j]/scaleceiling)/2 + .5;
           }
      }
      cnoisevals = noiseval;          
 }
 PerlinGenerator::PerlinGenerator(float size, float scale, float zdepth){
      //default size = 513
 //     Ogre::Log* tlog = Ogre::LogManager::getSingleton().getLog("Perlin.log");
      csize = size;
      cscale = scale;
      int maxnode = ((int)size)/scale + 2;
      Perlin* perlina = new Perlin(maxnode, maxnode, (int)zdepth);
 /*
      std::ostringstream ss5;
      ss5<< "Test2" << "\n";
      ss5<< "Scale: "<< scale<<"\n";
      ss5<< "Size: " << size<< "\n";
      ss5<< "MaxNode: "<< maxnode << "\n";
      tlog->logMessage(ss5.str());
 */
      float maxval = 0.0f, minval = 0.0f;
      vector<vector<vector<float> > > noiseval((int)size);
      //vector<vector<vector<vector<float> > > > noisepartials((int)size);
      //vector<float> retval(4);  
      for (int i = 0; i < size; i++){
           noiseval[i].resize((int)size);
      //     noisepartials[i].resize((int)size);
           for(int j = 0; j < size; j++){
             noiseval[i][j].resize((int)zdepth);
      //       noisepartials[i][j].resize((int)zdepth);
             for (int k = 0; k < zdepth-1; k++){
      //          noisepartials[i][j][k].resize(3);
                float x = i/scale;
                float y = j/scale;
                float z = k/scale;
 /*
                ss5.str(std::string());
                ss5<< "Test3: " << i<< ","<< j<< "\n";
                ss5<< "pos: " << x << ","<< y <<"\n";
                tlog->logMessage(ss5.str());
 */
                float val = perlina->getNoiseValue(x,y,z);
      //          perlina->dnoise3f( &retval, x, y, z );
      //          noiseval[i][j][k] = retval[0];
 //               float val = retval[0];
      //          noisepartials[i][j][k][1] = retval[1];
      //          noisepartials[i][j][k][2] = retval[2];
      //          noisepartials[i][j][k][3] = retval[3];
                if (val < minval){
                     minval = val;
                }
                if (val > maxval){
                     maxval = val;
                }
                noiseval[i][j][k] = val;
             }
           }
      }
      //std::ostringstream ss5;
 /*
      ss5.str(std::string());
      ss5<< "Test4" << "\n";
      tlog->logMessage(ss5.str());
 */
      //we assume that at least one value will be inclose proximity to  
      //a ceiling range of possible noise values here...
      //we can however limits the ceiling of values on greyscale returns further.
      //rescale values...we don't know what the possible range  
      //is formally on the set of returned noise values
      //so we test the min and max values for which ever
      //has the greatest magnitude  
      float scaleceiling;
      if (abs(minval)< abs(maxval)){
      //floor maxval to an int and then add 1 for ceiling.
           if ((int)maxval == abs(maxval)){
                scaleceiling = abs(maxval);
           }
           else{
                scaleceiling = (int)abs(maxval)+1;
           }
      }
      else{
           if (abs((int)minval) == abs(minval)){
                scaleceiling = abs(minval);
           }
           else{
                scaleceiling = (int)abs(minval)+1;
           }
      }
      //now we reiterate all noise points and divide by scaleceiling  
      //to ensure all points are within the range [-1,1]
      // divide this value by 1/2 to put it within range [-1/2, 1/2]
      // and then translate the value by +1/2 to put it within range  
      // [0,1]
      for (int i = 0; i < size; i++){      
           for(int j = 0; j < size; j++){
             for(int k = 0; k < (int)zdepth-1; k++){
                noiseval[i][j][k] = (noiseval[i][j][k]/scaleceiling)/2 + .5;
             }
           }
      }
      cnoisevals3d = noiseval;
      //cnoisepartials = noisepartials;          
 }
 vector<vector<float> > PerlinGenerator::getNoisevalues(){
      return cnoisevals;
 }
 vector<vector<vector<float> > > PerlinGenerator::getNoisevalues3d(){
      return cnoisevals3d;
 }


This is a Ogre middle interface that handles both sending and returning data for point to noise retrieval.

I handle this with a scaling algorithm both pre and post noise generation.


No comments:

Post a Comment

Oblivion

 Between the fascination of an upcoming pandemic ridden college football season, Taylor Swift, and Kim Kardashian, wildfires, crazier weathe...