unit _Noise;

interface

const
 Max_Sources = 3;
 M_S_E = 255;//Max Source Elements
 Max_Noise = 3;
 a=317;
 c=8023;             
 pi=3.14159265358979;

function Get_PN(fx,fy,fz:single;Scale:Single):byte;
procedure Create_Noise();

Var
  Source:array [0..M_S_E,0..M_S_E,0..Max_Sources] of byte;
  Grain:integer = 12345;

implementation

{$Region 'Create_noise'}
procedure Create_Noise();
var
  i,j,z,n,temp,rand:byte;
  gen:integer;
begin
 {creation}
 for j:=0 to M_S_E do
 for i:=0 to M_S_E do
  for z:=0 to Max_Sources do
   Source[i,j,z]:=i+j;
 {peremeshivaniye}
 gen:=Grain mod 256;
 for n:=0 to 15 do
  for z:=0 to Max_Sources do
  for j:=0 to M_S_E do
   for i:=0 to M_S_E do
    begin
      gen:=(a*gen+c) mod 54789;
      rand:=gen mod M_S_E;
      temp:=Source[i,rand,z];
      Source[i,rand,z]:=Source[i,j,z];
      Source[i,j,z]:=temp;
    end;
end;
{$EndRegion}

function Noise(X,Y,Z:integer):byte;
var a:byte;
begin
 a:=Source[0,z mod 256,0];
 Noise:=Source[(x+a) mod 256,(y+a) mod 256,0];
end;

{
function Get_PN(fx,fy,fz:single;Scale:Single):byte;
Var
a,b,c,d,n,m,
x,y,z:integer;kx,ky,kz:Single;
begin
 Scale:=Scale/256;
 fx:=(fx/Scale)+256*256;
 fy:=(fy/Scale)+256*256;
 fz:=(fz/Scale)+256*256;
 x:=trunc(fx);
 y:=trunc(fy);
 z:=trunc(fz);
 kx:=fx-x;
 ky:=fy-y;
 kz:=fz-z;
 //1-st plane
 a:=Noise(X  ,Y  ,Z);
 b:=Noise(X+1,Y  ,Z);
 c:=Noise(X  ,Y+1,Z);
 d:=Noise(X+1,Y+1,Z);
 a:=trunc(kx*b+(1-kx)*a);
 b:=trunc(kx*d+(1-kx)*c);
 n:=trunc(ky*b+(1-ky)*a);
 //2-nd plane
 a:=Noise(X  ,Y  ,Z+1);
 b:=Noise(X+1,Y  ,Z+1);
 c:=Noise(X  ,Y+1,Z+1);
 d:=Noise(X+1,Y+1,Z+1);
 a:=trunc(kx*b+(1-kx)*a);
 b:=trunc(kx*d+(1-kx)*c);
 m:=round(ky*b+(1-ky)*a);
 Get_PN:=round((m*kz+(1-kz)*n));
// Get_PN:=a;
end;    }
function Get_PN(fx,fy,fz:single;Scale:Single):byte;
Var
a,b,c,d,n,m,
x,y,z:integer;kx,ky,kz:Single;
begin
 Scale:=Scale/256;
 fx:=(fx/Scale)+256*256;
 fy:=(fy/Scale)+256*256;
 fz:=(fz/Scale)+256*256;
 x:=trunc(fx);
 y:=trunc(fy);
 z:=trunc(fz); 
{ kx:=fx-x;
 ky:=fy-y;
 kz:=fz-z;           }
 kx:=1-(cos((fx-x)*pi)/2+0.5);
 ky:=1-(cos((fy-y)*pi)/2+0.5);
 kz:=1-(cos((fz-z)*pi)/2+0.5);      
 //1-st plane
 a:=Noise(X  ,Y  ,Z);
 b:=Noise(X+1,Y  ,Z);
 c:=Noise(X  ,Y+1,Z);
 d:=Noise(X+1,Y+1,Z);
 a:=trunc(kx*b+(1-kx)*a);
 b:=trunc(kx*d+(1-kx)*c);
 n:=trunc(ky*b+(1-ky)*a);
 //2-nd plane
 a:=Noise(X  ,Y  ,Z+1);
 b:=Noise(X+1,Y  ,Z+1);
 c:=Noise(X  ,Y+1,Z+1);
 d:=Noise(X+1,Y+1,Z+1);
 a:=trunc(kx*b+(1-kx)*a);
 b:=trunc(kx*d+(1-kx)*c);
 m:=round(ky*b+(1-ky)*a);
 Get_PN:=round((m*kz+(1-kz)*n));
// Get_PN:=a;
end;

end.
