;; ----------------------------------------------------------------------------
;; 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 07: Particle System
;; This example creates a couple of simple particle systems To demonstrate
;; particle system effects
;; ----------------------------------------------------------------------------

;; ////////////////////////////////////////////////////////////////////////////
;; Include the Irr3D-Requester
XIncludeFile #PB_Compiler_Home + "Includes\IrrlichtWrapper_Include.pbi"


;EnableExplicit

;; ////////////////////////////////////////////////////////////////////////////
;; Global variables

; irrlicht objects
Define *ParticleTexture.irr_texture
Define *TestNodeTexture.irr_texture
Define SmokeParticles.irr_model
Define SmokeEmitter.IRR_PARTICLE_EMITTER
Define *ParticlesNode.irr_node
Define *TestNode.irr_node
Define *camera.irr_camera
Define *Particle.irr_node


Define *em.l  ; pointer to the Emitter


; -----------------------------------------------------------------------------
; 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  IrrStart( #IRR_EDT_DIRECT3D9, 640, 480, #IRR_WINDOWED, #IRR_NO_SHADOWS, #False)


  ; send the window caption
  IrrSetWindowCaption( "Example 07: Particle Systems" )

  *camera = IrrAddFPSCamera()
  IrrSetNodePosition(*camera,100,40,0)



  *mesh = IrrAddHillPlaneMesh("Hill", 20,20, 20,20, 2,2 , 20 ,2)


;   *ParticleTexture = IrrGetTexture( "..\media\Fire.bmp" )
;   IrrSetNodeMaterialTexture( *ParticlesNode, *ParticleTexture, 0 )


; 
; IrrAddHillPlaneMesh(name.p-ascii, sizeX.f, sizeY.f, tilesX.l, tilesY.l, texRepeatX.f, texRepeatY.f, hillsHeight.f, hillsCount.f)
; 
; 
; scene::IAnimatedMesh* mesh = smgr->addHillPlaneMesh("Hill",
; core::dimension2d<f32>(20,20),
; core::dimension2d<s32>(20,20), 0, 20,
; core::dimension2d<f32>(2,2),
; core::dimension2d<f32>(1,1));
; 
; 
; virtual IAnimatedMesh *  addHillPlaneMesh (const c8 *name, const core::dimension2d< f32 > &tileSize, 
; const core::dimension2d< s32 > &tileCount, video::SMaterial *material=0, f32 hillHeight=0.0f, 
; const core::dimension2d< f32 > &countHills=core::dimension2d< f32 >(0.0f, 0.0f), 
; const core::dimension2d< f32 > &textureRepeatCount=core::dimension2d< f32 >(1.0f, 1.0f))=0 


  *ParticlesNode = IrrAddParticleSystemToScene( #IRR_NO_EMITTER )
  
;  IrrSetNodePosition(*ParticlesNode, -160,170,80)
  IrrSetNodeScale(*ParticlesNode, 1,1,1)
  
  IrrSetParticleSize(*ParticlesNode,5,5)

  
  
  Define RainEmitter.IRR_PARTICLE_EMITTER    
  
  With RainEmitter

    \min_box_x = -270
    \min_box_y = -200
    \min_box_z = -270
    \max_box_x = 270
    \max_box_y = 300
    \max_box_z = 300

    \direction_x = 0.0
    \direction_y = 0.0
    \direction_z = 0.0
    \min_paritlcles_per_second = 400
    \max_paritlcles_per_second = 800
    \min_start_color_red = 255
    \min_start_color_green = 255
    \min_start_color_blue = 255
    \max_start_color_red = 255
    \max_start_color_green = 255
    \max_start_color_blue = 255
    \min_lifetime = 800
    \max_lifetime = 1000
    \max_angle_degrees = 0
   EndWith  
   
  *em = IrrAddParticleEmitter(*ParticlesNode, @RainEmitter)

  IrrAddGravityParticleAffector(*ParticlesNode, 0,-0.6,0,1000)
  
  
  ; Stop at Plane.....
  
  IrrAddCollisionParticleAffector(*ParticlesNode, 0,0.0,0, 0,1,0)

  
; scene::IParticleSystemSceneNode* ps = 0;
; ps = smgr->addParticleSystemSceneNode(false);
; ps->setPosition(core::vector3df(-160,170,80));
; ps->setScale(core::vector3df(1,1,1));
; 
; ps->setParticleSize(core::dimension2d<f32>(5.0f, 5.0f));

; scene::IParticleEmitter* em = ps->createBoxEmitter(
; core::aabbox3d<f32>(-270,-200,-270,270,300,300),
; core::vector3df(0.00f,0.00f,0.0f),
; 400,800,
; video::SColor(0,255,255,255), video::SColor(0,255,255,255),
; 8000,10000);
; 
; ps->setEmitter(em);
; em->drop();

; scene::IParticleAffector* paf =
; ps->createGravityAffector(core::vector3df(0.00f,0.00f, 0.0f), 1000);
; 
; ps->addAffector(paf);
; paf->drop();

  IrrSetNodeMaterialFlag( *ParticlesNode, #IRR_EMF_LIGHTING, #IRR_OFF )
  IrrSetNodeMaterialType ( *ParticlesNode, #IRR_EMT_TRANSPARENT_ADD_COLOR  ) ; uncomment me... ;)
  *ParticleTexture = IrrGetTexture( "..\media\Fire.bmp" )
  IrrSetNodeMaterialTexture( *ParticlesNode, *ParticleTexture, 0 )
  IrrSetNodeMaterialType ( *ParticlesNode, #IRR_EMT_TRANSPARENT_VERTEX_ALPHA  ) ; uncomment me... ;)
  
;  IrrSetNodeVertexColors( *ParticlesNode, 70,255,255,255)

  IrrAddChildToParent(*ParticlesNode, *camera)


; ps->setMaterialFlag(video::EMF_LIGHTING, false);
; ps->setMaterialType(EMT_TRANSPARENT_ADD_COLOR);
; ps->setMaterialTexture(0, driver->getTexture("Raindrop.bmp"));
; ps->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA);



  Dim *textures.irr_texture(6)
  *textures(0) = IrrGetTexture("..\media\irrlicht2_up.jpg")
  *textures(1) = IrrGetTexture("..\media\irrlicht2_dn.jpg")
  *textures(2) = IrrGetTexture("..\media\irrlicht2_lf.jpg")
  *textures(3) = IrrGetTexture("..\media\irrlicht2_rt.jpg")
  *textures(4) = IrrGetTexture("..\media\irrlicht2_ft.jpg")
  *textures(5) = IrrGetTexture("..\media\irrlicht2_bk.jpg")
  
  *SkyBox = IrrAddSkyBoxToScene( *textures(0),*textures(1),*textures(2),*textures(3),*textures(4),*textures(5));   

  IrrSetLogLevel(#IRR_ELL_NONE)

  IrrLogHint("Das kommt von", "Mir", #IRR_ELL_ERROR)



; scene::ISceneNode* skyboxNode = smgr->addSkyBoxSceneNode(
; driver->getTexture("irrlicht2_uzerp.bmp"),
; driver->getTexture("irrlicht2_up.bmp"),
; driver->getTexture("irrlicht2_lf.bmp"),
; driver->getTexture("irrlicht2_rt.bmp"),
; driver->getTexture("irrlicht2_ft.bmp"),
; driver->getTexture("irrlicht2_bk.bmp"));

; device->getCursorControl()->setVisible(false);
; 
; camera=smgr->addCameraSceneNode(0, vector3df(-50, 100, -100),vector3df(0, 0, 250));
; 
; ps->setParent(camera);
; int lastFPS = -1;
; 
; core::vector3df Pos = camera->getPosition(); 



  
  ; this adds a small test node to the scene, a test node is a simple cube, that
  ; you can move and texture like any other object however there is another
  ; reason for adding this node. the particle system needs another node rendered
  ; onto the display to allow it to display material effects. this may be an issue
  ; with the wrapper that needs investigation
  *TestNode = IrrAddCubeSceneNode(10)
  
  ; load a wall texture for our box
  *TestNodeTexture = IrrGetTexture( "..\media\wall.jpg" )
  
  ; apply the texture to the box
  IrrSetNodeMaterialTexture( *TestNode, *TestNodeTexture, 0 )
  ; Switch Lighting off - as we have no lights in the scene anyway ..
  IrrSetNodeMaterialFlag( *TestNode, #IRR_EMF_LIGHTING, #IRR_OFF )
  
  ; -*
  ; Exercise: Torchlike...
  ; This shows how Material flags affect the "Effect" of a Material
  ; Set our BoxNode Material to ADDITIVE Blending. 
  ; This will make the Smoke overdraw our Box : this Results in a "burn-like" Effect 
  ; for Example suitable for a Torch ( using the appropriate Textures and
  ; Emitter Settings for our Particles ). 
  ; Have fun! ;) ...
  ;
 IrrSetNodeMaterialType ( *TestNode, #IRR_EMT_TRANSPARENT_ADD_COLOR  ) ; uncomment me... ;)
  ; -*
  
  ; add a particle system to the irrlicht scene manager, a default emitter is not
  ; created as we will define out own. the particle system is blank at the moment
  *ParticlesNode = IrrAddParticleSystemToScene( #IRR_NO_EMITTER )
  
  ; when the particle system starts it creates objects similar to billboards,
  ; this command specifies how large each of those particles will be
  IrrSetParticleSize( *ParticlesNode, 15.0, 15.0 )
  
  ; here we define the particle emitter, a particle emitter is a mechanism that
  ; creates the particles over time and destroys them when their lifetime runs
  ; out. The parameters include: a box that defines the volume in which particles
  ; are created - the larger the box the more diffuse the particle cloud, a
  ; direction that determines where the particles drift off too, a range that
  ; defines hoe many particles will be generated each second, a colour range that
  ; determines a random tint that is applied to the particles, a range that
  ; determines the lifespan of the particles - the large the values the longer
  ; and larger (and slower) your particle cloud will be and finally an angle that 
  ; defines a cone around your direction that is the maximum deviation from the
  ; direction the particles can take - values here make your particles billow
  ; outward
  SmokeEmitter\min_box_x = -7
  SmokeEmitter\min_box_y = 0
  SmokeEmitter\min_box_z = -7
  SmokeEmitter\max_box_x = 7
  SmokeEmitter\max_box_y = 1
  SmokeEmitter\max_box_z = 7
  SmokeEmitter\direction_x = 0
  SmokeEmitter\direction_y = 0.06
  SmokeEmitter\direction_z = 0
  SmokeEmitter\min_paritlcles_per_second = 80
  SmokeEmitter\max_paritlcles_per_second = 100
  SmokeEmitter\min_start_color_red = 255
  SmokeEmitter\min_start_color_green = 255
  SmokeEmitter\min_start_color_blue = 255
  SmokeEmitter\max_start_color_red = 10
  SmokeEmitter\max_start_color_green = 12
  SmokeEmitter\max_start_color_blue = 14
  SmokeEmitter\min_lifetime = 800
  SmokeEmitter\max_lifetime = 2000
  SmokeEmitter\max_angle_degrees = 15
  
  ; finally we add this particle emitting object to the particle system
  *em.l = IrrAddParticleEmitter( *ParticlesNode, @SmokeEmitter )
  
  
  ; an affector is a mechanism that alters the particles over time, the fade out
  ; affector gradually fades the particles out so they are invisible when they
  ; are deleted this lets them smoothly vanish instead of poping out of existence
  IrrAddFadeOutParticleAffector( *ParticlesNode )
  
  ; another affector is the gravity affector, this adds a small amount of velocity
  ; to the particles each frame, although its called a gravity affector it can
  ; be used to push the particles in any direction so you can have drifting smoke
  ; bubbling fountains, etc ...
  IrrAddGravityParticleAffector ( *ParticlesNode, 0.05, 0.05, 0.0 )
  
  ; at the moment the particles are simple grey squares and before we apply a
  ; material to them we need to get the particle system as a scene node
  ;;ParticlesNode = SmokeParticles
  
  ; load a grey smoke like image for the particle
  *ParticleTexture = IrrGetTexture( "..\media\ParticleGrey.bmp" )
  
  ; apply the texture to the particles system, this texture will now be drawn
  ; across each particles surface
  IrrSetNodeMaterialTexture( *ParticlesNode, *ParticleTexture, 0 )
  
  ; out particle system is not affected by lighting so we make it self
  ; illuminating
  IrrSetNodeMaterialFlag( *ParticlesNode, #IRR_EMF_LIGHTING, #IRR_OFF )
  
  ; as the particle texture has black borders, each overlapping particle would
  ; draw this blackness ontop of one another as a sharp egde they would look like
  ; a lot of solid squares instead of the transparent gas effect we are trying
  ; to created. so here we change the material type of the node - instead of
  ; drawing the node solidly onto the screen it is added onto the colour
  ; underneath itself so black doesnt change the color and white would build up
  ; top of the existing color until it completly saturates the pixel
  IrrSetNodeMaterialType ( *ParticlesNode, #IRR_EMT_TRANSPARENT_ADD_COLOR  )
  
  IrrAddStopParticleAffector(*ParticlesNode, 1000)
  
  
  Define FireEmitter.IRR_PARTICLE_EMITTER

  ; add a particle system to the irrlicht scene manager, a default emitter is not
  ; created as we will define out own. the particle system is blank at the moment
  *Particle = IrrAddParticleSystemToScene( #IRR_NO_EMITTER )
  
  ; when the particle system starts it creates objects similar to billboards,
  ; this command specifies how large each of those particles will be
  IrrSetParticleSize( *Particle, 20.0, 20.0 )
  
  
  FireEmitter\min_box_x = -12
  FireEmitter\min_box_y = 0
  FireEmitter\min_box_z = -12
  FireEmitter\max_box_x = 12
  FireEmitter\max_box_y = 5
  FireEmitter\max_box_z = 12  


  FireEmitter\direction_x = 0.00
  FireEmitter\direction_y = 0.20
  FireEmitter\direction_z = 0.00
  FireEmitter\min_paritlcles_per_second = 100
  FireEmitter\max_paritlcles_per_second = 300
  FireEmitter\min_start_color_red = 255
  FireEmitter\min_start_color_green = 255
  FireEmitter\min_start_color_blue = 255
  FireEmitter\max_start_color_red = 0
  FireEmitter\max_start_color_green = 0
  FireEmitter\max_start_color_blue = 0
  FireEmitter\min_lifetime = 500
  FireEmitter\max_lifetime = 3000
  FireEmitter\max_angle_degrees = 25


; ring1ParticleSystem->createRingEmitter(
; 		center, 100.0f, 5.0f,
; 		core::vector3df( 0.0f, 0.0f, 0.0f ),
; 		800, 900,
; 		video::SColor( 0, 255, 255, 255 ), video::SColor( 0, 255, 255, 255 ),
; 		1500, 1500


; finally we add this particle emitting object to the particle system
; *em.l = IrrAddParticleRingEmitter( *Particle, @FireEmitter, 0,0,0, 100,20 )

*em = IrrAddParticleEmitter(*Particle, @FireEmitter);

 ; *em.l = IrrAddParticleSphereEmitter( *Particle, @FireEmitter, 0,0,0, 100 )

If *em = #Null
  Debug("Ring Problem")
EndIf

  IrrAddFadeOutParticleAffector( *Particle )
;  IrrAddRotationParticleAffector(*Particle, 50,0,0  ,0,0,0)
  IrrAddCollisionParticleAffector(*particle, 0,0.0,0, 0,1,0)
  IrrAddGravityParticleAffector ( *Particle, 0.00, -0.10, 0.00 )
  
  
  
  ; load a grey smoke like image for the particle
  *ParticleTexture = IrrGetTexture( "..\media\Fire.bmp" )
  IrrSetNodeMaterialTexture( *Particle, *ParticleTexture, 0 )
  IrrSetNodeMaterialFlag( *Particle, #IRR_EMF_LIGHTING, #IRR_OFF )
  IrrSetNodeMaterialType ( *Particle, #IRR_EMT_TRANSPARENT_ADD_COLOR  )


  IrrSetNodePosition( *Particle,0,00,0)

 IrrAddRotationAnimator( *Particle, 0, 0.1, 0 )

;  makeTheMeshEmitter()
  

  IrrAddStopParticleAffector(*Particle, 1000)
  
  ; add a fixed position camera to the scene so we can view the particle system.
  ; the first three parameters are the cameras location, the second three
  ; parameters are where the camera is looking at
;  *camera = IrrAddCamera( 100,40,0, 0,40,0 )

  
  ; -----------------------------------------------------------------------------
  ; while the irrlicht environment is still running
  While IrrRunning()
      ; clear the canvas to black to show the particles up better
      IrrBeginScene( 0, 0, 0 )
  
      ; draw the scene
      IrrDrawScene()
  
      ; end drawing the scene and display it
      IrrEndScene()
  Wend
  
  ; -----------------------------------------------------------------------------
  ; Stop the irrlicht engine and release resources
  IrrStop()
  
EndIf

End

; jaPBe Version=3.7.2.629
; Build=0
; FirstLine=23
; CursorPosition=44
; ExecutableFormat=Windows
; DontSaveDeclare
; IDE Options = PureBasic 4.10 Beta 3 (Windows - x86)
; ExecutableFormat = Console
; CursorPosition = 97
; FirstLine = 75
; Folding = -