2
// This unit is part of the GLScene Engine https://github.com/glscene
5
Functions for generating perlin noise.
8
20/05/10 - Yar - Fixes for Linux x64
9
30/03/07 - DaStr - Added $I GLScene.inc
10
28/03/07 - DaStr - Cosmetic fixes for FPC compatibility.
11
29/01/03 - JaJ - Submitted to GLScene.
21
T1DPerlinArray = array of Double;
22
T2DPerlinArray = array of T1DPerlinArray;
24
// Useless for final output! Usefull for after interpolation, as its FAST!
25
function Linear_Interpolate(const a, b, x: Double): Double;
26
// does a cubic interpolation
27
function Cubic_Interpolate(v0, v1, v2, v3, x: Double): Double;
28
// does a cosine interpolation
29
function Cosine_Interpolate(const a, b, x: Double): Double;
30
// just a random controlled by X
31
function Perlin_Random1(x: Integer): Double;
32
// just a random controlled by X,Y
33
function Perlin_Random2(Const x, Y: Integer): Double;
34
// generates a random strip
35
procedure Perlin_Random1DStrip(x, Width, Step: Integer; Amp: Double;
37
// cubic interpolate 4 strips into one...
38
procedure Cubic_Interpolate_Strip(B1, B2, B3, B4, Res: T1DPerlinArray;
40
// smooth interpolate 3 strips into one...
41
procedure Smooth_Interpolate_Strip(B1, B2, B3, Res: T1DPerlinArray;
44
// a function returning some integer based on the root^exponant concept,
45
// result is crap and is only for "random" usage... eg perlin.
46
function ExponateCrap(root, exponant: Integer): Integer;
53
function ExponateCrap(root, exponant: Integer): Integer;
61
D := exp(ln(root) * exponant);
62
If D >= 1E30 then // = Infinity then
64
// if you got a better(faster) way of carving some integer value out of a double let me know!
72
function Perlin_Random1(x: Integer): Double;
74
x := ExponateCrap((x shl 13) + (x shr 9), x);
75
// mess up the number real good!
77
// X X X those three number can be played with, primes are incouraged!
78
x := ((x * (x * x * 15731 + 789221) + 1376312589) And $7FFFFFFF);
80
Result := 1.0 - x / 1073741824.0 // make it a [-1;1] affair!
83
function Perlin_Random2(const x, Y: Integer): Double;
85
// it works! I guess any prime will do!
86
Result := Perlin_Random1(x + Y * 57);
89
procedure Perlin_Random1DStrip(x, Width, Step: Integer; Amp: Double;
96
For XC := 0 to Width - 1 do
98
Posi^ := Perlin_Random1(x) * Amp;
104
procedure Smooth_Interpolate_Strip(B1, B2, B3, Res: T1DPerlinArray;
127
T2 := Pointer(PtrUInt(T1) + SizeOf(Double));
128
C2 := Pointer(PtrUInt(C1) + SizeOf(Double));
129
L2 := Pointer(PtrUInt(L1) + SizeOf(Double));
131
T3 := Pointer(PtrUInt(T2) + SizeOf(Double));
132
C3 := Pointer(PtrUInt(C2) + SizeOf(Double));
133
L3 := Pointer(PtrUInt(L2) + SizeOf(Double));
135
for XC := 0 to Width - 1 do
137
Posi^ := (T1^ + T3^ + L1^ + L3^) / 16 + (T2^ + C1^ + C3^ + L2^) / 8
155
procedure Cubic_Interpolate_Strip(B1, B2, B3, B4, Res: T1DPerlinArray;
182
for XC := 0 to Width - 1 do
184
Posi^ := Cubic_Interpolate(v1^, v2^, v3^, V4^, 0.5) / 2 +
185
Cubic_Interpolate(H1^, H2^, H3^, H4^, 0.5) / 2;
200
function Linear_Interpolate(const a, b, x: Double): Double;
202
Result := a * (1 - x) + b * x
205
function Cosine_Interpolate(const a, b, x: Double): Double;
212
f := (1 - cos(ft)) * 0.5;
214
Result := a * (1 - f) + b * f;
217
function Cubic_Interpolate(v0, v1, v2, v3, x: Double): Double;
222
{ Result := Cosine_Interpolate(v1,v2,x);
228
P := (v3 - v2) - (v0 - v1);
233
Result := (P * x * x * x + Q * x * x + R * x + S);
234
// If (Abs(Result) > 1) then
235
// Raise exception.create('Cubic_Interpolate result to high, '+FloatToStr(Result)+' values ['+FloatToStr(v0)+';'+FloatToStr(v1)+';'+FloatToStr(v2)+';'+FloatToStr(v3)+']');{}