Code archives/3D Graphics - Mesh/Convert BlitzTerrain To Mesh

This code has been declared by its author to be Public Domain code.

Download source code

Convert BlitzTerrain To Mesh by _PJ_2016
Currently converts the topography and UV Coordinates of a BlitzTerrain to Mesh surface triangles.

I hope to include textures and hopefully cope with rotated Terrains.


This basic example shows the conversion:

Graphics3D 1024,768,32
SetBuffer BackBuffer()

Const TSize=64

AmbientLight 127,127,127
Global sun=CreateLight()

Global cam=CreateCamera()
MoveEntity cam,0,10,-20
TurnEntity cam,0,-35,0

Local terrain=CreateTerrain(TSize)
TerrainShading terrain,True

Local X#
Local Y#
Local Z#

;(Randomiseterrain)
For Z#= 0 To TSize-1
	For X#=0 To TSize-1
		ModifyTerrain(terrain,X#,Z#,Rnd(0,1))
	Next
Next
ScaleEntity terrain,1,Rand(2,8),1

;EFFECTS
EntityFX terrain,16
EntityAlpha terrain,0.5
EntityColor terrain,255,0,0

Local Mesh=ConvertTerrainToMesh(terrain)

;MESH EFFECTS
EntityFX Mesh,16
EntityAlpha Mesh,0.5
EntityColor Mesh,0,255,0

;EXAMPLE
Local SH

While Not KeyDown(1)
	
	If(KeyHit(57))
		SH=1-SH
		
		If SH
			ShowEntity terrain
			HideEntity Mesh
		Else	
			ShowEntity Mesh 
			HideEntity terrain
		End If
	End If	
	
	TurnEntity terrain,0,1,0
	TurnEntity Mesh,0,1,0
	
	
	UpdateWorld
	RenderWorld
	Flip
Wend
Function h3d_MESH_GenerateMeshFromTerrain(Terrain,StartX=0,StartZ=0,MeshSize=0)
	;TERRAIN MUST NOT BE ROTATED (Might do this later but it's really complicated... Maybe require TFormPoint or something with the Entitypitch and Yaw values)
	; No need to know SCALE factor - Mesh is generated to current actual scaled size of terrain
	
	;Establish Parameters
	Local Size=TerrainSize(Terrain)
	
	Local XOffset#=EntityX(Terrain,True)
	Local YOffset#=EntityY(Terrain,True)
	Local ZOffset#=EntityZ(Terrain,True)
	
	Local UVRatio#=1.0/Size
	
	;Declare locals
	
	Local U#
	Local V#
	Local W#
	
	Local X#
	Local Y#
	Local Z#
	
	Local TX#
	Local TY#
	Local TZ#
	
	Local v0
	Local v1
	Local v2
	Local v3
	
	Local Mesh=CreateMesh()
	Local Surface=CreateSurface(Mesh)
	
	For Z=0 To MeshSize-1
		For X=0 To MeshSize-1
			
			;Adjust for position
			TX=StartX+X+XOffset
			TZ=StartZ+Z+ZOffset
			
			;Vertex0
			Y#=GetRelativeTerrainHeight(Terrain,TX+1,TZ,YOffset)
			
			U#=(X+1)*UVRatio
			V#=1-(Z*UVRatio)
			W=(Z*UVRatio)
			
			v0=AddVertex(Surface,X+1,Y,Z,U,V,W)
			
			;Vertex1
			Y#=GetRelativeTerrainHeight(Terrain,TX,TZ,YOffset)
			
			U#=X*UVRatio
			V#=1-(Z*UVRatio)
			W=Z*UVRatio
			
			v1=AddVertex(Surface,X,Y,Z,U,V,W)
			
			;Vertex2
			Y#=GetRelativeTerrainHeight(Terrain,TX+1,TZ+1,YOffset)
			
			U#=(X+1)*UVRatio
			V#=1-((Z+1)*UVRatio)
			W=(Z+1)*UVRatio
			
			v2=AddVertex(Surface,X+1,Y,Z+1,U,V,W)
			
			;Vertex3
			Y#=GetRelativeTerrainHeight(Terrain,TX,TZ+1,YOffset)
			
			U#=X*UVRatio
			V#=1-((Z+1)*UVRatio)
			W=(Z+1)*UVRatio
			
			v3=AddVertex(Surface,X,Y,Z+1,U,V,W)
			
			;Create Surface Polys
			
			AddTriangle(Surface,v0,v1,v2)
			AddTriangle(Surface,v1,v3,v2)
			
		Next
	Next
	
	UpdateNormals Mesh
	
	PositionEntity Mesh,XOffset+StartX,YOffset,ZOffset+StartZ,True
	
	Return Mesh
	
End Function

Function GetRelativeTerrainHeight#(Terrain,X#,Z#,YOffset#)
	;Converts absolute value to relative
	Local AbsoluteHeight#=TerrainY(Terrain,X,0,Z)
	Return AbsoluteHeight#-YOffset
End Function

Comments

_PJ_2016
Updated to include StartX StartZ and MeshSize parameters.
This means that portions of a large terrain can be split into multiple meshes.
Necessary for Terrain sizes greater than around 64 units which exceed the polycount limit for mesh surfaces.


Code Archives Forum