Code archives/3D Graphics - Mesh/minib3d - converted terrain functions
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
A more B3D like terrain can be found here: http://www.blitzmax.com/Community/posts.php?topic=85741 I couldn't post it in the archives, because it has a certain license. Functions: LoadTerrain:TTerrain(filename$,RoamMaxHeightError,MaxTileDepth) TerrainY#(terrain:TTerrain, x#, z#) Update: this is a conversion of a Russian tutorial I found online. It uses ROAM to optimize a terrain. When areas need a bigger precision, more triangles are generated at that location. You can supply two optional paramers: 1. a cutoff value for terrain steepness 2. a cutoff value for triangle splitting (depth level) Basically, it starts with two big triangles and subdivides them on areas where that's needed. The first parameter determines where it splits and the second one determines how much levels of splitting is allowed. I tried to include routines that autodetect the right setting. If you omit the first parameter, the autodetection takes place. The pixmap is automatically rescaled to 512x512 in the LoadTerrain function. The pixmap has to be square. In the update I removed any global variables and I made it SuperStrict compatible. It is now also an OOP object. Example: Include "terrain.bmx" 'the below file Local terrain:TMesh = LoadTerrain("heightmap.png") PositionEntity terrain, -256, 0, -256 terrain.bmx: | |||||
Type TTerrain Extends TMesh Field HeightMap#[512, 512] '--------------------------------------------------------------------------------------------------------------- ' Create() '--------------------------------------------------------------------------------------------------------------- Method Create:TTerrain() Local m:TTerrain = New TTerrain class$ = "Terrain" AddParent(Null) EntityListAdd(TTerrain.entity_list) Return Self End Method '--------------------------------------------------------------------------------------------------------------- ' MakeTerrainMesh() '--------------------------------------------------------------------------------------------------------------- Method MakeTerrainMesh(HmapImage:TPixmap, RoamMaxHeightError#=-1, MaxTileDepth%) If HmapImage = Null Then Return 'clear array For Local i:Int = 0 To 511 For Local j:Int = 0 To 511 HeightMap[i,j]=0 Next Next Local RoamTerrainWidth%=Max(PixmapWidth(HmapImage),PixmapHeight(HmapImage))-1 Local RoamTerrainHeight#[RoamTerrainWidth+1+1,RoamTerrainWidth+1+1] Local maxv# = 0 Local minv# = 256 For Local PixX%=0 To RoamTerrainWidth For Local PixY%=0 To RoamTerrainWidth Local Pixel% = 0 If PixX < PixmapWidth(HmapImage) Then If PixY < PixmapHeight(HmapImage) Then Pixel=ReadPixel(HmapImage,PixX,PixY) End If End If RoamTerrainHeight#[PixX,PixY]=(Pixel & $FF) If RoamTerrainHeight#[PixX,PixY] < minv Then minv = RoamTerrainHeight#[PixX,PixY] If RoamTerrainHeight#[PixX,PixY] > maxv Then maxv = RoamTerrainHeight#[PixX,PixY] Next Next Local vwidth# = (maxv - minv) If vwidth = 0 Then vwidth = 1.0 For Local PixX%=0 To RoamTerrainWidth For Local PixY%=0 To RoamTerrainWidth RoamTerrainHeight#[PixX,PixY] = (RoamTerrainHeight#[PixX,PixY] - minv) * 30.0 / vwidth Next Next If RoamMaxHeightError = -1 Then For Local PixY%=0 To RoamTerrainWidth For Local PixX%=1 To RoamTerrainWidth Local dd# = (RoamTerrainHeight#[PixX,PixY] - RoamTerrainHeight#[PixX-1,PixY]) If Abs(dd) > 10 Then RoamTerrainHeight#[PixX,PixY] = RoamTerrainHeight#[PixX-1,PixY] + Sgn(dd)*10 Next Next For Local PixX%=0 To RoamTerrainWidth For Local PixY%=1 To RoamTerrainWidth Local dd# = (RoamTerrainHeight#[PixX,PixY] - RoamTerrainHeight#[PixX,PixY-1]) If Abs(dd) > 10 Then RoamTerrainHeight#[PixX,PixY] = RoamTerrainHeight#[PixX,PixY-1] + Sgn(dd)*10 Next Next Local ee# = 0 For Local PixY%=0 To RoamTerrainWidth For Local PixX%=1 To RoamTerrainWidth ee :+ Abs(RoamTerrainHeight#[PixX,PixY] - RoamTerrainHeight#[PixX-1,PixY]) Next Next For Local PixX%=0 To RoamTerrainWidth For Local PixY%=1 To RoamTerrainWidth ee :+ Abs(RoamTerrainHeight#[PixX,PixY] - RoamTerrainHeight#[PixX,PixY-1]) Next Next RoamMaxHeightError = Sqr(ee) / 264.0 If RoamMaxHeightError < 0.1 Then RoamMaxHeightError = 0.1 End If Local RoamMaxTriangles%=RoamTerrainWidth*RoamTerrainWidth*2-1 Local RoamBaseNeighbor%[RoamMaxTriangles*10+1] Local RoamBaseNeighborFlag%[RoamMaxTriangles*10+1] For Local CurrentNumber%=1 To RoamMaxTriangles FindTriBaseNeighbor(RoamBaseNeighbor, RoamBaseNeighborFlag, CurrentNumber) Next CreateLand(RoamTerrainHeight, RoamBaseNeighbor, RoamBaseNeighborFlag, .. RoamTerrainWidth, RoamMaxHeightError, MaxTileDepth) End Method '--------------------------------------------------------------------------------------------------------------- ' CreateLand() '--------------------------------------------------------------------------------------------------------------- Method CreateLand(RoamTerrainHeight:Float[,], RoamBaseNeighbor:Int[], RoamBaseNeighborFlag:Int[], .. RoamTerrainWidth:Int, RoamMaxHeightError#, MaxTileDepth%) Local RoamCriticalTriLevel%=RoamTerrainWidth*RoamTerrainWidth-1 Local MinTileSizeLevel%=2^MaxTileDepth Local RoamTriangle:TBank[2] Local RoamSurface:TSurface = CreateSurface() RoamTriangle[0]=CreateBank(RoamTerrainWidth*RoamTerrainWidth*2) RoamTriangle[1]=CreateBank(RoamTerrainWidth*RoamTerrainWidth*2) Local RoamVertex:Int[,] = New Int[RoamTerrainWidth+1,RoamTerrainWidth+1] AddVertex RoamSurface,0,0,0 RoamBreakTriangle(RoamTerrainHeight, RoamBaseNeighbor, RoamBaseNeighborFlag, RoamTriangle, 0, .. RoamTerrainWidth,RoamTerrainWidth,RoamTerrainWidth,RoamTerrainWidth,0,1,0, .. RoamCriticalTriLevel, MinTileSizeLevel, RoamMaxHeightError) RoamBreakTriangle(RoamTerrainHeight, RoamBaseNeighbor, RoamBaseNeighborFlag, RoamTriangle, .. RoamTerrainWidth,0,0,0,0,RoamTerrainWidth,1,1, RoamCriticalTriLevel, MinTileSizeLevel, .. RoamMaxHeightError) RoamCreateTriangle(RoamTerrainHeight, RoamTriangle, RoamVertex, RoamSurface, 0,RoamTerrainWidth, .. RoamTerrainWidth,RoamTerrainWidth,RoamTerrainWidth,0,1,0,RoamTerrainWidth) RoamCreateTriangle(RoamTerrainHeight, RoamTriangle, RoamVertex, RoamSurface, RoamTerrainWidth,0,0,0,0, .. RoamTerrainWidth,1,1,RoamTerrainWidth) UpdateNormals End Method '--------------------------------------------------------------------------------------------------------------- ' FindTriBaseNeighbor() '--------------------------------------------------------------------------------------------------------------- Method FindTriBaseNeighbor(RoamBaseNeighbor:Int[], RoamBaseNeighborFlag:Int[], Number%) If RoamBaseNeighbor[number]>0 Return EndIf If Number<4 Select Number Case 1 RoamBaseNeighbor[Number]=1 RoamBaseNeighborFlag[Number]=1 Case 2 RoamBaseNeighbor[Number]=0 RoamBaseNeighborFlag[Number]=0 Case 3 RoamBaseNeighbor[Number]=0 RoamBaseNeighborFlag[Number]=0 End Select Return EndIf Local Parent%=Number Shr 1 Local ParentLeftChild%=(Parent Shl 1) Local ParentRightChild%=(Parent Shl 1)+1 Local PraParent%=Parent Shr 1 Local PraParentLeftChild%=(PraParent Shl 1) Local PraParentRightChild%=(PraParent Shl 1)+1 Local PraParentRightChildRightChild% Local PraParentLeftChildLeftChild% If Number=ParentLeftChild And Parent=PraParentLeftChild PraParentRightChildRightChild=(PraParentRightChild Shl 1)+1 RoamBaseNeighbor[Number]=PraParentRightChildRightChild RoamBaseNeighborFlag[Number]=0 RoamBaseNeighbor[PraParentRightChildRightChild]=Number RoamBaseNeighborFlag[PraParentRightChildRightChild]=0 Return EndIf If Number=ParentRightChild And Parent=PraParentRightChild PraParentLeftChildLeftChild=(PraParentLeftChild Shl 1) RoamBaseNeighbor[Number]=PraParentLeftChildLeftChild RoamBaseNeighborFlag[Number]=0 RoamBaseNeighbor[PraParentLeftChildLeftChild]=Number RoamBaseNeighborFlag[PraParentLeftChildLeftChild]=0 Return EndIf Local PraParentBaseNeighbor%=RoamBaseNeighbor[PraParent] Local PraParentBaseNeighborFlag%=RoamBaseNeighborFlag[PraParent] If PraParentBaseNeighbor=0 RoamBaseNeighbor[Number]=0 RoamBaseNeighborFlag[Number]=0 Return EndIf Local PraParentBaseNeighborRightChild% Local PraParentBaseNeighborRightChildLeftChild% If Number=ParentRightChild And Parent=PraParentLeftChild PraParentBaseNeighborRightChild=(PraParentBaseNeighbor Shl 1)+1 PraParentBaseNeighborRightChildLeftChild=(PraParentBaseNeighborRightChild Shl 1) RoamBaseNeighbor[Number]=PraParentBaseNeighborRightChildLeftChild RoamBaseNeighborFlag[Number]=PraParentBaseNeighborFlag RoamBaseNeighbor[PraParentBaseNeighborRightChildLeftChild]=Number RoamBaseNeighborFlag[PraParentBaseNeighborRightChildLeftChild]=PraParentBaseNeighborFlag Return EndIf Local PraParentBaseNeighborLeftChild% Local PraParentBaseNeighborLeftChildRightChild% If Number=ParentLeftChild And Parent=PraParentRightChild PraParentBaseNeighborLeftChild=PraParentBaseNeighbor Shl 1 PraParentBaseNeighborLeftChildRightChild=(PraParentBaseNeighborLeftChild Shl 1)+1 RoamBaseNeighbor[Number]=PraParentBaseNeighborLeftChildRightChild RoamBaseNeighborFlag[Number]=PraParentBaseNeighborFlag RoamBaseNeighbor[PraParentBaseNeighborLeftChildRightChild]=Number RoamBaseNeighborFlag[PraParentBaseNeighborLeftChildRightChild]=PraParentBaseNeighborFlag EndIf End Method '--------------------------------------------------------------------------------------------------------------- ' RoamBreakTriangle() '--------------------------------------------------------------------------------------------------------------- Method RoamBreakTriangle(RoamTerrainHeight:Float[,], RoamBaseNeighbor:Int[], RoamBaseNeighborFlag:Int[], .. RoamTriangle:TBank[], x0%,z0%,x1%,z1%,x2%,z2%,Number%,Branch%, .. RoamCriticalTriLevel%, MinTileSizeLevel%, RoamMaxHeightError#) If Number>RoamCriticalTriLevel PokeByte(RoamTriangle[Branch],Number,0) Return EndIf Local xC%,zC% Local LeftChild%, RightChild% If number >= BankSize(RoamTriangle[0]) Then Print "out of memory" Return End If If Number<MinTileSizeLevel xC=(x0+x2)/2 zC=(z0+z2)/2 LeftChild=(Number Shl 1) RightChild=(Number Shl 1)+1 PokeByte(RoamTriangle[Branch],Number,1) RoamBreakTriangle(RoamTerrainHeight, RoamBaseNeighbor, RoamBaseNeighborFlag, RoamTriangle, .. x1,z1,xC,zC,x0,z0,LeftChild,Branch, RoamCriticalTriLevel, MinTileSizeLevel, .. RoamMaxHeightError) RoamBreakTriangle(RoamTerrainHeight, RoamBaseNeighbor, RoamBaseNeighborFlag, RoamTriangle, .. x2,z2,xC,zC,x1,z1,RightChild,Branch, RoamCriticalTriLevel, MinTileSizeLevel, .. RoamMaxHeightError) Return EndIf If PeekByte(RoamTriangle[Branch],Number)=1 xC=(x0+x2)/2 zC=(z0+z2)/2 LeftChild=(Number Shl 1) RightChild=(Number Shl 1)+1 RoamBreakTriangle(RoamTerrainHeight, RoamBaseNeighbor, RoamBaseNeighborFlag, RoamTriangle, .. x1,z1,xC,zC,x0,z0,LeftChild,Branch, RoamCriticalTriLevel, MinTileSizeLevel, .. RoamMaxHeightError) RoamBreakTriangle(RoamTerrainHeight, RoamBaseNeighbor, RoamBaseNeighborFlag, RoamTriangle, .. x2,z2,xC,zC,x1,z1,RightChild,Branch, RoamCriticalTriLevel, MinTileSizeLevel, .. RoamMaxHeightError) Return EndIf xC=(x0+x2)/2 zC=(z0+z2)/2 Local DeltaHeight#=Abs(RoamTerrainHeight[xC,zC]-(RoamTerrainHeight[x0,z0]+RoamTerrainHeight[x2,z2])*0.5) If (DeltaHeight < RoamMaxHeightError) Then Return xC=(x0+x2)/2 zC=(z0+z2)/2 LeftChild=(Number Shl 1) RightChild=(Number Shl 1)+1 PokeByte(RoamTriangle[Branch],Number,1) RoamBreakTriangle(RoamTerrainHeight, RoamBaseNeighbor, RoamBaseNeighborFlag, RoamTriangle, .. x1,z1,xC,zC,x0,z0,LeftChild,Branch, RoamCriticalTriLevel, MinTileSizeLevel, .. RoamMaxHeightError) RoamBreakTriangle(RoamTerrainHeight, RoamBaseNeighbor, RoamBaseNeighborFlag, RoamTriangle, .. x2,z2,xC,zC,x1,z1,RightChild,Branch, RoamCriticalTriLevel, MinTileSizeLevel, .. RoamMaxHeightError) If RoamBaseNeighbor[Number]>0 RoamForceSplitTri(RoamBaseNeighbor, RoamBaseNeighborFlag, RoamTriangle, .. RoamBaseNeighbor[Number],Branch ~ RoamBaseNeighborFlag[Number]) EndIf End Method '--------------------------------------------------------------------------------------------------------------- ' RoamForceSplitTri() '--------------------------------------------------------------------------------------------------------------- Method RoamForceSplitTri(RoamBaseNeighbor:Int[], RoamBaseNeighborFlag:Int[], RoamTriangle:TBank[], Number%, .. Branch%) If PeekByte(RoamTriangle[Branch],Number)=1 Return EndIf PokeByte(RoamTriangle[Branch],Number,1) If RoamBaseNeighbor[Number]>0 RoamForceSplitTri(RoamBaseNeighbor, RoamBaseNeighborFlag, RoamTriangle, RoamBaseNeighbor[Number], .. Branch ~ RoamBaseNeighborFlag[Number]) EndIf Local Parent%=Number Shr 1 RoamForceSplitTri(RoamBaseNeighbor, RoamBaseNeighborFlag, RoamTriangle, Parent,Branch) End Method '--------------------------------------------------------------------------------------------------------------- ' RoamCreateTriangle() '--------------------------------------------------------------------------------------------------------------- Method RoamCreateTriangle(RoamTerrainHeight:Float[,], RoamTriangle:TBank[], RoamVertex:Int[,], .. RoamSurface:TSurface, x0%,z0%,x1%,z1%,x2%,z2%,.. Number%,Branch%,RoamTerrainWidth%) Local xC%, zC% Local LeftChild% Local RightChild% If Number >= BankSize(RoamTriangle[0]) Then Print "out of memory" Return End If If PeekByte(RoamTriangle[Branch],Number)=1 xC=(x0+x2)/2 zC=(z0+z2)/2 LeftChild=(Number Shl 1) RightChild=(Number Shl 1)+1 If RoamSurface.CountVertices() > 16000 Then Print "new surface" RoamSurface = CreateSurface() RoamVertex = New Int[RoamTerrainWidth+1,RoamTerrainWidth+1] End If RoamCreateTriangle(RoamTerrainHeight, RoamTriangle, RoamVertex, RoamSurface, x1,z1,xC,zC,x0,z0,.. LeftChild,Branch,RoamTerrainWidth) RoamCreateTriangle(RoamTerrainHeight, RoamTriangle, RoamVertex, RoamSurface, x2,z2,xC,zC,x1,z1,.. RightChild,Branch,RoamTerrainWidth) Return Else If RoamVertex[x0,z0]=0 RoamVertex[x0,z0]=AddVertex(RoamSurface,x0,RoamTerrainHeight[x0,z0],z0,x0,z0) EndIf If RoamVertex[x1,z1]=0 RoamVertex[x1,z1]=AddVertex(RoamSurface,x1,RoamTerrainHeight[x1,z1],z1,x1,z1) EndIf If RoamVertex[x2,z2]=0 RoamVertex[x2,z2]=AddVertex(RoamSurface,x2,RoamTerrainHeight[x2,z2],z2,x2,z2) EndIf AddTriangle (RoamSurface,RoamVertex[x0,z0],RoamVertex[x1,z1],RoamVertex[x2,z2]) AddHeightTriangle(x0,RoamTerrainHeight[x0,z0],z0, .. x1,RoamTerrainHeight[x1,z1],z1, .. x2,RoamTerrainHeight[x2,z2],z2) EndIf End Method '--------------------------------------------------------------------------------------------------------------- ' AddHeightTriangle() '--------------------------------------------------------------------------------------------------------------- Method AddHeightTriangle(x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3#) If z3 < z1 Then Swap_Ter(x1,x3) Swap_Ter(y1,y3) Swap_Ter(z1,z3) End If If z2 < z1 Then Swap_Ter(x1,x2) Swap_Ter(y1,y2) Swap_Ter(z1,z2) End If If z3 < z2 Then Swap_Ter(x2,x3) Swap_Ter(y2,y3) Swap_Ter(z2,z3) End If Local dx12# = (x2 - x1) / (z2 - z1) Local dx13# = (x3 - x1) / (z3 - z1) Local dx23# = (x3 - x2) / (z3 - z2) Local ax# = x1 Local bx# = x1 Local x#, z# Local vv1# = PointDistToLine_Ter(x1, z1, x2, z2, x3, z3) Local vv2# = PointDistToLine_Ter(x2, z2, x1, z1, x3, z3) Local vv3# = PointDistToLine_Ter(x3, z3, x1, z1, x2, z2) For z = z1 To z3 If z = z2 Then ax = x2 Local s1#,s2# If ax < bx Then s1 = ax s2 = bx Else s1 = bx s2 = ax End If For x = s1 To s2 Local v1# = PointDistToLine_Ter(x, z, x2,z2,x3,z3) / vv1 Local v2# = PointDistToLine_Ter(x, z, x1,z1,x3,z3) / vv2 Local v3# = PointDistToLine_Ter(x, z, x1,z1,x2,z2) / vv3 Local h# = (v1 * y1) + (v2 * y2) + (v3 * y3) SetHeightmapPixel(x, h, z) Next If z < z2 Then ax = ax + dx12 Else ax = ax + dx23 End If bx = bx + dx13 Next End Method '--------------------------------------------------------------------------------------------------------------- ' Swap() '--------------------------------------------------------------------------------------------------------------- Method Swap_Ter(a# Var, b# Var) Local c# = a a = b b = c End Method '--------------------------------------------------------------------------------------------------------------- ' SetHeightmapPixel() '--------------------------------------------------------------------------------------------------------------- Method SetHeightMapPixel(x#,y#,z#) x# =Floor(x) z# =Floor(z) If x < 0 Then Return If z < 0 Then Return If x > 511 Then Return If z > 511 Then Return Heightmap[x, z] = y End Method Method ReadHeightMapHeight#(x#,z#) Local fx% = Floor(x) Local fz% = Floor(z) If (fx = x) And (fz = z) Then Return ReadHeightMapPixel(x, z) If (fx <> x) And (fz <> z) Then 'get integer position Local a:Int = Floor(x) Local b:Int = Floor(z) 'get fractional part (range 0..1) Local c1# = x - Floor(x) Local d1# = z - Floor(z) 'and invert it Local c2# = 1 - c1 Local d2# = 1 - d1 'get four points around position Local v00# = ReadHeightMapPixel(a + 0, b + 0) Local v10# = ReadHeightMapPixel(a + 1, b + 0) Local v01# = ReadHeightMapPixel(a + 0, b + 1) Local v11# = ReadHeightMapPixel(a + 1, b + 1) 'interpolate Local v0# = (c2 * v00) + (c1 * v10) Local v1# = (c2 * v01) + (c1 * v11) Local v# = (d2 * v0) + (d1 * v1) Return v End If If (fx <> x) Then 'get integer position Local a:Int = Floor(x) 'get fractional part (range 0..1) Local c1# = x - Floor(x) 'and invert it Local c2# = 1 - c1 'get two points around position Local v00# = ReadHeightMapPixel(a + 0, z) Local v10# = ReadHeightMapPixel(a + 1, z) 'interpolate Local v0# = (c2 * v00) + (c1 * v10) Return v0 End If If (fz <> z) Then 'get integer position Local b:Int = Floor(z) 'get fractional part (range 0..1) Local d1# = z - Floor(z) 'and invert it Local d2# = 1 - d1 'get two points around position Local v01# = ReadHeightMapPixel(x, b + 0) Local v11# = ReadHeightMapPixel(x, b + 1) 'interpolate Local v1# = (d2 * v01) + (d1 * v11) Return v1 End If End Method '--------------------------------------------------------------------------------------------------------------- ' ReadHeightmapPixel() '--------------------------------------------------------------------------------------------------------------- Method ReadHeightMapPixel#(x#,z#) x# =Floor(x) z# =Floor(z) If x < 0 Then Return 0 If z < 0 Then Return 0 If x > 511 Then Return 0 If z > 511 Then Return 0 Return Heightmap[x, z] End Method '--------------------------------------------------------------------------------------------------------------- ' PointToPointDist() '--------------------------------------------------------------------------------------------------------------- 'get distance between two points Function PointToPointDist_Ter#(x1#,y1#,x2#,y2#) Local dx# = x1-x2 Local dy# = y1-y2 Return Sqr(dx*dx + dy*dy) End Function '--------------------------------------------------------------------------------------------------------------- ' MinDistPointLine() '--------------------------------------------------------------------------------------------------------------- 'find distance point->line (thanks tomtoad) Function PointDistToLine_Ter#(px#,py#,x1#,y1#,x2#,y2#) If x1 = x2 And y1 = y2 Then Return PointToPointDist_Ter(px,py,x1,y1) Local sx# = x2-x1 Local sy# = y2-y1 Local q# = ((px-x1) * (x2-x1) + (py - y1) * (y2-y1)) / (sx*sx + sy*sy) If q < 0.0 Then q = 0.0 If q > 1.0 Then q = 1.0 Return PointToPointDist_Ter(px,py,(1-q)*x1+q*x2,(1-q)*y1 + q*y2) End Function '--------------------------------------------------------------------------------------------------------------- ' GetHeight() '--------------------------------------------------------------------------------------------------------------- Method GetHeight#(x#, z#) TFormPoint x, 0, z, Null, Self Local y# = ReadHeightmapHeight(TFormedX(), TFormedZ()) TFormPoint TFormedX(), y, TFormedZ(), Self, Null Return TFormedY() End Method End Type '--------------------------------------------------------------------------------------------------------------- ' LoadTerrain() '--------------------------------------------------------------------------------------------------------------- 'usage: ' Local terr:TTerrain = LoadTerrain("heightmap.bmp") ' ' RoamMaxHeightError = cutoff value terrain steepness ' MaxTileDepth = cutoff depth for splitting triangles ' Function LoadTerrain:TTerrain(filename$, RoamMaxHeightError#=-1, MaxTileDepth%=8) Local HmapImage:TPixmap If FileType(filename$) = 1 Then HmapImage = LoadPixmap(filename$) If HmapImage <> Null Then HmapImage = ResizePixmap(HmapImage, 512, 512) End If Local m:TTerrain = New TTerrain.Create() If HmapImage <> Null Then m.MakeTerrainMesh(HmapImage,RoamMaxHeightError,MaxTileDepth) Return m End Function '--------------------------------------------------------------------------------------------------------------- ' TerrainY() '--------------------------------------------------------------------------------------------------------------- 'usage: ' ' Print TerrainY(terr, 256, 0, 256) ' 'Terrain extends TMesh, but don't use Mesh deform commands (PositionMesh) 'Else it screws up the heightmap reading ' Function TerrainY#(t:TTerrain, x#, z#) If t = Null Then Return 0 Return t.GetHeight(x, z) End Function 'Heightmap is scaled to 512x512. I needed that for myself. Change it in LoadTerrain 'but also, change the HeightMap array size, and the array clearing routine in MakeTerrainMesh 'Not that input heightmap should be square. Not sure if it has to be a power of two ' 'The height is rescaled to a range 30. If you want to change that in MakeTerrainMesh. 'The automatic adjustment is based on that. 'So along, also change ' RoamMaxHeightError = Sqr(ee) / 264.0 ' |
Comments
| ||
Interesting discovery. Thanks. |
| ||
Very interesting (russian blitzers!??), I was just looking at terrain rendering and ROAM on wikipedia. EDIT: yikes! it uses 65k memory. |
| ||
EDIT: yikes! it uses 65k memory. Is that bad? 65k? Thats tiny! |
| ||
65k - as in 65 thousand, not kilobytes. If thats what you got before, it's still a lot to me. |
| ||
Thats not much. My engine use 200 mb only on th black and white JPG file. 5000x5000 :D |
| ||
Updated. |
Code Archives Forum