Blitz3D+ Command Reference

PhysicsRayNX# ( world )

Parameters

world - physics-world handle returned by CreatePhysicsWorld

Description

Returns the X component of the last cast hit's surface normal.

With PhysicsRayNY and PhysicsRayNZ this gives the unit normal of the surface struck by the last successful PhysicsRayCast or PhysicsSphereCast. Use it to face decals and particles away from the wall, to reflect a shot for ricochets, or to read slopes.

Valid only while a hit is stored: a miss clears the result and the getters raise a runtime error, so check the cast's returned handle first.

Requires Extended mode.

See also: PhysicsRayCast, PhysicsRayNY, PhysicsRayNZ, PhysicsRayX, PhysicsRayFraction.

Example

; PhysicsRayNX 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 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,"PhysicsRayNX(world) = "+normal_x
    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

Index