All pastes #795934 Raw Edit

Anonymous

public text v1 · immutable
#795934 ·published 2007-11-24 16:32 UTC
rendered paste body
SuperStrict

Global scx:Int = 640
Global scy:Int = 480


Global diameter:Int = scy

Graphics scx, scy
Cls

SetBlend ALPHABLEND
SetAlpha 1.0
SetColor 255, 255, 255
SetClsColor 0, 0, 40

Global sizefactor:Int = 1
SetScale sizefactor, sizefactor
Global planetsize:Int = 480 / sizefactor
Global frames:Int = 60
Global planetid:Int = 8
Global loopimage:TImage = CreateImage(planetsize, planetsize, frames + 1, DYNAMICIMAGE | FILTEREDIMAGE) 
'tplanet.create options:
'in order:


'Frame, Planet ID, Size, cloud coverage, land mass,day>night transition flag, "flare" flag,"Star" flag,cloud colour, land colour,water colour.

'Note that cloud coverage/land mass isnt spot on, you'll need to adjust it to get what you want.
'Higher cloud coverage and land mass increases generation time.

Local x:Float, Frame:Int
Repeat
	Local planet:tplanet = tplanet.Create(x + 1, planetid, planetsize, 0.8, 0.6, 0, 0, 0, $ffffff, $10ff10, $4040ff)     'normal planet
	'Local planet:tplanet = tplanet.Create(x + 1, planetid, planetsize, 1.0, 0.1, 0, 1, 1, $ff0000, $ff0000, $400000)          'red giant
	'Local planet:tplanet = tplanet.Create(x + 1, planetid, planetsize, 1.2, 0.1, 0, 1, 1, $FFFF33, $ff0000, $400000)             'sun
	DrawImage planet.image, 0, 0
	loopimage.SetPixmap(Frame, planet.worldpixmap) 
		SavePixmapPNG(planet.worldpixmap, "output\planet" + String(planetid) + "f" + String(Frame + 1) + ".png", 9) 
	Flip
	Cls
	x = x + Float(planetsize) / Float(frames) 
	Frame = Frame + 1
Until Frame > frames
Repeat
	For Local x:Int = 1 To frames
		DrawImage(loopimage, 0, 0, x) 
		Flip
		Cls
		Delay 1000 / 30
		If KeyHit(KEY_ESCAPE) Then End
	Next
Until KeyDown(KEY_ESCAPE) 




Type tplanet
	Field worldpixmap:TPixmap
	Field image:TImage
	Global heightmap:TBank
	Global cloudmap:TBank
	Global dimensions:Int
	
	Field cloudcolourr:Int
	Field cloudcolourg:Int
	Field cloudcolourb:Int

	Field landcolourr:Int
	Field landcolourg:Int
	Field landcolourb:Int
	
	Field watercolourr:Int
	Field watercolourg:Int
	Field watercolourb:Int
	
	Function Create:Tplanet(rot:Int, seed:Int = 10, diameter:Int, clouddensity:Float = 0.5, landmass:Float = 0.5, DAYNIGHT:Byte = 0, flares:Byte = 0, star:Byte = 0, CLOUDCOLOURRGB:Int = $909090, landcolourRGB:Int = $00FF00, WatercolourRGB:Int = $4040FF) 
	rot = (rot + diameter * 20) mod diameter
		Local planet:tplanet = New tplanet
		
		planet.cloudcolourr = (cloudcolourRGB & $FF0000) Shr 16
		planet.cloudcolourg = (cloudcolourrGB & $FF00) Shr 8
		planet.cloudcolourb = cloudcolourrGB mod 256

		planet.landcolourr = (landcolourRGB & $FF0000) Shr 16
		planet.landcolourg = (landcolourrGB & $FF00) Shr 8
		planet.landcolourb = landcolourrGB mod 256
		planet.watercolourr = (watercolourRGB & $FF0000) Shr 16
		planet.watercolourg = (watercolourrGB & $FF00) Shr 8
		planet.watercolourb = watercolourrGB mod 256
		
		
		planet._Init(rot, seed, diameter, clouddensity, landmass, daynight, flares, star) 
		Return planet
	End Function
	
	Method _init(rot:Int, seed:Int, diameter:Int, clouddensity:Float, landmass:Float, daynight:Byte, flares:Byte,star:byte) 

	Local edge:Float = diameter / 2.5
	Local faredge:Float = diameter / 2.4
	Local nearedge:Float = diameter / 2.6
	Local ms1:Int = MilliSecs() 
	
	'Do wierd pixmap creation as my machine wont allow normal usage ?! 
	Self.worldpixmap = GrabPixmap(0, 0, diameter + 1, diameter + 1) 
	Self.image = LoadImage(worldpixmap) 
	
		
	

	If heightmap = Null Then heightmap = TBank.Create(1) 
	If cloudmap= Null Then cloudmap = TBank.Create(1) 
	
		heightmap.Resize((((diameter + 1) ^ 2) * 4) + 1) 
		cloudmap.Resize((((diameter + 1) ^ 2) * 4) + 1) 

	tplanet.dimensions = diameter
	 	
	

		
	Print "Time till start: " + (MilliSecs() - ms1) 
	SeedRnd(seed) 

	Local colourmapr:Float[diameter + 1, diameter + 1] 
	Local colourmapg:Float[diameter + 1, diameter + 1] 
	Local colourmapb:Float[diameter + 1, diameter + 1] 
	Local x:Int, y:Int
	Local centx:Int = diameter / 2
	Local centy:Int = diameter / 2

	Local dx:Float, dy:Float, val:Int, distance:Float, x1:Int, y1:Int, x2:Int, y2:Int, rx:Int
	Local c:Int, d:Int, cloudavg:Float
	Global maxsize:Int = diameter / 10
	Global maxrocks:Int = landmass * 20
	
	ms1:Int = MilliSecs() 
	For x = 0 To diameter Step 1
		For y = 0 To diameter
			setheightmap(x, y, 0) 
			setcloudmap(x, y, 0) 
		Next
	Next
	Print "Map clear :" + (MilliSecs() - ms1) 
	

'generate other map
Local points:Int = maxrocks
ms1 = MilliSecs() 
Local pointx:Int[points + 1] 
Local pointy:Int[points + 1] 
local pointheight:Float[points + 1] 
Local rad:Int[points + 1] 

For x = 0 To points
	pointx[x] = ((Rand(0, diameter) - rot * 2) + diameter * 10) mod diameter
	pointy[x] = Rand(0, diameter) 
	pointheight[x] = Rand(64, 255) 
	rad[x] = Rand(diameter / 10, maxsize) * 2
	'pointx[x] = pointx[x] - (rot * Abs(pointy[x] - centy) / 100) 
Next

For x2 = 0 To diameter

	For y = 0 To diameter
		x = x2

		val = 64
		For Local z:Int = 0 To points
			dx = Abs(pointx[z] - x) 
			If dx > diameter / 2 Then dx = Abs(dx - diameter) 
			dy = Abs(pointy[z] - y) 
			If dy > diameter / 2 Then dy = Abs(dy - diameter) 
			Distance = (rad[z] - Sqr(dx * dx + dy * dy)) 
			If distance < 1 Then distance = 1 Else val = val + (Float(distance) / Float(rad[z] )) * pointheight[z] 
	
		Next
		setheightmap(x, y, val) 

	Next
Next
Print "Generated ground: " + (MilliSecs() - ms1) 

'now generate clouds
ms1 = MilliSecs() 
points:Int = 6 * clouddensity

pointx = pointx:Int[..points + 1] 
pointy = pointy:Int[..points + 1] 
pointheight = pointheight:Float[..points + 1] 
rad = rad:Int[..points + 1] 
Local cloudxsc:Float[points + 1] 
Local cloudysc:Float[points + 1] 

For x = 0 To points
		Local spd:Int = Rnd(1, 2) 
		Local xmov:Int, ymov:Int
		
		xmov = Sgn(Rnd(- 100, 0)) * Rand(2, 1) 
		ymov = Sgn(Rnd(- 100, 100))*0 
		
	pointx[x] = ((Rand(0, diameter) + (xmov * spd * rot)) + diameter) mod diameter
	pointy[x] = ((Rand(0, diameter) + (ymov * spd * rot)) + diameter) mod diameter

	cloudxsc[x] = Rnd(.1, 1) 
	cloudysc[x] = Rnd(.1, 1) 
	
	pointheight[x] = Rand(- 190, 512) 
	rad[x] = ((diameter / 30) * clouddensity) * (x + 1) 

Next

For x2 = 0 To diameter
	For y = 0 To diameter
		x = x2
		val = 64
		For Local z:Int = 0 To points
			Local snx:Int = Sgn(Rnd(- 100, 100)) 
			Local sny:Int = Sgn(Rnd(- 100, 100)) 
			Local xsc:Float = 1
			Local ysc:Float = 1
			Local px:Int = pointx[z] 
			Local py:Int = pointy[z] 
			If (px - x) < - diameter / 2 Then px = px + diameter
			If (px - x) > diameter / 2 Then px = px - diameter
			If (py - y) < - diameter / 2 Then py = py + diameter
			If (py - y) > diameter / 2 Then py = py - diameter
			dx = Abs(px - x) / xsc * cloudxsc[z] 
			dy = Abs(py - y) / ysc * cloudysc[z] 
			dx = dx + Rand(- diameter, diameter) / 40
			dy = dy + Rand(- diameter, diameter) / 40
			If Sgn(px - x) = snx Then dx = dx + 2
			If Sgn(px - y) = sny Then dy = dy + 2
			Local Distance:Float = rad[z] - Sqr(dx * dx + dy * dy) 
			If distance < 0 Then distance = 0
			If distance < 1 Then distance = 1 Else val = val + (Float(distance) / Float(rad[z] )) * pointheight[z] 
		Next
		setcloudmap(x, y, val) 

	Next
Next

Print "INitial cloud generation: " + (MilliSecs() - ms1) 

	
	'smooth now
	ms1:Int = MilliSecs() 
	Local smoothtype:Int = Rand(1, 2) 
	Local smooth:Int, avg:Float

	For Local smooth:Int = 1 To 5
		Local sm1:Int = Rand(0, 2) 
		Local sm2:Int = Rand(0, 2) 
		For x:Int = (centx - (faredge + 5)) To centx + (faredge + 5) Step 1
			For y:Int = (centy - (faredge + 5)) To (centy + (faredge + 5)) Step 1
				If getheightmapfast(x, y) <> 0 Then
				Local count:Float = 0
				avg = 0
				For c = -1 To 1
					For d = -1 To 1
						avg = avg + getheightmap(x + c, y + d) 
					Next
				Next
					setheightmap(x, y, avg / 9) 
					If getheightmap(x, y) > 512 Then setheightmap(x, y, 512) 
				EndIf
			Next
		Next
	Next

	Print "Blur ground: " + (MilliSecs() - ms1) 
	
	ms1 = MilliSecs() 
	'smooth clouds:
	
	
	For Local smooth:Int = 1 To 3
		For x:Int = (centx - faredge - 15) To centx + faredge Step 1
			For y:Int = centy - faredge To centy + faredge Step 1
				cloudavg:Float = 0
				For c:Int = -2 To - 0
					For d:Int = -1 To 1 Step 1

						cloudavg = cloudavg + getcloudmap(x + c, y + d) 
					Next
				Next
				dx:Float = centx - x
				dy:Float = centy - y
				distance = Sqr(dx * dx + dy * dy) 

				setcloudmap(x, y, cloudavg / 9) 

			Next
		Next
	Next

	'remove extra clouds
	
	For x = 0 To diameter
	For y = 0 To diameter
		dx:Float = centx - x
		dy:Float = centy - y
		Local distance:Float = Sqr(dx * dx + dy * dy) 
		Local v2:Float = (faredge * 1.5) - distance'('distance + (diameter / 18)) - (edge) 
		Local v3:Float = (v2 / (faredge)) * 2
		If v3 < 0 Then v3 = 0
		If v3 > 1 Then v3 = 1
		setcloudmap(x,y,getcloudmapfast(x,y)*v3)
	Next
	Next
	
	'Print "Blur clouds: " + (MilliSecs() - ms1) 

	'shadows:
	ms1 = MilliSecs() 
	For x = 0 To diameter
		For y = 0 To diameter
			Local diff:Float = getheightmap(x, y) - getheightmap(x + 1, y) 
			Local mul:Float
			colourmapg[x, y] = landcolourg
			colourmapr[x, y] = landcolourr
			colourmapb[x, y] = landcolourb
			
			If getheightmap(x, y) < 128 Then
				colourmapb[x, y] = watercolourb * 2;colourmapg[x, y] = watercolourg * 2;colourmapr[x, y] = watercolourr * 2

			Else
				If getheightmap(x, y) <= getheightmap(x + 1, y) Then
				Else
					mul:Float = 1.15
					If Abs(getheightmap(x, y) - getheightmap(x + 1, y)) < 10 Then mul = Rnd(1, 1.1) 
				EndIf
				mul = mul * Float((x - (centx / 2)) / 100.0) ;If mul < 1 Then mul = 1
					If Abs(getheightmap(x, y) - getheightmap(x + 1, y)) < 10 Then mul = mul * Rnd(1, 1.1) 
				
				
				setheightmap(x, y, getheightmap(x, y) * mul) 
				setheightmap(x, y, getheightmap(x, y) + diff * 10)  ' 250) 
				If getheightmap(x, y) < 0 Then setheightmap(x, y, 0) 
			EndIf
		Next
	Next
	'Print "Processing shadows: " + (MilliSecs() - ms1) 



	ms1 = MilliSecs() 
	'atmosphere and smoothing
	Local ox:Int, oy:Int
	For Local ang:Int = 0 To 360
		x = (Sin(ang) * (edge)) + centx
		y = (Cos(ang) * (edge)) + centy

		Local sz:Int = diameter / 240
		Local val:Int = 255
		For x2:Int = x - sz To x + sz / 2
			For y2:Int = y - sz To y + sz
				Local newval:Int = getcloudmap(x2, y2) + val
				If newval > 512 Then newval = 512
				setcloudmap(x2, y2, 128) 
			
			Next
		Next
	
	Next
	
	
	For Local ang:Int = 0 To 360
		x = (Sin(ang) * (faredge)) + centx
		y = (Cos(ang) * (faredge)) + centy
		If x <> ox Or y <> oy Then
		ox = x;oy = y
		Local sz:Int = Float(diameter / 20) 
		Local val:Int = 255
		For Local x2:Int = x - sz To x + sz
			For Local y2:Int = y - sz To y + sz

				Local cloudavg:Float = 0
				Local cloudcnt:Float = 0
				For Local c:Int = -1 To 1
					For Local d:Int = -1 To 1

						If c <> 0 Or d <> 0 Then
							'If (x2 + c) > 0 And (x2 + c) < diameter And (y2 + d) > 0 And (y2 + d) < diameter Then
							cloudavg = cloudavg + getcloudmap(x2 + c, y2 + d) 
							cloudcnt = cloudcnt + 1
							'endif
						EndIf
					Next
				Next
				setcloudmap(x2, y2, cloudavg / (cloudcnt - 0)) 
			Next
		Next
		EndIf
	Next
	Print "Atmosphere: " + (MilliSecs() - ms1) 

	worldpixmap = LockImage(image) 
	

ms1 = MilliSecs() 
	For x = 0 To diameter
		For y = 0 To diameter
			Local dx:Float = centx - x
			Local dy:Float = centy - y
			
			Local Distance:Float = Sqr(dx * dx + dy * dy) 
			If distance > edge Then setheightmap(x, y, 127) ;colourmapr[x, y] = 0;colourmapg[x, y] = 0;colourmapb[x, y] = 255
			Local colour:Float = getheightmap(x, y) / 2

			If daynight <> 0 Then colour = colour * ((x - diameter / 2) / Float(diameter)) * 1.3
			if colour<0 then colour=0
			colour = colour / 256
			Local colour1r:Float = colour * colourmapr[x, y] 
			Local colour1g:Float = colour * colourmapg[x, y] 
			Local colour1b:Float = colour * colourmapb[x, y] 
			
			
			
			Local colourmix:Float = (getcloudmap(x, y) - 0) / 255
			'colourmix = (colourmix -.2) * 0.8
			Local colour2r:Float = ((1 - colourmix) * cloudcolourr) + (colourmix * cloudcolourr) / 3
			Local colour2g:Float = ((1 - colourmix) * cloudcolourg) + (colourmix * cloudcolourg) / 3
			Local colour2b:Float = ((1 - colourmix) * cloudcolourb) + (colourmix * cloudcolourb) / 3
			If star = True Then
				colour2r:Float = ((colourmix) * cloudcolourr) + ((1 - colourmix) * cloudcolourr) / 3
				colour2g:Float = ((colourmix) * cloudcolourg) + ((1 - colourmix) * cloudcolourg) / 3
				colour2b:Float = ((colourmix) * cloudcolourb) + ((1 - colourmix) * cloudcolourb) / 3
			EndIf
					
			colourmix = (colourmix -.2) * 4.5
			If colourmix < 0 Then colourmix = 0
			If colourmix > 1 Then colourmix = 1

			Local finalcolourr:Int = (colour1r * (1 - colourmix)) + (colour2r * colourmix) 
			Local finalcolourg:Int = (colour1g * (1 - colourmix)) + (colour2g * colourmix) 
			Local finalcolourb:Int = (colour1b * (1 - colourmix)) + (colour2b * colourmix) 

			
			Local alpha:Int = 255
			alpha = Float(colourmix * 255) 
		

			Local v2:Float = (nearedge - distance) 
			Local v3:Float = v2 / (edge - distance) 
			If distance < faredge Then v3 = 0
			If v3 < 0 Then v3 = 0
			If v3 > 1 Then v3 = 1

			alpha = ((1 - v3))  ' * 255
			If alpha < 0 Then alpha = 0

			If finalcolourr > 255 Then finalcolourr = 255
			If finalcolourg > 255 Then finalcolourg = 255
			If finalcolourb > 255 Then finalcolourb = 255
			If finalcolourr < 0 Then finalcolourr = 0
			If finalcolourg < 0 Then finalcolourg = 0
			If finalcolourb < 0 Then finalcolourb = 0
			alpha = (alpha * 255) + (colourmix * 255) 
			If colourmix > 0 Then
				Local alpha2:Float = ((diameter / 20) - (distance - faredge)) 
				If flares Then alpha2 = alpha2 / 1.3
				If alpha2 < 0 Then alpha2 = 0
				alpha = alpha * (alpha2 / (diameter / 20)) 
				alpha = alpha - colourmix
			EndIf
			Local alpha2:Float = ((Float(distance - edge)) / (edge - faredge)) +.95
			If alpha2 < 0 Then alpha2 = 0 Else If alpha2 > 1 Then alpha2 = 1
			If flares = 0 Then alpha = alpha * alpha2  ' * 255
			If alpha < 0 Then alpha = 0 Else If alpha > 255 Then alpha = 255
			Local pixel:Int = (finalcolourb | finalcolourg Shl 8 | finalcolourr Shl 16 | alpha Shl 24) 
			worldpixmap.WritePixel(x, y, pixel) 
		Next
	Next
	ms1 = MilliSecs() 
	UnlockImage(image) 
	Print "Unlocking image:" + (MilliSecs() - ms1) 
'	SetScale 2, 2
	End Method

	Function blurheightmap() 
		Local x:Int, y:Int, x1:Int, y1:Int, c:Int, d:Int
		Local val:Float
		For x = 0 To dimensions
			For y = 0 To dimensions
				For c = -1 To 1
					For d = -1 To 1
						x1 = x + c;y1 = y + d
						If x1 < 1 Or x1 > dimensions - 1 Or y1 < 1 Or y1 > dimensions - 1 Then
							x1 = (x1 + dimensions) mod dimensions
							y1 = (y1 + dimensions) mod dimensions
						EndIf
						val = val + PeekFloat(heightmap, ((x1 * dimensions) + y1) * 4) 
					Next
				Next
				PokeFloat(heightmap, ((x * dimensions) + y) * 4, val / 9.0) 
			Next
		Next
	End Function
	
	Function getcloudmap:Float(x:Int, y:Int) nodebug

		x = (x + dimensions) mod dimensions
		y = (y + dimensions) mod dimensions
		Local add:Int = ((x * dimensions) + y) * 4
		Return cloudmap.PeekFloat(add) 
	
	End Function

	Function setcloudmap(x:Int, y:Int, val:Float) nodebug

		x = (x + dimensions) mod dimensions
		y = (y + dimensions) mod dimensions
		Local add:Int = ((x * dimensions) + y) * 4
		cloudmap.PokeFloat(add, val) 

	End Function
	
	
	Function getheightmap:Float(x:Int, y:Int) nodebug
		x = (x + dimensions) mod dimensions
		y = (y + dimensions) mod dimensions
		Local add:Int = ((x * dimensions) + y) * 4
		Return heightmap.PeekFloat(add) 
	End Function

	Function getheightmapfast:Float(x:Int, y:Int) 
		Return heightmap.PeekFloat(((x * dimensions) + y) * 4) 
	End Function
	
	Function getcloudmapfast:Float(x:Int, y:Int) 
		Return cloudmap.PeekFloat(((x * dimensions) + y) * 4) 
	End Function
	
	Function setheightmap(x:Int, y:Int, val:Float) nodebug
		x = (x + dimensions) mod dimensions
		y = (y + dimensions) mod dimensions
		Local add:Int = ((x * dimensions) + y) * 4
		heightmap.PokeFloat(add, val) 
	End Function
	
End Type