particlebuffer.monkey2 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. Namespace mojo3d
  2. Class ParticleBuffer
  3. Method New( length:Int=15000 )
  4. _length=length
  5. _vbuffer=New VertexBuffer( Vertex3f.Format,_length )
  6. _uniforms=New UniformBlock( 4,true )
  7. Local vertices:=_vbuffer.Lock()
  8. libc.memset( vertices,0,_vbuffer.Length*_vbuffer.Pitch)
  9. _vbuffer.Invalidate()
  10. _vbuffer.Unlock()
  11. Gravity=New Vec3f( 0,-9.81,0 )
  12. Duration=5.0
  13. Fade=0.0
  14. Colors=New Color[]( Color.White )
  15. ConeAngle=30
  16. MinVelocity=20.0
  17. MinVelocity=24.0
  18. MinSize=8.0
  19. MaxSize=12.0
  20. End
  21. Property Length:Int()
  22. Return _length
  23. End
  24. Property Gravity:Vec3f()
  25. Return _uniforms.GetVec3f( "Gravity" )
  26. Setter( gravity:Vec3f )
  27. _uniforms.SetVec3f( "Gravity",gravity )
  28. End
  29. Property Duration:Float()
  30. Return _duration
  31. Setter( duration:Float )
  32. _uniforms.SetFloat( "Duration",duration )
  33. _duration=duration
  34. End
  35. Property Fade:Float ()
  36. Return _uniforms.GetFloat( "Fade" )
  37. Setter( fade:Float )
  38. _uniforms.SetFloat( "Fade",fade )
  39. End
  40. Property Colors:Color[]()
  41. Return _colors
  42. Setter( colors:Color[] )
  43. If Not colors colors=New Color[]( Color.White )
  44. _colors=colors
  45. End
  46. Property ConeAngle:Float()
  47. Return _coneAngle
  48. Setter( angle:Float )
  49. Assert( angle>0 And angle<180,"Cone angle must be in the range (0,180)" )
  50. _coneAngle=angle
  51. End
  52. Property MinVelocity:Float()
  53. Return _minVelocity
  54. Setter( velocity:Float )
  55. _minVelocity=velocity
  56. End
  57. Property MaxVelocity:Float()
  58. Return _maxVelocity
  59. Setter( velocity:Float )
  60. _maxVelocity=velocity
  61. End
  62. Property MinSize:Float()
  63. Return _minSize
  64. Setter( size:Float )
  65. _minSize=size
  66. End
  67. Property MaxSize:Float()
  68. Return _maxSize
  69. Setter( size:Float )
  70. _maxSize=size
  71. End
  72. Internal
  73. Method OnRender( rq:RenderQueue,material:Material,instance:Entity )
  74. Local time:=rq.Time
  75. If Not _time
  76. _time=time
  77. Return
  78. Endif
  79. Local frames:=Int( (time-_time) * 60 )
  80. If frames
  81. Local n:=Min( Int( Float(_length)/60.0/_duration * frames ),_length )
  82. local timeStep:=frames * (1.0/60.0) / n
  83. Local vertices:=Cast<Vertex3f Ptr>( _vbuffer.Lock() )
  84. For Local i:=0 Until n
  85. AddParticle( vertices,_time )
  86. _time+=timeStep
  87. Next
  88. _vbuffer.Invalidate()
  89. _vbuffer.Unlock()
  90. Endif
  91. rq.AddRenderOp( material,_uniforms,instance,_vbuffer,Null,1,_length,0 )
  92. End
  93. Private
  94. Field _length:Int
  95. Field _vbuffer:VertexBuffer
  96. Field _uniforms:UniformBlock
  97. Field _duration:Float
  98. Field _colors:Color[]
  99. Field _coneAngle:Float
  100. Field _minVelocity:Float
  101. Field _maxVelocity:Float
  102. Field _minSize:Float
  103. Field _maxSize:Float
  104. Field _time:Float
  105. Field _index:Int
  106. Method AddParticle( vertices:Vertex3f Ptr,time:Float )
  107. Local vertex:=vertices+_index
  108. _index=(_index+1) Mod _length
  109. Local r:=Rnd( -Pi,Pi )
  110. Local d:=Rnd( 0,Tan( _coneAngle*.5*TwoPi/360.0 ) )
  111. Local dir:=New Vec3f( Cos( r ) * d,Sin( r ) * d,1.0 ).Normalize()
  112. Local velocity:=dir * Rnd( _minVelocity,_maxVelocity )
  113. vertex->position=velocity 'velocity
  114. vertex->texCoord0=New Vec2f( time,Rnd( _minSize,_maxSize ) ) 'time, size
  115. vertex->tangent=_colors[ Rnd( _colors.Length ) ] 'color
  116. End
  117. End