Blitz3D+ Command Reference

PhysicsSphereCast ( world,x#,y#,z#,diameter#,dx#,dy#,dz# )

Parameters

world - physics-world handle returned by CreatePhysicsWorld

x# - sweep start position (sphere centre), world X

y# - sweep start position, world Y

z# - sweep start position, world Z

diameter# - diameter of the swept sphere in metres; must be positive

dx# - translation of the sweep, world X; the translation must not be zero length

dy# - translation, world Y

dz# - translation, world Z

Description

Sweeps a sphere through the world and returns the closest shape it hits, or 0.

A sphere cast is a ray with thickness. Where a thin ray slips through railings or clips past a ledge by a whisker, a swept sphere catches everything a real object of that size would - which is why it suits sized projectiles, grenade paths and ground checks that should not fall through grates.

Results land in the same place as PhysicsRayCast results: PhysicsRayX/Y/Z, PhysicsRayNX/NY/NZ and PhysicsRayFraction describe the closest hit, and the fraction measures how far the sphere's centre travelled along the translation. The stored result lasts until the next cast in the same world; a miss clears it, so check the returned handle before calling the getters.

Requires Extended mode.

See also: PhysicsRayCast, PhysicsRayX, PhysicsRayNX, PhysicsRayFraction, PhysicsMoveCharacter.

Example

; PhysicsSphereCast Example
; -------------------------
; Requires Extended mode.

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

Const PHYSICS_STATIC=0

camera=CreateCamera()
PositionEntity camera,0,7,-8
RotateEntity camera,30,0,0

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

world=CreatePhysicsWorld()

; A ring of static pillars for the swept sphere to hit
For i=1 To 5
    pillar=CreateCylinder()
    ScaleEntity pillar,0.5,1.5,0.5
    PositionEntity pillar,Cos(i*72)*(2.5+i*0.5),1.5,Sin(i*72)*(2.5+i*0.5),True
    EntityColor pillar,80,160,255
    pillar_body=CreatePhysicsBody(world,pillar,PHYSICS_STATIC)
    pillar_shape=PhysicsBodyCapsule(pillar_body,1,3,0)
Next

; The cast emitter at the centre of the scene
emitter=CreateSphere(8)
ScaleEntity emitter,0.3,0.3,0.3
PositionEntity emitter,0,1,0,True
EntityColor emitter,255,255,255

; A thin cylinder visualises the sweep direction
beam=CreateCylinder(8)
EntityColor beam,255,120,70

; Translucent probe sphere shows where the swept sphere stopped
probe=CreateSphere(16)
EntityColor probe,255,180,80
EntityAlpha probe,0.4

; Red marker for the exact hit point
marker=CreateSphere(8)
ScaleEntity marker,0.15,0.15,0.15
EntityColor marker,255,60,60
HideEntity marker

angle#=0
ray_len#=9
diameter#=1

While Not KeyDown(1)

    ; A / D keys sweep the cast; [ and ] change the sphere diameter
    If KeyDown(30) Then angle=angle-1.5
    If KeyDown(32) Then angle=angle+1.5
    If KeyDown(26) And diameter>0.2 Then diameter=diameter-0.02
    If KeyDown(27) And diameter<3 Then diameter=diameter+0.02
    dx#=Cos(angle)*ray_len
    dz#=Sin(angle)*ray_len

    ; Sweep the sphere through the world and read the hit data back
    hit_shape=PhysicsSphereCast(world,0,1,0,diameter,dx,0,dz)
    If hit_shape<>0
        hit_x#=PhysicsRayX(world)
        hit_y#=PhysicsRayY(world)
        hit_z#=PhysicsRayZ(world)
        fraction#=PhysicsRayFraction(world)
        beam_len#=fraction*ray_len
        PositionEntity marker,hit_x,hit_y,hit_z,True
        ShowEntity marker
    Else
        beam_len=ray_len
        HideEntity marker
    EndIf

    ; Stretch the beam and park the probe sphere at the stop position
    ScaleEntity beam,0.05,beam_len/2,0.05
    AlignToVector beam,dx,0,dz,2
    PositionEntity beam,Cos(angle)*beam_len/2,1,Sin(angle)*beam_len/2,True
    ScaleEntity probe,diameter/2,diameter/2,diameter/2
    PositionEntity probe,Cos(angle)*beam_len,1,Sin(angle)*beam_len,True

    ; 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,"A / D: sweep   [ / ]: diameter   Arrow keys: camera   Esc: exit"
    Text 0,20,"PhysicsSphereCast(world,0,1,0,"+diameter+","+dx+",0,"+dz+") = "+hit_shape
    Text 0,40,"Hit point: "+hit_x+", "+hit_y+", "+hit_z+"   Fraction: "+fraction

    Flip

Wend

FreePhysicsWorld world
End

Index