Initial commit, yay
This commit is contained in:
commit
25e26756cd
85 changed files with 7077 additions and 0 deletions
2
src/rand/CMakeLists.txt
Normal file
2
src/rand/CMakeLists.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
add_library(rand STATIC opensimplex.c
|
||||
xoshiro256.c)
|
175
src/rand/opensimplex.c
Normal file
175
src/rand/opensimplex.c
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* This code is part of the strategy game operational-space.
|
||||
* operational-space comes with ABSOLUTELY NO WARRANTY and is licensed under GPL-2.0.
|
||||
* Copyright (C) 2024 VegOwOtenks, Sleppo04
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#include "opensimplex.h"
|
||||
|
||||
float GRADIENTS_2D[] = {6.9808965, 16.853374, 16.853374, 6.9808965, 16.853374, -6.9808965, 6.9808965, -16.853374, -6.9808965, -16.853374, -16.853374, -6.9808965, -16.853374, 6.9808965, -6.9808965, 16.853374, 2.3810537, 18.0859, 11.105002, 14.4723215, 14.4723215, 11.105002, 18.0859, 2.3810537, 18.0859, -2.3810537, 14.4723215, -11.105002, 11.105002, -14.4723215, 2.3810537, -18.0859, -2.3810537, -18.0859, -11.105002, -14.4723215, -14.4723215, -11.105002, -18.0859, -2.3810537, -18.0859, 2.3810537, -14.4723215, 11.105002, -11.105002, 14.4723215, -2.3810537, 18.0859, 6.9808965, 16.853374, 16.853374, 6.9808965, 16.853374, -6.9808965, 6.9808965, -16.853374, -6.9808965, -16.853374, -16.853374, -6.9808965, -16.853374, 6.9808965, -6.9808965, 16.853374, 2.3810537, 18.0859, 11.105002, 14.4723215, 14.4723215, 11.105002, 18.0859, 2.3810537, 18.0859, -2.3810537, 14.4723215, -11.105002, 11.105002, -14.4723215, 2.3810537, -18.0859, -2.3810537, -18.0859, -11.105002, -14.4723215, -14.4723215, -11.105002, -18.0859, -2.3810537, -18.0859, 2.3810537, -14.4723215, 11.105002, -11.105002, 14.4723215, -2.3810537, 18.0859, 6.9808965, 16.853374, 16.853374, 6.9808965, 16.853374, -6.9808965, 6.9808965, -16.853374, -6.9808965, -16.853374, -16.853374, -6.9808965, -16.853374, 6.9808965, -6.9808965, 16.853374, 2.3810537, 18.0859, 11.105002, 14.4723215, 14.4723215, 11.105002, 18.0859, 2.3810537, 18.0859, -2.3810537, 14.4723215, -11.105002, 11.105002, -14.4723215, 2.3810537, -18.0859, -2.3810537, -18.0859, -11.105002, -14.4723215, -14.4723215, -11.105002, -18.0859, -2.3810537, -18.0859, 2.3810537, -14.4723215, 11.105002, -11.105002, 14.4723215, -2.3810537, 18.0859, 6.9808965, 16.853374, 16.853374, 6.9808965, 16.853374, -6.9808965, 6.9808965, -16.853374, -6.9808965, -16.853374, -16.853374, -6.9808965, -16.853374, 6.9808965, -6.9808965, 16.853374, 2.3810537, 18.0859, 11.105002, 14.4723215, 14.4723215, 11.105002, 18.0859, 2.3810537, 18.0859, -2.3810537, 14.4723215, -11.105002, 11.105002, -14.4723215, 2.3810537, -18.0859, -2.3810537, -18.0859, -11.105002, -14.4723215, -14.4723215, -11.105002, -18.0859, -2.3810537, -18.0859, 2.3810537, -14.4723215, 11.105002, -11.105002, 14.4723215, -2.3810537, 18.0859, 6.9808965, 16.853374, 16.853374, 6.9808965, 16.853374, -6.9808965, 6.9808965, -16.853374, -6.9808965, -16.853374, -16.853374, -6.9808965, -16.853374, 6.9808965, -6.9808965, 16.853374, 2.3810537, 18.0859, 11.105002, 14.4723215, 14.4723215, 11.105002, 18.0859, 2.3810537, 18.0859, -2.3810537, 14.4723215, -11.105002, 11.105002, -14.4723215, 2.3810537, -18.0859, -2.3810537, -18.0859, -11.105002, -14.4723215, -14.4723215, -11.105002, -18.0859, -2.3810537, -18.0859, 2.3810537, -14.4723215, 11.105002, -11.105002, 14.4723215, -2.3810537, 18.0859, 6.9808965, 16.853374, 16.853374, 6.9808965, 16.853374, -6.9808965, 6.9808965, -16.853374, -6.9808965, -16.853374, -16.853374, -6.9808965, -16.853374, 6.9808965, -6.9808965, 16.853374};
|
||||
|
||||
int OpenSimplex_Floor(double n)
|
||||
{
|
||||
return (int) floor(n);
|
||||
}
|
||||
|
||||
float OpenSimplex_2DGrad(int64_t seed, int64_t xsvp, int64_t ysvp, float dx, float dy) {
|
||||
int64_t hash = seed ^ xsvp ^ ysvp;
|
||||
hash *= HASH_MULTIPLIER;
|
||||
hash ^= hash >> (64 - N_GRADS_2D_EXPONENT + 1);
|
||||
int gi = (int)hash & ((N_GRADS_2D - 1) << 1);
|
||||
return GRADIENTS_2D[gi | 0] * dx + GRADIENTS_2D[gi | 1] * dy;
|
||||
}
|
||||
|
||||
/**
|
||||
* 2D OpenSimplex2S/SuperSimplex noise base.
|
||||
*/
|
||||
float OpenSimplex_2DNoise_UnskewedBase(int64_t seed, double xs, double ys) {
|
||||
|
||||
// Get base points and offsets.
|
||||
int xsb = OpenSimplex_Floor(xs), ysb = OpenSimplex_Floor(ys);
|
||||
float xi = (float)(xs - xsb), yi = (float)(ys - ysb);
|
||||
|
||||
// Prime pre-multiplication for hash.
|
||||
int64_t xsbp = xsb * PRIME_X, ysbp = ysb * PRIME_Y;
|
||||
|
||||
// Unskew.
|
||||
float t = (xi + yi) * (float)UNSKEW_2D;
|
||||
float dx0 = xi + t, dy0 = yi + t;
|
||||
|
||||
// First vertex.
|
||||
float a0 = RSQUARED_2D - dx0 * dx0 - dy0 * dy0;
|
||||
float value = (a0 * a0) * (a0 * a0) * OpenSimplex_2DGrad(seed, xsbp, ysbp, dx0, dy0);
|
||||
|
||||
// Second vertex.
|
||||
float a1 = (float)(2 * (1 + 2 * UNSKEW_2D) * (1 / UNSKEW_2D + 2)) * t + ((float)(-2 * (1 + 2 * UNSKEW_2D) * (1 + 2 * UNSKEW_2D)) + a0);
|
||||
float dx1 = dx0 - (float)(1 + 2 * UNSKEW_2D);
|
||||
float dy1 = dy0 - (float)(1 + 2 * UNSKEW_2D);
|
||||
value += (a1 * a1) * (a1 * a1) * OpenSimplex_2DGrad(seed, xsbp + PRIME_X, ysbp + PRIME_Y, dx1, dy1);
|
||||
|
||||
// Third and fourth vertices.
|
||||
// Nested conditionals were faster than compact bit logic/arithmetic.
|
||||
float xmyi = xi - yi;
|
||||
if (t < UNSKEW_2D) {
|
||||
if (xi + xmyi > 1) {
|
||||
float dx2 = dx0 - (float)(3 * UNSKEW_2D + 2);
|
||||
float dy2 = dy0 - (float)(3 * UNSKEW_2D + 1);
|
||||
float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2;
|
||||
if (a2 > 0) {
|
||||
value += (a2 * a2) * (a2 * a2) * OpenSimplex_2DGrad(seed, xsbp + (PRIME_X << 1), ysbp + PRIME_Y, dx2, dy2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float dx2 = dx0 - (float)UNSKEW_2D;
|
||||
float dy2 = dy0 - (float)(UNSKEW_2D + 1);
|
||||
float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2;
|
||||
if (a2 > 0) {
|
||||
value += (a2 * a2) * (a2 * a2) * OpenSimplex_2DGrad(seed, xsbp, ysbp + PRIME_Y, dx2, dy2);
|
||||
}
|
||||
}
|
||||
|
||||
if (yi - xmyi > 1) {
|
||||
float dx3 = dx0 - (float)(3 * UNSKEW_2D + 1);
|
||||
float dy3 = dy0 - (float)(3 * UNSKEW_2D + 2);
|
||||
float a3 = RSQUARED_2D - dx3 * dx3 - dy3 * dy3;
|
||||
if (a3 > 0) {
|
||||
value += (a3 * a3) * (a3 * a3) * OpenSimplex_2DGrad(seed, xsbp + PRIME_X, ysbp + (PRIME_Y << 1), dx3, dy3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float dx3 = dx0 - (float)(UNSKEW_2D + 1);
|
||||
float dy3 = dy0 - (float)UNSKEW_2D;
|
||||
float a3 = RSQUARED_2D - dx3 * dx3 - dy3 * dy3;
|
||||
if (a3 > 0) {
|
||||
value += (a3 * a3) * (a3 * a3) * OpenSimplex_2DGrad(seed, xsbp + PRIME_X, ysbp, dx3, dy3);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xi + xmyi < 0) {
|
||||
float dx2 = dx0 + (float)(1 + UNSKEW_2D);
|
||||
float dy2 = dy0 + (float)UNSKEW_2D;
|
||||
float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2;
|
||||
if (a2 > 0) {
|
||||
value += (a2 * a2) * (a2 * a2) * OpenSimplex_2DGrad(seed, xsbp - PRIME_X, ysbp, dx2, dy2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float dx2 = dx0 - (float)(UNSKEW_2D + 1);
|
||||
float dy2 = dy0 - (float)UNSKEW_2D;
|
||||
float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2;
|
||||
if (a2 > 0) {
|
||||
value += (a2 * a2) * (a2 * a2) * OpenSimplex_2DGrad(seed, xsbp + PRIME_X, ysbp, dx2, dy2);
|
||||
}
|
||||
}
|
||||
|
||||
if (yi < xmyi) {
|
||||
float dx2 = dx0 + (float)UNSKEW_2D;
|
||||
float dy2 = dy0 + (float)(UNSKEW_2D + 1);
|
||||
float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2;
|
||||
if (a2 > 0) {
|
||||
value += (a2 * a2) * (a2 * a2) * OpenSimplex_2DGrad(seed, xsbp, ysbp - PRIME_Y, dx2, dy2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float dx2 = dx0 - (float)UNSKEW_2D;
|
||||
float dy2 = dy0 - (float)(UNSKEW_2D + 1);
|
||||
float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2;
|
||||
if (a2 > 0) {
|
||||
value += (a2 * a2) * (a2 * a2) * OpenSimplex_2DGrad(seed, xsbp, ysbp + PRIME_Y, dx2, dy2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Noise Evaluators
|
||||
*/
|
||||
|
||||
/**
|
||||
* 2D OpenSimplex2S/SuperSimplex noise, standard lattice orientation.
|
||||
*/
|
||||
float OpenSimplex_2DNoise(int64_t seed, double x, double y) {
|
||||
|
||||
// Get points for A2* lattice
|
||||
double s = SKEW_2D * (x + y);
|
||||
double xs = x + s, ys = y + s;
|
||||
|
||||
return OpenSimplex_2DNoise_UnskewedBase(seed, xs, ys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 2D OpenSimplex2S/SuperSimplex noise, with Y pointing down the main diagonal.
|
||||
* Might be better for a 2D sandbox style game, where Y is vertical.
|
||||
* Probably slightly less optimal for heightmaps or continent maps,
|
||||
* unless your map is centered around an equator. It's a slight
|
||||
* difference, but the option is here to make it easy.
|
||||
*/
|
||||
float OpenSimplex_2DNoise_ImprovedX(int64_t seed, double x, double y) {
|
||||
|
||||
// Skew transform and rotation baked into one.
|
||||
double xx = x * ROOT2OVER2;
|
||||
double yy = y * (ROOT2OVER2 * (1 + 2 * SKEW_2D));
|
||||
|
||||
return OpenSimplex_2DNoise_UnskewedBase(seed, yy + xx, yy - xx);
|
||||
}
|
52
src/rand/opensimplex.h
Normal file
52
src/rand/opensimplex.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* This code is part of the strategy game operational-space.
|
||||
* operational-space comes with ABSOLUTELY NO WARRANTY and is licensed under GPL-2.0.
|
||||
* Copyright (C) 2024 VegOwOtenks, Sleppo04
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef OPENSIMPLEX2S_H
|
||||
#define OPENSIMPLEX2S_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
#define PRIME_X (0x5205402B9270C86FL)
|
||||
#define PRIME_Y (0x598CD327003817B5L)
|
||||
#define HASH_MULTIPLIER (0x53A3F72DEEC546F5L)
|
||||
|
||||
#define ROOT2OVER2 (0.7071067811865476)
|
||||
#define SKEW_2D (0.366025403784439)
|
||||
#define UNSKEW_2D (-0.21132486540518713)
|
||||
|
||||
#define N_GRADS_2D_EXPONENT (7)
|
||||
#define N_GRADS_2D (1 << N_GRADS_2D_EXPONENT)
|
||||
|
||||
#define NORMALIZER_2D (0.05481866495625118)
|
||||
|
||||
#define RSQUARED_2D (2.0f / 3.0f)
|
||||
|
||||
/// @brief Get the standard noise using the at position x and y with seed seed
|
||||
/// @param seed
|
||||
/// @param x
|
||||
/// @param y
|
||||
/// @return noise at x, y with seed seed
|
||||
// TODO: Don't use this one, it has weird diagonal artifacts
|
||||
float OpenSimplex_2DNoise(int64_t seed, double x, double y);
|
||||
|
||||
float OpenSimplex_2DNoise_ImprovedX(int64_t seed, double x, double y);
|
||||
|
||||
#endif
|
106
src/rand/xoshiro256.c
Normal file
106
src/rand/xoshiro256.c
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* This code is part of the strategy game operational-space.
|
||||
* operational-space comes with ABSOLUTELY NO WARRANTY and is licensed under GPL-2.0.
|
||||
* Copyright (C) 2024 VegOwOtenks, Sleppo04
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#include "xoshiro256.h"
|
||||
|
||||
uint64_t rotate_uint64_left(uint64_t bytes, int degree)
|
||||
{
|
||||
return (bytes << degree) | (bytes >> (64 - degree));
|
||||
}
|
||||
|
||||
|
||||
uint64_t xoshiro256_next(xoshiro256_state_t* state) {
|
||||
uint64_t* uint64_state = state->state;
|
||||
const uint64_t result = rotate_uint64_left(uint64_state[0] + uint64_state[3], 23) + uint64_state[0];
|
||||
|
||||
const uint64_t t = uint64_state[1] << 17;
|
||||
|
||||
uint64_state[2] ^= uint64_state[0];
|
||||
uint64_state[3] ^= uint64_state[1];
|
||||
uint64_state[1] ^= uint64_state[2];
|
||||
uint64_state[0] ^= uint64_state[3];
|
||||
|
||||
uint64_state[2] ^= t;
|
||||
|
||||
uint64_state[3] = rotate_uint64_left(uint64_state[3], 45);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* This is the jump function for the generator. It is equivalent
|
||||
to 2^128 calls to next(); it can be used to generate 2^128
|
||||
non-overlapping subsequences for parallel computations. */
|
||||
|
||||
void jump(xoshiro256_state_t* state) {
|
||||
uint64_t* uint64_state = state->state;
|
||||
static const uint64_t JUMP[] = { 0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c };
|
||||
|
||||
uint64_t s0 = 0;
|
||||
uint64_t s1 = 0;
|
||||
uint64_t s2 = 0;
|
||||
uint64_t s3 = 0;
|
||||
for(uint64_t i = 0; i < sizeof JUMP / sizeof *JUMP; i++)
|
||||
for(int b = 0; b < 64; b++) {
|
||||
if (JUMP[i] & UINT64_C(1) << b) {
|
||||
s0 ^= uint64_state[0];
|
||||
s1 ^= uint64_state[1];
|
||||
s2 ^= uint64_state[2];
|
||||
s3 ^= uint64_state[3];
|
||||
}
|
||||
xoshiro256_next(state);
|
||||
}
|
||||
|
||||
uint64_state[0] = s0;
|
||||
uint64_state[1] = s1;
|
||||
uint64_state[2] = s2;
|
||||
uint64_state[3] = s3;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This is the long-jump function for the generator. It is equivalent to
|
||||
2^192 calls to next(); it can be used to generate 2^64 starting points,
|
||||
from each of which jump() will generate 2^64 non-overlapping
|
||||
subsequences for parallel distributed computations. */
|
||||
|
||||
void long_jump(xoshiro256_state_t* state) {
|
||||
uint64_t* uint64_state = state->state;
|
||||
static const uint64_t LONG_JUMP[] = { 0x76e15d3efefdcbbf, 0xc5004e441c522fb3, 0x77710069854ee241, 0x39109bb02acbe635 };
|
||||
|
||||
uint64_t s0 = 0;
|
||||
uint64_t s1 = 0;
|
||||
uint64_t s2 = 0;
|
||||
uint64_t s3 = 0;
|
||||
for(uint64_t i = 0; i < sizeof LONG_JUMP / sizeof *LONG_JUMP; i++)
|
||||
for(int b = 0; b < 64; b++) {
|
||||
if (LONG_JUMP[i] & UINT64_C(1) << b) {
|
||||
s0 ^= uint64_state[0];
|
||||
s1 ^= uint64_state[1];
|
||||
s2 ^= uint64_state[2];
|
||||
s3 ^= uint64_state[3];
|
||||
}
|
||||
xoshiro256_next(state);
|
||||
}
|
||||
|
||||
uint64_state[0] = s0;
|
||||
uint64_state[1] = s1;
|
||||
uint64_state[2] = s2;
|
||||
uint64_state[3] = s3;
|
||||
}
|
33
src/rand/xoshiro256.h
Normal file
33
src/rand/xoshiro256.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* This code is part of the strategy game operational-space.
|
||||
* operational-space comes with ABSOLUTELY NO WARRANTY and is licensed under GPL-2.0.
|
||||
* Copyright (C) 2024 VegOwOtenks, Sleppo04
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef XOSHIRO256_H
|
||||
#define XOSHIRO256_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct XoshiroState {
|
||||
uint64_t state[4];
|
||||
} xoshiro256_state_t;
|
||||
|
||||
uint64_t rotate_uint64_left(uint64_t bytes, int degree);
|
||||
|
||||
uint64_t xoshiro256_next(xoshiro256_state_t *state);
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue