Exemple #1
0
bool raycast(game* g, vec2 from, vec2 to) {
	ivec2 cur(fast_floor(from.x), fast_floor(from.y));
	ivec2 end(fast_floor(to.x), fast_floor(to.y));
	ivec2 sign(sign(to.x - from.x), sign(to.y - from.y));
	vec2 abs_delta(abs(to.x - from.x), abs(to.y - from.y));
	vec2 delta_t(vec2(1.0f) / abs_delta);
	vec2 lb(to_vec2(cur));
	vec2 ub(lb + vec2(1.0f));
	vec2 t(vec2((from.x > to.x) ? (from.x - lb.x) : (ub.x - from.x), (from.y > to.y) ? (from.y - lb.y) : (ub.y - from.y)) / abs_delta);

	for(;;) {
		if (g->is_raycast_solid(cur.x, cur.y))
			return true;

		if (t.x <= t.y) {
			if (cur.x == end.x) break;
			t.x += delta_t.x;
			cur.x += sign.x;
		}
		else {
			if (cur.y == end.y) break;
			t.y += delta_t.y;
			cur.y += sign.y;
		}
	}

	return false;
}
Exemple #2
0
	chunk_pos&
	chunk_pos::operator= (const entity_pos &other)
	{
		this->x = fast_floor (other.x) / 16;
		this->z = fast_floor (other.z) / 16;
		return *this;
	}
Exemple #3
0
	block_pos&
	block_pos::operator= (const entity_pos &other)
	{
		this->x = fast_floor (other.x);
		this->y = fast_floor (other.y);
		this->z = fast_floor (other.z);
		
		//if (this->y <   0) this->y = 0;
		//if (this->y > 255) this->y = 255;
		return *this;
	}
float raw_noise_2d(float x, float y, const uint8_t* perm)
{
    const float F2 = 0.5f * (std::sqrt(3.0f) - 1.0f);
    float s = (x + y) * F2;

    int32_t i = fast_floor(x + s);
    int32_t j = fast_floor(y + s);

    const float G2 = (3.0f - std::sqrt(3.0f)) / 6.0f;
    float t = (i + j) * G2;

    float x0 = x - (i - t);
    float y0 = y - (j - t);

    uint8_t i1 = 0;
    uint8_t j1 = 1;
    if(x0 > y0)
    {
        i1 = 1;
        j1 = 0;
    }

    float x1 = x0 - i1 + G2;
    float y1 = y0 - j1 + G2;
    float x2 = x0 - 1.0f + 2.0f * G2;
    float y2 = y0 - 1.0f + 2.0f * G2;

    uint8_t ii = i & 255;
    uint8_t jj = j & 255;

    uint8_t gi0 = perm[ii + perm[jj     ]     ] % 12;
    uint8_t gi1 = perm[ii + perm[jj + j1] + i1] % 12;
    uint8_t gi2 = perm[ii + perm[jj + 1 ] + 1 ] % 12;

    float t0 = 0.5f - x0 * x0 - y0 * y0;
    float t1 = 0.5f - x1 * x1 - y1 * y1;
    float t2 = 0.5f - x2 * x2 - y2 * y2;

    float n0 = (t0 < 0) ? 0.0f : t0*t0*t0*t0 * dot(grad3[gi0], x0, y0);
    float n1 = (t1 < 0) ? 0.0f : t1*t1*t1*t1 * dot(grad3[gi1], x1, y1);
    float n2 = (t2 < 0) ? 0.0f : t2*t2*t2*t2 * dot(grad3[gi2], x2, y2);

    return 70.0f * (n0 + n1 + n2);
}
    // Classic Perlin noise, 3D version
    float base(float x, float y)
    {

        x *= xscale;  //replace with multiplication
        y *= xscale;
        //get grid point
        int X = fast_floor(x);
        int Y = fast_floor(y);

        x = x - X;
        y = y - Y;

        int gi00 = get_gradient(X+0,Y+0);
        int gi01 = get_gradient(X+0,Y+1);
        int gi10 = get_gradient(X+1,Y+0);
        int gi11 = get_gradient(X+1,Y+1);

        // Calculate noise contributions from each of the eight corners
        float n00= dot(grad+2*gi00, x, y);
        float n10= dot(grad+2*gi10, x-1, y);
        float n01= dot(grad+2*gi01, x, y-1);
        float n11= dot(grad+2*gi11, x-1, y-1);
        // Compute the fade curve value for each of x, y, z

    #if 1
        float u = fade(x);
        float v = fade(y);
    #else
        float u = x;
        float v = y;
    #endif

        // Interpolate along x the contributions from each of the corners
        float nx00 = mix(n00, n10, u);
        float nx10 = mix(n01, n11, u);
        // Interpolate the four results along y
        float nxy = mix(nx00, nx10, v);

        if (nxy < -1 || nxy > 1 ) printf("Error: noise %f \n", nxy);
        //return nxy / 0.707106781f;   //-1 to 1
        return nxy;   //-1 to 1
    }
Exemple #6
0
aabb2 cast_aabb(game* g, aabb2 self, vec2 delta, int* clipped) {
	aabb2 bounds(expand_toward(self, delta));

	int x0 = fast_floor(bounds.min.x);
	int y0 = fast_floor(bounds.min.y);
	int x1 = fast_floor(bounds.max.x);
	int y1 = fast_floor(bounds.max.y);

	vec2 clipped_delta = delta;

	for(int x = x0; x <= x1; x++) {
		for(int y = y0; y <= y1; y++) {
			if (g->get_tile(x, y) != TT_EMPTY) {
				clipped_delta.x = clip_x(aabb2(vec2((float)x, (float)y), vec2((float)(x + 1), (float)(y + 1))), self, clipped_delta.x);
			}
		}
	}

	self.min.x += clipped_delta.x;
	self.max.x += clipped_delta.x;

	for(int x = x0; x <= x1; x++) {
		for(int y = y0; y <= y1; y++) {
			if (g->get_tile(x, y) != TT_EMPTY) {
				clipped_delta.y = clip_y(aabb2(vec2((float)x, (float)y), vec2((float)(x + 1), (float)(y + 1))), self, clipped_delta.y);
			}
		}
	}

	self.min.y += clipped_delta.y;
	self.max.y += clipped_delta.y;

	if (clipped) {
		*clipped = 0;
		if (delta.x != clipped_delta.x) *clipped |= (delta.x > 0.0f) ? CLIPPED_XP : CLIPPED_XN;
		if (delta.y != clipped_delta.y) *clipped |= (delta.y > 0.0f) ? CLIPPED_YP : CLIPPED_YN;
	}

	return self;
}
/** @brief MATLAB Driver.
 **/
void
mexFunction(int nout, mxArray *out[], 
            int nin, const mxArray *in[])
{
  int M,N,S=0,smin=0,K,num_levels=0 ;
  const int* dimensions ;
  const double* P_pt ;
  const double* G_pt ;
  float* descr_pt ;
  float* buffer_pt ;
  float sigma0 ;
  float magnif = 3.0f ; /* Spatial bin extension factor. */
  int NBP = 4 ;         /* Number of bins for one spatial direction (even). */
  int NBO = 8 ;         /* Number of bins for the ortientation. */
  int mode = NOSCALESPACE ;
  int buffer_size=0;

  enum {IN_G=0,IN_P,IN_SIGMA0,IN_S,IN_SMIN} ;
  enum {OUT_L=0} ;

  /* ------------------------------------------------------------------
  **                                                Check the arguments
  ** --------------------------------------------------------------- */ 
 
  if (nin < 3) {
    mexErrMsgTxt("At least three arguments are required") ;
  } else if (nout > 1) {
    mexErrMsgTxt("Too many output arguments.");
  }
                
  if( !uIsRealScalar(in[IN_SIGMA0]) ) {
    mexErrMsgTxt("SIGMA0 should be a real scalar") ;
  }
        
  if(!mxIsDouble(in[IN_G]) ||
     mxGetNumberOfDimensions(in[IN_G]) > 3) {
    mexErrMsgTxt("G should be a real matrix or 3-D array") ;
  }
  
  sigma0 = (float) *mxGetPr(in[IN_SIGMA0]) ;
  
  dimensions = mxGetDimensions(in[IN_G]) ;
  M = dimensions[0] ;
  N = dimensions[1] ;
  G_pt = mxGetPr(in[IN_G]) ;
  
  P_pt = mxGetPr(in[IN_P]) ;    
  K = mxGetN(in[IN_P]) ;
  
  if( !uIsRealMatrix(in[IN_P],-1,-1)) {
    mexErrMsgTxt("P should be a real matrix") ;
  }

  if ( mxGetM(in[IN_P])  == 4) {
    /* Standard (scale space) mode */ 
    mode = SCALESPACE ;
    num_levels = dimensions[2] ;
    
    if(nin < 5) {
      mexErrMsgTxt("Five arguments are required in standard mode") ;
    }
    
    if( !uIsRealScalar(in[IN_S]) ) {
      mexErrMsgTxt("S should be a real scalar") ;
    }
    
    if( !uIsRealScalar(in[IN_SMIN]) ) {
      mexErrMsgTxt("SMIN should be a real scalar") ;
    }
    
    if( !uIsRealMatrix(in[IN_P],4,-1)) {
      mexErrMsgTxt("When the e mode P should be a 4xK matrix.") ;
    }
    
    S = (int)(*mxGetPr(in[IN_S])) ;
    smin = (int)(*mxGetPr(in[IN_SMIN])) ;
    
  } else if (  mxGetM(in[IN_P])  == 3 ) {
    mode = NOSCALESPACE ;
    num_levels = 1 ;
    S      = 1 ;
    smin   = 0 ;
  } else {
    mexErrMsgTxt("P should be either a 3xK or a 4xK matrix.") ;
  }

  /* Parse the property-value pairs */
  {
    char str [80] ;
    int arg = (mode == SCALESPACE) ? IN_SMIN + 1 : IN_SIGMA0 + 1 ;

    while(arg < nin) {
      int k ;

      if( !uIsString(in[arg],-1) ) {
        mexErrMsgTxt("The first argument in a property-value pair"
                     " should be a string") ;
      }
      mxGetString(in[arg], str, 80) ;

#ifdef WINDOWS      
      for(k = 0 ; properties[k] && strcmpi(str, properties[k]) ; ++k) ;
#else
      for(k = 0 ; properties[k] && strcasecmp(str, properties[k]) ; ++k) ;
#endif

      switch (k) {
      case PROP_NBP:
        if( !uIsRealScalar(in[arg+1]) ) {
          mexErrMsgTxt("'NumSpatialBins' should be real scalar") ;
        }
        NBP = (int) *mxGetPr(in[arg+1]) ;
        if( NBP <= 0 || (NBP & 0x1) ) {
          mexErrMsgTxt("'NumSpatialBins' must be positive and even") ;
        }
        break ;

      case PROP_NBO:
        if( !uIsRealScalar(in[arg+1]) ) {
          mexErrMsgTxt("'NumOrientBins' should be a real scalar") ;
        }
        NBO = (int) *mxGetPr(in[arg+1]) ;
        if( NBO <= 0 ) {
          mexErrMsgTxt("'NumOrientlBins' must be positive") ;
        }
        break ;

      case PROP_MAGNIF:
        if( !uIsRealScalar(in[arg+1]) ) {
          mexErrMsgTxt("'Magnif' should be a real scalar") ;
        }
        magnif = (float) *mxGetPr(in[arg+1]) ;
        if( magnif <= 0 ) {
          mexErrMsgTxt("'Magnif' must be positive") ;
        }
        break ;

      case PROP_UNKNOWN:
        mexErrMsgTxt("Property unknown.") ;
        break ;
      }
      arg += 2 ;
    }
  }
  
  /* -----------------------------------------------------------------
   *                                   Pre-compute gradient and angles
   * -------------------------------------------------------------- */
  /* Alloc two buffers and make sure their size is multiple of 128 for
   * better alignment (used also by the Altivec code below.)
   */
  buffer_size = (M*N*num_levels + 0x7f) & (~ 0x7f) ;
  buffer_pt = (float*) mxMalloc( sizeof(float) * 2 * buffer_size ) ;
  descr_pt  = (float*) mxCalloc( NBP*NBP*NBO*K,  sizeof(float)  ) ;

  {
    /* Offsets to move in the scale space. */
    const int yo = 1 ;
    const int xo = M ;
    const int so = M*N ;
    int x,y,s ;

#define at(x,y) (*(pt + (x)*xo + (y)*yo))

    /* Compute the gradient */
    for(s = 0 ; s < num_levels ; ++s) {
      const double* pt = G_pt + s*so ;
      for(x = 1 ; x < N-1 ; ++x) {
        for(y = 1 ; y < M-1 ; ++y) {
          float Dx = 0.5 * ( at(x+1,y) - at(x-1,y) ) ;
          float Dy = 0.5 * ( at(x,y+1) - at(x,y-1) ) ;
          buffer_pt[(x*xo+y*yo+s*so) + 0          ] = Dx ;
          buffer_pt[(x*xo+y*yo+s*so) + buffer_size] = Dy ;
        }
      }
    }
    
    /* Compute angles and modules */
    {
      float* pt = buffer_pt ;
      int j = 0 ;
      while (j < N*M*num_levels) {

#if defined( MACOSX ) && defined( __ALTIVEC__ )
        if( ((unsigned int)pt & 0x7) == 0 && j+3 < N*M*num_levels ) {
          /* If aligned to 128 bit and there are at least 4 pixels left */
          float4 a, b, c, d ;
          a.vec = vec_ld(0,(vector float*)(pt              )) ;
          b.vec = vec_ld(0,(vector float*)(pt + buffer_size)) ;
          c.vec = vatan2f(b.vec,a.vec) ;
          a.x[0] = a.x[0]*a.x[0]+b.x[0]*b.x[0] ;
          a.x[1] = a.x[1]*a.x[1]+b.x[1]*b.x[1] ;
          a.x[2] = a.x[2]*a.x[2]+b.x[2]*b.x[2] ;
          a.x[3] = a.x[3]*a.x[3]+b.x[3]*b.x[3] ;
          d.vec = vsqrtf(a.vec) ;
          vec_st(c.vec,0,(vector float*)(pt + buffer_size)) ;
          vec_st(d.vec,0,(vector float*)(pt              )) ;
          j += 4 ;
          pt += 4 ;
        } else {
#endif
          float Dx = *(pt              ) ;
          float Dy = *(pt + buffer_size) ;
          *(pt              ) = sqrtf(Dx*Dx + Dy*Dy) ;
          if (*pt > 0) 
            *(pt + buffer_size) = atan2f(Dy, Dx) ;
          else
            *(pt + buffer_size) = 0 ;
          j += 1 ;
          pt += 1 ;
#if defined( MACOSX ) && defined( __ALTIVEC__ )
        }
#endif

      }
    }
  }

  /* -----------------------------------------------------------------
   *                                                        Do the job
   * -------------------------------------------------------------- */ 
  if(K > 0) {    
    int p ;

    /* Offsets to move in the buffer */
    const int yo = 1 ;
    const int xo = M ;
    const int so = M*N ;

    /* Offsets to move in the descriptor. */
    /* Use Lowe's convention. */
    const int binto = 1 ;
    const int binyo = NBO * NBP ;
    const int binxo = NBO ;
    const int bino  = NBO * NBP * NBP ;

    for(p = 0 ; p < K ; ++p, descr_pt += bino) {
      /* The SIFT descriptor is a  three dimensional histogram of the position
       * and orientation of the gradient.  There are NBP bins for each spatial
       * dimesions and NBO  bins for the orientation dimesion,  for a total of
       * NBP x NBP x NBO bins.
       *
       * The support  of each  spatial bin  has an extension  of SBP  = 3sigma
       * pixels, where sigma is the scale  of the keypoint.  Thus all the bins
       * together have a  support SBP x NBP pixels wide  . Since weighting and
       * interpolation of  pixel is used, another  half bin is  needed at both
       * ends of  the extension. Therefore, we  need a square window  of SBP x
       * (NBP + 1) pixels. Finally, since the patch can be arbitrarly rotated,
       * we need to consider  a window 2W += sqrt(2) x SBP  x (NBP + 1) pixels
       * wide.
       */      
      const float x = (float) *P_pt++ ;
      const float y = (float) *P_pt++ ;
      const float s = (float) (mode == SCALESPACE) ? (*P_pt++) : 0.0 ;
      const float theta0 = (float) *P_pt++ ;

      const float st0 = sinf(theta0) ;
      const float ct0 = cosf(theta0) ;
      const int xi = (int) floor(x+0.5) ; /* Round-off */
      const int yi = (int) floor(y+0.5) ;
      const int si = (int) floor(s+0.5) - smin ;
      const float sigma = sigma0 * powf(2, s / S) ;
      const float SBP = magnif * sigma ;
      const int W = (int) floor( sqrt(2.0) * SBP * (NBP + 1) / 2.0 + 0.5) ;      
      int bin ;
      int dxi ;
      int dyi ;
      const float* pt ;
      float* dpt ;
      
      /* Check that keypoints are within bounds . */

      if(xi < 0   || 
         xi > N-1 || 
         yi < 0   || 
         yi > M-1 ||
         ((mode==SCALESPACE) && 
          (si < 0   ||
           si > dimensions[2]-1) ) )
        continue ;

      /* Center the scale space and the descriptor on the current keypoint. 
       * Note that dpt is pointing to the bin of center (SBP/2,SBP/2,0).
       */
      pt  = buffer_pt + xi*xo + yi*yo + si*so ;
      dpt = descr_pt + (NBP/2) * binyo + (NBP/2) * binxo ;
     
#define atd(dbinx,dbiny,dbint) (*(dpt + (dbint)*binto + (dbiny)*binyo + (dbinx)*binxo))
      
      /*
       * Process each pixel in the window and in the (1,1)-(M-1,N-1)
       * rectangle.
       */
      for(dxi = max(-W, 1-xi) ; dxi <= min(+W, N-2-xi) ; ++dxi) {
        for(dyi = max(-W, 1-yi) ; dyi <= min(+W, M-2-yi) ; ++dyi) {

          /* Compute the gradient. */
          float mod   = *(pt + dxi*xo + dyi*yo + 0           ) ;
          float angle = *(pt + dxi*xo + dyi*yo + buffer_size ) ;
#ifdef LOWE_COMPATIBLE         
          float theta = fast_mod(-angle + theta0) ;
#else
          float theta = fast_mod(angle - theta0) ;
#endif
          /* Get the fractional displacement. */
          float dx = ((float)(xi+dxi)) - x;
          float dy = ((float)(yi+dyi)) - y;

          /* Get the displacement normalized w.r.t. the keypoint orientation
           * and extension. */
          float nx = ( ct0 * dx + st0 * dy) / SBP ;
          float ny = (-st0 * dx + ct0 * dy) / SBP ; 
          float nt = NBO * theta / (2*M_PI) ;

          /* Get the gaussian weight of the sample. The gaussian window
           * has a standard deviation of NBP/2. Note that dx and dy are in
           * the normalized frame, so that -NBP/2 <= dx <= NBP/2. */
          const float wsigma = NBP/2 ;
          float win =  expf(-(nx*nx + ny*ny)/(2.0 * wsigma * wsigma)) ;

          /* The sample will be distributed in 8 adijacient bins. 
           * Now we get the ``lower-left'' bin. */
          int binx = fast_floor( nx - 0.5 ) ;
          int biny = fast_floor( ny - 0.5 ) ;
          int bint = fast_floor( nt ) ;
          float rbinx = nx - (binx+0.5) ;
          float rbiny = ny - (biny+0.5) ;
          float rbint = nt - bint ;
          int dbinx ;
          int dbiny ;
          int dbint ;

          /* Distribute the current sample into the 8 adijacient bins. */
          for(dbinx = 0 ; dbinx < 2 ; ++dbinx) {
            for(dbiny = 0 ; dbiny < 2 ; ++dbiny) {
              for(dbint = 0 ; dbint < 2 ; ++dbint) {
                
                if( binx+dbinx >= -(NBP/2) &&
                    binx+dbinx <   (NBP/2) &&
                    biny+dbiny >= -(NBP/2) &&
                    biny+dbiny <   (NBP/2) ) {
                  float weight = win 
                    * mod 
                    * fabsf(1 - dbinx - rbinx)
                    * fabsf(1 - dbiny - rbiny)
                    * fabsf(1 - dbint - rbint) ;

                      atd(binx+dbinx, biny+dbiny, (bint+dbint) % NBO) += weight ;
                }
              }            
            }
          }
        }  
      }


      {
        /* Normalize the histogram to L2 unit length. */        
        normalize_histogram(descr_pt, descr_pt + NBO*NBP*NBP) ;
        
        /* Truncate at 0.2. */
        for(bin = 0; bin < NBO*NBP*NBP ; ++bin) {
          if (descr_pt[bin] > 0.2) descr_pt[bin] = 0.2;
        }
        
        /* Normalize again. */
        normalize_histogram(descr_pt, descr_pt + NBO*NBP*NBP) ;
      }
    }
  }

  /* Restore pointer to the beginning of the descriptors. */
  descr_pt -= NBO*NBP*NBP*K ;

  {
    int k ;
    double* L_pt ;
    out[OUT_L] = mxCreateDoubleMatrix(NBP*NBP*NBO, K, mxREAL) ;
    L_pt = mxGetPr(out[OUT_L]) ;
    for(k = 0 ; k < NBP*NBP*NBO*K ; ++k) {
      L_pt[k] = descr_pt[k] ;
    }
  }

  mxFree(descr_pt) ;  
  mxFree(buffer_pt) ;
}
Exemple #8
0
static float generate(float x, float y)
{
	const float F2 = 0.366025403f; // F2 = 0.5*(sqrt(3.0)-1.0)
	const float G2 = 0.211324865f; // G2 = (3.0-Math.sqrt(3.0))/6.0

	float n0, n1, n2; // Noise contributions from the three corners

	// Skew the input space to determine which simplex cell we're in
	float s = (x + y) * F2; // Hairy factor for 2D
	float xs = x + s;
	float ys = y + s;
	sint32 i = fast_floor(xs);
	sint32 j = fast_floor(ys);

	float t = (float)(i + j) * G2;
	float X0 = i - t; // Unskew the cell origin back to (x,y) space
	float Y0 = j - t;
	float x0 = x - X0; // The x,y distances from the cell origin
	float y0 = y - Y0;

	// For the 2D case, the simplex shape is an equilateral triangle.
	// Determine which simplex we are in.
	sint32 i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords
	if (x0 > y0) { i1 = 1; j1 = 0; } // lower triangle, XY order: (0,0)->(1,0)->(1,1)
	else { i1 = 0; j1 = 1; }      // upper triangle, YX order: (0,0)->(0,1)->(1,1)

	// A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
	// a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
	// c = (3-sqrt(3))/6

	float x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords
	float y1 = y0 - j1 + G2;
	float x2 = x0 - 1.0f + 2.0f * G2; // Offsets for last corner in (x,y) unskewed coords
	float y2 = y0 - 1.0f + 2.0f * G2;

	// Wrap the integer indices at 256, to avoid indexing perm[] out of bounds
	sint32 ii = i % 256;
	sint32 jj = j % 256;

	// Calculate the contribution from the three corners
	float t0 = 0.5f - x0 * x0 - y0 * y0;
	if (t0 < 0.0f) n0 = 0.0f;
	else {
		t0 *= t0;
		n0 = t0 * t0 * grad(perm[ii + perm[jj]], x0, y0);
	}

	float t1 = 0.5f - x1 * x1 - y1 * y1;
	if (t1 < 0.0f) n1 = 0.0f;
	else {
		t1 *= t1;
		n1 = t1 * t1 * grad(perm[ii + i1 + perm[jj + j1]], x1, y1);
	}

	float t2 = 0.5f - x2 * x2 - y2 * y2;
	if (t2 < 0.0f) n2 = 0.0f;
	else {
		t2 *= t2;
		n2 = t2 * t2 * grad(perm[ii + 1 + perm[jj + 1]], x2, y2);
	}

	// Add contributions from each corner to get the final noise value.
	// The result is scaled to return values in the interval [-1,1].
	return 40.0f * (n0 + n1 + n2); // TODO: The scale factor is preliminary!
}
#include "catch/catch.hpp"

#include "cata_utility.h"

#include <cmath>
#include <random>

TEST_CASE( "fast_floor", "[math]" )
{
    REQUIRE( fast_floor( -2.0 ) == -2 );
    REQUIRE( fast_floor( -1.9 ) == -2 );
    REQUIRE( fast_floor( -1.1 ) == -2 );
    REQUIRE( fast_floor( -1.0 ) == -1 );
    REQUIRE( fast_floor( -0.9 ) == -1 );
    REQUIRE( fast_floor( -0.1 ) == -1 );
    REQUIRE( fast_floor( 0.0 ) ==  0 );
    REQUIRE( fast_floor( 0.1 ) ==  0 );
    REQUIRE( fast_floor( 0.9 ) ==  0 );
    REQUIRE( fast_floor( 1.0 ) ==  1 );
    REQUIRE( fast_floor( 1.1 ) ==  1 );
    REQUIRE( fast_floor( 1.9 ) ==  1 );
    REQUIRE( fast_floor( 2.0 ) ==  2 );
    REQUIRE( fast_floor( 2.1 ) ==  2 );
    REQUIRE( fast_floor( 2.9 ) ==  2 );

    std::random_device rd;
    std::mt19937 mt( rd() );
    std::uniform_real_distribution<double> dist( -10.0, 10.0 );

    for( size_t i = 0; i != 1000; ++i ) {
        double val = dist( mt );
Exemple #10
0
    // Classic Perlin noise, 3D version
    float base(float x, float y, float z)
    {
    /*
        // Find unit grid cell containing point
        int X = fast_floor(x);
        int Y = fast_floor(y);
        int Z = fast_floor(z);
        // Get relative xyz coordinates of point within that cell
        x = x - X;
        y = y - Y;
        z = z - Z;
        // Wrap the integer cells at 255 (smaller integer period can be introduced here)
        X = X & 255;
        Y = Y & 255;
        Z = Z & 255;
    */
        x /= 8.0;  //replace with multiplication
        y /= 8.0;
        z /= 4.0;
        //get grid point
        int X = fast_floor(x);
        int Y = fast_floor(y);
        int Z = fast_floor(z);

        //get interpolation ratio

        //if (z >= 32 || z < 0) printf("ERROR1 z = %f \n", z);

        x = x - X;
        y = y - Y;
        z = z - Z;

        //if (z >= 32 || z < 0) printf("ERROR2 z = %f \n", z);
        //if (x<0 || y<0 || z<0) printf("x,y,z= %f %f %f \n", x,y,z);
        //if (z >= 32) printf("x,y,z= %f %f %f X,Y,Z= %i %i %i \n", x+X,y+Y,z+Z,X,Y,Z);
        // Calculate a set of eight hashed gradient indices


        int gi000 = get_gradient(X+0,Y+0,Z+0);
        int gi001 = get_gradient(X+0,Y+0,Z+1);
        int gi010 = get_gradient(X+0,Y+1,Z+0);
        int gi011 = get_gradient(X+0,Y+1,Z+1);

        int gi100 = get_gradient(X+1,Y+0,Z+0);
        int gi101 = get_gradient(X+1,Y+0,Z+1);
        int gi110 = get_gradient(X+1,Y+1,Z+0);
        int gi111 = get_gradient(X+1,Y+1,Z+1);

    /*
        int gi000 = perm[X+perm[Y+perm[Z]]] % 12;
        int gi001 = perm[X+perm[Y+perm[Z+1]]] % 12;
        int gi010 = perm[X+perm[Y+1+perm[Z]]] % 12;
        int gi011 = perm[X+perm[Y+1+perm[Z+1]]] % 12;

        int gi100 = perm[X+1+perm[Y+perm[Z]]] % 12;
        int gi101 = perm[X+1+perm[Y+perm[Z+1]]] % 12;
        int gi110 = perm[X+1+perm[Y+1+perm[Z]]] % 12;
        int gi111 = perm[X+1+perm[Y+1+perm[Z+1]]] % 12;
    */
        // The gradients of each corner are now:
        // g000 = grad3[gi000];
        // g001 = grad3[gi001];
        // g010 = grad3[gi010];
        // g011 = grad3[gi011];
        // g100 = grad3[gi100];
        // g101 = grad3[gi101];
        // g110 = grad3[gi110];
        // g111 = grad3[gi111];

        // Calculate noise contributions from each of the eight corners
        float n000= dot(_grad3[gi000], x, y, z);
        float n100= dot(_grad3[gi100], x-1, y, z);
        float n010= dot(_grad3[gi010], x, y-1, z);
        float n110= dot(_grad3[gi110], x-1, y-1, z);
        float n001= dot(_grad3[gi001], x, y, z-1);
        float n101= dot(_grad3[gi101], x-1, y, z-1);
        float n011= dot(_grad3[gi011], x, y-1, z-1);
        float n111= dot(_grad3[gi111], x-1, y-1, z-1);
        // Compute the fade curve value for each of x, y, z

    #if 1
        float u = fade(x);
        float v = fade(y);
        float w = fade(z);
    #else
        float u = x;
        float v = y;
        float w = z;
    #endif

        // Interpolate along x the contributions from each of the corners
        float nx00 = mix(n000, n100, u);
        float nx01 = mix(n001, n101, u);
        float nx10 = mix(n010, n110, u);
        float nx11 = mix(n011, n111, u);
        // Interpolate the four results along y
        float nxy0 = mix(nx00, nx10, v);
        float nxy1 = mix(nx01, nx11, v);
        // Interpolate the two last results along z
        float nxyz = mix(nxy0, nxy1, w);

        return nxyz * 0.707106781;   //-1 to 1
    }
float raw_noise_3d(float x, float y, float z, const uint8_t* perm)
{
    constexpr float F3 = 1.0f / 3.0f;
    float s = (x + y + z) * F3;

    float i = fast_floor(x + s);
    float j = fast_floor(y + s);
    float k = fast_floor(z + s);

    constexpr float G3 = 1.0f / 6.0f;
    float t = (i + j + k) * G3;

    float x0 = x - (i - t);
    float y0 = y - (j - t);
    float z0 = z - (k - t);

    uint8_t i1 = 0, j1 = 1, k1 = 0;
    uint8_t i2 = 1, j2 = 1, k2 = 0;
    if(x0 >= y0)
    {
        if(y0 >= z0)
        {
            i1 = 1;
            j1 = 0;
            k1 = 0;
            i2 = 1;
            j2 = 1;
            k2 = 0;
        }
        else if(x0 >= z0)
        {
            i1 = 1;
            j1 = 0;
            k1 = 0;
            i2 = 1;
            j2 = 0;
            k2 = 1;
        }
        else
        {
            i1 = 0;
            j1 = 0;
            k1 = 1;
            i2 = 1;
            j2 = 0;
            k2 = 1;
        }
    }
    else
    {
        if(y0 < z0)
        {
            i1 = 0;
            j1 = 0;
            k1 = 1;
            i2 = 0;
            j2 = 1;
            k2 = 1;
        }
        else if(x0 < z0)
        {
            i1 = 0;
            j1 = 1;
            k1 = 0;
            i2 = 0;
            j2 = 1;
            k2 = 1;
        }
    }

    float x1 = x0 - i1   + G3;
    float y1 = y0 - j1   + G3;
    float z1 = z0 - k1   + G3;
    float x2 = x0 - i2   + G3 * 2.0f;
    float y2 = y0 - j2   + G3 * 2.0f;
    float z2 = z0 - k2   + G3 * 2.0f;
    float x3 = x0 - 1.0f + G3 * 3.0f;
    float y3 = y0 - 1.0f + G3 * 3.0f;
    float z3 = z0 - 1.0f + G3 * 3.0f;

    uint8_t ii = int32_t(i);
    uint8_t jj = int32_t(j);
    uint8_t kk = int32_t(k);

    uint8_t gi0 = perm[ii + perm[jj + perm[kk     ]     ]     ] % 12;
    uint8_t gi1 = perm[ii + perm[jj + perm[kk + k1] + j1] + i1] % 12;
    uint8_t gi2 = perm[ii + perm[jj + perm[kk + k2] + j2] + i2] % 12;
    uint8_t gi3 = perm[ii + perm[jj + perm[kk + 1 ] + 1 ] + 1 ] % 12;

    float t0 = 0.5f - x0 * x0 - y0 * y0 - z0 * z0;
    float t1 = 0.5f - x1 * x1 - y1 * y1 - z1 * z1;
    float t2 = 0.5f - x2 * x2 - y2 * y2 - z2 * z2;
    float t3 = 0.5f - x3 * x3 - y3 * y3 - z3 * z3;

    float n0 = (t0 < 0) ? 0.0f : t0*t0*t0*t0 * dot(grad3[gi0], x0, y0, z0);
    float n1 = (t1 < 0) ? 0.0f : t1*t1*t1*t1 * dot(grad3[gi1], x1, y1, z1);
    float n2 = (t2 < 0) ? 0.0f : t2*t2*t2*t2 * dot(grad3[gi2], x2, y2, z2);
    float n3 = (t3 < 0) ? 0.0f : t3*t3*t3*t3 * dot(grad3[gi3], x3, y3, z3);

    return 32.0f * (n0 + n1 + n2 + n3);
}