Blitz3D+ Command Reference

CreateTerrain ( grid_size[,parent] )

Parameters

grid_size - number of grid squares along each side of the terrain; must be a power of two, e.g. 8, 16, 32, 64, 128, 256, 512, 1024

parent (optional) - parent entity of the terrain

Description

Creates an empty terrain and returns its handle.

A terrain is a landscape entity built from a height field rather than from triangles you supply. You get a grid of grid_size by grid_size squares that all start perfectly flat, and you raise and lower it afterwards with ModifyTerrain. If you would rather start from a picture of your landscape, use LoadTerrain instead - the two commands produce exactly the same kind of entity.

Before you scale it, the terrain runs from 0,0,0 to grid_size,1,grid_size: one world unit per grid square, and exactly one unit from the lowest possible ground to the highest. That is deliberately tiny for a landscape, so the usual next step is ScaleEntity to stretch it out - something like ScaleEntity terrain,8,40,8 gives you 8 units per square and 40 units of height range.

The point of a terrain entity is level of detail. It quietly rebuilds itself every frame so that ground near the camera is drawn in fine detail and distant ground is drawn coarsely, which lets a landscape that would be millions of triangles at full resolution render in a few thousand. TerrainDetail sets that triangle budget, and switching on its vertex morphing hides most of the 'popping' you would otherwise see as detail shifts around.

grid_size really must be a power of two. Any other value stops the program with an "Illegal terrain size" runtime error, so build it from a constant or a shift rather than from a number the player can influence. Bigger grids cost memory whether you use the detail or not, so 128 or 256 is plenty for most games; 1024 is a large open world.

One thing that catches people sculpting a fresh terrain: the height field wraps. Grid index grid_size is the same storage as index 0, so a loop written For x=0 To grid_size writes its last column straight over its first. Loop to grid_size-1 unless you actually want that. Coordinates outside 0 to grid_size are ignored entirely rather than reported.

The optional parent parameter attaches the terrain to another entity so that moving the parent moves the terrain with it. The relationship is one way - moving the terrain does not move the parent. The terrain is created at local position 0,0,0, which means it starts sitting on top of the parent rather than at the world origin.

Terrains take part in collisions like any other entity, so a Collisions rule using method 2 will let a player walk over the landscape. For flying cameras and cheap ground-following, TerrainY is usually faster and simpler.

See also: LoadTerrain, ModifyTerrain, TerrainDetail, TerrainShading, TerrainSize, TerrainY.

Example

; CreateTerrain Example
; ---------------------

Graphics3D 640,480,0,2
SetBuffer BackBuffer()

camera=CreateCamera()
CameraRange camera,1,500

light=CreateLight()
RotateEntity light,45,45,0

; CreateTerrain builds a flat LOD terrain with 64 grid squares per side
terrain=CreateTerrain(64)

; Stretch it into a landscape: 8 units per grid square, 40 units tall
ScaleEntity terrain,8,40,8

; Sculpt some rolling hills into the flat grid (heights range 0 to 1)
; Grid points run 0 to size-1; index 64 would wrap around onto index 0
For gx=0 To 63
    For gz=0 To 63
        ModifyTerrain terrain,gx,gz,(Sin(gx*22)+Cos(gz*17)+2)*0.15
    Next
Next

; Texture the landscape
grass_tex=LoadTexture("media/MossyGround.BMP")
EntityTexture terrain,grass_tex

; Start in the middle of the terrain
PositionEntity camera,256,30,256

While Not KeyDown(1)

    ; Drift forward on its own; arrow keys steer and speed up
    MoveEntity camera,0,0,0.2
    If KeyDown(200) Then MoveEntity camera,0,0,1
    If KeyDown(208) Then MoveEntity camera,0,0,-1
    If KeyDown(203) Then TurnEntity camera,0,1,0
    If KeyDown(205) Then TurnEntity camera,0,-1,0

    ; Glide at a fixed height above the ground
    x#=EntityX(camera)
    z#=EntityZ(camera)
    y#=TerrainY(terrain,x,EntityY(camera),z)+8
    PositionEntity camera,x,y,z

    RenderWorld

    Text 0,0,"Arrows: fly over the terrain   Esc: exit"
    Text 0,20,"CreateTerrain(64) made this landscape - no height map file needed"

    Flip

Wend

End

Index