Howto: Fireworks

From FlightGear wiki
Jump to navigation Jump to search


Each New Year's Eve at 0 o'clock, in most cities of the world the sky is illuminated by fireworks in all possible shapes, colors, … This is very beautiful to look at, and a highlight of the year for many people. We don't have that in FlightGear. Not yet. But we can have it - if you want to know how to do it, read on !

Creating fireworks - Particle system

My approach to creating fireworks uses the particle system - if anyone has a (better ?) solution, feel free to add it.


First we need to decide where to put the files - for simplicity, I will put them into $FGDATA/Models/Effects/Fireworks.


Then we need to create a particle texture. I have simply copied the texture of $FG_DATA/Models/Effects/RedLight10000.xml. Then we need to give it the right color, if we want it to be something different from red. For that, load the texture in GIMP, then use Menu -> Colors -> Colorize…. Set the desired color of the firework, click Apply and export the image to $FGDATA/Models/Effects/Fireworks/particle.png.


The firework will be composed from multiple particle effects - one for each radial. You can compose multiple different radials for complex figures, but for this Howto we will just make a simple two-dimensional firework from one type of radial, like the red part of this real one. Now, paste the following code into some .xml file below $FGDATA/Models/Effects/Fireworks - in this example, I will name it circular-white-radial.xml:

<?xml version="1.0"?>
<PropertyList>
	<particlesystem>
		<name>firework</name>
		<texture>particle.png</texture> <!-- which texture to use - relative to model -->
		<emissive>true</emissive> <!-- whether the particles should emit light - always true for a firework -->
		<lighting>false</lighting> <!-- setting this to true results in the firework not being visible in darkness - no idea why -->
		<attach>world</attach> <!-- local or world - local particles will be placed relative to the aircraft - we want world to have the firework stay in its place -->
		
		<placer>
			<type>point</type> <!-- particles will be emitted from one point -->
		</placer>
		
		<shooter>
			<theta-min-deg>0</theta-min-deg> <!-- in aircraft terms: minimum roll angle around the particle system's origin -->
			<theta-max-deg>0</theta-max-deg> <!-- in aircraft terms: maximum roll angle around the particle system's origin -->
			<phi-min-deg>0</phi-min-deg> <!-- in aircraft terms: minimum pitch angle around the particle system's origin -->
			<phi-max-deg>0</phi-max-deg> <!-- in aircraft terms: maximum pitch angle around the particle system's origin -->
			<speed-mps>
				<value>100</value> <!-- how fast the particles will go away from the origin -->
				<spread>0</spread> <!-- random variation of <value> -> always value - spread <= speed <= value + spread -->
			</speed-mps>
			<rotation-speed> <!-- rotation speeds of the particles around their center - as our particles are circular, it doesn't matter so is set all to zero -->
				<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>0.5</value> <!-- how many particles to shoot per second - for a firework, a value of 0.05 seems reasonable (a particle will be emitted every 20 seconds - I use more for testing, e.g. one particle every two seconds as here -->
				<spread>0</spread> <!-- random variation, same as with speed-mps -->
			</particles-per-sec>
		</counter>
		<align>billboard</align> <!-- needed so that particles are rotated to always face the viewer -->
			 
		<particle> <!-- definition of a single particle -->
			<start> <!-- how the particle looks when emitted -->
				<color>
					<red>
						<value>1</value>
					</red>
					<green>
						<value>1</value>
					</green>
					<blue>
						<value>1</value>
					</blue>
					<alpha>
						<value>1.0</value>
					</alpha>
				</color>
				<size> <!-- start size in feet -->
					<value>1</value>
				</size>
			</start>
		
			<end> <!-- how the particle looks when it is removed aka dies -->
				<color>
					<red>
						<value>1</value>
					</red>
					<green>
						<value>1</value>
					</green>
					<blue>
						<value>1</value>
					</blue>
					<alpha>
						<value>0.1</value>
					</alpha>
				</color>
				<size> <!-- end size of the particle -->
					<value>1.5</value>
				</size>
			</end>
		
			<life-sec> <!-- how long the particle will be visible -->
				<value>5</value>
			</life-sec>
			<mass-kg>0.5</mass-kg> 
			<radius-m>0.1</radius-m>
		</particle>
		
		<program>
			<fluid>air</fluid>
			<gravity type="bool">true</gravity> <!-- should be set to true for fireworks to simulate fallout -->
			<wind type="bool">true</wind>
		</program>
	 </particlesystem>
 </PropertyList>

So now we have one radial. Now create another file to put multiple radials into a circle - I name it $FGDATA/Models/Effects/Fireworks/circular-white.xml. For each radial, we use a <model> tag to load the radial file we created above and an roll offset so that the radials actually form a circle:

<?xml version="1.0"?>
<PropertyList>
	<offsets>
		<z-m>500</z-m> <!-- this is the height in meters above the ground at which the firework will be seen -->
	</offsets>
	
	<!-- one <model> section per radial -->
	<model>
		<path>circular-white-radial.xml</path> <!-- path to the radial XML file we created above - relative to this file -->
		<offsets>
			<roll-deg>0</roll-deg> <!-- use this to rotate the radials around the X axis so they don't go all on top of the others -->
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>20</roll-deg>
		</offsets>
	</model>		
 	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>40</roll-deg>
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>60</roll-deg>
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>80</roll-deg>
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>100</roll-deg>
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>120</roll-deg>
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>140</roll-deg>
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>160</roll-deg>
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>180</roll-deg>
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>200</roll-deg>
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>220</roll-deg>
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>240</roll-deg>
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>260</roll-deg>
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>280</roll-deg>
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>300</roll-deg>
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>320</roll-deg>
		</offsets>
	</model>		
	<model>
		<path>circular-white-radial.xml</path>
		<offsets>
			<roll-deg>340</roll-deg>
		</offsets>
	</model>		
</PropertyList>

Now, hop into the UFO, set the time to Night so you have a dark sky, press l and select the $FGDATA/Models/Effects/Fireworks/circular-white.xml file we just created. Click anywhere on the ground some distance away, look up and watch the result of your work ! If you have done everything right, the result should be like this (I have placed the firework multiple times and used both red and white fireworks):