Blitz3D+ Command Reference

MeshCullBox mesh,x#,y#,z#,width#,height#,depth#

Parameters

mesh - handle of the mesh

x#,y#,z# - corner of the cull box, in the mesh's own local coordinates

width#,height#,depth# - size of the box out from that corner

Description

Sets the box a mesh is tested against when the renderer decides whether it is on screen.

Before drawing anything, the engine works out a bounding box for each mesh from its vertex positions and checks that box against the camera's view frustum. If the box is completely outside, the mesh is skipped. MeshCullBox lets you replace that automatic box with one of your own - like EntityBox, it is a corner plus a size, so the box runs from (x,y,z) to (x+width, y+height, z+depth).

You need this whenever the vertices end up somewhere the static box does not cover. A flag mesh whose vertices are pushed around every frame, a character whose skinning swings limbs out well past the rest pose, a particle sheet a shader expands - all of them can pop out of view while they are still clearly on screen, because the box the engine measured no longer matches what gets drawn. Give the mesh a generous cull box and the popping stops.

It works the other way too. Making the box deliberately smaller than the mesh culls it earlier, which is handy for background scenery you would rather drop as soon as it is mostly off screen. The same box is used for the distance test behind EntityCullRange and mesh LOD levels, so a tighter box also changes when a mesh swaps detail level.

The coordinates are in the mesh's own space, before any ScaleEntity, RotateEntity or PositionEntity - so a box you set once stays correct as the entity moves around the level. Get it wrong in the small direction and the effect is unmistakable: the mesh vanishes in one frame while a good part of it is still in front of you.

To go back to the automatic vertex bounding box, pass a negative size (for example MeshCullBox mesh,0,0,0,-1,-1,-1). The engine treats a box whose far corner is behind its near corner as empty and falls back to measuring the vertices again. A zero size is not the same thing - that is a legal box one point across, and the mesh will be culled almost everywhere.

See also: EntityCullRange, EntityBox, EntityInView, TrisRendered, AddEntityLOD.

Example

; MeshCullBox Example
; -------------------

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

camera=CreateCamera()
PositionEntity camera,0,2,-12

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

; A long fence welded into ONE mesh, 40 units wide but centred on the origin
fence=CreateMesh()
For i=0 To 20
    post=CreateCube()
    ScaleMesh post,0.4,1.5,0.4
    PositionMesh post,i*2-20,0,0
    AddMesh post,fence
    FreeEntity post
Next

; Half-size of the box the renderer tests against the view frustum
half#=20.0

While Not KeyDown(1)

    ; [ and ] shrink and grow the cull box
    If KeyDown(26) And half>0.5 Then half=half-0.2
    If KeyDown(27) And half<20 Then half=half+0.2

    ; Corner plus width/height/depth, in the mesh's own local space
    MeshCullBox fence,-half,-half,-half,half*2,half*2,half*2

    ; The fence drifts across the view all by itself
    PositionEntity fence,Sin(MilliSecs()/20.0)*22,0,0

    ; 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,"[ / ]: resize the cull box   Arrows: camera   Esc: exit"
    Text 0,20,"MeshCullBox fence,"+(-half)+","+(-half)+","+(-half)+","+(half*2)+","+(half*2)+","+(half*2)
    Text 0,40,"TrisRendered() = "+TrisRendered()+"   (0 means the fence was culled away)"
    Text 0,60,"Shrink the box and the fence pops out while it is still on screen"

    Flip

Wend

End

Index