s32 PcgRandom::range(s32 min, s32 max)
{
- assert(max >= min);
+ if (max < min)
+ throw PrngException("Invalid range (max < min)");
+
u32 bound = max - min + 1;
return range(bound) + min;
}
void PcgRandom::bytes(void *out, size_t len)
{
- u32 r;
u8 *outb = (u8 *)out;
+ int bytes_left = 0;
+ u32 r;
- size_t len_alignment = (uintptr_t)out % sizeof(u32);
- if (len_alignment) {
- len -= len_alignment;
- r = next();
- while (len_alignment--) {
- *outb = r & 0xFF;
- outb++;
- r >>= 8;
+ while (len--) {
+ if (bytes_left == 0) {
+ bytes_left = sizeof(u32);
+ r = next();
}
- }
-
- size_t len_dwords = len / sizeof(u32);
- while (len_dwords--) {
- r = next();
- *(u32 *)outb = next();
- outb += sizeof(u32);
- }
- size_t len_remaining = len % sizeof(u32);
- if (len_remaining) {
- r = next();
- while (len_remaining--) {
- *outb = r & 0xFF;
- outb++;
- r >>= 8;
- }
+ *outb = r & 0xFF;
+ outb++;
+ bytes_left--;
+ r >>= 8;
}
}
s32 accum = 0;
for (int i = 0; i != num_trials; i++)
accum += range(min, max);
- return ((float)accum / num_trials) + 0.5f;
+ return myround((float)accum / num_trials);
}
///////////////////////////////////////////////////////////////////////////////
}
-Noise::Noise(NoiseParams *np_, int seed, int sx, int sy, int sz)
+Noise::Noise(NoiseParams *np_, int seed, u32 sx, u32 sy, u32 sz)
{
memcpy(&np, np_, sizeof(np));
this->seed = seed;
void Noise::allocBuffers()
{
+ if (sx < 1)
+ sx = 1;
+ if (sy < 1)
+ sy = 1;
+ if (sz < 1)
+ sz = 1;
+
this->noise_buf = NULL;
resizeNoiseBuf(sz > 1);
}
-void Noise::setSize(int sx, int sy, int sz)
+void Noise::setSize(u32 sx, u32 sy, u32 sz)
{
this->sx = sx;
this->sy = sy;
void Noise::resizeNoiseBuf(bool is3d)
{
- int nlx, nly, nlz;
- float ofactor;
-
//maximum possible spread value factor
- ofactor = pow(np.lacunarity, np.octaves - 1);
+ float ofactor = (np.lacunarity > 1.0) ?
+ pow(np.lacunarity, np.octaves - 1) :
+ np.lacunarity;
+
+ // noise lattice point count
+ // (int)(sz * spread * ofactor) is # of lattice points crossed due to length
+ float num_noise_points_x = sx * ofactor / np.spread.X;
+ float num_noise_points_y = sy * ofactor / np.spread.Y;
+ float num_noise_points_z = sz * ofactor / np.spread.Z;
+
+ // protect against obviously invalid parameters
+ if (num_noise_points_x > 1000000000.f ||
+ num_noise_points_y > 1000000000.f ||
+ num_noise_points_z > 1000000000.f)
+ throw InvalidNoiseParamsException();
- //noise lattice point count
- //(int)(sz * spread * ofactor) is # of lattice points crossed due to length
// + 2 for the two initial endpoints
// + 1 for potentially crossing a boundary due to offset
- nlx = (int)ceil(sx * ofactor / np.spread.X) + 3;
- nly = (int)ceil(sy * ofactor / np.spread.Y) + 3;
- nlz = is3d ? (int)ceil(sz * ofactor / np.spread.Z) + 3 : 1;
+ size_t nlx = (size_t)ceil(num_noise_points_x) + 3;
+ size_t nly = (size_t)ceil(num_noise_points_y) + 3;
+ size_t nlz = is3d ? (size_t)ceil(num_noise_points_z) + 3 : 1;
delete[] noise_buf;
try {
int seed)
{
float v00, v01, v10, v11, u, v, orig_u;
- int index, i, j, x0, y0, noisex, noisey;
- int nlx, nly;
+ u32 index, i, j, noisex, noisey;
+ u32 nlx, nly;
+ s32 x0, y0;
bool eased = np.flags & (NOISE_FLAG_DEFAULTS | NOISE_FLAG_EASED);
Interp2dFxn interpolate = eased ?
orig_u = u;
//calculate noise point lattice
- nlx = (int)(u + sx * step_x) + 2;
- nly = (int)(v + sy * step_y) + 2;
+ nlx = (u32)(u + sx * step_x) + 2;
+ nly = (u32)(v + sy * step_y) + 2;
index = 0;
for (j = 0; j != nly; j++)
for (i = 0; i != nlx; i++)
float v000, v010, v100, v110;
float v001, v011, v101, v111;
float u, v, w, orig_u, orig_v;
- int index, i, j, k, x0, y0, z0, noisex, noisey, noisez;
- int nlx, nly, nlz;
+ u32 index, i, j, k, noisex, noisey, noisez;
+ u32 nlx, nly, nlz;
+ s32 x0, y0, z0;
Interp3dFxn interpolate = (np.flags & NOISE_FLAG_EASED) ?
triLinearInterpolation : triLinearInterpolationNoEase;
orig_v = v;
//calculate noise point lattice
- nlx = (int)(u + sx * step_x) + 2;
- nly = (int)(v + sy * step_y) + 2;
- nlz = (int)(w + sz * step_z) + 2;
+ nlx = (u32)(u + sx * step_x) + 2;
+ nly = (u32)(v + sy * step_y) + 2;
+ nlz = (u32)(w + sz * step_z) + 2;
index = 0;
for (k = 0; k != nlz; k++)
for (j = 0; j != nly; j++)