hedgewars/uLandGenPerlin.pas
author unc0rr
Sat, 08 Mar 2014 23:51:50 +0400
changeset 10187 0d506346c1f0
parent 10186 3fa109a1ae95
child 10188 e8f2dbabd01b
permissions -rw-r--r--
Experiment: enforce a plate at bottom so the map generated is more connected
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
     1
{$INCLUDE "options.inc"}
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
     2
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
     3
unit uLandGenPerlin;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
     4
interface
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
     5
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
     6
procedure GenPerlin;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
     7
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
     8
implementation
10182
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
     9
uses uVariables, uConsts, uRandom, math; // for min()
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    10
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    11
var fadear: array[byte] of LongInt;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    12
    p: array[0..511] of LongInt;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    13
10183
189afaf2d076 Some tweaks to perlin generator
unc0rr
parents: 10182
diff changeset
    14
function fade(t: LongInt) : LongInt; inline;
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    15
var t0, t1: LongInt;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    16
begin
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    17
    t0:= fadear[t shr 8];
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    18
    t1:= fadear[min(255, t shr 8 + 1)];
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    19
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    20
    fade:= t0 + ((t and 255) * (t1 - t0) shr 8)
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    21
end;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    22
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    23
10183
189afaf2d076 Some tweaks to perlin generator
unc0rr
parents: 10182
diff changeset
    24
function lerp(t, a, b: LongInt) : LongInt; inline;
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    25
begin
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    26
    lerp:= a + (t * (b - a) shr 12)
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    27
end;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    28
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    29
10185
007a40cfbb3d Strip Z axis from calculations
unc0rr
parents: 10184
diff changeset
    30
function grad(hash, x, y: LongInt) : LongInt;
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    31
var h, v, u: LongInt;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    32
begin
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    33
    h:= hash and 15;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    34
    if h < 8 then u:= x else u:= y;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    35
    if h < 4 then v:= y else
10185
007a40cfbb3d Strip Z axis from calculations
unc0rr
parents: 10184
diff changeset
    36
        if (h = 12) or (h = 14) then v:= x else v:= 0;
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    37
10185
007a40cfbb3d Strip Z axis from calculations
unc0rr
parents: 10184
diff changeset
    38
    if (h and 1) <> 0 then u:= -u;
007a40cfbb3d Strip Z axis from calculations
unc0rr
parents: 10184
diff changeset
    39
    if (h and 2) <> 0 then v:= -v;
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    40
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    41
    grad:= u + v
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    42
end;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    43
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    44
10185
007a40cfbb3d Strip Z axis from calculations
unc0rr
parents: 10184
diff changeset
    45
function inoise(x, y: LongInt) : LongInt;
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    46
const N = $10000;
10185
007a40cfbb3d Strip Z axis from calculations
unc0rr
parents: 10184
diff changeset
    47
var xx, yy, u, v, A, AA, AB, B, BA, BB: LongInt;
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    48
begin
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    49
    xx:= (x shr 16) and 255;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    50
    yy:= (y shr 16) and 255;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    51
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    52
    x:= x and $FFFF;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    53
    y:= y and $FFFF;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    54
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    55
    u:= fade(x);
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    56
    v:= fade(y);
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    57
10185
007a40cfbb3d Strip Z axis from calculations
unc0rr
parents: 10184
diff changeset
    58
    A:= p[xx    ] + yy; AA:= p[A]; AB:= p[A + 1];
007a40cfbb3d Strip Z axis from calculations
unc0rr
parents: 10184
diff changeset
    59
    B:= p[xx + 1] + yy; BA:= p[B]; BB:= p[B + 1];
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    60
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    61
    inoise:=
10185
007a40cfbb3d Strip Z axis from calculations
unc0rr
parents: 10184
diff changeset
    62
            lerp(v, lerp(u, grad(p[AA  ], x   , y  ),
007a40cfbb3d Strip Z axis from calculations
unc0rr
parents: 10184
diff changeset
    63
                            grad(p[BA  ], x-N , y  )),
007a40cfbb3d Strip Z axis from calculations
unc0rr
parents: 10184
diff changeset
    64
                    lerp(u, grad(p[AB  ], x   , y-N),
007a40cfbb3d Strip Z axis from calculations
unc0rr
parents: 10184
diff changeset
    65
                            grad(p[BB  ], x-N , y-N)));
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    66
end;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    67
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    68
function f(t: double): double;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    69
begin
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    70
    f:= t * t * t * (t * (t * 6 - 15) + 10);
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    71
end;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    72
10182
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
    73
procedure inoise_setup();
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
    74
var i, ii, t: LongInt;
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
    75
begin
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
    76
    for i:= 0 to 254 do
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
    77
        p[i]:= i + 1;
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
    78
    p[255]:= 0;
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    79
10182
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
    80
    for i:= 0 to 254 do
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
    81
    begin
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
    82
        ii:= GetRandom(256 - i) + i;
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
    83
        t:= p[i];
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
    84
        p[i]:= p[ii];
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
    85
        p[ii]:= t
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
    86
    end;
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
    87
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    88
    for i:= 0 to 255 do
10182
9d34898b22f7 Add randomness
unc0rr
parents: 10181
diff changeset
    89
        p[256 + i]:= p[i];
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    90
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    91
    for i:= 0 to 255 do
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    92
        fadear[i]:= trunc($1000 * f(i / 256));
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    93
end;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    94
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    95
const detail = 120000*3;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    96
    field = 3;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    97
    width = 4096;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
    98
    height = 2048;
10187
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
    99
    bottomPlateHeight = 90;
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   100
    bottomPlateMargin = 1200;
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   101
    plateFactor = 1;
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   102
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   103
procedure GenPerlin;
10187
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   104
var y, x, dy, di, dj, r: LongInt;
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   105
begin
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   106
    inoise_setup();
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   107
10186
3fa109a1ae95 Some optimizations
unc0rr
parents: 10185
diff changeset
   108
    for y:= 1024 to pred(height) do
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   109
    begin
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   110
        di:= detail * field * y div height;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   111
        for x:= 0 to pred(width) do
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   112
        begin
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   113
            dj:= detail * field * x div width;
10186
3fa109a1ae95 Some optimizations
unc0rr
parents: 10185
diff changeset
   114
            r:= (abs(inoise(di, dj))) shr 8 and $ff;
10187
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   115
            //r:= r - max(0, abs(x - width div 2) - width * 55 div 128); // fade on edges
10183
189afaf2d076 Some tweaks to perlin generator
unc0rr
parents: 10182
diff changeset
   116
            //r:= r - max(0, - abs(x - width div 2) + width * 2 div 100); // split vertically in the middle
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   117
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   118
10183
189afaf2d076 Some tweaks to perlin generator
unc0rr
parents: 10182
diff changeset
   119
            //r:= r + (trunc(1000 - sqrt(sqr(x - (width div 2)) * 4 + sqr(y - height * 5 div 4) * 22))) div 600 * 20; // ellipse
10187
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   120
            r:= r + (trunc(2000 - (abs(x - (width div 2)) * 2 + abs(y - height * 5 div 4) * 4))) div 26; // manhattan length ellipse
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   121
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   122
            if (y > height - bottomPlateHeight) and (x > bottomPlateMargin) and (x + bottomPlateMargin < width) then
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   123
            begin
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   124
                dy:= (y - height + bottomPlateHeight) * plateFactor;
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   125
                r:= r + dy;
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   126
10187
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   127
                if x < bottomPlateMargin + bottomPlateHeight then
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   128
                    r:= r + (x - bottomPlateMargin - bottomPlateHeight) * plateFactor
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   129
                else
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   130
                if x + bottomPlateMargin + bottomPlateHeight > width then
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   131
                    r:= r - (x - width + bottomPlateMargin + bottomPlateHeight) * plateFactor;
0d506346c1f0 Experiment: enforce a plate at bottom so the map generated is more connected
unc0rr
parents: 10186
diff changeset
   132
            end;
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   133
            if r < 0 then Land[y, x]:= 0 else Land[y, x]:= lfBasic;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   134
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   135
        end;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   136
    end;
10184
f87776bd5acd Setup leftX, rightX and topY
unc0rr
parents: 10183
diff changeset
   137
f87776bd5acd Setup leftX, rightX and topY
unc0rr
parents: 10183
diff changeset
   138
    leftX:= 0;
f87776bd5acd Setup leftX, rightX and topY
unc0rr
parents: 10183
diff changeset
   139
    rightX:= 4095;
f87776bd5acd Setup leftX, rightX and topY
unc0rr
parents: 10183
diff changeset
   140
    topY:= 0;
f87776bd5acd Setup leftX, rightX and topY
unc0rr
parents: 10183
diff changeset
   141
    hasBorder:= false;
10181
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   142
end;
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   143
4708343d5963 Perlin noise generator untweaked, temporarily replacing maze generator
unc0rr
parents:
diff changeset
   144
end.