; PhysicsQueryTriangle Example
; ----------------------------

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

Const PHYSICS_STATIC=0
Const PHYSICS_DYNAMIC=2

camera=CreateCamera()
PositionEntity camera,0,3,-7
RotateEntity camera,20,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)

; A static mesh ramp made of 8 strips, each strip two triangles
ramp=CreateMesh()
surface=CreateSurface(ramp)
For strip=0 To 7
    x#=strip-4
    AddVertex surface,x,1.6-strip*0.2,-1.5
    AddVertex surface,x,1.6-strip*0.2,1.5
    AddVertex surface,x+1,1.4-strip*0.2,-1.5
    AddVertex surface,x+1,1.4-strip*0.2,1.5
    AddTriangle surface,strip*4,strip*4+1,strip*4+3
    AddTriangle surface,strip*4,strip*4+3,strip*4+2
Next
UpdateNormals ramp
EntityFX ramp,2
ramp_body=CreatePhysicsBody(world,ramp,PHYSICS_STATIC)
ramp_shape=PhysicsBodyMesh(ramp_body,ramp)

; Slot 2 of the ramp's material table is ice, with no friction
PhysicsShapeMaterials ramp_shape,2
PhysicsShapeMaterialFriction ramp_shape,2,0

; A yellow probe you move along the ramp with A and D
probe=CreateSphere(8)
ScaleEntity probe,0.15,0.15,0.15
EntityColor probe,255,230,60
PositionEntity probe,0,3,-1
query=CreatePhysicsQuery(world)

; Crates resting on the grippy ramp
Dim crate_bodies(3)
For i=0 To 3
    crate=CreateCube()
    ScaleEntity crate,0.3,0.3,0.3
    EntityColor crate,255,120,70
    crate_bodies(i)=CreatePhysicsBody(world,crate,PHYSICS_DYNAMIC)
    crate_shape=PhysicsBodyBox(crate_bodies(i),0.6,0.6,0.6)
    ResetPhysicsBody crate_bodies(i),-3.5+i*2,2-i*0.4,0,0,0,-0.2
Next
PaintStrips(ramp,painted)

While Not KeyDown(1)

    ; Space paints the next strip as ice, so the crates slide
    If KeyHit(57) And painted<8
        PhysicsMeshTriangleMaterial ramp_shape,painted*2,2,2
        painted=painted+1
        PaintStrips(ramp,painted)
    EndIf

    ; A and D move the probe, and a ray looks straight down from it
    If KeyDown(30) Then MoveEntity probe,-0.05,0,0
    If KeyDown(32) Then MoveEntity probe,0.05,0,0
    StepPhysics world,1.0/60.0,4

    hits=QueryPhysicsRay(query,EntityX(probe),3,EntityZ(probe),0,-4,0)

    ; 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   Space: paint ice   A / D: move the probe   Esc: exit"
    If hits>0 Then Text 0,20,"PhysicsQueryTriangle(query,1) = "+PhysicsQueryTriangle(query,1)+"   (strip "+PhysicsQueryTriangle(query,1)/2+")"

    Flip

Wend

FreePhysicsWorld world
End

Function PaintStrips(ramp,painted)
    ; Ice strips are pale blue, grippy strips are green
    surface=GetSurface(ramp,1)
    For v=0 To CountVertices(surface)-1
        If v/4<painted
            VertexColor surface,v,200,230,255
        Else
            VertexColor surface,v,120,200,140
        EndIf
    Next
End Function
