Skip to content

Commit

Permalink
Cellular 4D
Browse files Browse the repository at this point in the history
  • Loading branch information
Auburn committed Aug 16, 2020
1 parent 9bd6984 commit ca4072a
Show file tree
Hide file tree
Showing 2 changed files with 222 additions and 4 deletions.
1 change: 1 addition & 0 deletions include/FastNoise/Generators/Cellular.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace FastNoise

const float kJitter2D = 0.5f;
const float kJitter3D = 0.45f;
const float kJitter4D = 0.45f;

FASTNOISE_METADATA_ABSTRACT( Generator )

Expand Down
225 changes: 221 additions & 4 deletions include/FastNoise/Generators/Cellular.inl
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,77 @@ public:

return cellValue;
}

float32v FS_VECTORCALL Gen( int32v seed, float32v x, float32v y, float32v z , float32v w ) const final
{
float32v jitter = float32v( kJitter4D ) * this->GetSourceValue( mJitterModifier, seed, x, y, z, w );
float32v distance( FLT_MAX );
float32v cellValue;

int32v xc = FS_Convertf32_i32( x ) + int32v( -1 );
int32v ycBase = FS_Convertf32_i32( y ) + int32v( -1 );
int32v zcBase = FS_Convertf32_i32( z ) + int32v( -1 );
int32v wcBase = FS_Convertf32_i32( w ) + int32v( -1 );

float32v xcf = FS_Converti32_f32( xc ) - x;
float32v ycfBase = FS_Converti32_f32( ycBase ) - y;
float32v zcfBase = FS_Converti32_f32( zcBase ) - z;
float32v wcfBase = FS_Converti32_f32( wcBase ) - w;

xc *= int32v( Primes::X );
ycBase *= int32v( Primes::Y );
zcBase *= int32v( Primes::Z );
wcBase *= int32v( Primes::W );

for( int xi = 0; xi < 3; xi++ )
{
float32v ycf = ycfBase;
int32v yc = ycBase;
for( int yi = 0; yi < 3; yi++ )
{
float32v zcf = zcfBase;
int32v zc = zcBase;
for( int zi = 0; zi < 3; zi++ )
{
float32v wcf = wcfBase;
int32v wc = wcBase;
for( int wi = 0; wi < 3; wi++ )
{
int32v hash = HashPrimesHB( seed, xc, yc, zc, wc );
float32v xd = FS_Converti32_f32( hash & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
float32v yd = FS_Converti32_f32( (hash >> 8) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
float32v zd = FS_Converti32_f32( (hash >> 16) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
float32v wd = FS_Converti32_f32( (hash >> 24) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );

float32v invMag = jitter * FS_InvSqrt_f32( FS_FMulAdd_f32( xd, xd, FS_FMulAdd_f32( yd, yd, FS_FMulAdd_f32( zd, zd, wd * wd ) ) ) );
xd = FS_FMulAdd_f32( xd, invMag, xcf );
yd = FS_FMulAdd_f32( yd, invMag, ycf );
zd = FS_FMulAdd_f32( zd, invMag, zcf );
wd = FS_FMulAdd_f32( wd, invMag, wcf );

float32v newCellValue = float32v( (float)(1.0 / INT_MAX) ) * FS_Converti32_f32( hash );
float32v newDistance = CalcDistance( mDistanceFunction, xd, yd, zd, wd );

mask32v closer = FS_LessThan_f32( newDistance, distance );

distance = FS_Min_f32( newDistance, distance );
cellValue = FS_Select_f32( closer, newCellValue, cellValue );

wcf += float32v( 1 );
wc += int32v( Primes::W );
}
zcf += float32v( 1 );
zc += int32v( Primes::Z );
}
ycf += float32v( 1 );
yc += int32v( Primes::Y );
}
xcf += float32v( 1 );
xc += int32v( Primes::X );
}

return cellValue;
}
};

template<typename FS>
Expand All @@ -130,7 +201,6 @@ public:
{
float32v jitter = float32v( kJitter2D ) * this->GetSourceValue( mJitterModifier, seed, x, y );

int maxDistanceIndex = (mReturnType == ReturnType::Index0) ? mDistanceIndex0 : std::max( mDistanceIndex0, mDistanceIndex1 );
std::array<float32v, kMaxDistanceCount> distance;
distance.fill( float32v( INFINITY ) );

Expand Down Expand Up @@ -159,7 +229,7 @@ public:

float32v newDistance = CalcDistance( mDistanceFunction, xd, yd );

for( int i = maxDistanceIndex; i > 0; i-- )
for( int i = kMaxDistanceCount - 1; i > 0; i-- )
{
distance[i] = FS_Max_f32( FS_Min_f32( distance[i], newDistance ), distance[i - 1] );
}
Expand All @@ -180,7 +250,6 @@ public:
{
float32v jitter = float32v( kJitter3D ) * this->GetSourceValue( mJitterModifier, seed, x, y, z );

int maxDistanceIndex = (mReturnType == ReturnType::Index0) ? mDistanceIndex0 : std::max( mDistanceIndex0, mDistanceIndex1 );
std::array<float32v, kMaxDistanceCount> distance;
distance.fill( float32v( INFINITY ) );

Expand Down Expand Up @@ -218,7 +287,7 @@ public:

float32v newDistance = CalcDistance( mDistanceFunction, xd, yd, zd );

for( int i = maxDistanceIndex; i > 0; i-- )
for( int i = kMaxDistanceCount - 1; i > 0; i-- )
{
distance[i] = FS_Max_f32( FS_Min_f32( distance[i], newDistance ), distance[i - 1] );
}
Expand All @@ -238,6 +307,79 @@ public:
return GetReturn( distance );
}

float32v FS_VECTORCALL Gen( int32v seed, float32v x, float32v y, float32v z, float32v w ) const final
{
float32v jitter = float32v( kJitter4D ) * this->GetSourceValue( mJitterModifier, seed, x, y, z, w );

std::array<float32v, kMaxDistanceCount> distance;
distance.fill( float32v( INFINITY ) );

int32v xc = FS_Convertf32_i32( x ) + int32v( -1 );
int32v ycBase = FS_Convertf32_i32( y ) + int32v( -1 );
int32v zcBase = FS_Convertf32_i32( z ) + int32v( -1 );
int32v wcBase = FS_Convertf32_i32( w ) + int32v( -1 );

float32v xcf = FS_Converti32_f32( xc ) - x;
float32v ycfBase = FS_Converti32_f32( ycBase ) - y;
float32v zcfBase = FS_Converti32_f32( zcBase ) - z;
float32v wcfBase = FS_Converti32_f32( wcBase ) - w;

xc *= int32v( Primes::X );
ycBase *= int32v( Primes::Y );
zcBase *= int32v( Primes::Z );
wcBase *= int32v( Primes::W );

for( int xi = 0; xi < 3; xi++ )
{
float32v ycf = ycfBase;
int32v yc = ycBase;
for( int yi = 0; yi < 3; yi++ )
{
float32v zcf = zcfBase;
int32v zc = zcBase;
for( int zi = 0; zi < 3; zi++ )
{
float32v wcf = wcfBase;
int32v wc = wcBase;
for( int wi = 0; wi < 3; wi++ )
{
int32v hash = HashPrimesHB( seed, xc, yc, zc, wc );
float32v xd = FS_Converti32_f32( hash & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
float32v yd = FS_Converti32_f32( (hash >> 8) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
float32v zd = FS_Converti32_f32( (hash >> 16) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
float32v wd = FS_Converti32_f32( (hash >> 24) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );

float32v invMag = jitter * FS_InvSqrt_f32( FS_FMulAdd_f32( xd, xd, FS_FMulAdd_f32( yd, yd, FS_FMulAdd_f32( zd, zd, wd * wd ) ) ) );
xd = FS_FMulAdd_f32( xd, invMag, xcf );
yd = FS_FMulAdd_f32( yd, invMag, ycf );
zd = FS_FMulAdd_f32( zd, invMag, zcf );
wd = FS_FMulAdd_f32( wd, invMag, wcf );

float32v newDistance = CalcDistance( mDistanceFunction, xd, yd, zd, wd );

for( int i = kMaxDistanceCount - 1; i > 0; i-- )
{
distance[i] = FS_Max_f32( FS_Min_f32( distance[i], newDistance ), distance[i - 1] );
}

distance[0] = FS_Min_f32( distance[0], newDistance );

wcf += float32v( 1 );
wc += int32v( Primes::W );
}
zcf += float32v( 1 );
zc += int32v( Primes::Z );
}
ycf += float32v( 1 );
yc += int32v( Primes::Y );
}
xcf += float32v( 1 );
xc += int32v( Primes::X );
}

return GetReturn( distance );
}

protected:
FS_INLINE float32v GetReturn( std::array<float32v, kMaxDistanceCount>& distance ) const
{
Expand Down Expand Up @@ -384,4 +526,79 @@ public:

return this->GetSourceValue( mLookup, seed - int32v( -1 ), cellX * float32v( mLookupFreq ), cellY * float32v( mLookupFreq ), cellZ * float32v( mLookupFreq ) );
}


float32v FS_VECTORCALL Gen( int32v seed, float32v x, float32v y, float32v z, float32v w ) const final
{
float32v jitter = float32v( kJitter4D ) * this->GetSourceValue( mJitterModifier, seed, x, y, z, w );
float32v distance( FLT_MAX );
float32v cellX, cellY, cellZ, cellW;

int32v xc = FS_Convertf32_i32( x ) + int32v( -1 );
int32v ycBase = FS_Convertf32_i32( y ) + int32v( -1 );
int32v zcBase = FS_Convertf32_i32( z ) + int32v( -1 );
int32v wcBase = FS_Convertf32_i32( w ) + int32v( -1 );

float32v xcf = FS_Converti32_f32( xc ) - x;
float32v ycfBase = FS_Converti32_f32( ycBase ) - y;
float32v zcfBase = FS_Converti32_f32( zcBase ) - z;
float32v wcfBase = FS_Converti32_f32( wcBase ) - w;

xc *= int32v( Primes::X );
ycBase *= int32v( Primes::Y );
zcBase *= int32v( Primes::Z );
wcBase *= int32v( Primes::W );

for( int xi = 0; xi < 3; xi++ )
{
float32v ycf = ycfBase;
int32v yc = ycBase;
for( int yi = 0; yi < 3; yi++ )
{
float32v zcf = zcfBase;
int32v zc = zcBase;
for( int zi = 0; zi < 3; zi++ )
{
float32v wcf = wcfBase;
int32v wc = wcBase;
for( int wi = 0; wi < 3; wi++ )
{
int32v hash = HashPrimesHB( seed, xc, yc, zc, wc );
float32v xd = FS_Converti32_f32( hash & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
float32v yd = FS_Converti32_f32( (hash >> 8) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
float32v zd = FS_Converti32_f32( (hash >> 16) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
float32v wd = FS_Converti32_f32( (hash >> 24) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );

float32v invMag = jitter * FS_InvSqrt_f32( FS_FMulAdd_f32( xd, xd, FS_FMulAdd_f32( yd, yd, FS_FMulAdd_f32( zd, zd, wd * wd ) ) ) );
xd = FS_FMulAdd_f32( xd, invMag, xcf );
yd = FS_FMulAdd_f32( yd, invMag, ycf );
zd = FS_FMulAdd_f32( zd, invMag, zcf );
wd = FS_FMulAdd_f32( wd, invMag, wcf );

float32v newCellValue = float32v( (float)(1.0 / INT_MAX) ) * FS_Converti32_f32( hash );
float32v newDistance = CalcDistance( mDistanceFunction, xd, yd, zd, wd );

mask32v closer = FS_LessThan_f32( newDistance, distance );
distance = FS_Min_f32( newDistance, distance );

cellX = FS_Select_f32( closer, xd + x, cellX );
cellY = FS_Select_f32( closer, yd + y, cellY );
cellZ = FS_Select_f32( closer, zd + z, cellZ );
cellW = FS_Select_f32( closer, wd + w, cellW );

wcf += float32v( 1 );
wc += int32v( Primes::W );
}
zcf += float32v( 1 );
zc += int32v( Primes::Z );
}
ycf += float32v( 1 );
yc += int32v( Primes::Y );
}
xcf += float32v( 1 );
xc += int32v( Primes::X );
}

return this->GetSourceValue( mLookup, seed - int32v( -1 ), cellX * float32v( mLookupFreq ), cellY * float32v( mLookupFreq ), cellZ * float32v( mLookupFreq ), cellW * float32v( mLookupFreq ) );
}
};

0 comments on commit ca4072a

Please sign in to comment.