123
This commit is contained in:
216
Editor/Noise.cpp
Normal file
216
Editor/Noise.cpp
Normal file
@@ -0,0 +1,216 @@
|
||||
// Noise.cpp: implementation of the CNoise class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Noise.h"
|
||||
#include "Util\DynamicArray2D.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[]=__FILE__;
|
||||
#define new DEBUG_NEW
|
||||
#endif
|
||||
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable : 4244)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
CNoise::CNoise()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CNoise::~CNoise()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
__forceinline float CNoise::Spline( float x, float *knot )
|
||||
{
|
||||
/*
|
||||
* spline(...)
|
||||
*
|
||||
* interpolate a 1d spline
|
||||
* taken from _Texturing & Modeling: A Procedural Approach_
|
||||
* chapter 2 - by Darwyn Peachey
|
||||
*/
|
||||
|
||||
// Const is a bit faster, nknots does not need to be of different size
|
||||
const int nknots = 4;
|
||||
const int nspans = nknots - 3;
|
||||
|
||||
int span;
|
||||
float c0, c1, c2, c3; // coefficients of the cubic
|
||||
|
||||
/*
|
||||
if( nspans < 1)
|
||||
{
|
||||
// illegal
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
// find the appropriate 4-point span of the spline
|
||||
x = (x < 0 ? 0 : (x > 1 ? 1 : x)) * nspans;
|
||||
span = ftoi(x); // Slow cast is already fast because of the overloaded C float/int conversion
|
||||
if( span >= nknots -3 )
|
||||
span = nknots - 3;
|
||||
x -= span;
|
||||
knot += span;
|
||||
|
||||
// evaluate the span cubic at x using horner's rule
|
||||
c3 = CR00*knot[0] + CR01*knot[1]
|
||||
+ CR02*knot[2] + CR03*knot[3];
|
||||
c2 = CR10*knot[0] + CR11*knot[1]
|
||||
+ CR12*knot[2] + CR13*knot[3];
|
||||
c1 = CR20*knot[0] + CR21*knot[1]
|
||||
+ CR22*knot[2] + CR23*knot[3];
|
||||
c0 = CR30*knot[0] + CR31*knot[1]
|
||||
+ CR32*knot[2] + CR33*knot[3];
|
||||
|
||||
return ((c3*x + c2)*x + c1)*x + c0;
|
||||
}
|
||||
|
||||
void CNoise::FracSynthPass( CDynamicArray2D *hBuf, float freq, float zscale, int xres, int zres, BOOL bLoop )
|
||||
{
|
||||
// WARNING: Function is messy like hell, and lots of dirty optimisation is used...
|
||||
|
||||
/*
|
||||
* FracSynthPass(...)
|
||||
*
|
||||
* generate basic points
|
||||
* interpolate along spline & scale
|
||||
* add to existing hbuffer
|
||||
*/
|
||||
|
||||
int i;
|
||||
int x, z;
|
||||
float *val;
|
||||
|
||||
float dfx, dfz;
|
||||
float *zknots, *knots;
|
||||
float xk, zk;
|
||||
float *hlist;
|
||||
float *buf;
|
||||
|
||||
// how many to generate (need 4 extra for smooth 2d spline interpolation)
|
||||
const int max = freq + 2;
|
||||
// delta x and z - pixels per spline segment
|
||||
dfx = xres / (freq-1);
|
||||
dfz = zres / (freq-1);
|
||||
|
||||
// the generated values - to be equally spread across buf
|
||||
val = (float*)calloc( sizeof(float)*max*max, 1 );
|
||||
if(!val)
|
||||
{ CLogFile::WriteLine("Critical calloc error during noise calculation !"); return; }
|
||||
|
||||
// intermediately calculated spline knots (for 2d)
|
||||
zknots = (float*)calloc( sizeof(float)*max, 1 );
|
||||
if(!zknots)
|
||||
{ CLogFile::WriteLine("Critical calloc error during noise calculation !"); return; }
|
||||
|
||||
// horizontal lines through knots
|
||||
hlist = (float*)calloc( sizeof(float)*max*xres, 1 );
|
||||
if(!hlist)
|
||||
{ CLogFile::WriteLine("Critical calloc error during noise calculation !"); return; }
|
||||
|
||||
// local buffer - to be added to hbuf
|
||||
buf = (float*)calloc( sizeof(float)*xres*zres, 1 );
|
||||
if(!buf)
|
||||
{ CLogFile::WriteLine("Critical calloc error during noise calculation !"); return; }
|
||||
|
||||
// start at -dfx, -dfz - generate knots
|
||||
for( z=0; z<max; z++ )
|
||||
{
|
||||
int zm = z*max;
|
||||
|
||||
for( x=0;x<max;x++ )
|
||||
{
|
||||
val[zm+x] = SRANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(bLoop)
|
||||
{
|
||||
for( z=0; z<max; z++ )
|
||||
{
|
||||
val[z*max+0] = val[z*max+max-1];
|
||||
val[z*max+1] = val[z*max+max-2];
|
||||
}
|
||||
|
||||
for( x=0; x<max; x++ )
|
||||
{
|
||||
val[0*max+x] = val[(max-1)*max+x];
|
||||
val[1*max+x] = val[(max-2)*max+x];
|
||||
}
|
||||
}
|
||||
|
||||
// interpolate horizontal lines through knots
|
||||
float *pOldHList = hlist;
|
||||
for( i=0;i<max;i++ )
|
||||
{
|
||||
knots = &val[i*max];
|
||||
xk = 0;
|
||||
for( x=0;x<xres;x++ )
|
||||
{
|
||||
// Incremental pointer is faster
|
||||
*hlist++ = Spline( xk/dfx,/* 4,*/ knots );
|
||||
xk += 1.0f;
|
||||
if( xk >= dfx )
|
||||
{
|
||||
xk -= dfx;
|
||||
knots++;
|
||||
}
|
||||
}
|
||||
}
|
||||
hlist = pOldHList;
|
||||
|
||||
// interpolate all vertical lines
|
||||
float *pOldBuf = buf;
|
||||
for( x=0;x<xres;x++ )
|
||||
{
|
||||
zk = 0;
|
||||
knots = zknots;
|
||||
// build knot list
|
||||
for( i=0;i<max;i++ )
|
||||
{
|
||||
knots[i] = hlist[i*xres+x];
|
||||
}
|
||||
|
||||
for( z=0;z<zres;z++ )
|
||||
{
|
||||
// Incremental pointer is *much* faster
|
||||
*buf++ = Spline( zk/dfz, /*4,*/ knots ) * zscale;
|
||||
|
||||
zk += 1.0f;
|
||||
if( zk >= dfz )
|
||||
{
|
||||
zk -= dfz;
|
||||
knots++;
|
||||
}
|
||||
}
|
||||
}
|
||||
buf = pOldBuf;
|
||||
|
||||
// update hBuf (Some hacks are used to get around the pointer overhead)
|
||||
float **pArray = hBuf->m_Array;
|
||||
float *pArray2 = NULL;
|
||||
for( z=0;z<zres;z++ )
|
||||
{
|
||||
pArray2 = pArray[z];
|
||||
for( x=0;x<xres;x++ )
|
||||
//hBuf->m_Array[z][x] += buf[z*xres+x];
|
||||
pArray2 [x] += *buf++;
|
||||
}
|
||||
|
||||
free( val );
|
||||
free( pOldBuf );
|
||||
free( pOldHList );
|
||||
free( zknots );
|
||||
}
|
||||
|
||||
#pragma warning (pop)
|
||||
Reference in New Issue
Block a user