// 4D Scaled Multi-octave Simplex noise. // // Returned value will be between loBound and hiBound. float scaled_octave_noise_4d( const float octaves, const float persistence, const float scale, const float loBound, const float hiBound, const float x, const float y, const float z, const float w ) { return octave_noise_4d( octaves, persistence, scale, x, y, z, w ) * ( hiBound - loBound ) / 2 + ( hiBound + loBound ) / 2; }
/* Takes points (x, y, z) and returns a height (n) */ VALUE Perlin_Generator_run3d(const VALUE self, const VALUE x, const VALUE y, const VALUE z) { GENERATOR(); if(generator->is_classic) { seed = generator->seed; // Store in global, for speed. return rb_float_new(perlin_octaves_3d(NUM2DBL(x), NUM2DBL(y), NUM2DBL(z), generator->persistence, generator->octave)); } else { return rb_float_new(octave_noise_4d(generator->octave, generator->persistence, 1.0, NUM2DBL(x), NUM2DBL(y), NUM2DBL(z), generator->seed)); } }
// 4D Scaled Multi-octave Simplex noise. // // Returned value will be between loBound and hiBound. double scaled_octave_noise_4d( const int octaves, const double persistence, const double scale, const double loBound, const double hiBound, const double x, const double y, const double z, const double w ) { return octave_noise_4d(octaves, persistence, scale, x, y, z, w) * (hiBound - loBound) / 2 + (hiBound + loBound) / 2; }
// 4D Marble Noise: x-axis. float marble_noise_4d( const float octaves, const float persistence, const float scale, const float x, const float y, const float z, const float w ) { return cosf( x * scale + octave_noise_4d(octaves, persistence, scale / 3, x, y, z, w) ); }
/* Returns a chunk of coordinates starting from x, y, z and of size steps_x, steps_y, size_z with interval. */ VALUE Perlin_Generator_chunk3d(const VALUE self, const VALUE x, const VALUE y, const VALUE z, const VALUE steps_x, const VALUE steps_y, const VALUE steps_z, const VALUE interval) { GENERATOR(); VALUE arr, row, column; int i, j, k; const float x_min = NUM2DBL(x), y_min = NUM2DBL(y), z_min = NUM2DBL(z); float _x, _y, _z; const int _steps_x = NUM2INT(steps_x), _steps_y = NUM2INT(steps_y), _steps_z = NUM2INT(steps_z); const float _interval = NUM2DBL(interval); if(_steps_x < 1 || _steps_y < 1 || _steps_z < 1) { rb_raise(rb_eArgError, "steps must be >= 1"); } if(generator->is_classic) seed = generator->seed; // Store in global, for speed. if(rb_block_given_p()) { _x = x_min; for (i = 0; i < _steps_x; i++) { _y = y_min; for (j = 0; j < _steps_y; j++) { _z = z_min; for (k = 0; k < _steps_z; k++) { if(generator->is_classic) { rb_yield_values(4, rb_float_new(perlin_octaves_3d(_x, _y, _z, generator->persistence, generator->octave)), rb_float_new(_x), rb_float_new(_y), rb_float_new(_z)); } else { rb_yield_values(4, rb_float_new(octave_noise_4d(generator->octave, generator->persistence, 1.0, _x, _y, _z, generator->seed)), rb_float_new(_x), rb_float_new(_y), rb_float_new(_z)); } _z += _interval; } _y += _interval; } _x += _interval; } return Qnil; } else { arr = rb_ary_new(); _x = x_min; for (i = 0; i < _steps_x; i++) { row = rb_ary_new(); _y = y_min; for (j = 0; j < _steps_y; j++) { column = rb_ary_new(); _z = z_min; for (k = 0; k < _steps_z; k++) { if(generator->is_classic) { rb_ary_push(column, rb_float_new(perlin_octaves_3d(_x, _y, _z, generator->persistence, generator->octave))); } else { rb_ary_push(column, rb_float_new(octave_noise_4d(generator->octave, generator->persistence, 1.0, _x, _y, _z, generator->seed))); } _z += _interval; } rb_ary_push(row, column); _y += _interval; } rb_ary_push(arr, row); _x += _interval; } return arr; } }