December 04, 2020, 11:54:39 AM

Author Topic: [bmx] Difference Clouds heightmap by JoshK [ 1+ years ago ]  (Read 712 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
Title : Difference Clouds heightmap
Author : JoshK
Posted : 1+ years ago

Description : This is an implementation of the diamond-square fractal algorithm used to make difference clouds.  A heightfield class was used for greater resolution.  If BlitzMax had a PF_I16 format  pixel map could be used.

Code :
Code: BlitzMax
  1. Strict
  2.  
  3. Type THeightField
  4.        
  5.         Field size
  6.         Field height:Short[,]
  7.        
  8.         Function Create:THeightField(size)
  9.                 Local h:THeightfield=New THeightField
  10.                 Local height:Short[size,size]
  11.                 h.height=height
  12.                 h.size=size
  13.                 Return h
  14.         EndFunction
  15.        
  16.         Method Copy:THeightField()
  17.                 Local h:THeightfield=New THeightField
  18.                 Local height:Short[size,size]
  19.                 Local x,y
  20.                 h.height=height
  21.                 h.size=size
  22.                 MemCopy h.height,height,size*size*2
  23.                 Return h
  24.         EndMethod
  25.        
  26.         Method Blend(h:THeightfield,b#=0.5)
  27.                 Local x,y
  28.                 For x=0 To size-1
  29.                         For y=0 To size-1
  30.                                 height[x,y]=height[x,y]*b+h.height[x,y]*(1.0-b)
  31.                         Next
  32.                 Next
  33.         EndMethod
  34.        
  35.         Method Noise()
  36.                 Local x,y
  37.                 For x=0 To size-1
  38.                         For y=0 To size-1
  39.                                 height[x,y]=Rand(65536)
  40.                         Next
  41.                 Next
  42.         EndMethod
  43.        
  44.         Method Flatten(h#=0)
  45.                 Local x,y
  46.                 For x=0 To size-1
  47.                         For y=0 To size-1
  48.                                 height[x,y]=h*65536
  49.                         Next
  50.                 Next
  51.         EndMethod
  52.        
  53.         Method DiamondSquareFractal(blend#=0.5,featuresize#=64)
  54.                 Local x,y,res
  55.                 height[0,0]=Rand(0,65536)
  56.                 height[size-1,0]=Rand(0,65536)
  57.                 height[0,size-1]=Rand(0,65536)
  58.                 height[size-1,size-1]=Rand(0,65536)
  59.                 res=size
  60.                 Local iteration
  61.                 Local passes=1
  62.                 Local gridsize=size
  63.                 Repeat
  64.                         iteration:+1
  65.                        
  66.                         'Diamond
  67.                         For x=0 To passes-1
  68.                                 For y=0 To passes-1
  69.                                         DiamondFractal(x*(gridsize-1),y*(gridsize-1),res,blend,featuresize)
  70.                                 Next
  71.                         Next
  72.                        
  73.                         'Square
  74.                         For x=0 To passes-1
  75.                                 For y=0 To passes-1
  76.                                         SquareFractal(x*(gridsize-1)+(res-1)/2,y*(gridsize-1),res,blend,featuresize)
  77.                                         SquareFractal(x*(gridsize-1),y*(gridsize-1)+(res-1)/2,res,blend,featuresize)
  78.                                         SquareFractal(x*(gridsize-1)+(res-1),y*(gridsize-1)+(res-1)/2,res,blend,featuresize)
  79.                                         SquareFractal(x*(gridsize-1)+(res-1)/2,y*(gridsize-1)+(res-1),res,blend,featuresize)
  80.                                 Next
  81.                         Next
  82.                        
  83.                         res=(res+1)/2
  84.                         passes:*2
  85.                         If res=2 Exit
  86.                         gridsize=(gridsize+1)/2
  87.                 Forever
  88.         EndMethod
  89.  
  90.         Method DiamondFractal(x0,y0,d,blend#,featuresize#)
  91.                 Local hd,x1,y1
  92.                 x1=x0+d-1
  93.                 y1=y0+d-1
  94.                 hd=(d+1)/2
  95.                 Local i,avg#
  96.                 'Print x0+", "+y0+", "+x1+", "+y1
  97.                 Local distblend#=Min(Float(d)/featuresize,1.0)
  98.                 blend:*distblend
  99.                
  100.                 height[x0+hd-1,y0+hd-1] = ( height[x0,y0] + height[x0,y1] + height[x1,y0] + height[x1,y1] ) / 4
  101.         EndMethod
  102.        
  103.         Method SquareFractal(x0,y0,d,blend#,featuresize#)
  104.                 Local hd,x1,y1
  105.                 x1=x0+d-1
  106.                 y1=y0+d-1
  107.                 hd=(d-1)/2
  108.                 'Print x0+", "+y0+", "+x1+", "+y1
  109.                 Local i=0
  110.                 Local avg#=0.0
  111.                
  112.                 If x0-hd=>0
  113.                         i:+height[x0-hd,y0]
  114.                         avg:+1
  115.                 EndIf
  116.  
  117.                 If x0+hd<=size-1
  118.                         i:+height[x0+hd,y0]
  119.                         avg:+1
  120.                 EndIf
  121.  
  122.                 If y0-hd=>0
  123.                         i:+height[x0,y0-hd]
  124.                         avg:+1
  125.                 EndIf
  126.  
  127.                 If y0+hd<=size-1
  128.                         i:+height[x0,y0+hd]
  129.                         avg:+1
  130.                 EndIf
  131.                
  132.                 Local distblend#=Min(Float(d)/featuresize,1.0)
  133.                 blend:*distblend
  134.                 height[x0,y0]=i/avg * (1.0 - blend) + Rand(65535) * blend
  135.         EndMethod
  136.        
  137.         Method Multiply(m#)
  138.                 Local x,y
  139.                 For x=0 To size-1
  140.                         For y=0 To size-1
  141.                                 height[x,y]:*m
  142.                         Next
  143.                 Next
  144.         EndMethod
  145.        
  146.         Method ToPixmap:TPixmap()
  147.                 Local x,y,r
  148.                 Local p:TPixmap=CreatePixmap(size,size,PF_I8)
  149.                 For x=0 To size-1
  150.                         For y=0 To size-1
  151.                                 r=height[x,y]/65536.0*255.0
  152.                                 p.WritePixel x,y,r+(r Shl 8)+(r Shl 16)
  153.                         Next
  154.                 Next
  155.                 Return p
  156.         EndMethod
  157.        
  158.         Method FromPixmap(pixmap:TPixmap)
  159.                 Local x,y,px,py
  160.                 For x=0 To size-1
  161.                         For y=0 To size-1
  162.                                 px=Min(x,pixmap.width-1)
  163.                                 py=Min(y,pixmap.height-1)                      
  164.                                 height[x,y]=((pixmap.ReadPixel(px,py) & $00FF0000) Shr 16)/255.0*65536
  165.                         Next
  166.                 Next
  167.         EndMethod
  168.        
  169. EndType
  170.  
  171. Local h:THeightfield
  172. h=THeightfield.Create(1025)
  173. SeedRnd MilliSecs()
  174. h.DiamondSquareFractal(1.0,256)
  175.  
  176. SavePixmapPNG h.topixmap(),"test.png"
  177. OpenURL "test.png"


Comments :


jankupila(Posted 1+ years ago)

 Work's fine, thanks


degac(Posted 1+ years ago)

 Fine, but I don't like the 'final' size of the images (in your example 1025x1025 pixel for the pixmap),I can't understand why I got an 'error' in the following method
Code: [Select]
Method ToPixmap:TPixmap()
Local x , y , r
Print "Size: "+size
Local p:TPixmap=CreatePixmap(size-1,size-1,PF_I8)' I want to create a 512x512 pixel image NOT 513x513!!!
For x=0 To size-1
For y=0 To size-1
r=height[x,y]/65536.0*255.0
p.WritePixel x,y,r+(r Shl 8)+(r Shl 16)
Next
Next
Return p
EndMethod
Well, this is not a proper error: if I change the pixel format in PF_RGB888 I obtain a pixmap of Size-1 x Size-1 pixels.Maybe it's a problem with my gfx drivers...


JoshK(Posted 1+ years ago)

 If BRL adds PF_I16 I will fix it for you. [/i]

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal