BeginTerrainUpdate terrain
Parameters
| terrain - terrain entity you are about to edit |
Description
|
Starts a batch of terrain edits so the derived data is rebuilt only once. Outside a batch, every ModifyTerrain and ModifyTerrainHole commits its own rebuild of the chunks it touched, along with their normals and bounds. For one crater that is fine. For the hundreds or thousands of samples a script changes in a single frame - a river carved along a path, a landslide sliding down a hillside, an editor brush dragged across the map, a rippling patch animated every frame - doing that work per call is the difference between a smooth frame and a stutter. So wrap the edits. Call BeginTerrainUpdate, make all your changes, then call EndTerrainUpdate. Everything in between grows one dirty rectangle instead of committing separately, and closing the batch rebuilds only the chunks that rectangle covers plus the neighbours that need the changed border to recalculate their normals. Both height edits and hole edits take part. Inside a batch, ModifyTerrain's realtime argument is ignored - EndTerrainUpdate commits either way, so you can leave it out of batched code entirely. Gotcha: batches do not nest. Opening a second one raises "Terrain update is already active", so a helper function that edits terrain should not open its own batch when a caller might already have one open - pick one level to own the batch. If you render the terrain with a batch still open the engine finalises it for you and writes a warning to the debug log, and freeing the terrain discards an unfinished batch safely, but neither is something to rely on. Box3D collision does not follow terrain edits by itself. If a physics height field has to match the new shape, call RefreshPhysicsTerrain once after the batch closes. See also: EndTerrainUpdate, ModifyTerrain, ModifyTerrainHole, TerrainRebuiltChunks, RefreshPhysicsTerrain. |
Example
; BeginTerrainUpdate Example ; -------------------------- Graphics3D 640,480,0,2 SetBuffer BackBuffer() camera=CreateCamera() PositionEntity camera,0,6,-40 CameraClsColor camera,110,150,200 light=CreateLight(1) RotateEntity light,50,-30,0 ; Rolling hills built from a sine-wave height field terrain=CreateTerrain(128) For z=0 To 127 For x=0 To 127 ModifyTerrain terrain,x,z,0.2+Sin(x*10)*Cos(z*10)*0.12 Next Next ScaleEntity terrain,0.5,20,0.5 PositionEntity terrain,-32,-5,-32 TerrainShading terrain,True TerrainDetail terrain,8000,True ; Plain grass texture drawn in code grass=CreateTexture(8,8,1+8) SetBuffer TextureBuffer(grass) : ClsColor 75,135,60 : Cls : SetBuffer BackBuffer() EntityTexture terrain,grass phase#=0 While Not KeyDown(1) ; Animate a rippling patch: 1024 edits collected into ONE batch, ; so the derived chunk data is rebuilt once per frame, not per call phase=phase+5 BeginTerrainUpdate terrain For z=48 To 79 For x=48 To 79 ripple#=Sin((x-48)*5.8)*Sin((z-48)*5.8)*Sin((x+z)*12+phase)*0.05 ModifyTerrain terrain,x,z,0.2+Sin(x*10)*Cos(z*10)*0.12+ripple Next Next EndTerrainUpdate terrain ; Arrow keys move the camera If KeyDown(200) Then MoveEntity camera,0,0,0.1 If KeyDown(208) Then MoveEntity camera,0,0,-0.1 If KeyDown(203) Then TurnEntity camera,0,1,0 If KeyDown(205) Then TurnEntity camera,0,-1,0 RenderWorld Text 0,0,"Arrow keys: move camera Esc: exit" Text 0,20,"BeginTerrainUpdate batches 1024 ModifyTerrain calls per frame" Text 0,40,"Chunks rebuilt this frame: "+TerrainRebuiltChunks(terrain) Flip Wend End
Index