'' ----------------------------------------------------------------------------
'' Irrlicht Wrapper For Imperative Languages - Freebasic Examples
'' Frank Dodd (2006)
'' ----------------------------------------------------------------------------
'' Blitz-Irrlicht 1.8.3 Interface by Ed Musolino (AquaLung 2015)
'' ----------------------------------------------------------------------------
'' Example 103: Billboard Groups
'' This example demonstrated Billboard groups. While billboards are already
'' very efficient large numbers of them can be made even more efficient by
'' collecting them up into a single group.
'' ----------------------------------------------------------------------------

'' ////////////////////////////////////////////////////////////////////////////
'' Includes For extension libraries
Framework usr.birrlicht
Import brl.retro

'' ////////////////////////////////////////////////////////////////////////////
'' Global variables

Const PARTICLE_COUNT:Int = 5
Const PARTICLE_LAYERS:Int = 15
Const SPACING:Float = 75.0
Const SCALE:Float = 100.0
Const CAMERA_SPEED:Float = 1.1


' irrlicht objects
Global metrics:String
Global Billboard:Int
Global BillboardTexture:Int
Global Sun:Int
Global Camera:Int
Global particles[ PARTICLE_COUNT * PARTICLE_LAYERS ]


'' ////////////////////////////////////////////////////////////////////////////
' start the irrlicht interface
iIrr3D( 1024, 768, 32, False )

' add a skybox with a space theme To the scene as a backdrop
Sky = iLoadTexture("./media/starbox1.jpg")
Global SkyBox% = iCreateSkybox( Sky,Sky,Sky,Sky,Sky,Sky)

' Create a billboard representing the Sun
' Load the texture resource For the billboard
BillboardTexture = iLoadTexture( "./media/sun.tga" )

' add the billboard To the scene
Sun = iCreateBillBoard( 256.0, 256.0,  0.0, 0.0, 998.0 )

' now we apply the loaded texture To the billboard using node material index 0
iNodeTexture( Sun, BillboardTexture, 0 )

' hide transparent areas
iNodeMaterialFlag( Sun, IRR_EMF_LIGHTING, False )
iNodeMaterialType ( Sun, IRR_EMT_TRANSPARENT_ALPHA_CHANNEL )

' Create a billboard representing the Moon
' Load the texture resource For the billboard
BillboardTexture = iLoadTexture( "./media/moon.tga" )

' add the billboard To the scene
Global Moon% = iCreateBillBoard( 20.0, 20.0,  0.0, 0.0, 1200.0 )

' now we apply the loaded texture To the billboard using node material index 0
iNodeMaterialFlag( Moon, IRR_EMF_LIGHTING, False )
iNodeTexture( Moon, BillboardTexture, 0 )

' hide transparent areas
iNodeMaterialType( Moon, IRR_EMT_TRANSPARENT_ALPHA_CHANNEL_REF )

' make the moon orbit the sun
iFlyCircleAnimator( Moon, 0.0,0.0,1000.0, 800.0, 0.0001 )

' Load the texture resource For the billboard
BillboardTexture = iLoadTexture( "./media/cloudtest.bmp" )

' add a billboard group To the scene
Billboard = iCreateBillBoardGroup()

For j = 1 To PARTICLE_LAYERS 
    For i = 1 To PARTICLE_COUNT 

        ' Generate a random co-ordinate in a cube
       	x# = Rnd( -0.5, 0.5 )
        y# = Rnd( -0.5, 0.5 )
        z# = Rnd( -0.5, 0.5 )
        
        ' normalise the co-ordinate. this scales the x,y,z so they are
        ' exactly a distance of 1 * SCALE from origin And when they are
        ' all the same distance they appear as points on a sphere
        factor# = 1 / Sqr( x*x + y*y + z*z )
        x = x * factor * SPACING * j
        y = y * factor * SPACING * j
        z = z * factor * SPACING * j

        ' calculate a couple of color values
        small = (255 / PARTICLE_LAYERS) * j / 3
        big   = (255 / PARTICLE_LAYERS) * j

        ' the particle can be one of two colors To add some tone To the cloud
        Select  (i Mod 2)
        Case 0
            ' add a billboard To the group. the parameters are as follows: -
            ' The billboard group node
            ' the X,Y scale of the billboard
            ' X,Y,Z co-ordinates For the billboard
            ' a roll For the billboard that allows each billboard To be rotated
            ' A,R,G,B color values
            particles(i+(j-1)*PARTICLE_COUNT) = iBillBoardToGroup( Billboard, 15.0*SCALE - 3.0*SCALE*j, 15.0*SCALE - 3.0*SCALE*j, x,y,z, 0.0, 255, 255-big, 255, 255-small )
        Case 1
            ' this billboard is slightly bigger And more yellow
            particles(i+(j-1)*PARTICLE_COUNT) = iBillBoardToGroup( Billboard, 20.0*SCALE - 3.0*SCALE*j, 20.0*SCALE - 3.0*SCALE*j, x,y,z, 0.0, 255, 255-small, 255, 255-big )
        End Select
    Next
Next

' just move the particles forward so we can have a good look at them
iPositionNode( Billboard, 0.0, 0.0, 1000.0 )

' this can be used To apply a graduated shading To billboards color
iBillBoardGroupShadows( BillBoard, 1, 0, 0, 1.0, 0.5 )

' apply the loaded texture To the billboard group using node material index 0
iNodeTexture( Billboard, BillboardTexture, 0 )

' disabling lighting
iNodeMaterialFlag( Billboard, IRR_EMF_LIGHTING, False )

' layer the colour upon what is already there (works well For clouds)
iNodeMaterialType( Billboard, IRR_EMT_TRANSPARENT_ADD_COLOR )

' add a first person perspective camera into the scene so we can move around
' the billboard And see how it reacts
Camera = iCreateFPSCamera( False, 100.0, CAMERA_SPEED,-1,0,0,0,0.0 )
iCameraRange( Camera, 128000, 1.0 )

' hide the mouse pointer
iHideMouse()

' -----------------------------------------------------------------------------
i = PARTICLE_COUNT * PARTICLE_LAYERS

' While the irrlicht environment is still running
While iRun() And (Not iKeyHit( KEY_ESCAPE ))

        ' remove particles over time
'        If i > 0 Then
'            iFreeBillBoardFromGroup( Billboard, particles( i ))
'            i = i - 1
'        End If

        ' begin the scene
        iBeginScene()


        ' Change the title To show the frame rate
        metrics = "Example 103: Billboard groups ("+String(iBillBoardGroupCount( Billboard ))+" clouds) ("+String( iGetFPS() )+" fps)"
        iAppTitle( metrics )

        ' we are drawing in two passes first the sun, moon And sky
        iHideNode( Billboard )
        iShowNode( Sun )
        iShowNode( Moon )
        iShowNode( SkyBox )

        ' draw the scene
        iDrawScene()

        ' on the second pass we are just drawing the clouds. by doing this we
        ' ensure that If billboards get in front of the clouds origin but are
        ' still IN the clouds they are still covered by cloud
        iShowNode( Billboard )
        iHideNode( Sun )
        iHideNode( Moon )
        iHideNode( SkyBox )

        ' draw the scene
        iDrawScene()
    
        ' End drawing the scene And render it
        iEndScene()

Wend 

' -----------------------------------------------------------------------------
' Stop the irrlicht engine And Release resources
iEndIrr3D()


End