|
world - physics-world handle returned by CreatePhysicsWorld x# - ray start position, world X y# - ray start position, world Y z# - ray start position, world Z dx# - translation to the ray end, world X; the translation must not be zero length dy# - translation, world Y dz# - translation, world Z |
|
Casts a ray and returns the closest shape it hits, or 0 for none. The physics answer to "what is over there?": line-of-sight checks, hitscan weapons, ground probes under a character, lasers and tripwires. The ray is a segment, not an infinite line - it runs from the start position along the translation and stops, so make dx,dy,dz long enough to reach. On a hit, the world stores the details for its getter family: PhysicsRayX/Y/Z give the hit point, PhysicsRayNX/NY/NZ the surface normal, and PhysicsRayFraction how far along the ray it happened. The stored result lasts until the next PhysicsRayCast or PhysicsSphereCast in the same world. On a miss the stored result is cleared - check the returned handle before calling the getters, or they raise a runtime error. See also: PhysicsSphereCast, PhysicsRayX, PhysicsRayNX, PhysicsRayFraction, LinePick. |
; PhysicsRayCast Example
; ----------------------
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 ray 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 ray 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 ray itself
beam=CreateCylinder(8)
EntityColor beam,255,120,70
; Red marker for the 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
While Not KeyDown(1)
; A / D keys sweep the ray around the emitter
If KeyDown(30) Then angle=angle-1.5
If KeyDown(32) Then angle=angle+1.5
dx#=Cos(angle)*ray_len
dz#=Sin(angle)*ray_len
; Cast the ray and read the hit data back
hit_shape=PhysicsRayCast(world,0,1,0,dx,0,dz)
If hit_shape<>0
hit_x#=PhysicsRayX(world)
hit_y#=PhysicsRayY(world)
hit_z#=PhysicsRayZ(world)
normal_x#=PhysicsRayNX(world)
normal_y#=PhysicsRayNY(world)
normal_z#=PhysicsRayNZ(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 cylinder from the emitter towards the hit
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
; 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 the ray Arrow keys: move camera Esc: exit"
Text 0,20,"PhysicsRayCast(world,0,1,0,"+dx+",0,"+dz+") = "+hit_shape
Text 0,40,"Hit point: "+hit_x+", "+hit_y+", "+hit_z
Text 0,60,"Normal: "+normal_x+", "+normal_y+", "+normal_z+" Fraction: "+fraction
Flip
Wend
FreePhysicsWorld world
End