;; ----------------------------------------------------------------------------
;; Irrlicht Wrapper For Imperative Languages - Purebasic Examples
;; IrrlichtWrapper and FreeBasic-Example by Frank Dodd (2006)
;; Improved IrrlichtWrapper - Michael Taupitz (2007)
;; PureBasic-Examples by Michael Taupitz (neotoma) & Marius Eckardt (Thalius) 
;; ----------------------------------------------------------------------------
;; Example 18 : Selecting Nodes With a Ray
;; This example selects a node in the scene that is hit by a ray we specify As
;; a line in 3D space
;; ----------------------------------------------------------------------------

;; ////////////////////////////////////////////////////////////////////////////
;; Include the Irr3D-Requester
XIncludeFile "Irr3DRequester.pb"


EnableExplicit


#TEST_NODES = 19

; irrlicht objects
Define *MeshTexture.irr_texture
Dim *TestNode.irr_node(#TEST_NODES)
Define *SelectedNode.irr_node
Define *OurCamera.irr_camera
Define *BitmapFont.irr_font
Define POSX.f
Define POSY.f
Define POSZ.f
Define x.f
Define y.f
Define *KeyEvent.IRR_KEY_EVENT
Define selected_node.s
Define start_vector.IRR_VECTOR
Define end_vector.IRR_VECTOR

Define i.l
;; ////////////////////////////////////////////////////////////////////////////
;; GDB debugger main() function

; -----------------------------------------------------------------------------
; To Start the Irrlicht-Device we use the Irr3DRequester, to make it more comfortable
; for the Users, and also easier to test different resolutions and devices.
If Irr3DRequester()

  ; send the window caption
  IrrSetWindowCaption( "Example 18: Selecting Nodes with a Ray" )
  
  ; load the bitmap font as a texture
  *BitmapFont = IrrGetFont ( "media\bitmapfont.bmp" )
  
  ; load the test cube texture
  *MeshTexture = IrrGetTexture( "media\texture.jpg" )
  
  ; itterate all of the test nodes
  For i.l = 1 To #TEST_NODES
      ; add a test node to the scene
      *TestNode(i) = IrrAddCubeSceneNode(10)
      
      ; move the node so that it is arranged into a circle
      IrrSetNodePosition( *TestNode(i), 0.0, (Sin(i/3))*50, (Cos(i/3))*50 )
  
      ; apply a material to the node
      IrrSetNodeMaterialTexture( *TestNode(i), *MeshTexture, 0 )
  
    ; switch off lighting effects on the model
    IrrSetNodeMaterialFlag( *TestNode(i), #IRR_EMF_LIGHTING, #IRR_OFF )
      
  Next i
  
  ; add a camera into the scene and move it into position
  *OurCamera = IrrAddCamera( 120,50,50, 0,0,0)
  
  ; prepare to display a message informing the user how to move the cubes
  selected_node = "MOVE WITH A S D W"
  
  ; define a ray starting at (100,0,0) and passing through (0,0,0) make sure that
  ; it doesn;t pass through the camera As this can be identified As the nearest
  ; node too
  start_vector\x = 100
  start_vector\y = 0
  start_vector\z = 0
  
  end_vector\x = 0
  end_vector\y = 0
  end_vector\z = 0
  
  ; -----------------------------------------------------------------------------
  ; while the irrlicht environment is still running
  While IrrRunning()
      ; begin the scene, erasing the canvas with grey before rendering
      IrrBeginScene( 128,128,128 )
  
      ; draw the scene
      IrrDrawScene()
  
      ; while there are key events waiting
      While IrrKeyEventAvailable()
          ; read the key event out
          *KeyEvent = IrrReadKeyEvent()
  
          ; if this is a key down event we might need to start moving in a
          ; specific direction
          If *KeyEvent\direction = #IRR_KEY_DOWN
              Select *KeyEvent\key
              Case 65 ; A
                  y = -0.1
              Case 87 ; W
                  x = 0.1
              Case 68 ; S
                  y = 0.1
              Case 83 ; D
                  x = -0.1
              EndSelect
          Else
              ; this is a key up event we might need to stop moving in a specific
              ; direction
              Select *KeyEvent\key
              Case 87, 83 ; W and D
                  x = 0
              Case 65, 68 ; A and S
                  y = 0
              EndSelect
          EndIf
      Wend
      
  ;     ; reposition all of the objects
      For i = 1 To #TEST_NODES
          IrrGetNodePosition( *TestNode(i), @POSX, @POSY, @POSZ )
          POSY = POSY + x
          POSZ = POSZ + y
          
          IrrSetNodePosition( *TestNode(i), POSX, POSY, POSZ )
      Next i
  
      ; get the nearest node that collides with the ray we defined earlier
      *SelectedNode = IrrGetCollisionNodeFromRay( @start_vector, @end_vector )
      
      ; if the node value that was returned is 0 there is no node selected
      If *SelectedNode = 0
          ; Display a message informing the user how to move the cubes
          selected_node = "MOVE WITH A S D W"
      Else
          ; some node was hit, scan through the array of nodes to find which one
          ; it was
          For i = 1 To #TEST_NODES
              ; if this was the collided node
              If  *SelectedNode = *TestNode(i)
                  ; display the node index
                  selected_node = "NODE "+Str(i)+" SELECTED"
                  ; switch lighting off on this node to indicate that it is
                  ; selected
                  IrrSetNodeMaterialFlag( *SelectedNode, #IRR_EMF_LIGHTING, #IRR_ON )
              Else
                  ; this node is not selected, switch lighting on for this node
                  ; to indicate this fact
                  IrrSetNodeMaterialFlag( *TestNode(i), #IRR_EMF_LIGHTING, #IRR_OFF )
              EndIf
          Next i
      EndIf
      ; draw the text indicating which node was selected
      Irr2DFontDraw ( *BitmapFont, selected_node, 0, 0, 100, 16 )
  
      ; end drawing the scene and render it
      IrrEndScene()
  Wend
  
  ; -----------------------------------------------------------------------------
  ; Stop the irrlicht engine and release resources
  IrrStop()
EndIf  

End

; IDE Options = PureBasic 4.10 Beta 2 (Windows - x86)
; CursorPosition = 58
; FirstLine = 36
; Folding = -