Particle system: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
(Added warning about select animation on particle system object)
(Syntax highlighting; Partially proper xml comments; Removing credits, see the page history for that; +-cat)
Line 1: Line 1:
This is a short specification/tutorial to define particle systems in FlightGear using XML
This is a short specification/tutorial to define particle systems in FlightGear using XML


Note: Start & end size appear to be given in feet; some other measurements are in meters.  There may be some internal confusion between the two measurement systems.
{{note|Start & end size appear to be given in feet; some other measurements are in meters.  There may be some internal confusion between the two measurement systems.}}


<syntaxhighlight lang="xml">
   <particlesystem>
   <particlesystem>
     <name>fuel</name>
     <name>fuel</name>
<!--     <texture>particle.rgb</texture> -->
  <!-- <texture>particle.rgb</texture> -->
     <emissive>false</emissive>
     <emissive>false</emissive>
     <lighting>true</lighting>
     <lighting>true</lighting>
Line 13: Line 14:
       <y-m>-0.3</y-m>
       <y-m>-0.3</y-m>
       <z-m>0</z-m>
       <z-m>0</z-m>
       <!--<pitch-deg>90</pitch-deg>-->
       <!-- <pitch-deg>90</pitch-deg> -->
     </offsets>
     </offsets>
     <!--<condition>
     <!-- <condition>
       <and>
       <and>
         <equals>
         <equals>
Line 26: Line 27:
         </less-than>
         </less-than>
       </and>
       </and>
     </condition>-->
     </condition> -->
     <attach>world</attach>
     <attach>world</attach>
    
    
Line 115: Line 116:
     </program>
     </program>
  </particlesystem>
  </particlesystem>
</syntaxhighlight>


Stick this inside any model XML like it was an animation and it should
Stick this inside any model XML like it was an animation and it should
work (notice the condition requires wheel on the ground)
work (notice the condition requires wheel on the ground)


==Specification==
== Specification ==


Note:
{{note| <code>&lt;VALUEORPROP/&gt;</code> means you can either specify a property with factor and offset (result = (prop*factor)+offset ) in the usual way.}}
<VALUEORPROP/> means you can either specify a property with factor and
offset (result = (prop*factor)+offset ) in the usual way


 
<syntaxhighlight lang="xml">
 
  <particlesystem>                       <!-- The base tag -->
  <particlesystem> = the base tag
   <type>string</type>                   <!-- Can be "normal" or "trail", normal is the usual quad
   <type>string</type> can be "normal" or "trail", normal is the usual quad particles, trail is a string of connected line shapes by default.
                                        particles, trail is a string of connected line shapes
   <offsets> = this places the source of the particles (the emitter) in relation to the perhaps already offset model (see model-howto.html for details)
                                        by default. -->
   <offsets>                             <!-- this places the source of the particles (the emitter)
                                        in relation to the perhaps already offset model (see
                                        model-howto.html for details) -->
     <x-m>float</x-m>
     <x-m>float</x-m>
     <y-m>float</y-m>
     <y-m>float</y-m>
Line 137: Line 140:
     <heading-deg>float</heading-deg>
     <heading-deg>float</heading-deg>
   </offsets>
   </offsets>
   <condition> =a typical condition that if not true stops particles from being emitted (PPS=0)
   <condition>                           <!-- A typical condition that if not true stops particles
    ....
                                        from being emitted (PPS=0) -->
  <!-- ... -->
   </condition>
   </condition>
   <name>string</name> = the name of the particle system (so it can be referenced by normal animations)
   <name>string</name>                   <!-- The name of the particle system (so it can be
   <attach>string</attach> = can be "world" or "local". "world means the particles aren't "physically linked" to the model (necessary for use outside moving models), "local" means the opposite (can be used for static objects or inside moving objects)
                                        referenced by normal animations) -->
   <texture>string</texture> = the texture path relative to the XML file location
   <attach>string</attach>               <!-- An be "world" or "local". "world means the particles
   <emissive>bool</emissive> = self-explanatory
                                        aren't "physically linked" to the model (necessary for
   <lighting>bool</lighting> = yet to be tested, but seems obvious
                                        use outside moving models), "local" means the opposite
   <align>string</align> = can be "billboard" or "fixed"
                                        (can be used for static objects or inside moving
   <placer> = where particles are born
                                        objects) -->
     <type>string</type> = can be "sector" (inside a circle), "segments"(user-defined segments) and "point" (default)
   <texture>string</texture>             <!-- The texture path relative to the XML file location -->
     *<radius-min-m>float</radius-min-m> = only for sector, inner radius at which particles appear
   <emissive>bool</emissive>             <!-- Self-explanatory -->
     *<radius-max-m>float</radius-max-m> = only for sector, outer radius at which particles appear
   <lighting>bool</lighting>             <!-- Yet to be tested, but seems obvious -->
     *<phi-min-deg>float</phi-min-deg> = only for sector, starting angle of the slide at which particles appear
   <align>string</align>                 <!-- Can be "billboard" or "fixed" -->
     *<phi-max-deg>float</phi-max-deg> = only for sector, ending angle of the slide at which particles appear
   <placer>                             <!-- where particles are born -->
     <segments> = only for segments, encloses sequential points that form segments
     <type>string</type>                 <!-- Can be "sector" (inside a circle), "segments"
       <vertex> = specifies one point, put as many as you want
                                        (user-defined segments) and "point" (default) -->
     *<radius-min-m>float</radius-min-m> <!-- Only for sector, inner radius at which particles appear -->
     *<radius-max-m>float</radius-max-m> <!-- Only for sector, outer radius at which particles appear -->
     *<phi-min-deg>float</phi-min-deg>   <!-- Only for sector, starting angle of the slide at which
                                        particles appear -->
     *<phi-max-deg>float</phi-max-deg>   <!-- Only for sector, ending angle of
                                        the slide at which particles appear -->
     <segments>                         <!-- Only for segments, encloses sequential points that
                                        form segments -->
       <vertex>                         <!-- Specifies one point, put as many as you want -->
         <x-m>float</x-m>
         <x-m>float</x-m>
         <y-m>float</y-m>
         <y-m>float</y-m>
         <z-m>float</z-m>
         <z-m>float</z-m>
       </vertex>
       </vertex>
      ....
  <!-- ... -->
       <vertex>
       <vertex>
      ...
  <!-- ... -->
       </vertex>
       </vertex>
     </segments>
     </segments>
   </placer>
   </placer>
   <shooter> = the shooter defines the initial velocity vector for your particles
   <shooter>                             <!-- The shooter defines the initial velocity vector for
     *<theta-min-deg>float</theta-min-deg> = horizontal angle limits of the particle cone
                                        your particles -->
     *<theta-min-deg>float</theta-min-deg> <!-- Horizontal angle limits of the particle cone -->
     *<theta-max-deg>float</theta-max-deg>
     *<theta-max-deg>float</theta-max-deg>
     *<phi-min-deg>float</phi-min-deg> = vertical angle limits of the particle cone
     *<phi-min-deg>float</phi-min-deg>   <!-- Vertical angle limits of the particle cone -->
     *<phi-max-deg>float</phi-max-deg>  for an illustration of theta/phi see http://www.cs.clemson.edu/~malloy/courses/3dgames-2007/tutor/web/particles/particles.html
     *<phi-max-deg>float</phi-max-deg>  <!-- For an illustration of theta/phi see  
     <speed-mps> = the scalar velocity (meter per second)
                                        http://www.cs.clemson.edu/~malloy/courses/3dgames-2007/
     <VALUEORPROP/> = see note
                                        tutor/web/particles/particles.html -->
     *<spread> the "tolerance" in each direction so values are in the range [value-spread, value+spread]
     <speed-mps>                         <!-- The scalar velocity (meter per second) -->
     <VALUEORPROP/>                     <!-- See note -->
     *<spread>                         <!-- The "tolerance" in each direction so values are in the
                                        range [value-spread, value+spread] -->
     </speed-mps>
     </speed-mps>
     <rotation-speed> = the range of initial rotational speed of the particles
     <rotation-speed>                   <!-- The range of initial rotational speed of the particles -->
       *<x-min-deg-sec>float</x-min-deg-sec>
       *<x-min-deg-sec>float</x-min-deg-sec>
       *<y-min-deg-sec>float</y-min-deg-sec>
       *<y-min-deg-sec>float</y-min-deg-sec>
Line 184: Line 201:
   <counter>
   <counter>
     <particles-per-sec>
     <particles-per-sec>
       <VALUEORPROP/> = see note
       <VALUEORPROP/>                   <!-- See note -->
       *<spread> the "tolerance" in each direction so values are in the range [value-spread, value+spread]
       *<spread>                         <!-- The "tolerance" in each direction so values are in the
                                        range [value-spread, value+spread] -->
     </particles-per-sec>
     </particles-per-sec>
   </counter>
   </counter>
   <particle> = defines the particle properties
   <particle>                           <!-- Defines the particle properties -->
     <start>
     <start>
       <color> = initial color (at time of emission)
       <color>                           <!-- Initial color (at time of emission) -->
         <red><VALUEORPROP/></red> = color component in normalized value [0,1]
         <red><VALUEORPROP/></red>       <!-- Color component in normalized value [0,1] -->
         <green><VALUEORPROP/></green>
         <green><VALUEORPROP/></green>
         <blue><VALUEORPROP/></blue>
         <blue><VALUEORPROP/></blue>
         <alpha><VALUEORPROP/></alpha>
         <alpha><VALUEORPROP/></alpha>
       </color>
       </color>
       <size> = as above, but for size (given in feet)
       <size>                           <!-- As above, but for size (given in feet) -->
         <VALUEORPROP/>
         <VALUEORPROP/>
       </size>
       </size>
     </start>
     </start>
     <end>
     <end>
       <color> = final color (at the end of the particle life)
       <color>                           <!-- Final color (at the end of the particle life) -->
         <red><VALUEORPROP/></red>
         <red><VALUEORPROP/></red>
         <green><VALUEORPROP/></green>
         <green><VALUEORPROP/></green>
Line 208: Line 226:
       </color>
       </color>
       <size>
       <size>
         <VALUEORPROP/> (in feet)
         <VALUEORPROP/>                 <!-- (In feet) -->
       </size>
       </size>
     </end>
     </end>
     *<life-sec> = the time the particles will be alive, in seconds
     *<life-sec>                         <!-- The time the particles will be alive, in seconds -->
       <VALUEORPROP/>
       <VALUEORPROP/>
     *</life-sec>
     *</life-sec>
     *<radius-m>float</radius-m> = each particles is physically treated as a sphere with this radius
     *<radius-m>float</radius-m>         <!-- Each particles is physically treated as a sphere with
     *<mass-kg>float</mass-kg> = mass in KG
                                        this radius -->
     *<mass-kg>float</mass-kg>           <!-- Mass in Kg -->
   </particle>
   </particle>
   <program> = defines external forces acting upon a particle
   <program>                             <!-- Defines external forces acting upon a particle -->
     <fluid>string<fluid> = can be "air" or "water"
     <fluid>string<fluid>               <!-- Can be "air" or "water" -->
     <gravity>bool</gravity> = can be "true" or "false". uses standard gravity
     <gravity>bool</gravity>             <!-- Can be "true" or "false". uses standard gravity -->
     <wind>bool</wind> = can be "true" or "false". uses user position wind (not the model position, but shouldn't be noticeable, you want to disabled it when using local attach)
     <wind>bool</wind>                   <!-- Can be "true" or "false". uses user position wind (not
                                        the model position, but shouldn't be noticeable, you want
                                        to disabled it when using local attach) -->
   </program>
   </program>
  </particlesystem>
  </particlesystem>
</syntaxhighlight>


==Remarks==
== Remarks ==
Don't forget you can use existing animations with particles, so if you want to direct or translate the emitter, just use translate, rotate, spin and so on (other animations might have interesting effects too I guess).
Don't forget you can use existing animations with particles, so if you want to direct or translate the emitter, just use translate, rotate, spin and so on (other animations might have interesting effects too I guess).


Line 243: Line 265:
Consider your options correctly! You should consider giving them no initial velocity and most important, no spread, otherwise particles will race and the trail will fold. Start simple (no velocities and forces) and work your way up.
Consider your options correctly! You should consider giving them no initial velocity and most important, no spread, otherwise particles will race and the trail will fold. Start simple (no velocities and forces) and work your way up.


==Credits & History==
[[Category:Particle system]]
Document started 27/01/2008 by Tiago Gusmão
 
Updated 02/02/2008 to reflect syntax changes
 
Updated 03/02/2008 to add trails (connected particles)
 
[[Category:Particle System]]
[[Category:XML]]
[[Category:XML]]
[[Category:FlightGear feature]]
[[Category:FlightGear feature]]

Revision as of 23:09, 1 September 2015

This is a short specification/tutorial to define particle systems in FlightGear using XML

Note  Start & end size appear to be given in feet; some other measurements are in meters. There may be some internal confusion between the two measurement systems.
  <particlesystem>
    <name>fuel</name>
  <!-- <texture>particle.rgb</texture> -->
    <emissive>false</emissive>
    <lighting>true</lighting>
  
    <offsets>
      <x-m>35</x-m>
      <y-m>-0.3</y-m>
      <z-m>0</z-m>
      <!-- <pitch-deg>90</pitch-deg> -->
    </offsets>
    <!-- <condition>
      <and>
        <equals>
          <property>engines/engine/smoking</property>
          <value>true</value>
        </equals>
        <less-than>
          <property>position/altitude-agl-ft</property>
          <value>12000</value>
        </less-than>
      </and>
    </condition> -->
    <attach>world</attach>
  
    <placer>
      <type>point</type>
    </placer>
  
    <shooter>
      <theta-min-deg>84</theta-min-deg>
      <theta-max-deg>86</theta-max-deg>
      <phi-min-deg>-1.5</phi-min-deg>
      <phi-max-deg>1.5</phi-max-deg>
      <speed>
        <value>10</value>
        <spread>2.5</spread>
      </speed>
      <rotation-speed>
        <x-min-deg-sec>0</x-min-deg-sec>
        <y-min-deg-sec>0</y-min-deg-sec>
        <z-min-deg-sec>0</z-min-deg-sec>
        <x-max-deg-sec>0</x-max-deg-sec>
        <y-max-deg-sec>0</y-max-deg-sec>
        <z-max-deg-sec>0</z-max-deg-sec>
      </rotation-speed>
    </shooter>
      
    <counter>
      <particles-per-sec>
        <value>1</value>
        <spread>0</spread>
      </particles-per-sec>
    </counter>
    <align>billboard</align>
       
    <particle>
      <start>
        <color>
          <red>
            <value>0.9</value>
          </red>
          <green>
            <value>0.09</value>
          </green>
          <blue>
            <value>0.09</value>
          </blue>
          <alpha>
            <value>1.0</value>
          </alpha>
        </color>
        <size>
          <value>0.25</value>
        </size>
      </start>
  
      <end>
        <color>
          <red>
            <value>1</value>
          </red>
          <green>
            <value>0.1</value>
          </green>
          <blue>
            <value>0.1</value>
          </blue>
          <alpha>
            <value>0.0</value>
          </alpha>
        </color>
        <size>
          <value>4</value>
        </size>
      </end>
  
      <life-sec>
        <value>10</value>
      </life-sec>
  
      <mass-kg>0.25</mass-kg>
      <radius-m>0.1</radius-m>
    </particle>
  
    <program>
      <fluid>air</fluid>
      <gravity type="bool">true</gravity>
      <wind type="bool">true</wind>
    </program>
 </particlesystem>

Stick this inside any model XML like it was an animation and it should work (notice the condition requires wheel on the ground)

Specification

Note  Add message
 <particlesystem>                       <!-- The base tag -->
  <type>string</type>                   <!-- Can be "normal" or "trail", normal is the usual quad
                                         particles, trail is  a string of connected line shapes
                                         by default. -->
  <offsets>                             <!-- this places the source of the particles (the emitter)
                                         in relation to the perhaps already offset model (see
                                         model-howto.html for details) -->
    <x-m>float</x-m>
    <y-m>float</y-m>
    <z-m>float</z-m>
    <pitch-deg>float</pitch-deg>
    <roll-deg>float</roll-deg>
    <heading-deg>float</heading-deg>
  </offsets>
  <condition>                           <!-- A typical condition that if not true stops particles
                                         from being emitted (PPS=0) -->
   <!-- ... -->
  </condition>
  <name>string</name>                   <!-- The name of the particle system (so it can be
                                         referenced by normal animations) -->
  <attach>string</attach>               <!-- An be "world" or "local". "world means the particles
                                         aren't "physically linked" to the model (necessary for
                                         use outside moving models), "local" means the opposite
                                         (can be used for static objects or inside moving
                                         objects) -->
  <texture>string</texture>             <!-- The texture path relative to the XML file location -->
  <emissive>bool</emissive>             <!-- Self-explanatory -->
  <lighting>bool</lighting>             <!-- Yet to be tested, but seems obvious -->
  <align>string</align>                 <!-- Can be "billboard" or "fixed" -->
  <placer>                              <!-- where particles are born -->
    <type>string</type>                 <!-- Can be "sector" (inside a circle), "segments"
                                         (user-defined segments) and "point" (default) -->
    *<radius-min-m>float</radius-min-m> <!-- Only for sector, inner radius at which particles appear -->
    *<radius-max-m>float</radius-max-m> <!-- Only for sector, outer radius at which particles appear -->
    *<phi-min-deg>float</phi-min-deg>   <!-- Only for sector, starting angle of the slide at which
                                         particles appear -->
    *<phi-max-deg>float</phi-max-deg>   <!-- Only for sector, ending angle of
                                        the slide at which particles appear -->
    <segments>                          <!-- Only for segments, encloses sequential points that
                                         form segments -->
      <vertex>                          <!-- Specifies one point, put as many as you want -->
        <x-m>float</x-m>
        <y-m>float</y-m>
        <z-m>float</z-m>
      </vertex>
  <!-- ... -->
      <vertex>
  <!-- ... -->
      </vertex>
    </segments>
  </placer>
  <shooter>                             <!-- The shooter defines the initial velocity vector for
                                         your particles -->
    *<theta-min-deg>float</theta-min-deg>  <!-- Horizontal angle limits of the particle cone -->
    *<theta-max-deg>float</theta-max-deg>
    *<phi-min-deg>float</phi-min-deg>   <!-- Vertical angle limits of the particle cone -->
    *<phi-max-deg>float</phi-max-deg>   <!-- For an illustration of theta/phi see 
                                         http://www.cs.clemson.edu/~malloy/courses/3dgames-2007/
                                         tutor/web/particles/particles.html -->
    <speed-mps>                         <!-- The scalar velocity (meter per second) -->
     <VALUEORPROP/>                     <!-- See note -->
     *<spread>                          <!-- The "tolerance" in each direction so values are in the
                                         range  [value-spread, value+spread] -->
    </speed-mps>
    <rotation-speed>                    <!-- The range of initial rotational speed of the particles -->
      *<x-min-deg-sec>float</x-min-deg-sec>
      *<y-min-deg-sec>float</y-min-deg-sec>
      *<z-min-deg-sec>float</z-min-deg-sec>
      *<x-max-deg-sec>float</x-max-deg-sec>
      *<y-max-deg-sec>float</y-max-deg-sec>
      *<z-max-deg-sec>float</z-max-deg-sec>
    </rotation-speed>
  </shooter>
  <counter>
    <particles-per-sec>
      <VALUEORPROP/>                    <!-- See note -->
      *<spread>                         <!-- The "tolerance" in each direction so values are in the
                                         range [value-spread, value+spread] -->
    </particles-per-sec>
  </counter>
  <particle>                            <!-- Defines the particle properties -->
    <start>
      <color>                           <!-- Initial color (at time of emission) -->
        <red><VALUEORPROP/></red>       <!-- Color component in normalized value [0,1] -->
        <green><VALUEORPROP/></green>
        <blue><VALUEORPROP/></blue>
        <alpha><VALUEORPROP/></alpha>
      </color>
      <size>                            <!-- As above, but for size (given in feet) -->
        <VALUEORPROP/>
      </size>
    </start>
    <end>
      <color>                           <!-- Final color (at the end of the particle life) -->
        <red><VALUEORPROP/></red>
        <green><VALUEORPROP/></green>
        <blue><VALUEORPROP/></blue>
        <alpha><VALUEORPROP/></alpha>
      </color>
      <size>
        <VALUEORPROP/>                  <!-- (In feet) -->
      </size>
    </end>
    *<life-sec>                         <!-- The time the particles will be alive, in seconds -->
      <VALUEORPROP/>
    *</life-sec>
    *<radius-m>float</radius-m>         <!-- Each particles is physically treated as a sphere with
                                         this radius -->
    *<mass-kg>float</mass-kg>           <!-- Mass in Kg -->
  </particle>
  <program>                             <!-- Defines external forces acting upon a particle -->
    <fluid>string<fluid>                <!-- Can be "air" or "water" -->
    <gravity>bool</gravity>             <!-- Can be "true" or "false". uses standard gravity -->
    <wind>bool</wind>                   <!-- Can be "true" or "false". uses user position wind (not
                                         the model position, but shouldn't be noticeable, you want
                                         to disabled it when using local attach) -->
  </program>
 </particlesystem>

Remarks

Don't forget you can use existing animations with particles, so if you want to direct or translate the emitter, just use translate, rotate, spin and so on (other animations might have interesting effects too I guess).

However, avoid using the select animation for triggering the particle emission, use the condition directly in the particle system. Otherwise there is an issue with old particles reappearing when triggered again. It is fine to use it for longer-term hiding (like smoke emitting device being or not being installed), but not for conditions that might change often (like the command to start/stop emitting smoke).

Particle XML should be compatible with plib, as the tags will be ignored (you might get some warning if you attach them to animations though)

Try not to use a lot of particles in a way that fills the screen, that will demand lots of fill rate and hurt FPS

If you don't use any properties nor conditions, your particle system doesn't need to use a callback a so it's slightly better on the CPU (mostly useful for static models)

If your particle lifetime is too big you might run out of particles temporarily (still being investigated)

Use mass and size(radius) to adjust the reaction to gravity and wind (mass/size = density)

Although at the moment severe graphical bugs can be seen in the trails, they are usable.

Consider your options correctly! You should consider giving them no initial velocity and most important, no spread, otherwise particles will race and the trail will fold. Start simple (no velocities and forces) and work your way up.