Global Permutation:Int[513], GRAYD:Float[512], hmap:Float[2048, 1024], nmap:Float[2048, 1024]

Function InitNoise(range:Float=0.7,seed:Int=1)
	
	Local i:Int,perm:Int
	
	RestoreData permutation
	
	For i=0 To 256-1
		
		ReadData perm
		
		Permutation[i]=perm
		Permutation[256+i]=perm
		
		GRAYD[i]=Noise(Permutation[i],i,seed)'Rnd(-range,range)
		GRAYD[256+i]=Noise(Permutation[i],i,seed)'Rnd(-range,range)
		
	Next
	
End Function

Function Perlin3D:Float(x:Float,y:Float,z:Float,size:Float=64,seed:Int=0,MinOctaves:Int=0,MaxOctaves:Int=9999,range:Float=1.0) 
	
	Local value:Float,initialSize:Float,i:Int,r:Float
	
	If seed=0 Then seed=MilliSecs()
	
	x=x+seed
	y=y+seed
	z=z+seed
	
	value=0.0
	initialSize=size
	
	For i = 1 To MinOctaves
		size=size/2
	Next
	
	While(size>=1.0) And MaxOctaves>MinOctaves
		
		value=value+SmoothNoise(x/size,y/size,z/size,seed)*size
		size=size/2.0
		MaxOctaves=MaxOctaves-1
		
	Wend

	r=(value/Float(initialSize))

	If r<-range Then r=-range
	If r>range Then r=range
	
	Return r
	
End Function

Function SmoothNoise:Float(x:Float,y:Float,z:Float,seed:Int=0)
	
	Local x1:Float,y1:Float,z1:Float,u:Float,v:Float,w:Float,a:Float,aa:Float,ab:Float,b:Float,ba:Float,bb:Float
	Local g1:Float,g2:Float,g3:Float,g4:Float,g5:Float,g6:Float,g7:Float,g8:Float
	Local l1:Float,l2:Float,l3:Float,l4:Float,l5:Float,l6:Float,l7:Float
	
	x=x+seed
	y=y+seed
	z=z+seed
	
	x1=(Int(Floor(x)) & 255)
	y1=(Int(Floor(y)) & 255)
	z1=(Int(Floor(z)) & 255)
	
	x=x-Floor(x)
	y=y-Floor(y)
	z=z-Floor(z)
	
	u=Fade(x)
	v=Fade(y)
	w=Fade(z)
	
	a=Permutation[x1]+y1
	aa=Permutation[a]+z1
	ab=Permutation[a+1]+z1
	
	b=Permutation[x1+1]+y1
	ba=Permutation[b]+z1
	bb=Permutation[b+1]+z1
	
	g1=GRAYD[bb+1]
	g2=GRAYD[ab+1]
	g3=GRAYD[ba+1]
	g4=GRAYD[aa+1]
	g5=GRAYD[bb]
	g6=GRAYD[ab]
	g7=GRAYD[ba]
	g8=GRAYD[aa]
	
	l1=Lerp(u,g2,g1)
	l2=Lerp(u,g4,g3)
	l3=Lerp(v,l2,l1)
	l4=Lerp(u,g6,g5)
	l5=Lerp(u,g8,g7)
	l6=Lerp(v,l5,l4)
	l7=Lerp(w,l6,l3)
	
	Return l7
	
End Function

Function Fade:Float(t:Float)
	
	Return t*t*t*(t*(t*6-15)+10)
	
End Function

Function Lerp:Float(t:Float,a:Float,b:Float)
	
	Return a+t*(b-a)
	
End Function

Function FastNoise:TBank(size:Int,scale:Float,multiplier:Float,xoff:Int=0,yoff:Int=0,seed:Int=1,wrapx:Int=True,wrapy:Int=False,bilinear:Int=True)
	
	Local Max_Height:Float,NoiseMapSize:Int,ScaleDifference:Float,StepSize:Float
	Local N1:Float,N2:Float,N3:Float,N4:Float,HX:Float,HY:Float,IX:Float,IY:Float,ICX:Float,ICY:Float,NA:Float,NB:Float,NC:Float,ND:Float
	Local i:Int,x:Int,y:Int,xx:Int,yy:Int
	Local v:Float,maxh:Float=2^16,minh:Float
	
	Local hm:TBank=CreateBank(size*(size/2))
	
	Max_Height=scale*multiplier*16
	
	For y=0 To (size/2)-1 Step 1
		
		For x=0 To size-1 Step 1
			
			hmap[x,y]=Noise((x+xoff),(y+yoff),seed) ' or use Rnd(1)
			
		Next
		
	Next
	
	NoiseMapSize=size/2
	Max_Height=Max_Height*multiplier
	
	Repeat
		
		For y=0 To (NoiseMapSize/2)-1
			
			For x=0 To NoiseMapSize-1
				
				nmap[x,y]=Noise(x,y,seed)*Max_Height
				
			Next
			
		Next
		
		If wrapy=True Then
			
			For i=0 To NoiseMapSize-1
				
				nmap[i,0]=nmap[i,NoiseMapSize/2]
				
			Next
			
		EndIf
		
		If wrapx=True Then
		
			For i=0 To NoiseMapSize-1
			
				nmap[0,i]=nmap[NoiseMapSize,i]
			
			Next
	
		EndIf
		
		ScaleDifference=size*1.0/NoiseMapSize
		StepSize=1.0/Float(ScaleDifference)
		
		For y=0 To (NoiseMapSize/2)-1
			
			For x=0 To NoiseMapSize-1
				
				N1=nmap[x,  y  ]
				N2=nmap[x+1,y  ]
				N3=nmap[x,  y+1]
				N4=nmap[x+1,y+1]
				
				HX=x*ScaleDifference
				HY=y*ScaleDifference
				
				IY=0
				
				For yy=0 To ScaleDifference-1
					
					ICY=1.0-((Cos(IY*180.0)+1.0)/2.0)
					
					IX=0	
					
					For xx=0 To ScaleDifference-1
					
						If bilinear Then
						
							ICX=1.0-((Cos(IX*180.0)+1.0)/2.0)
							NA=N1*(1.0-ICX)
							NB=N2*ICX
							NC=N3*(1.0-ICX)
							ND=N4*ICX
							
						Else
						
							NA = N1*(1.0-Ix)
							NB = N2*Ix
							NC = N3*(1.0-Ix)
							ND = N4*Ix
							
						EndIf
						
						v=hmap[HX+xx,HY+yy]+(NA+NB)*(1.0-ICY)+(NC+ND)*ICY
						
						If v>maxh Then maxh=v
						If v<minh Then minh=v
						
						hmap[HX+xx,HY+yy]=v
						
						IX=IX+StepSize
						
					Next
									
					IY=IY+StepSize	
					
				Next
							
			Next
			
		Next
		
		NoiseMapSize=NoiseMapSize/2
		
		Max_Height=Max_Height*multiplier
		
	Until NoiseMapSize<=2
	
	For x=0 To size-1
		
		For y=0 To (size/2)-1
			
			SetBankPixel(hm,Normalize(hmap[x,y],minh,maxh,0,255),x,y,size)
						
		Next
		
	Next
	
	Return hm
	
End Function

Function Noise:Float(x:Int,y:Int,seed:Int)
	
	Local n:Int=x+y*57+seed
	
	n=n Shl Int(Floor((13^n)))
	
	Return (1.0-((n*(n*n*15731+789221)+1376312589) & $7fffffff)/1073741824.0)
	
End Function

#permutation
DefData 151,160,137,91,90,15
DefData 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23
DefData 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33
DefData 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166
DefData 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244
DefData 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196
DefData 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123
DefData 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42
DefData 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9
DefData 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228
DefData 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107
DefData 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254
DefData 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180