December 01, 2020, 02:27:37 PM

Author Topic: [bb] Random Tileable Terrain Generator by Delerna [ 1+ years ago ]  (Read 1279 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
Title : Random Tileable Terrain Generator
Author : Delerna
Posted : 1+ years ago

Description : Uses the diamond square methodology to generate random terrain meshes that are completely tileable in all four directions. You can vary the number of vertices in the terrain as well as the ruggedness and the evenness of the transitions in the ruggedness,if that senetence makes sense!!!   Use it/change it   however you like,  I give it to the Blitz community.

Code :
Code: BlitzBasic
  1. ;Changeable Parameters
  2. GridSize%=9; Must be a 2^n+1
  3. Landform#=10;The bigger the number the greater the difference in heights between highspots and lowspots
  4. Smoothness#=6;The bigger the number the more smoothly the transition between highspots and low spots will occur
  5.  
  6.  
  7. ;Setup the 3D environment
  8. Graphics3D 1024,700,16,2
  9. SetBuffer BackBuffer()
  10. Dim vert(GridSize,GridSize)
  11. WireFrame True
  12. AmbientLight(255,255,255)
  13. cam=CreateCamera()
  14. MoveEntity cam, 0, 50, -140 ; Our camera...
  15. CameraRange cam,1,10000
  16.  
  17. ;Create 4 copies of the same terrain and position them to show that they are tileable
  18. RandomTerrain=TileableRandomDiamondSquareTerrain(GridSize,Landform,Smoothness)
  19. RandomTerrain2=CopyMesh(RandomTerrain,RandomTerrain)
  20. PositionEntity(RandomTerrain2,-45,0,0)
  21. RandomTerrain3=CopyMesh(RandomTerrain,RandomTerrain)
  22. PositionEntity(RandomTerrain3,-45,0,45)
  23. RandomTerrain4=CopyMesh(RandomTerrain,RandomTerrain)
  24. PositionEntity(RandomTerrain4,0,0,45)
  25.  
  26.  
  27. While Not KeyDown(1)
  28.         Cls
  29.         TurnEntity RandomTerrain,0,0.5,0
  30.         RenderWorld
  31.         Flip
  32. Wend
  33. End
  34. Function TileableRandomDiamondSquareTerrain(GridSize,Range#,Smoothness#)
  35.         NumSquares=1; We start with 1 square that is the size of the mesh
  36.         XS=1
  37.         Iterations#=Log2(GridSize-1) ;In the loops we work with progressively smaller and smaller squares
  38.                                                                                           ;This is the number of times to execute the loops to get to the smallest
  39.                                                                                           ;possible square defined by the vertices.
  40.         Terrain=CreateGrid(GridSize,GridSize)
  41.         surf=GetSurface(Terrain,1)
  42.         SeedRnd (MilliSecs())
  43.         For i= 1 To iterations
  44.                 s=((GridSize-1)/XS)
  45.                 For z=1 To NumSquares/XS
  46.                 For x=1 To NumSquares/XS
  47.                         ;Get the corner vertices of the square defined by z,x
  48.                         v1=0+(s*(x-1))+s*(z-1)*GridSize  :  v2=v1+s  :  v3=v1+s*GridSize  :  v4=v3+s
  49.                         ;Now get the centre vertice of the z,x square and raise or lower it by a random amount
  50.                         vc=v1+s/2+(s/2)* GridSize
  51.                         AvgHeight=(VertexY(surf,v1)+VertexY(surf,v2)+VertexY(surf,v3)+VertexY(surf,v4))/4
  52.                         VertexCoords surf,vc,VertexX(surf,vc),Rand(AvgHeight-Range,AvgHeight+Range),VertexZ(surf,vc)
  53.                        
  54.                         ;next we get the centre vertice of the left edge of the z.x square and raise or lower it by a random amount
  55.                         v5=vc-s/2  :  v15=v5-(s/2)*GridSize  :  v25=v15+(s/2)  :  v35=v5+(s/2)
  56.                         AvgHeight=(VertexY(surf,v15)+VertexY(surf,v25)+VertexY(surf,v35))/3
  57.                         VertexCoords surf,v5,VertexX(surf,v5),Rand(AvgHeight-Range,AvgHeight+Range),VertexZ(surf,v5)
  58.                         ;if the vertex is on the left edge of the mesh then set the vertex on the right edge to the same height to ensure tileability
  59.                         If v5*1.0/gridsize*1.0=Int(v5/gridsize) Then
  60.                                 ve=v5+gridsize-1:VertexCoords surf,ve,VertexX(surf,ve),VertexY(surf,v5),VertexZ(surf,ve)
  61.                         End If
  62.                        
  63.                         ;next we get the centre vertice of the top edge of the z.x square and raise or lower it by a random amount
  64.                         v6=vc-(s/2)*GridSize  :  v16=v6+(s/2)   :  v26=v16+(s/2)*GridSize  :  v36=v26-(s/2)                    
  65.                         AvgHeight=(VertexY(surf,v16)+VertexY(surf,v26)+VertexY(surf,v36))/3
  66.                         VertexCoords surf,v6,VertexX(surf,v6),Rand(AvgHeight-Range,AvgHeight+Range),VertexZ(surf,v6)
  67.                         ;if the vertex is on the top edge of the mesh then set the vertex on the bottom edge to the same height to ensure tileability
  68.                         If v6<GridSize Then
  69.                                 ve=v6+gridsize*(gridsize-1):VertexCoords surf,ve,VertexX(surf,ve),VertexY(surf,v6),VertexZ(surf,ve)
  70.                         End If
  71.  
  72.                         ;next we get the centre vertice of the right edge of the z.x square and raise or lower it by a random amount
  73.                         v7=vc+s/2  :  v17=v7-(s/2)   :  v27=v17+(s/2)*GridSize  :  v37=v27+(s/2)
  74.                         AvgHeight=(VertexY(surf,v17)+VertexY(surf,v27)+VertexY(surf,v37))/3
  75.                         VertexCoords surf,v7,VertexX(surf,v7),Rand(AvgHeight-Range,AvgHeight+Range),VertexZ(surf,v7)
  76.                         ;if the vertex is on the right edge of the mesh then set the vertex on the left edge to the same height to ensure tileability
  77.                         If ((v7-gridsize+1)*1.0)/(gridsize*1.0)=Int((v7-gridsize+1)/(gridsize-1))  Then
  78.                                 ve=v7-gridsize+1:VertexCoords surf,ve,VertexX(surf,ve),VertexY(surf,v7),VertexZ(surf,ve)
  79.                         End If
  80.                        
  81.                         ;next we get the centre vertice of the bottom edge of the z.x square and raise or lower it by a random amount
  82.                         v8=vc+(s/2)*GridSize  :  v18=v8-(s/2)*GridSize  :  v28=v18+(s/2)  :  v38=v8+(s/2)
  83.                         AvgHeight=(VertexY(surf,v17)+VertexY(surf,v27)+VertexY(surf,v37))/3
  84.                         VertexCoords surf,v8,VertexX(surf,v8),Rand(AvgHeight-Range,AvgHeight+Range),VertexZ(surf,v8)
  85.                         ;if the vertex is on the top edge of the mesh then set the vertex on the bottom edge to the same height to ensure tileability
  86.                         If v8>GridSize*(gridsize-1) Then
  87.                                 ve=v8-gridsize*(gridsize-1):VertexCoords surf,ve,VertexX(surf,ve),VertexY(surf,v8),VertexZ(surf,ve)
  88.                         End If
  89.                         Next
  90.                 Next
  91.                 NumSquares=NumSquares*4
  92.                 xs=xs*2
  93.                 Print numsquares
  94.                 range=range/smoothness
  95.         Next
  96.         Return terrain
  97. End Function
  98. Function CreateGrid(x=9,z=9,w=5,h=5)
  99.         mesh=CreateMesh()
  100.         surf=CreateSurface(mesh)
  101.        
  102.         For xl=0 To x-1
  103.                 v=AddVertex(surf,xl*w,0,0)
  104.                 vert(xl,0)=v
  105.         Next
  106.        
  107.         For zl=1 To z-1
  108.                 For xl=0 To x-1
  109.                         v=AddVertex(surf,xl*w,0,zl*-h)
  110.                         vert(xl,zl)=v
  111.                         If xl>0 Then
  112.                                 AddTriangle surf,vert(xl,zl),vert(xl-1,zl),vert(xl,zl-1)
  113.                                 AddTriangle surf,vert(xl,zl-1),vert(xl-1,zl),vert(xl-1,zl-1)                                   
  114.                         End If
  115.                        
  116.                 Next
  117.         Next
  118.         Return mesh
  119. End Function
  120. Function Log2# ( x# )
  121.         Return Log( x ) / Log( 2 )
  122. End Function


Comments :


Delerna(Posted 1+ years ago)

 IMPROVED1) Previous version didn't really work as intended. This has been corrected2) The grid of 2X2 meshes now automatically position themselves automatically to suit the size of the idividual meshes3) Previous version could produce jagged terrains. A smothing function has been added to even out the transitions from high spots to low spots4) The vertices are now colored in relation to their height. Black for lowest vertices through shades of green then yellow and on to white for the highest verticesThe terrains are random so you may need to run the program a few times to get a good one. Also a mesh save function might be a good addition, i'll get around to writing one someday, just experimenting at the moment.If you like this, or it is usefull, or you have suggestions then make a comment and I will continue to post improvements
Code: [Select]
;Changeable Parameters
GridSize%=129; Must be a 2^n+1
Landform#=600;The bigger the number the greater the difference in heights between highspots and lowspots
Smoothness#=50;The bigger the number the more smoothly the transition between highspots and low spots will occur


;Setup the 3D environment
Graphics3D 1024,700,16,2
SetBuffer BackBuffer()
Dim vert(GridSize,GridSize)
WireFrame False
AmbientLight(255,255,255)
cam=CreateCamera()
MoveEntity cam, 0, (GridSize-1)*3, -(GridSize-1)*10 ; Our camera...
;MoveEntity cam, 0, 10, 0 ; Our camera...
CameraRange cam,1,10000

;Create 4 copies of the same terrain and position them to show that they are tileable
RandomTerrain=TileableRandomDiamondSquareTerrain(GridSize,Landform,Smoothness)
SmoothTerrain(RandomTerrain,Gridsize)
SmoothTerrain(RandomTerrain,Gridsize)
SmoothTerrain(RandomTerrain,Gridsize)
spacing=(GridSize-1)*5;+5
RandomTerrain2=CopyMesh(RandomTerrain,RandomTerrain)
EntityFX RandomTerrain2,2
PositionEntity(RandomTerrain2,-spacing,0,0)

RandomTerrain3=CopyMesh(RandomTerrain,RandomTerrain)
EntityFX RandomTerrain3,2
PositionEntity(RandomTerrain3,-spacing,0,spacing)

RandomTerrain4=CopyMesh(RandomTerrain,RandomTerrain)
PositionEntity(RandomTerrain4,0,0,spacing)
EntityFX RandomTerrain4,2

While Not KeyDown(1)
Cls
TurnEntity RandomTerrain,0,0.5,0
RenderWorld
Flip
Wend
End

Function SmoothTerrain(Terrain,Gridsize)
EntityFX Terrain,2
surf=GetSurface(Terrain,1)
For r=0 To Gridsize-1
fv=r*Gridsize
For c= 1 To Gridsize-2
v1=fv+c-1 : v2=fv+c : v3=fv+c+1
h1=VertexY(surf,v1) : h2=VertexY(surf,v2) : h3=VertexY(surf,v3)
h2=h1+((h3-h1)/2)
cr=255-(255-h2)
cg=255-(255-h2)+90
cb=255-(255-(h2-200))
If cr>255 Then cr=255
If cg>255 Then cg=255
If cb>255 Then cb=255
VertexCoords surf,v2,VertexX(surf,v2),h2,VertexZ(surf,v2)
VertexColor surf,v2,cr,cg,cb
Next
Next

For c=0 To Gridsize-1
For r= 1 To Gridsize-2
v1=c+r*Gridsize-Gridsize : v2=c+r*Gridsize : v3=c+r*Gridsize+Gridsize
h1=VertexY(surf,v1) : h2=VertexY(surf,v2) : h3=VertexY(surf,v3)
h2=h1+((h3-h1)/2)
VertexCoords surf,v2,VertexX(surf,v2),h2,VertexZ(surf,v2)
cr=255-(255-h2)
cg=255-(255-h2)+90
cb=255-(255-(h2-200))
If cr>255 Then cr=255
If cg>255 Then cg=255
If cb>255 Then cb=255
VertexColor surf,v2,cr,cg,cb
Next
Next

End Function


Function TileableRandomDiamondSquareTerrain(GridSize,Range#,Smoothness#)
NumSquares=1; We start with 1 square that is the size of the mesh
XS=1
Iterations#=Log2(GridSize-1) ;In the loops we work with progressively smaller and smaller squares
 ;This is the number of times to execute the loops to get to the smallest
 ;possible square defined by the vertices.

Terrain=CreateGrid(GridSize,GridSize)

surf=GetSurface(Terrain,1)
SeedRnd (MilliSecs())
For i= 1 To iterations
s=((GridSize-1)/XS)
For z=1 To NumSquares/XS
For x=1 To NumSquares/XS
;Get the corner vertices of the square defined by z,x
v1=0+(s*(x-1))+s*(z-1)*GridSize  :  v2=v1+s  :  v3=v1+s*GridSize  :  v4=v3+s
;Now get the centre vertice of the z,x square and raise or lower it by a random amount
vc=v1+s/2+(s/2)* GridSize
AvgHeight=(VertexY(surf,v1)+VertexY(surf,v2)+VertexY(surf,v3)+VertexY(surf,v4))/4
VertexCoords surf,vc,VertexX(surf,vc),Rand(AvgHeight-Range,AvgHeight+Range),VertexZ(surf,vc)

;next we get the centre vertice of the left edge of the z.x square and raise or lower it by a random amount
v5=vc-s/2  :  v15=v5-(s/2)*GridSize  :  v25=v15+(s/2)  :  v35=v5+(s/2)
AvgHeight=(VertexY(surf,v15)+VertexY(surf,v25)+VertexY(surf,v35))/3
VertexCoords surf,v5,VertexX(surf,v5),Rand(AvgHeight-Range,AvgHeight+Range),VertexZ(surf,v5)
;if the vertex is on the left edge of the mesh then set the vertex on the right edge to the same height to ensure tileability
If v5*1.0/gridsize*1.0=Int(v5/gridsize) Then
ve=v5+gridsize-1:VertexCoords surf,ve,VertexX(surf,ve),VertexY(surf,v5),VertexZ(surf,ve)
End If

;next we get the centre vertice of the top edge of the z.x square and raise or lower it by a random amount
v6=vc-(s/2)*GridSize  :  v16=v6+(s/2)   :  v26=v16+(s/2)*GridSize  :  v36=v26-(s/2)
AvgHeight=(VertexY(surf,v16)+VertexY(surf,v26)+VertexY(surf,v36))/3
VertexCoords surf,v6,VertexX(surf,v6),Rand(AvgHeight-Range,AvgHeight+Range),VertexZ(surf,v6)
;if the vertex is on the top edge of the mesh then set the vertex on the bottom edge to the same height to ensure tileability
If v6<GridSize Then
ve=v6+gridsize*(gridsize-1):VertexCoords surf,ve,VertexX(surf,ve),VertexY(surf,v6),VertexZ(surf,ve)
End If

;next we get the centre vertice of the right edge of the z.x square and raise or lower it by a random amount
v7=vc+s/2  :  v17=v7-(s/2)   :  v27=v17+(s/2)*GridSize  :  v37=v27+(s/2)
AvgHeight=(VertexY(surf,v17)+VertexY(surf,v27)+VertexY(surf,v37))/3
VertexCoords surf,v7,VertexX(surf,v7),Rand(AvgHeight-Range,AvgHeight+Range),VertexZ(surf,v7)
;if the vertex is on the right edge of the mesh then set the vertex on the left edge to the same height to ensure tileability
If ((v7-gridsize+1)*1.0)/(gridsize*1.0)=Int((v7-gridsize+1)/(gridsize-1))  Then
ve=v7-gridsize+1:VertexCoords surf,ve,VertexX(surf,ve),VertexY(surf,v7),VertexZ(surf,ve)
End If

;next we get the centre vertice of the bottom edge of the z.x square and raise or lower it by a random amount
v8=vc+(s/2)*GridSize  :  v18=v8-(s/2)*GridSize  :  v28=v18+(s/2)  :  v38=v8+(s/2)
AvgHeight=(VertexY(surf,v17)+VertexY(surf,v27)+VertexY(surf,v37))/3
VertexCoords surf,v8,VertexX(surf,v8),Rand(AvgHeight-Range,AvgHeight+Range),VertexZ(surf,v8)
;if the vertex is on the top edge of the mesh then set the vertex on the bottom edge to the same height to ensure tileability
If v8>GridSize*(gridsize-1) Then
ve=v8-gridsize*(gridsize-1):VertexCoords surf,ve,VertexX(surf,ve),VertexY(surf,v8),VertexZ(surf,ve)
End If
Next
Next
NumSquares=NumSquares*4
xs=xs*2

range=range/smoothness
Next
Return terrain
End Function
Function CreateGrid(x=9,z=9,w=5,h=5)
mesh=CreateMesh()
surf=CreateSurface(mesh)

For xl=0 To x-1
v=AddVertex(surf,xl*w,0,0)
vert(xl,0)=v
Next

For zl=1 To z-1
For xl=0 To x-1
v=AddVertex(surf,xl*w,0,zl*-h)
vert(xl,zl)=v
If xl>0 Then
AddTriangle surf,vert(xl,zl),vert(xl-1,zl),vert(xl,zl-1)
AddTriangle surf,vert(xl,zl-1),vert(xl-1,zl),vert(xl-1,zl-1)
End If

Next
Next
Return mesh
End Function
Function Log2# ( x# )
Return Log( x ) / Log( 2 )
End Function







Function RandomDiamondSquareTerrain(GridSize,Range#,Smoothness#)
NumSquares=1; We start with 1 square that is the size of the mesh
XS=1
Iterations#=Log2(GridSize-1) ;In the loops we work with progressively smaller and smaller squares
 ;This is the number of times to execute the loops to get to the smallest
 ;possible square defined by the vertices.
Terrain=CreateGrid(GridSize,GridSize)
surf=GetSurface(Terrain,1)
SeedRnd (MilliSecs())
For i= 1 To iterations
s=((GridSize-1)/XS)
For z=1 To NumSquares/XS
For x=1 To NumSquares/XS
;Get the corner vertices of the square defined by z,x
v1=0+(s*(x-1))+s*(z-1)*GridSize  :  v2=v1+s  :  v3=v1+s*GridSize  :  v4=v3+s
;Now get the centre vertice of the z,x square and raise or lower it by a random amount
vc=v1+s/2+(s/2)* GridSize
AvgHeight=(VertexY(surf,v1)+VertexY(surf,v2)+VertexY(surf,v3)+VertexY(surf,v4))/4
VertexCoords surf,vc,VertexX(surf,vc),Rand(AvgHeight-Range,AvgHeight+Range),VertexZ(surf,vc)
;next we get the centre vertice of the left edge of the z.x square
v5=vc-s/2  :  v15=v5-(s/2)*GridSize  :  v25=v15+(s/2)  :  v35=v5+(s/2)
AvgHeight=(VertexY(surf,v15)+VertexY(surf,v25)+VertexY(surf,v35))/3
VertexCoords surf,v5,VertexX(surf,v5),Rand(AvgHeight-Range,AvgHeight+Range),VertexZ(surf,v5)

v6=vc-(s/2)*GridSize  :  v16=v6+(s/2)   :  v26=v16+(s/2)*GridSize  :  v36=v26-(s/2)
AvgHeight=(VertexY(surf,v16)+VertexY(surf,v26)+VertexY(surf,v36))/3
VertexCoords surf,v6,VertexX(surf,v6),Rand(AvgHeight-Range,AvgHeight+Range),VertexZ(surf,v6)
v7=vc+s/2  :  v17=v7-(s/2)   :  v27=v17+(s/2)*GridSize  :  v37=v27+(s/2)
AvgHeight=(VertexY(surf,v17)+VertexY(surf,v27)+VertexY(surf,v37))/3
VertexCoords surf,v7,VertexX(surf,v7),Rand(AvgHeight-Range,AvgHeight+Range),VertexZ(surf,v7)

v8=vc+(s/2)*GridSize  :  v18=v8-(s/2)*GridSize  :  v28=v18+(s/2)  :  v38=v8+(s/2)
AvgHeight=(VertexY(surf,v17)+VertexY(surf,v27)+VertexY(surf,v37))/3
VertexCoords surf,v8,VertexX(surf,v8),Rand(AvgHeight-Range,AvgHeight+Range),VertexZ(surf,v8)
Next
Next
NumSquares=NumSquares*4
xs=xs*2
Print numsquares
range=range/smoothness
Next
Return terrain
End Function



Ryudin(Posted 1+ years ago)

 Great code! I'm going to try to add a heightmap saving function to it to export the good maps and use them in my games.


plash(Posted 1+ years ago)

 blitzmax, non-superstrict (minib3d):
Code: [Select]
Import sidesign.minib3d
'Changeable Parameters
GridSize:Int = 129' Must be a 2^n+1
Landform:Float = 600'The bigger the number the greater the difference in heights between highspots And lowspots
Smoothness:Float = 50'The bigger the number the more smoothly the transition between highspots And low spots will occur


'Setup the 3D environment
Graphics3D 1024, 700, 16, 2

Global vert:Int[GridSize, GridSize]
Wireframe False
AmbientLight(255, 255, 255)

Local Cam:TCamera = createCamera()
MoveEntity Cam, 0, (GridSize - 1) * 3, - (GridSize - 1) * 10 ' Our camera...
'MoveEntity cam, 0, 10, 0 ' Our camera...
CameraRange cam,1,10000

'Create 4 copies of the same terrain And position them To show that they are tileable
RandomTerrain = TileableRandomDiamondSquareTerrain(GridSize, Landform, Smoothness)
'ScaleEntity randomterrain, 5.0, 5.0, 5.0
SmoothTerrain(RandomTerrain, Gridsize)
SmoothTerrain(RandomTerrain, Gridsize)
SmoothTerrain(RandomTerrain, Gridsize)
spacing = (GridSize - 1) * 5'+5
'RandomTerrain2 = CopyMesh(RandomTerrain, RandomTerrain)
'EntityFX RandomTerrain2, 2
'PositionEntity(RandomTerrain2, - spacing, 0, 0)

'RandomTerrain3 = CopyMesh(RandomTerrain, RandomTerrain)
'EntityFX RandomTerrain3, 2
'PositionEntity(RandomTerrain3, - spacing, 0, spacing)

'RandomTerrain4 = CopyMesh(RandomTerrain, RandomTerrain)
'PositionEntity(RandomTerrain4, 0, 0, spacing)
'EntityFX RandomTerrain4, 2

While Not KeyHit(KEY_ESCAPE)
   Cls
If KeyHit(KEY_W) Wireframe True
TurnEntity RandomTerrain, 0, 1.0, 0
RenderWorld

   Flip
   Delay 20
Wend
End

Function SmoothTerrain(TERRAIN:TMesh, Gridsize)
 EntityFX TERRAIN, 2

  Local surf:TSurface = getSurface(TERRAIN, 1)

For r = 0 To Gridsize - 1
fv = r * Gridsize
For c = 1 To Gridsize - 2
v1 = fv + c - 1;v2 = fv + c;v3 = fv + c + 1
h1 = VertexY(surf, v1) ;h2 = VertexY(surf, v2) ;h3 = VertexY(surf, v3)
h2 = h1 + ((h3 - h1) / 2)
cr = 255 - (255 - h2)
cg = 255 - (255 - h2) + 90
cb = 255 - (255 - (h2 - 200))
If cr > 255 Then cr = 255
If cg > 255 Then cg = 255
If cb > 255 Then cb = 255
VertexCoords surf, v2, VertexX(surf, v2), h2, VertexZ(surf, v2)
VertexColor surf, v2, cr, cg, cb
Next
Next

For c = 0 To Gridsize - 1
For r = 1 To Gridsize - 2
v1 = c + r * Gridsize - Gridsize;v2 = c + r * Gridsize;v3 = c + r * Gridsize + Gridsize
h1 = VertexY(surf, v1) ;h2 = VertexY(surf, v2) ;h3 = VertexY(surf, v3)
h2 = h1 + ((h3 - h1) / 2)
VertexCoords surf, v2, VertexX(surf, v2), h2, VertexZ(surf, v2)
cr = 255 - (255 - h2)
cg = 255 - (255 - h2) + 90
cb = 255 - (255 - (h2 - 200))
If cr > 255 Then cr = 255
If cg > 255 Then cg = 255
If cb > 255 Then cb = 255
VertexColor surf, v2, cr, cg, cb
Next
Next

End Function


Function TileableRandomDiamondSquareTerrain:TMesh(GridSize:Int, Range:Float, Smoothness:Float)
NumSquares:Int = 1' We Start with 1 square that is the size of the MESH
XS:Int = 1
Iterations:Float = Log2(GridSize - 1)    'In the loops we work with progressively smaller And smaller squares
 'This is the number of times To execute the loops To get To the smallest
 'possible square defined by the vertices.

Local TERRAIN:TMesh = CreateGrid(GridSize, GridSize)
surf = getSurface(TERRAIN, 1)
SeedRnd (MilliSecs())
For i = 1 To iterations
s = ((GridSize - 1) / XS)
For Z = 1 To NumSquares / XS
For X = 1 To NumSquares / XS
'Get the corner vertices of the square defined by z,x
v1 = 0 + (s * (X - 1)) + s * (Z - 1) * GridSize ; v2 = v1 + s ; v3 = v1 + s * GridSize ; v4 = v3 + s
'Now get the centre vertice of the z,x square And raise Or Lower it by a random amount
vc=v1+s/2+(s/2)* GridSize
AvgHeight = (VertexY(surf, v1) + VertexY(surf, v2) + VertexY(surf, v3) + VertexY(surf, v4)) / 4
VertexCoords surf, vc, VertexX(surf, vc), Rand(AvgHeight - Range, AvgHeight + Range), VertexZ(surf, vc)

'Next we get the centre vertice of the Left edge of the z.x square And raise Or Lower it by a random amount
v5 = vc - s / 2 ; v15 = v5 - (s / 2) * GridSize ; v25 = v15 + (s / 2) ; v35 = v5 + (s / 2)
AvgHeight = (VertexY(surf, v15) + VertexY(surf, v25) + VertexY(surf, v35)) / 3
VertexCoords surf, v5, VertexX(surf, v5), Rand(AvgHeight - Range, AvgHeight + Range), VertexZ(surf, v5)
'If the vertex is on the Left edge of the mesh Then set the vertex on the Right edge To the same height To ensure tileability
If v5 * 1.0 / gridsize * 1.0 = Int(v5 / gridsize) Then
ve = v5 + gridsize - 1;VertexCoords surf, ve, VertexX(surf, ve), VertexY(surf, v5), VertexZ(surf, ve)
End If

'Next we get the centre vertice of the top edge of the z.x square And raise Or Lower it by a random amount
v6 = vc - (s / 2) * GridSize ; v16 = v6 + (s / 2) ; v26 = v16 + (s / 2) * GridSize ; v36 = v26 - (s / 2)
AvgHeight = (VertexY(surf, v16) + VertexY(surf, v26) + VertexY(surf, v36)) / 3
VertexCoords surf, v6, VertexX(surf, v6), Rand(AvgHeight - Range, AvgHeight + Range), VertexZ(surf, v6)
'If the vertex is on the top edge of the mesh Then set the vertex on the bottom edge To the same height To ensure tileability
If v6 < GridSize Then
ve = v6 + gridsize * (gridsize - 1) ;VertexCoords surf, ve, VertexX(surf, ve), VertexY(surf, v6), VertexZ(surf, ve)
End If

'Next we get the centre vertice of the Right edge of the z.x square And raise Or Lower it by a random amount
v7 = vc + s / 2 ; v17 = v7 - (s / 2) ; v27 = v17 + (s / 2) * GridSize ; v37 = v27 + (s / 2)
AvgHeight = (VertexY(surf, v17) + VertexY(surf, v27) + VertexY(surf, v37)) / 3
VertexCoords surf, v7, VertexX(surf, v7), Rand(AvgHeight - Range, AvgHeight + Range), VertexZ(surf, v7)
'If the vertex is on the Right edge of the mesh Then set the vertex on the Left edge To the same height To ensure tileability
If ((v7 - gridsize + 1) * 1.0) / (gridsize * 1.0) = Int((v7 - gridsize + 1) / (gridsize - 1)) Then
ve = v7 - gridsize + 1;VertexCoords surf, ve, VertexX(surf, ve), VertexY(surf, v7), VertexZ(surf, ve)
End If

'Next we get the centre vertice of the bottom edge of the z.x square And raise Or Lower it by a random amount
v8 = vc + (s / 2) * GridSize ; v18 = v8 - (s / 2) * GridSize ; v28 = v18 + (s / 2) ; v38 = v8 + (s / 2)
AvgHeight = (VertexY(surf, v17) + VertexY(surf, v27) + VertexY(surf, v37)) / 3
VertexCoords surf, v8, VertexX(surf, v8), Rand(AvgHeight - Range, AvgHeight + Range), VertexZ(surf, v8)
'If the vertex is on the top edge of the mesh Then set the vertex on the bottom edge To the same height To ensure tileability
If v8 > GridSize * (gridsize - 1) Then
ve = v8 - gridsize * (gridsize - 1) ; VertexCoords surf, ve, VertexX(surf, ve), VertexY(surf, v8), VertexZ(surf, ve)
End If
Next
Next
NumSquares = NumSquares * 4
xs = xs * 2

Range = Range / smoothness
Next

Return TERRAIN

End Function

Function CreateGrid:TMesh(X = 9, Z = 9, W = 5, h = 5)
  Local MESH:TMesh = createMesh()
  Local surf:TSurface = CreateSurface(MESH)

For xl = 0 To X - 1
v = addVertex(surf, xl * W, 0, 0)
vert(xl, 0) = v
Next

For zl=1 To z-1
For xl=0 To x-1
v = addVertex(surf, xl * W, 0, zl * -h)
vert[xl, zl] = v

If xl > 0 Then
addTriangle surf, vert(xl, zl), vert(xl - 1, zl), vert(xl, zl - 1)
addTriangle surf, vert(xl, zl - 1), vert(xl - 1, zl), vert(xl - 1, zl - 1)

End If

Next
Next

   Return MESH

End Function

Function Log2:Float(X:Float)
Return Log(X) / Log(2)

End Function

Function RandomDiamondSquareTerrain:Tmesh(GridSize:Int, Range:Float, Smoothness:Float)
  Local NumSquares:Int = 1' We start with 1 square that is the size of the mesh
  Local XS:Int = 1
  Local Iterations:Float = Log2(GridSize - 1) 'In the loops we work with progressively smaller And smaller squares
 'This is the number of times To execute the loops To get To the smallest
 'possible square defined by the vertices.
  Local TERRAIN:TMesh = CreateGrid(GridSize, GridSize)
  Local surf:TSurface = getSurface(TERRAIN, 1)

SeedRnd (MilliSecs())
For i = 1 To iterations
s = ((GridSize - 1) / XS)
For Z:Int = 1 To NumSquares / XS
For X:Int = 1 To NumSquares / XS
'Get the corner vertices of the square defined by z,x
v1 = 0 + (s * (X - 1)) + s * (Z - 1) * GridSize ; v2 = v1 + s ; v3 = v1 + s * GridSize ; v4 = v3 + s
'Now get the centre vertice of the z,x square And raise Or Lower it by a random amount
vc = v1 + s / 2 + (s / 2) * GridSize
AvgHeight = (VertexY(surf, v1) + VertexY(surf, v2) + VertexY(surf, v3) + VertexY(surf, v4)) / 4
VertexCoords surf, vc, VertexX(surf, vc), Rand(AvgHeight - Range, AvgHeight + Range), VertexZ(surf, vc)
'Next we get the centre vertice of the Left edge of the z.x square
v5 = vc - s / 2 ; v15 = v5 - (s / 2) * GridSize ; v25 = v15 + (s / 2) ; v35 = v5 + (s / 2)
AvgHeight = (VertexY(surf, v15) + VertexY(surf, v25) + VertexY(surf, v35)) / 3
VertexCoords surf, v5, VertexX(surf, v5), Rand(AvgHeight - Range, AvgHeight + Range), VertexZ(surf, v5)

v6 = vc - (s / 2) * GridSize ; v16 = v6 + (s / 2) ; v26 = v16 + (s / 2) * GridSize ; v36 = v26 - (s / 2)
AvgHeight = (VertexY(surf, v16) + VertexY(surf, v26) + VertexY(surf, v36)) / 3
VertexCoords surf, v6, VertexX(surf, v6), Rand(AvgHeight - Range, AvgHeight + Range), VertexZ(surf, v6)
v7 = vc + s / 2 ; v17 = v7 - (s / 2) ; v27 = v17 + (s / 2) * GridSize ; v37 = v27 + (s / 2)
AvgHeight = (VertexY(surf, v17) + VertexY(surf, v27) + VertexY(surf, v37)) / 3
VertexCoords surf, v7, VertexX(surf, v7), Rand(AvgHeight - Range, AvgHeight + Range), VertexZ(surf, v7)

v8 = vc + (s / 2) * GridSize ; v18 = v8 - (s / 2) * GridSize ; v28 = v18 + (s / 2) ; v38 = v8 + (s / 2)
AvgHeight = (VertexY(surf, v17) + VertexY(surf, v27) + VertexY(surf, v37)) / 3
VertexCoords surf, v8, VertexX(surf, v8), Rand(AvgHeight - Range, AvgHeight + Range), VertexZ(surf, v8)
Next
Next
NumSquares = NumSquares * 4
xs = xs * 2
Print numsquares
Range = Range / smoothness
Next

   Return TERRAIN
   
End Function


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal