Skip to content

Commit ca4072a

Browse files
committed
Cellular 4D
1 parent 9bd6984 commit ca4072a

File tree

2 files changed

+222
-4
lines changed

2 files changed

+222
-4
lines changed

include/FastNoise/Generators/Cellular.h

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ namespace FastNoise
1717

1818
const float kJitter2D = 0.5f;
1919
const float kJitter3D = 0.45f;
20+
const float kJitter4D = 0.45f;
2021

2122
FASTNOISE_METADATA_ABSTRACT( Generator )
2223

include/FastNoise/Generators/Cellular.inl

+221-4
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,77 @@ public:
120120

121121
return cellValue;
122122
}
123+
124+
float32v FS_VECTORCALL Gen( int32v seed, float32v x, float32v y, float32v z , float32v w ) const final
125+
{
126+
float32v jitter = float32v( kJitter4D ) * this->GetSourceValue( mJitterModifier, seed, x, y, z, w );
127+
float32v distance( FLT_MAX );
128+
float32v cellValue;
129+
130+
int32v xc = FS_Convertf32_i32( x ) + int32v( -1 );
131+
int32v ycBase = FS_Convertf32_i32( y ) + int32v( -1 );
132+
int32v zcBase = FS_Convertf32_i32( z ) + int32v( -1 );
133+
int32v wcBase = FS_Convertf32_i32( w ) + int32v( -1 );
134+
135+
float32v xcf = FS_Converti32_f32( xc ) - x;
136+
float32v ycfBase = FS_Converti32_f32( ycBase ) - y;
137+
float32v zcfBase = FS_Converti32_f32( zcBase ) - z;
138+
float32v wcfBase = FS_Converti32_f32( wcBase ) - w;
139+
140+
xc *= int32v( Primes::X );
141+
ycBase *= int32v( Primes::Y );
142+
zcBase *= int32v( Primes::Z );
143+
wcBase *= int32v( Primes::W );
144+
145+
for( int xi = 0; xi < 3; xi++ )
146+
{
147+
float32v ycf = ycfBase;
148+
int32v yc = ycBase;
149+
for( int yi = 0; yi < 3; yi++ )
150+
{
151+
float32v zcf = zcfBase;
152+
int32v zc = zcBase;
153+
for( int zi = 0; zi < 3; zi++ )
154+
{
155+
float32v wcf = wcfBase;
156+
int32v wc = wcBase;
157+
for( int wi = 0; wi < 3; wi++ )
158+
{
159+
int32v hash = HashPrimesHB( seed, xc, yc, zc, wc );
160+
float32v xd = FS_Converti32_f32( hash & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
161+
float32v yd = FS_Converti32_f32( (hash >> 8) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
162+
float32v zd = FS_Converti32_f32( (hash >> 16) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
163+
float32v wd = FS_Converti32_f32( (hash >> 24) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
164+
165+
float32v invMag = jitter * FS_InvSqrt_f32( FS_FMulAdd_f32( xd, xd, FS_FMulAdd_f32( yd, yd, FS_FMulAdd_f32( zd, zd, wd * wd ) ) ) );
166+
xd = FS_FMulAdd_f32( xd, invMag, xcf );
167+
yd = FS_FMulAdd_f32( yd, invMag, ycf );
168+
zd = FS_FMulAdd_f32( zd, invMag, zcf );
169+
wd = FS_FMulAdd_f32( wd, invMag, wcf );
170+
171+
float32v newCellValue = float32v( (float)(1.0 / INT_MAX) ) * FS_Converti32_f32( hash );
172+
float32v newDistance = CalcDistance( mDistanceFunction, xd, yd, zd, wd );
173+
174+
mask32v closer = FS_LessThan_f32( newDistance, distance );
175+
176+
distance = FS_Min_f32( newDistance, distance );
177+
cellValue = FS_Select_f32( closer, newCellValue, cellValue );
178+
179+
wcf += float32v( 1 );
180+
wc += int32v( Primes::W );
181+
}
182+
zcf += float32v( 1 );
183+
zc += int32v( Primes::Z );
184+
}
185+
ycf += float32v( 1 );
186+
yc += int32v( Primes::Y );
187+
}
188+
xcf += float32v( 1 );
189+
xc += int32v( Primes::X );
190+
}
191+
192+
return cellValue;
193+
}
123194
};
124195

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

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

@@ -159,7 +229,7 @@ public:
159229

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

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

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

@@ -218,7 +287,7 @@ public:
218287

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

221-
for( int i = maxDistanceIndex; i > 0; i-- )
290+
for( int i = kMaxDistanceCount - 1; i > 0; i-- )
222291
{
223292
distance[i] = FS_Max_f32( FS_Min_f32( distance[i], newDistance ), distance[i - 1] );
224293
}
@@ -238,6 +307,79 @@ public:
238307
return GetReturn( distance );
239308
}
240309

310+
float32v FS_VECTORCALL Gen( int32v seed, float32v x, float32v y, float32v z, float32v w ) const final
311+
{
312+
float32v jitter = float32v( kJitter4D ) * this->GetSourceValue( mJitterModifier, seed, x, y, z, w );
313+
314+
std::array<float32v, kMaxDistanceCount> distance;
315+
distance.fill( float32v( INFINITY ) );
316+
317+
int32v xc = FS_Convertf32_i32( x ) + int32v( -1 );
318+
int32v ycBase = FS_Convertf32_i32( y ) + int32v( -1 );
319+
int32v zcBase = FS_Convertf32_i32( z ) + int32v( -1 );
320+
int32v wcBase = FS_Convertf32_i32( w ) + int32v( -1 );
321+
322+
float32v xcf = FS_Converti32_f32( xc ) - x;
323+
float32v ycfBase = FS_Converti32_f32( ycBase ) - y;
324+
float32v zcfBase = FS_Converti32_f32( zcBase ) - z;
325+
float32v wcfBase = FS_Converti32_f32( wcBase ) - w;
326+
327+
xc *= int32v( Primes::X );
328+
ycBase *= int32v( Primes::Y );
329+
zcBase *= int32v( Primes::Z );
330+
wcBase *= int32v( Primes::W );
331+
332+
for( int xi = 0; xi < 3; xi++ )
333+
{
334+
float32v ycf = ycfBase;
335+
int32v yc = ycBase;
336+
for( int yi = 0; yi < 3; yi++ )
337+
{
338+
float32v zcf = zcfBase;
339+
int32v zc = zcBase;
340+
for( int zi = 0; zi < 3; zi++ )
341+
{
342+
float32v wcf = wcfBase;
343+
int32v wc = wcBase;
344+
for( int wi = 0; wi < 3; wi++ )
345+
{
346+
int32v hash = HashPrimesHB( seed, xc, yc, zc, wc );
347+
float32v xd = FS_Converti32_f32( hash & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
348+
float32v yd = FS_Converti32_f32( (hash >> 8) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
349+
float32v zd = FS_Converti32_f32( (hash >> 16) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
350+
float32v wd = FS_Converti32_f32( (hash >> 24) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
351+
352+
float32v invMag = jitter * FS_InvSqrt_f32( FS_FMulAdd_f32( xd, xd, FS_FMulAdd_f32( yd, yd, FS_FMulAdd_f32( zd, zd, wd * wd ) ) ) );
353+
xd = FS_FMulAdd_f32( xd, invMag, xcf );
354+
yd = FS_FMulAdd_f32( yd, invMag, ycf );
355+
zd = FS_FMulAdd_f32( zd, invMag, zcf );
356+
wd = FS_FMulAdd_f32( wd, invMag, wcf );
357+
358+
float32v newDistance = CalcDistance( mDistanceFunction, xd, yd, zd, wd );
359+
360+
for( int i = kMaxDistanceCount - 1; i > 0; i-- )
361+
{
362+
distance[i] = FS_Max_f32( FS_Min_f32( distance[i], newDistance ), distance[i - 1] );
363+
}
364+
365+
distance[0] = FS_Min_f32( distance[0], newDistance );
366+
367+
wcf += float32v( 1 );
368+
wc += int32v( Primes::W );
369+
}
370+
zcf += float32v( 1 );
371+
zc += int32v( Primes::Z );
372+
}
373+
ycf += float32v( 1 );
374+
yc += int32v( Primes::Y );
375+
}
376+
xcf += float32v( 1 );
377+
xc += int32v( Primes::X );
378+
}
379+
380+
return GetReturn( distance );
381+
}
382+
241383
protected:
242384
FS_INLINE float32v GetReturn( std::array<float32v, kMaxDistanceCount>& distance ) const
243385
{
@@ -384,4 +526,79 @@ public:
384526

385527
return this->GetSourceValue( mLookup, seed - int32v( -1 ), cellX * float32v( mLookupFreq ), cellY * float32v( mLookupFreq ), cellZ * float32v( mLookupFreq ) );
386528
}
529+
530+
531+
float32v FS_VECTORCALL Gen( int32v seed, float32v x, float32v y, float32v z, float32v w ) const final
532+
{
533+
float32v jitter = float32v( kJitter4D ) * this->GetSourceValue( mJitterModifier, seed, x, y, z, w );
534+
float32v distance( FLT_MAX );
535+
float32v cellX, cellY, cellZ, cellW;
536+
537+
int32v xc = FS_Convertf32_i32( x ) + int32v( -1 );
538+
int32v ycBase = FS_Convertf32_i32( y ) + int32v( -1 );
539+
int32v zcBase = FS_Convertf32_i32( z ) + int32v( -1 );
540+
int32v wcBase = FS_Convertf32_i32( w ) + int32v( -1 );
541+
542+
float32v xcf = FS_Converti32_f32( xc ) - x;
543+
float32v ycfBase = FS_Converti32_f32( ycBase ) - y;
544+
float32v zcfBase = FS_Converti32_f32( zcBase ) - z;
545+
float32v wcfBase = FS_Converti32_f32( wcBase ) - w;
546+
547+
xc *= int32v( Primes::X );
548+
ycBase *= int32v( Primes::Y );
549+
zcBase *= int32v( Primes::Z );
550+
wcBase *= int32v( Primes::W );
551+
552+
for( int xi = 0; xi < 3; xi++ )
553+
{
554+
float32v ycf = ycfBase;
555+
int32v yc = ycBase;
556+
for( int yi = 0; yi < 3; yi++ )
557+
{
558+
float32v zcf = zcfBase;
559+
int32v zc = zcBase;
560+
for( int zi = 0; zi < 3; zi++ )
561+
{
562+
float32v wcf = wcfBase;
563+
int32v wc = wcBase;
564+
for( int wi = 0; wi < 3; wi++ )
565+
{
566+
int32v hash = HashPrimesHB( seed, xc, yc, zc, wc );
567+
float32v xd = FS_Converti32_f32( hash & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
568+
float32v yd = FS_Converti32_f32( (hash >> 8) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
569+
float32v zd = FS_Converti32_f32( (hash >> 16) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
570+
float32v wd = FS_Converti32_f32( (hash >> 24) & int32v( 0xff ) ) - float32v( 0xff / 2.0f );
571+
572+
float32v invMag = jitter * FS_InvSqrt_f32( FS_FMulAdd_f32( xd, xd, FS_FMulAdd_f32( yd, yd, FS_FMulAdd_f32( zd, zd, wd * wd ) ) ) );
573+
xd = FS_FMulAdd_f32( xd, invMag, xcf );
574+
yd = FS_FMulAdd_f32( yd, invMag, ycf );
575+
zd = FS_FMulAdd_f32( zd, invMag, zcf );
576+
wd = FS_FMulAdd_f32( wd, invMag, wcf );
577+
578+
float32v newCellValue = float32v( (float)(1.0 / INT_MAX) ) * FS_Converti32_f32( hash );
579+
float32v newDistance = CalcDistance( mDistanceFunction, xd, yd, zd, wd );
580+
581+
mask32v closer = FS_LessThan_f32( newDistance, distance );
582+
distance = FS_Min_f32( newDistance, distance );
583+
584+
cellX = FS_Select_f32( closer, xd + x, cellX );
585+
cellY = FS_Select_f32( closer, yd + y, cellY );
586+
cellZ = FS_Select_f32( closer, zd + z, cellZ );
587+
cellW = FS_Select_f32( closer, wd + w, cellW );
588+
589+
wcf += float32v( 1 );
590+
wc += int32v( Primes::W );
591+
}
592+
zcf += float32v( 1 );
593+
zc += int32v( Primes::Z );
594+
}
595+
ycf += float32v( 1 );
596+
yc += int32v( Primes::Y );
597+
}
598+
xcf += float32v( 1 );
599+
xc += int32v( Primes::X );
600+
}
601+
602+
return this->GetSourceValue( mLookup, seed - int32v( -1 ), cellX * float32v( mLookupFreq ), cellY * float32v( mLookupFreq ), cellZ * float32v( mLookupFreq ), cellW * float32v( mLookupFreq ) );
603+
}
387604
};

0 commit comments

Comments
 (0)