Blitz3D+ Command Reference

MovePhysicsCharacter# ( query,entity,diameter#,height#,dx#,dy#,dz# )

Parameters

query - owned query handle from CreatePhysicsQuery

entity - ordinary entity at the capsule centre, without a physics body

diameter# - positive capsule diameter in world metres

height# - full capsule height, including caps, at least diameter

dx# - requested world X displacement in metres
dy# - requested world Y displacement in metres
dz# - requested world Z displacement in metres

Description

Moves an entity as an upright capsule character that slides along what it hits.

Moves an ordinary entity using an upright world-Y capsule and returns the native cast fraction, from 0 to 1, of the displacement produced by the plane solver. Dimensions are in world metres; height includes both rounded caps. The entity origin is the capsule centre. Entity rotation and scale do not change these dimensions. World-space movement works with parented entities. The entity must not own an explicit Physics body or a hidden classic collision body.

Pending EntityPhysics enrollment or modern Collisions participation also prevents using the entity as a character mover, even before its native body exists. Parented movement requires a finite invertible parent transform and a representable final local position. Conversion failure preserves both the entity position and the previous query result.

Character results have PhysicsQueryKind 9. CountPhysicsQueryHits counts copied starting-pose planes, including multiple planes from the same shape. Each hit supplies live body/shape/entity identity, copied tags, a world-space surface point and an outward world normal. It supplies no hit fraction, material, triangle or child metadata. The final cast returns only a movement fraction: it may stop against a new shape absent from the starting planes. Inspect the final pose separately when support classification is needed.

PhysicsQueryFilter and PhysicsQueryTarget apply to both plane gathering and the movement cast. Sensors are excluded by default and disabled bodies are excluded. Planes use deterministic wrapper-shape/geometry ordering. PhysicsQueryLimit defaults to 1024 and can be set up to 65536; all retained and temporary query buffers share a 64 MiB runtime budget. A single native shape producing a full 64-plane batch is conservatively rejected because Box3D may have truncated it. Errors retain the entity position and the entire previous query result.

Results remain available after stepping or entity/body deletion until this query runs successfully again or is freed. Deleted body/shape/entity identities read as zero; copied numerical data and tags remain. Freeing the owning world frees its queries. Getters and clipping require a character result; indices are one-based.

The mover does not simulate a dynamic body, apply gravity, push other bodies, choose a slope limit, climb steps or snap to the ground. Deep overlaps whose capsule centre segment intersects geometry have no useful native plane result; start in a valid pose and use bounded movement. Replay validation covers recorded native operations; wrapper-only entity movement and application support/jump state are not restored by physics replay.

Requires Extended mode.

See also: CreatePhysicsQuery, QueryPhysicsCharacter, ClipPhysicsCharacterVelocity, PhysicsQueryPlaneOffset, PhysicsQueryPlanePush, PhysicsQueryFilter.

Example

; MovePhysicsCharacter Example
; ----------------------------
; Requires Extended mode.

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

Const PHYSICS_STATIC=0
Const PHYSICS_DYNAMIC=2

camera=CreateCamera()
PositionEntity camera,0,5,-10
RotateEntity camera,25,0,0

light=CreateLight()
RotateEntity light,45,-30,0
AmbientLight 60,60,60

; An independent Box3D world with standard gravity
world=CreatePhysicsWorld()

; Blue static floor
ground=CreateCube()
ScaleEntity ground,6,0.5,6
PositionEntity ground,0,-0.5,0
EntityColor ground,80,160,255
ground_body=CreatePhysicsBody(world,ground,PHYSICS_STATIC)
ground_shape=PhysicsBodyBox(ground_body,12,1,12)

; Scenery: a wall, a low step and a ramp
wall=CreateCube()
ScaleEntity wall,0.2,1,2
PositionEntity wall,3,1,0
wall_body=CreatePhysicsBody(world,wall,PHYSICS_STATIC)
wall_shape=PhysicsBodyBox(wall_body,0.4,2,4)
stair=CreateCube()
ScaleEntity stair,1,0.15,1
PositionEntity stair,-2,0.15,2
stair_body=CreatePhysicsBody(world,stair,PHYSICS_STATIC)
stair_shape=PhysicsBodyBox(stair_body,2,0.3,2)
ramp=CreateCube()
ScaleEntity ramp,1.5,0.1,1
RotateEntity ramp,0,0,20
PositionEntity ramp,-2,0.4,-2
ramp_body=CreatePhysicsBody(world,ramp,PHYSICS_STATIC)
ramp_shape=PhysicsBodyBox(ramp_body,3,0.2,2)

; The character is an ordinary entity moved by capsule queries, not a body
character=CreateCylinder(12)
ScaleEntity character,0.3,0.9,0.3
PositionEntity character,0,1,0
EntityColor character,255,230,60
query=CreatePhysicsQuery(world)
vy#=0

While Not KeyDown(1)

    ; A / D / W / S walk, Space jumps when standing on something
    vx#=(KeyDown(32)-KeyDown(30))*3
    vz#=(KeyDown(17)-KeyDown(31))*3
    If KeyHit(57) And Abs(vy)<0.01 Then vy=5
    vy=vy-10.0/60.0

    ; Move a 0.6 m wide, 1.8 m tall capsule; it slides along what it hits
    fraction#=MovePhysicsCharacter(query,character,0.6,1.8,vx/60,vy/60,vz/60)

    ; Remove the part of the velocity that pushes into what it hit,
    ; so landing stops the fall and walls stop the walk
    ClipPhysicsCharacterVelocity query,vx,vy,vz
    vy=PhysicsQueryMoveVelocityY(query)

    StepPhysics world,1.0/60.0,4

    ; 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   A / D / W / S: walk   Space: jump   Esc: exit"
    Text 0,20,"MovePhysicsCharacter(query,character,0.6,1.8,...) = "+fraction
    Text 0,40,"(the fraction of the move completed; walk into the wall to see it drop)"

    Flip

Wend

FreePhysicsWorld world
End

Index