Initial source commit

This commit is contained in:
Tony Bark 2025-10-03 02:19:59 -04:00
commit f1384c11ee
335 changed files with 52715 additions and 0 deletions

View file

@ -0,0 +1,312 @@
// Jason Rohrer
// Noise.cpp
/**
*
* Noise generation implementation
*
*
* Created 11-3-99
* Mods:
* Jason Rohrer 12-20-2000 Changed genFractalNoise2d function to make
* it less blocky.
*
*/
#include "Noise.h"
// fills 2d image with ARGB noise
void genRandNoise2d(unsigned long *buff, int buffHigh, int buffWide) {
int *yOffset = new int[buffHigh];
// precalc y offsets
for( int y=0; y<buffHigh; y++) {
yOffset[y] = buffWide*y;
}
int red = (int)(255 * floatRand());
int green = (int)(255 * floatRand());
int blue = (int)(255 * floatRand());
int alpha = (int)(255 * floatRand());
for( int y=0; y<buffHigh; y++) {
int yContrib = yOffset[y];
for( int x=0; x<buffWide; x++) {
/* int red = (int)(255 * floatRand());
int green = (int)(255 * floatRand());
int blue = (int)(255 * floatRand());
int alpha = (int)(255 * floatRand());
*/
buff[ yContrib + x] = blue | green << 8 | red << 16 | alpha << 24;
}
}
delete [] yOffset;
}
// fills 2d image with ARGB fractal noise
void genFractalNoise2d(unsigned long *buff, int buffHigh, int buffWide) {
int *yOffset = new int[buffHigh];
// precalc y offsets
for( int y=0; y<buffHigh; y++) {
yOffset[y] = buffWide*y;
}
// first, zero out the buffer
for( int y=0; y<buffHigh; y++) {
int yContrib = yOffset[y];
for( int x=0; x<buffWide; x++) {
buff[ yContrib + x] = 127 | 127 << 8 | 127 << 16 | 127 << 24;
}
}
// walk through each frequency....
// weight in sum of frequencies by 1/f
// frequency in cycles per buffer width
// stop when frequency == buffer width
for( int f=1; f<=buffWide; f++) { // for each frequency
float weight = 1 / (float)(f);
// number of pixels in each cycle
int blockWide = (int)(buffWide * weight );
int blockHigh = (int)(buffHigh * weight );
int buffY = 0;
while( buffY < buffHigh ) {
int startY = buffY;
int buffX = 0;
while( buffX < buffWide ) {
buffY = startY;
int startX = buffX;
// color components for this block
// weighted by frequency
int red = (int)((255 * floatRand() - 127) * weight);
int green = (int)((255 * floatRand() - 127) * weight);
int blue = (int)((255 * floatRand() - 127) * weight);
int alpha = (int)((255 * floatRand() - 127) * weight);
int blockY = 0;
while( blockY < blockHigh) {
int blockX = 0;
buffX = startX;
while( blockX < blockWide) {
unsigned long buffARGB = buff[ yOffset[buffY] + buffX];
int buffAlpha = (buffARGB >> 24 & 0xFF) + alpha;
int buffRed = (buffARGB >> 16 & 0xFF) + red;
int buffGreen = (buffARGB >> 8 & 0xFF) + green;
int buffBlue = (buffARGB & 0xFF) + blue;
if( buffAlpha < 0) buffAlpha = 0;
if( buffRed < 0) buffRed = 0;
if( buffGreen < 0) buffGreen = 0;
if( buffBlue < 0) buffBlue = 0;
if( buffAlpha > 255) buffAlpha = 255;
if( buffRed > 255) buffRed = 255;
if( buffGreen > 255) buffGreen = 255;
if( buffBlue > 255) buffBlue = 255;
buff[ yOffset[buffY] + buffX] = buffBlue | buffGreen << 8 | buffRed << 16 | buffAlpha << 24;
buffX++;
blockX++;
if( buffX >= buffWide ) blockX = blockWide; // if this block hangs outside buffer
}
buffY++;
blockY++;
if( buffY >= buffHigh ) blockY = blockHigh; // if this block hangs outside buffer
}
buffX = startX + blockWide;
}
buffY = startY + blockHigh;
}
}
delete [] yOffset;
}
void genFractalNoise2d( double *inBuffer, int inWidth, int inMaxFrequency,
double inFPower, char inInterpolate, RandomSource *inRandSource ) {
RandomSource *r = inRandSource;
int w = inWidth;
int i, x, y, f;
int numPoints = w * w;
// first, fill surface with a uniform 0.5 value
for( i=0; i<numPoints; i++ ) {
inBuffer[i] = 0.5;
}
// for each frequency
for( f=2; f<=inMaxFrequency; f = f * 2 ) {
double weight = 1.0 / pow( f, inFPower );
int blockSize = (int)( (double)w / (double)f + 1.0 );
// one extra block to handle boundary case where x or y is 0
int numBlocks = (f+1) * (f+1);
double *blockValues = new double[ numBlocks ];
// assign a random value to each block
for( i=0; i<numBlocks; i++ ) {
blockValues[i] = ( 2 * r->getRandomDouble() - 1 ) * weight;
}
// now walk though 2d array and perform
// bilinear interpolation between blocks
for( y=0; y<w; y++ ) {
// handle boundary case by skipping first row of blocks
int yBlock = y / blockSize + 1;
double yWeight;
yWeight = (double)(y % blockSize) / blockSize;
for( x=0; x<w; x++ ) {
// handle boundary case by skipping first column of blocks
int xBlock = x / blockSize + 1;
double xWeight;
xWeight = (double)(x % blockSize) / blockSize;
// if interpolating take weighted sum with previous blocks
double value;
if( inInterpolate ) {
value =
xWeight *
( yWeight *
blockValues[ yBlock * f + xBlock ] +
(1-yWeight) *
blockValues[ (yBlock-1) * f + xBlock ] ) +
(1-xWeight) *
( yWeight *
blockValues[ yBlock * f + xBlock - 1 ] +
(1-yWeight) *
blockValues[ (yBlock-1) * f + xBlock - 1 ] );
}
else {
value =
blockValues[ yBlock * f + xBlock ];
}
// modulate current value by new value
inBuffer[ y * w + x ] += value;
// clip values as we go along
if( inBuffer[y * w + x] > 1.0 ) {
inBuffer[y * w + x] = 1.0;
}
else if( inBuffer[y * w + x] < 0.0 ) {
inBuffer[y * w + x] = 0.0;
}
}
}
delete [] blockValues;
}
}
void genFractalNoise( double *inBuffer, int inWidth, int inMaxFrequency,
double inFPower, char inInterpolate, RandomSource *inRandSource ) {
RandomSource *r = inRandSource;
int w = inWidth;
int i, x, f;
// first, fill array with uniform 0.5 values
for( i=0; i<w; i++ ) {
inBuffer[i] = 0.5;
}
// for each frequency
for( f=2; f<=inMaxFrequency; f = f * 2 ) {
double weight = 1.0 / pow( f, inFPower );
int blockSize = (int)( (double)w / (double)f + 1.0 );
// one extra block to handle boundary case where x is 0
int numBlocks = (f+1);
double *blockValues = new double[ numBlocks ];
// assign a random value to each block
for( i=0; i<numBlocks; i++ ) {
blockValues[i] = ( 2 * r->getRandomDouble() - 1 ) * weight;
}
// now walk though array and perform linear interpolation between blocks
for( x=0; x<w; x++ ) {
// handle boundary case by skipping first column of blocks
int xBlock = x / blockSize + 1;
double xWeight;
xWeight = (double)(x % blockSize) / blockSize;
// take weighted sum with previous blocks, but watch for
// boundary cases
double value;
if( inInterpolate ) {
value =
xWeight * blockValues[ xBlock ] +
(1-xWeight) * blockValues[ xBlock - 1 ];
}
else {
value =
blockValues[ xBlock ];
}
// modulate current value by new value
inBuffer[ x ] += value;
// clip values as we go along
if( inBuffer[x] > 1.0 ) {
inBuffer[x] = 1.0;
}
else if( inBuffer[x] < 0.0 ) {
inBuffer[x] = 0.0;
}
}
delete [] blockValues;
}
}