PhysicsDebugDraw world,camera[,flags]
Parameters
world - live physics-world handle.
camera - live camera entity used to project the overlay.
flags - combined bits from the table below; default 7 retains joints, contacts and bounds. Zero draws nothing. Negative values and unknown bits cause a runtime error.
| Bit | Layer |
|---|---|
| 1 | Native joint geometry, with available limits and extra geometry. |
| 2 | Contact crosses, normals and signed separation labels in centimetres. |
| 4 | Native fat shape AABBs, including broad-phase margin; not exact body bounds. |
| 8 | Collider wire geometry: sphere circles, capsule rings/arcs, hull edges and solid mesh/terrain triangle edges. |
| 16 | Dynamic-body centre-of-mass axes and mass labels in kilograms. |
| 32 | Both joint attachment frames, including joints with shapeless or disabled bodies. |
| 64 | Approximate native normal-force arrows and labels. |
| 128 | Independent approximate native friction-force arrows and magnitude labels. |
| 256 | Native hexadecimal contact feature labels; these are not Blitz handles. |
| 512 | Native island bounds. |
| 1024 | Contact crosses coloured by solver graph assignment. |
| 4096 | Managed scene colliders, movement roles and body identities. Requires the shared world returned by GetWorldPhysics. |
Description
Draws a world's diagnostics through renderer-owned 2D lines and text. Call after RenderWorld and before Flip. Add distinct flags or combine with Or; for example 24 shows collider geometry, centres of mass and mass labels. Default 7 does not include the new layers.
The overlay is not depth-tested. It respects camera viewport offsets, near/far clipping, perspective or orthographic projection, current 2D Viewport and buffer bounds. It ignores the current Origin while aligning to the camera, then restores Origin and Viewport and leaves Color white. A camera with projection mode 0 draws nothing. Text uses the current font; crowded or combined labels can overlap.
Shape, COM and island selection uses enabled native shape proxies. Sleeping enabled shapes remain visible; disabled shapes do not. Contact layers show awake solver pairs, including speculative contacts, rather than sensor overlaps or retained event history. Native joint geometry requires at least one participating body selected through a shape proxy. Flag 32 separately visits all public joints. Frame axes are red X, green Y and blue Z, each 0.3 metres long.
Force arrows are native solver estimates, not calibrated physical reaction-force measurements. The display uses half the stored impulse times the last step's inverse timestep. Normal estimates use totalNormalImpulse, which includes repeated bias/relaxation solver passes; friction uses the manifold friction impulse. Arrow length is 0.05 metres per displayed estimate unit. Do not treat changes between substep settings as physical force changes. Use the documented joint reaction getters for joint loads.
Drawing neither steps nor wakes bodies, consumes no events and records no mutations. Geometry replacement updates the next draw without another step. Sphere/capsule curves are sampled wire outlines; hull edges and mesh/terrain solid triangle edges use native cooked geometry, scale and transforms. Terrain holes are omitted.
For entity physics, keep the handle from GetWorldPhysics and use PhysicsDebugDraw world,camera,4096 after RenderWorld. This optional layer draws committed canonical geometry in the body's role colour: grey for static, blue for kinematic, green for free dynamic and purple for Collisions-controlled. Compatibility geometry uses short orange segments, leaving canonical edges visible when the shapes coincide. Each label shows the same body handle returned by EntityPhysicsBody, its movement role, and C/K counts for canonical/compatibility colliders. Counts describe actual colliders; they do not imply additional bodies or mass.
Layer 4096 includes sleeping enabled bodies and omits disabled bodies. It replaces layer 8 when both are selected; other diagnostic layers can be combined normally. It reads committed native geometry without applying pending entity edits, cooking colliders or stepping. Use UpdateWorld to apply edits, or GetWorldPhysics to explicitly reconcile without stepping. A previously obtained world handle can inspect the retained scene after a rejected edit. The layer is unavailable for standalone physics worlds or replay players. Bit 2048 remains unsupported by this command; PhysicsPlayerDebugDraw uses it for replayed queries.
Each world retains at most 262,144 lines and 8,192 labels (127 bytes per label). Exceeding either bound raises a runtime error before any primitives from that capture are drawn. Storage is reused until world teardown. Large scenes and many labels can be expensive; enable only the layers needed.
Optional native logging: set environment variable B3D_BOX3D_LOG to 1, including with SetEnv. Native messages then enter the existing bounded diagnostics store at Information level, category physics, source Box3D. Unset or other values preserve console logging. Ordinary steps may emit no messages. This is process-wide, thread-safe diagnostic routing; native workers never call Blitz functions. Native assertions retain their existing handler and fail-fast behaviour.
Requires Extended mode.
See also: StepPhysics, PhysicsBodyCenterX, PhysicsJointForceX, CapturePhysicsProfile, CountDiagnostics, DiagnosticMessage, ClearDiagnostics.
Example
; Native physics overlays. Requires Extended mode. Graphics3D 1120,820,0,2 SetBuffer BackBuffer() AppTitle "Blitz3D+ - physics debug layers" Global world=CreatePhysicsWorld(),flags=8,overlay=True,paused=False,show_meshes=True,ortho=False Global ball=CreateSphere(20),ball_body,ball_shape,ball_size#=1 Global block=CreateCube(),block_body,hinge,enabled=True Dim layer_bits(11): Dim layer_keys(11): Dim layer_names$(11) For i=1 To 11: layer_bits(i)=1 Shl (i-1): layer_keys(i)=i+1: Next layer_keys(11)=34 layer_names(1)="1 Joint geometry / limits" layer_names(2)="2 Contact points / normals" layer_names(3)="3 Fat shape bounds" layer_names(4)="4 Collider wire geometry" layer_names(5)="5 Dynamic COM / mass" layer_names(6)="6 Joint attachment frames" layer_names(7)="7 Approx. normal forces" layer_names(8)="8 Approx. friction forces" layer_names(9)="9 Contact feature labels" layer_names(10)="0 Island bounds" layer_names(11)="G Solver graph colours" camera=CreateCamera(): CameraViewport camera,340,130,760,660 CameraClsColor camera,16,23,36: PositionEntity camera,13,13,-20: CameraZoom camera,2.8 target=CreatePivot(): PositionEntity target,0,1,0: PointEntity camera,target light=CreateLight(): RotateEntity light,45,-30,0: AmbientLight 110,120,140 floor=CreateCube(): ScaleEntity floor,5,.25,4: PositionEntity floor,0,-.25,0: EntityColor floor,45,55,70 floor_body=CreatePhysicsBody(world,floor,0): fs=PhysicsBodyBox(floor_body,10,.5,8) ScaleEntity ball,.5,.5,.5: EntityColor ball,240,155,65 ball_body=CreatePhysicsBody(world,ball,2): ball_shape=PhysicsBodySphere(ball_body,1): PhysicsShapeRestitution ball_shape,.5 PhysicsBodySleeping ball_body,False: PhysicsBodyDamping ball_body,.3,.2 ScaleEntity block,1,.3,.6: EntityColor block,70,175,235 block_body=CreatePhysicsBody(world,block,2): bs=PhysicsBodyBox(block_body,2,.6,1.2) ; A shaped fixed anchor keeps native joint geometry visible. anchor=CreatePivot(): PositionEntity anchor,1,2,0 anchor_body=CreatePhysicsBody(world,anchor,0): aps=PhysicsBodySphere(anchor_body,.15,0) ResetPhysicsBody block_body,2,2,0,0,0,0 hinge=CreatePhysicsHingeJoint(anchor_body,block_body,1,2,0,0,0,1) PhysicsJointLimits hinge,True,-.7,.7 PhysicsJointMotor hinge,True,1.2,20 capsule=CreatePivot(): PositionEntity capsule,-3,1.25,2 cap_body=CreatePhysicsBody(world,capsule,0): cs=PhysicsBodyCapsule(cap_body,1,2.5) cap_mid=CreateCylinder(20,True,capsule): ScaleEntity cap_mid,.5,.75,.5: EntityColor cap_mid,100,210,150 For side=-1 To 1 Step 2 cap_end=CreateSphere(16,capsule): ScaleEntity cap_end,.5,.5,.5: PositionEntity cap_end,0,.75*side,0: EntityColor cap_end,100,210,150 Next ; A cooked hull and a triangle ramp expose their actual edges. hull=CreateCone(8): ScaleEntity hull,.8,1,.8: PositionEntity hull,3,1,2: EntityColor hull,180,120,225 hull_body=CreatePhysicsBody(world,hull,0): hs=PhysicsBodyHull(hull_body,hull) ramp=CreateMesh(): surf=CreateSurface(ramp) AddVertex surf,-1,0,-1: AddVertex surf,1,0,-1: AddVertex surf,1,.8,1: AddVertex surf,-1,.8,1 AddTriangle surf,0,2,1: AddTriangle surf,0,3,2: UpdateNormals ramp PositionEntity ramp,-1,0,2: EntityColor ramp,200,190,100: EntityFX ramp,16 ramp_body=CreatePhysicsBody(world,ramp,0): rs=PhysicsBodyMesh(ramp_body,ramp) ResetDebugLoads() timer=CreateTimer(60) While Not KeyDown(1) For i=1 To 11 If KeyHit(layer_keys(i)) Then flags=flags Xor layer_bits(i) Next If KeyHit(57) Then overlay=Not overlay If KeyHit(25) Then paused=Not paused If KeyHit(50) show_meshes=Not show_meshes If show_meshes ShowEntity ball: ShowEntity block: ShowEntity capsule: ShowEntity hull: ShowEntity ramp: ShowEntity floor Else HideEntity ball: HideEntity block: HideEntity capsule: HideEntity hull: HideEntity ramp: HideEntity floor EndIf EndIf If KeyHit(24) ortho=Not ortho If ortho Then CameraProjMode camera,2: CameraZoom camera,.09 Else CameraProjMode camera,1: CameraZoom camera,2.8 EndIf If KeyHit(18) Then enabled=Not enabled: PhysicsBodyActive ball_body,enabled If KeyHit(44) ball_size=2.5-ball_size PhysicsShapeSphere ball_shape,ball_size,0,0,0 ScaleEntity ball,ball_size/2,ball_size/2,ball_size/2 EndIf If KeyHit(19) Then ResetDebugLoads() ticks=WaitTimer(timer): If ticks>6 Then ticks=6 If paused=False For tick=1 To ticks If enabled Then PhysicsBodyForce ball_body,.5,0,0 StepPhysics world,1.0/60,4 Next If EntityY(ball)<-4 Then ResetPhysicsBody ball_body,-2,4,-1,0,0,0 EndIf RenderWorld If overlay Then PhysicsDebugDraw world,camera,flags Color 235,240,250 Text 18,18,"PHYSICS DEBUG LAYERS" Text 18,49,"Native collider geometry, contacts and constraints" Text 18,82,"Space: overlay P: pause M: meshes O: projection E: enable ball Z: resize ball R: reset Esc: exit" For i=1 To 11 Color 115,130,150: state$="off" If flags And layer_bits(i) Then Color 115,230,170: state="ON" Text 18,146+(i-1)*29,layer_names(i) Text 298,146+(i-1)*29,state Next Color 235,240,250 Text 18,488,"Flags: "+flags+" Overlay: "+overlay Text 18,514,"Paused: "+paused+" Meshes: "+show_meshes Text 18,540,"Ortho: "+ortho+" Ball active: "+PhysicsBodyIsEnabled(ball_body) Text 18,566,"Ball diameter: "+ball_size+" m" Text 18,610,"Frames: red X / green Y / blue Z" Text 18,636,"Mass labels: kilograms" Text 18,662,"Forces: native diagnostic estimates" Text 18,688,"Contact layers show awake pairs." Text 18,714,"Combine layers; crowded labels overlap." Text 18,750,"M hides meshes so wire edges stand out." Text 18,776,"R resets poses; layer choices stay set." Flip Wend FreeTimer timer FreePhysicsWorld world ClearWorld End Function ResetDebugLoads() ResetPhysicsBody ball_body,-2,4,-1,0,0,0 ResetPhysicsBody block_body,2,2,0,0,0,0 PhysicsBodyAwake block_body,True End Function
Index