1360 lines
51 KiB
HTML
1360 lines
51 KiB
HTML
|
|
<!-- Standard Header Begin -->
|
|
<html>
|
|
|
|
<head>
|
|
<title>FlightGear Flight Simulator</title>
|
|
<link rel="stylesheet" type="text/css" href="../default.css">
|
|
</head>
|
|
|
|
<body>
|
|
<div id="top">
|
|
<a href="../"><img id="titlebar" src="../images/fglogosm.jpg" alt=""></a>
|
|
</div>
|
|
|
|
<table id="global">
|
|
<tbody><tr>
|
|
<td id="menu">
|
|
<!-- Use a replacescript to update the menu -->
|
|
<h3>About</h3>
|
|
<a href="..">Home</a><br>
|
|
</td>
|
|
<td id="page">
|
|
<!-- Standard Header End -->
|
|
<h1>Mini-HOWTO: 3D Aircraft Models in FlightGear</h1>
|
|
|
|
<h2>11 March 2002</h2>
|
|
<h2>David Megginson</h2>
|
|
<br>
|
|
|
|
<div>
|
|
<h3>Introduction</h3>
|
|
|
|
<br>This mini-HOWTO explains how to add 3D aircraft models to
|
|
FlightGear, and how to animate and position those models. No C++
|
|
programming is required, but the user will need some knowledge of
|
|
FlightGear's property system and XML markup, and will need to
|
|
understand the coordinate system FlightGear uses for its models:<br>
|
|
|
|
<ul>
|
|
<li>distances are in meters
|
|
<li>angles are in degrees
|
|
<li>the x-axis runs lengthwise, towards the back
|
|
<li>the y-axis runs sideways, towards the right
|
|
<li>the z-axis runs upwards
|
|
<li>heading is a rotation around the z-axis, where
|
|
positive is clockwise viewed from above
|
|
<li>pitch is a rotation around the y-axis, where
|
|
positive is clockwise viewed from the left
|
|
<li>roll is a rotation around the x-axis, where positive is clockwise
|
|
viewed from behind</li>
|
|
</ul>
|
|
|
|
<img src="img/model-howto-heading.jpg" width="500" height="497" alt="Heading Illiustration">
|
|
<img src="img/model-howto-pitch.jpg" width="499" height="349" alt="Pitch Illiustration">
|
|
<img src="img/model-howto-roll.jpg" width="500" height="244" alt="Roll Illiustration">
|
|
|
|
<p>This mini-HOWTO contains three parts:</p>
|
|
|
|
<ol>
|
|
<li><a href="#loading">Loading the model</a>
|
|
<li><a href="#repositioning">Repositioning the model</a>
|
|
<li><a href="#animating">Animating the model</a></li>
|
|
</ol>
|
|
|
|
<!-- end of "Summary" -->
|
|
</div>
|
|
|
|
|
|
<div><a name="loading"></a>
|
|
<h3>1. Loading the model</h3>
|
|
|
|
<p>Through <a href="http://www.openscenegraph.org/">OpenSceneGraph</a>,
|
|
FlightGear supports many different 3D file formats, including VRML2,
|
|
AC3D, DXF, and
|
|
<a href="http://www.openscenegraph.org/osgwiki/pmwiki.php/UserGuides/Plugins">many others</a>.
|
|
The property <var>/sim/model/path</var> in the main FlightGear
|
|
property tree controls what model will be loaded; it takes
|
|
a string value giving the relative path of the model from
|
|
<var>FG_ROOT</var> (the root of the base package, such as
|
|
<code>/usr/local/lib/FlightGear</code> or
|
|
<code>C:\FLIGHTGEAR\</code>).</p>
|
|
|
|
<p>The easiest way to load a new model is to set the property at
|
|
startup with the <var>--prop:</var> command-line option; for example,
|
|
to use a 3D aircraft model that you have installed in
|
|
<code>$FG_ROOT/Models/my-cessna.wrl</code>, you could invoke
|
|
FlightGear like this (under Unix-like systems):</p>
|
|
|
|
<blockquote><pre>fgfs --prop:/sim/model/path=Models/my-cessna.wrl
|
|
</pre></blockquote>
|
|
|
|
<p>(<strong>Note:</strong> Normaly any textures used by the model must appear
|
|
in the same directory. If <code>my-cessna.wrl</code> uses the
|
|
textures <code>cessna01.rgb</code> and <code>cessna02.rgb</code>, you
|
|
should install those textures in <code>$FG_ROOT/Models/</code>.
|
|
It is howerever possible to specify a path (relative to the model path)
|
|
to specify where the textures could be found.)</p>
|
|
|
|
<p>When you want to set a 3D model permanently as the default for an
|
|
aircraft rather than specifying it on the command line, you need to
|
|
edit an aircraft settings file. In the
|
|
<code>$FG_ROOT/Aircraft/</code> directory there is a series of files
|
|
ending in <code>-set.xml</code>, such as <code>c172-set.xml</code>,
|
|
<code>dc3-yasim-set.xml</code>, and <code>beech99-uiuc-set.xml</code>.
|
|
When you start FlightGear with the <var>--aircraft</var> option, it
|
|
reads the properties from one of these files; for example</p>
|
|
|
|
<blockquote><pre>fgfs --aircraft=dc3-yasim
|
|
</pre></blockquote>
|
|
|
|
<p>Loads the properties from
|
|
<code>$FG_ROOT/Aircraft/dc3-yasim-set.xml</code> into the main
|
|
FlightGear property tree. These files are in the same XML
|
|
property-list format as <code>$FG_ROOT/preferences.xml</code> and the
|
|
FlightGear save files. There may be many XML files with different
|
|
startup conditions, sounds, panels, 3D models, etc. for any single
|
|
aircraft type, so you are best off copying an existing one, renaming
|
|
it, then changing the value inside the <var>path</var> element inside
|
|
<var>model</var> inside <var>sim</var>:</p>
|
|
|
|
<blockquote><pre><PropertyList>
|
|
<sim>
|
|
<model>
|
|
<path>Models/my-cessna.wrl</path>
|
|
<texture-path>./Textures</texture-path>
|
|
</model>
|
|
</sim>
|
|
</PropertyList>
|
|
</pre></blockquote>
|
|
|
|
<p>So far, all of the examples have had the <var>/sim/model/path</var>
|
|
property point directly at the 3D model file
|
|
(<code>Models/my-cessna.wrl</code>); however, if you want to be able
|
|
to reposition or animate the model, you need to point to an
|
|
intermediate XML file instead, and then put the repositioning and
|
|
animation information into the XML file. Here's a simple example of a
|
|
3D-model wrapper file, with no repositioning or animation
|
|
information:</p>
|
|
|
|
<blockquote><pre><PropertyList>
|
|
<path>my-cessna.wrl</path>
|
|
<texture-path>./Textures</texture-path>
|
|
</PropertyList>
|
|
</pre></blockquote>
|
|
|
|
<p>Like the <var>-set.xml</var> files, this file is in XML property
|
|
list format, but the properties in it are not added to the main
|
|
FlightGear property tree; they're used only while loading the
|
|
model. The following sections will explain how to add repositioning
|
|
and animation information to the file; for now, the only property to
|
|
worry about is <var>path</var>: it provides the relative path to the
|
|
actual 3D file from the XML wrapper file (<strong>not</strong> from
|
|
<var>FG_ROOT</var>!). Usually, you should put the wrapper file in the
|
|
same directory as the 3D file, and then have
|
|
<var>/sim/model/path</var> point to the wrapper file, either on the
|
|
command line</p>
|
|
|
|
<blockquote><pre>fgfs --prop:/sim/model/path=Models/my-cessna.xml
|
|
</pre></blockquote>
|
|
|
|
<p>or in the <code>-set.xml</code> file:</p>
|
|
|
|
<blockquote><pre><PropertyList>
|
|
<sim>
|
|
<model>
|
|
<path>Models/my-cessna.xml</path>
|
|
</model>
|
|
</sim>
|
|
</PropertyList>
|
|
</pre></blockquote>
|
|
|
|
<!-- end of "Loading the model" -->
|
|
</div>
|
|
|
|
|
|
<div><a name="repositioning"></a>
|
|
<h3>2. Repositioning the Model</h3>
|
|
|
|
<p>Often, an aircraft model not designed specifically for FlightGear
|
|
will not be positioned or oriented correctly; for example, it might be
|
|
too far off the ground, and the nose might point to the side or even
|
|
straight up.</p>
|
|
|
|
<p>Inside the XML wrapper file (<em>not</em> the main FlightGear
|
|
property tree), there are six properties that allow you to tweak the
|
|
default position and orientation of the model:</p>
|
|
|
|
<dl compact ><dt><strong>/offsets/x-m</strong><dd>The distance to reposition the model along the
|
|
x-axis.<dt><strong>/offsets/y-m</strong><dd>The distance to reposition the model along the
|
|
y-axis.<dt><strong>/offsets/z-m</strong><dd>The distance to reposition the model along the
|
|
z-axis.<dt><strong>/offsets/heading-deg</strong><dd>The angle by which to rotate the model around
|
|
the z-axis.<dt><strong>/offsets/roll-deg</strong><dd>The angle by which to rotate the model around
|
|
the x-axis.<dt><strong>/offsets/pitch-deg</strong><dd>The angle by which to rotate the model around the y-axis.</dd></dl>
|
|
|
|
<p>For example, if you wanted to use the 3D model
|
|
<code>my-cessna.wrl</code> but found that the nose was pointing to the
|
|
right instead of straight-ahead and the wheels were 1.5 meters off the
|
|
ground, you could reorient it in the XML wrapper file like this:</p>
|
|
|
|
<blockquote><pre><PropertyList>
|
|
<sim>
|
|
<model>
|
|
<path>Models/my-cessna.xml</path>
|
|
</model>
|
|
</sim>
|
|
<offsets>
|
|
<heading-deg>270</heading-deg>
|
|
<z-m>-1.5</z-m>
|
|
</offsets>
|
|
</PropertyList>
|
|
</pre></blockquote>
|
|
|
|
<p>It usually takes a bit of experimentation to get the model
|
|
positioned correctly.</p>
|
|
|
|
<!-- end of "Repositioning the Model" -->
|
|
</div>
|
|
|
|
|
|
<div><a name="animating"></a>
|
|
<h3>3. Animating the Model</h3>
|
|
|
|
<p>Now for the interesting part. FlightGear allows you to animate
|
|
models by having parts rotate or spin in response to property changes:
|
|
for example, the propellers can spin when the engine is on and the
|
|
elevators can move up and down with your controller. There is no
|
|
fixed limit on what parts can be animated: the only requirements are
|
|
that the part is named in the 3D model file, and that there is a
|
|
property in the main tree that you can use to get the positioning
|
|
information.</p>
|
|
|
|
<p>Currently, there are several types of animation recognized:</p>
|
|
|
|
<ol>
|
|
<li>none
|
|
<li>billboard
|
|
<li>rotate
|
|
<li><a href="#scale">scale</a>
|
|
<li><a href="#blend">blend</a>
|
|
<li><a href="#select">select</a>
|
|
<li>spin
|
|
<li>timed
|
|
<li>translate
|
|
<li><a href="#texrotate">texrotate</a>
|
|
<li><a href="#textranslate">textranslate</a>
|
|
<li><a href="#textmultiple">textmultiple</a>
|
|
<li><a href="#material">material</a>
|
|
<li><a href="#range">range</a>
|
|
<li><a href="#alphatest">alpha-test</a>
|
|
<li><a href="#noshadow">noshadow</a>
|
|
<li><a href="#dist-scale">dist-scale</a>
|
|
<li><a href="#flash">flash</a></li>
|
|
</ol>
|
|
|
|
<p>Typically you will use combinations of rotate, spin, and translate
|
|
to animate the main control surfaces for most standard-configuration
|
|
aircraft. <var>spin</var> rotates the
|
|
object around an axis with a known rotational velocity (not worrying
|
|
about the exact position), and <var>rotate</var> rotates the object
|
|
around an axis to an exact position.</p>
|
|
|
|
<p>Every animation appears inside an <var>animation</var> element, and
|
|
contains a <var>type</var> property and at least one
|
|
<var>object-name</var> property:</p>
|
|
|
|
<blockquote><pre><animation>
|
|
<type>rotate</type>
|
|
<object-name>Rudder</object-name>
|
|
</animation>
|
|
</pre></blockquote>
|
|
|
|
<p>It is possible to omit the <var>type</var> parameter. In this case,
|
|
the type is <var>none</var> and the animation is there only to group
|
|
objets under a single name that can be used in another animation located
|
|
farther in the file. Grouping objects in animations, with a <var>type</var>
|
|
or not, has the effect of reparenting the objects specified in <var>object-name</var>.
|
|
The rule is that the group is inserted between the first object and its parent,
|
|
and then subsequent objects are removed from their original parent and added
|
|
to the new group.</p>
|
|
|
|
<p><var>none</var> animations are also handy to reorganise objects in a model.
|
|
When objects are translucents, they should be drawn back to front in order to
|
|
see the world that lies behind through the object. But the drawing order is often
|
|
the order of appearance in the model file, and it is hard to control inside the
|
|
modeler. This way, one can ignore the order in the modeler, and force the
|
|
reordering at load time. The order is of course the order of appearance of
|
|
the <var>object-name</var> clause inside the animation. Be aware that this
|
|
can be ruined by another subsequent animation (last have precedence over first).</p>
|
|
|
|
<p>The object name must match exactly the object name used in the 3D
|
|
file (including case). You may include more than one object name to
|
|
apply the same transformation to more than one object, assuming that
|
|
they rotate around exactly the same line:</p>
|
|
|
|
<blockquote><pre><animation>
|
|
<type>rotate</type>
|
|
<object-name>LeftElevator</object-name>
|
|
<object-name>RightElevator</object-name>
|
|
</animation>
|
|
</pre></blockquote>
|
|
|
|
<p>It is possible to omit the <var>type</var> parameter. In this case,
|
|
the type is <var>null</var> and the animation is there only to group
|
|
objets under a single name that can be used in another animation located
|
|
farther in the file. Grouping objects in animations, with a <var>type</var>
|
|
or not, has the effect of reparenting the objects specified in <var>object-name</var>.
|
|
The rule is that the group is inserted between the first object and its parent,
|
|
and then subsequent objects are removed from their original parent and added
|
|
to the new group.</p>
|
|
|
|
<p>The resulting branch is solid when it comes to compute Height Over Terrain (HOT).
|
|
When an object is there to model a beam of light, or another non solid artefact, it
|
|
can be interesting to ignore it for crash detection. It is done by inserting </p>
|
|
<blockquote><pre><enable-hot type="boolean">false</enable-hot></pre></blockquote>
|
|
<p>in the animation clause. By default, <var>enable-hot</var> is set to true and one
|
|
can land on the roof of a building.</p>
|
|
|
|
<p>Each animation must be associated with exactly one property from
|
|
the main FlightGear property tree (remember that the properties in the
|
|
wrapper file are not part of the main tree), using <var>property</var>
|
|
to provide the property name:</p>
|
|
|
|
<blockquote><pre><animation>
|
|
<type>rotate</type>
|
|
<object-name>Rudder</object-name>
|
|
<property>/controls/rudder</property>
|
|
</animation>
|
|
</pre></blockquote>
|
|
|
|
<p>This example rotates the rudder according to the value of the
|
|
<var>/controls/rudder</var> property (or at least, it will when we
|
|
specify the center and axis of rotation below); however,
|
|
<var>/controls/rudder</var> is normalized from -1.0 to 1.0, and we
|
|
probably want to rotate the rudder more than that; as a result, we
|
|
need to use the <var>factor</var> property to do scaling. For
|
|
example, if the rudder on the actual aircraft rotates 18 degrees in
|
|
each direction, we would use a factor of 18 to scale the rudder
|
|
position from -18 degrees to 18 degrees:</p>
|
|
|
|
<blockquote><pre><animation>
|
|
<type>rotate</type>
|
|
<object-name>Rudder</object-name>
|
|
<property>/controls/rudder</property>
|
|
<factor>18</factor>
|
|
</animation>
|
|
</pre></blockquote>
|
|
|
|
<p>If you wanted to reverse the direction of rudder movement, you
|
|
would use a factor of -18.</p>
|
|
|
|
<p>There is also an <var>offset-deg</var> property that can be useful for
|
|
starting the rotation from a point other than center. For example,
|
|
let's say that you want the rudder to start 1% to the left rather than
|
|
dead center; you could specify that like this:</p>
|
|
|
|
<blockquote><pre><animation>
|
|
<type>rotate</type>
|
|
<object-name>Rudder</object-name>
|
|
<property>/controls/rudder</property>
|
|
<offset-deg>-0.01</offset-deg>
|
|
<factor>18</factor>
|
|
</animation>
|
|
</pre></blockquote>
|
|
|
|
<p>The offset is applied <em>after</em> the factor.</p>
|
|
|
|
<p>Finally, there are <var>min</var> and <var>max</var> properties
|
|
that can constrain the amount of rotation in degrees, as in this (very
|
|
complicated) example for the Cessna 310 landing gear:</p>
|
|
|
|
<blockquote><pre><animation>
|
|
<type>rotate</type>
|
|
<object-name>NoseWheel</object-name>
|
|
<property>/gear/gear[0]/position-norm</property>
|
|
<factor>120</factor>
|
|
<offset-deg>-1</offset-deg>
|
|
<min>-90</min>
|
|
<max>0</max>
|
|
<center>
|
|
<x-m>-2.28</x-m>
|
|
<y-m>0.0</y-m>
|
|
<z-m>-0.65</z-m>
|
|
</center>
|
|
<axis>
|
|
<x>0</x>
|
|
<y>1</y>
|
|
<z>0</z>
|
|
</axis>
|
|
</animation>
|
|
</pre></blockquote>
|
|
|
|
<p>In this example, the gear position (from 0.0 for fully retracted to
|
|
1.0 for fully extended) is multiplied by a factor of 120 and an offset
|
|
of -1, then clamped to between -90 and 0. In the 3D model, the gear
|
|
is extended by default, so we end up with the following rotations
|
|
through the gear's range of movement:</p>
|
|
|
|
<table border="1">
|
|
|
|
<tbody><tr>
|
|
<th>position-norm</th>
|
|
<th>+ offset -1</th>
|
|
<th>* factor 120</th>
|
|
<th>clamped to min/max -90:0</th>
|
|
<th>comments</th>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>0.0</td>
|
|
<td>-1.0</td>
|
|
<td>-120.0</td>
|
|
<td>-90.0</td>
|
|
<td>fully retracted</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>0.25</td>
|
|
<td>-0.75</td>
|
|
<td>-90.0</td>
|
|
<td>-90.0</td>
|
|
<td>still retracted</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>0.5</td>
|
|
<td>-0.5</td>
|
|
<td>-60.0</td>
|
|
<td>-50.0</td>
|
|
<td>1/3 extended</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>0.75</td>
|
|
<td>-0.25</td>
|
|
<td>-30.0</td>
|
|
<td>-30.0</td>
|
|
<td>2/3 extended</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td>1.0</td>
|
|
<td>0.0</td>
|
|
<td>0.0</td>
|
|
<td>0.0</td>
|
|
<td>fully extended (default position)</td>
|
|
</tr>
|
|
|
|
</tbody></table>
|
|
|
|
<p>The gear does not move at all during the first 1/4 of the
|
|
position-norm value, giving the doors a chance to open and close in a
|
|
separate animation. Obviously, this would be easier to manage with an
|
|
interpolation table, and future versions of the model animation will
|
|
likely support interpolation.</p>
|
|
|
|
<p>Update: Interpolation tables our now supported. Each table entry
|
|
plots a dependency point and output values
|
|
are interpolated in a linear manner between two points. In the following
|
|
example an input property value of
|
|
25 will result in an application of a value 65 to the animation
|
|
(65 degrees rotation maybe):</p>
|
|
|
|
<blockquote><pre> <interpolation>
|
|
<entry>
|
|
<ind>0</ind>
|
|
<dep>0</dep>
|
|
</entry>
|
|
<entry>
|
|
<ind>16.67</ind>
|
|
<dep>60</dep>
|
|
</entry>
|
|
<entry>
|
|
<ind>25</ind>
|
|
<dep>65</dep>
|
|
</entry>
|
|
<entry>
|
|
<ind>33.3333</ind>
|
|
<dep>70</dep>
|
|
</entry>
|
|
<entry>
|
|
<ind>66.6667</ind>
|
|
<dep>71</dep>
|
|
</entry>
|
|
<entry>
|
|
<ind>100</ind>
|
|
<dep>75</dep>
|
|
</entry>
|
|
</interpolation>
|
|
</pre></blockquote>
|
|
|
|
<p>For a <var>spin</var> animation, the property provides a value in
|
|
revolutions per minute (RPM) rather than an absolute position in
|
|
degrees, and offset is not used. You can still use <var>factor</var>
|
|
to scale the property value if it is not in RPM.</p>
|
|
|
|
<p>Now, it is necessary to specify the axis of rotation for the
|
|
object, its virtual hinge. This is often the hardest part, requiring
|
|
a lot of trial-and-error when the axis of rotation is not lined up
|
|
with the x-, y-, or z- axis (think of ailerons on a swept wing with a
|
|
non-zero dihedral angle). You need to provide two groups of
|
|
information: a point through which the axis of rotation passes, and
|
|
the direction in which the axis is moving.</p>
|
|
|
|
<p>Update: there is now an alternate method for specifying axes
|
|
that avoids the trial-and-error approach. See below after the Cessna
|
|
172 animation examples.<p>
|
|
<p>For the point through which the axis passes, you use the
|
|
<var>/center/x-m</var>, <var>/center/y-m</var>, and
|
|
<var>/center/z-m</var> properties to specify a position in meters,
|
|
using the aircraft's coordinate system. Note that this is the system
|
|
before repositioning: if the original model was pointing sideways,
|
|
then your fuselage will run along the y-axis rather than the
|
|
x-axis. Here is an example for a rudder:</p>
|
|
|
|
<blockquote><pre><animation>
|
|
<type>rotate</type>
|
|
<object-name>Rudder</object-name>
|
|
<property>/controls/rudder</property>
|
|
<factor>18</factor>
|
|
<center>
|
|
<x-m>5.45</x-m>
|
|
<y-m>0.0</y-m>
|
|
<z-m>0.0</z-m>
|
|
</center>
|
|
</animation>
|
|
</pre></blockquote>
|
|
|
|
<p>In this example, the point is right on the y and z axes, but 5.45
|
|
meters along the x axis (i.e. towards the back of the plane).</p>
|
|
|
|
<p>Finally, in addition to the center point, it's necessary to specify
|
|
the direction of the axis that passes through it, using the properties
|
|
<var>/axis/x</var>, <var>/axis/y</var>, and <var>axis/z</var>. These
|
|
are unitless values showing the rate of change in each direction; for
|
|
example, a straight up-and-down rotational axis could be specified
|
|
like this:</p>
|
|
|
|
<blockquote><pre><axis>
|
|
<x>0</x>
|
|
<y>0</y>
|
|
<z>1</z>
|
|
</axis>
|
|
</pre></blockquote>
|
|
|
|
<p>or like this:</p>
|
|
|
|
<blockquote><pre><axis>
|
|
<x>0</x>
|
|
<y>0</y>
|
|
<z>1000000</z>
|
|
</axis>
|
|
</pre></blockquote>
|
|
|
|
<p>Since there's 0 movement along the other two axes, it doesn't
|
|
matter. On the other hand, let's say that the rudder hinge sloped
|
|
back 5% because of a swept tail. In that case, the x-axis would have
|
|
to show some movement as well:</p>
|
|
|
|
<blockquote><pre><axis>
|
|
<x>0.05</x>
|
|
<y>0</y>
|
|
<z>1</z>
|
|
</axis>
|
|
</pre></blockquote>
|
|
|
|
<p>That could just as easily be written as</p>
|
|
|
|
<blockquote><pre><axis>
|
|
<x>1</x>
|
|
<y>0</y>
|
|
<z>20</z>
|
|
</axis>
|
|
</pre></blockquote>
|
|
|
|
<p>as long as the ratios are the same. For a complicated rotation
|
|
axis, like that for an aileron on a swept-back wing with a significant
|
|
dihedral angle, you'll have to specify movement along all three
|
|
axes:</p>
|
|
|
|
<blockquote><pre><axis>
|
|
<x>0.15</x>
|
|
<y>1.00</y>
|
|
<z>0.01</z>
|
|
</axis>
|
|
</pre></blockquote>
|
|
|
|
<p>Here's a complete example, showing the animation for the rudder on
|
|
the Cessna 172:</p>
|
|
|
|
<blockquote><pre><animation>
|
|
<type>rotate</type>
|
|
<object-name>Rudder</object-name>
|
|
<property>/controls/rudder</property>
|
|
<factor>18</factor>
|
|
<center>
|
|
<x-m>5.45</x-m>
|
|
<y-m>0.0</y-m>
|
|
<z-m>0.0</z-m>
|
|
</center>
|
|
<axis>
|
|
<x>0.72</x>
|
|
<y>0.0</y>
|
|
<z>1.0</z>
|
|
</axis>
|
|
</animation>
|
|
</pre></blockquote>
|
|
|
|
<p>And here's an example of a spin, using the Cessna 172
|
|
propeller:</p>
|
|
|
|
<blockquote><pre><animation>
|
|
<type>spin</type>
|
|
<object-name>Propeller</object-name>
|
|
<property>/engines/engine[0]/rpm</property>
|
|
<center>
|
|
<x-m>0</x-m>
|
|
<y-m>0</y-m>
|
|
<z-m>-.25</z-m>
|
|
</center>
|
|
<axis>
|
|
<x>1.0</x>
|
|
<y>0.0</y>
|
|
<z>0.0</z>
|
|
</axis>
|
|
</animation>
|
|
</pre></blockquote>
|
|
|
|
<p>There is an alternate method of specifying the axis that can often be find much easier.
|
|
This method is particularly
|
|
helpful for rotating on axes that are at odd angles, such as ailerons on dihedral swept
|
|
wings.</p>
|
|
|
|
<p>It is not necessary to specify a <center> tag for this method as it will be calculated
|
|
automatically. The <axis> tag requres two sets of coordinates (x1-m,y1-m,z1-m and
|
|
x2-m,y2-m,z2-m), one for each end of the axis.
|
|
With an aileron, for example, you would need to specify coordinates from both the right and left
|
|
corner of the aileron along the hinged edge. If your object rotates in the direction opposite
|
|
of what you intended you may correct it by simply swapping the two sets of coordinate values (swap x1
|
|
and x2, y1 and y2, z1 and z2).</p>
|
|
|
|
<p>Here is an example from the 747-400:</p>
|
|
|
|
<blockquote><pre><animation>
|
|
<type>rotate</type>
|
|
<object-name>AileronLeftOuter</object-name>
|
|
<property>/surface-positions/left-aileron-pos-norm</property>
|
|
<factor>-30</factor>
|
|
<axis>
|
|
<x1-m>18.28</x1-m>
|
|
<y1-m>-21.55</y1-m>
|
|
<z1-m>-0.37</z1-m>
|
|
<x2-m>22.51</x2-m>
|
|
<y2-m>-28.37</y2-m>
|
|
<z2-m>0.08</z2-m>
|
|
</axis>
|
|
</animation>
|
|
</pre></blockquote>
|
|
|
|
<p>You can get a lot of your initial measurements by viewing the model
|
|
in a 3D editor like <a href="http://prettypoly.sourceforge.net/">PPE</a>, and you can also
|
|
use PPE to name or rename objects so that you can animate them in
|
|
FlightGear. In the end, though, you'll almost have to do a little
|
|
tweaking by trial and error until everything looks right.</p>
|
|
|
|
<p>This document will likely be out of date by the time you read it.
|
|
Look at the actual XML wrapper files (currently in
|
|
<code>$FG_ROOT/Aircraft/<em>aircraft-type</em>/Models/</code>) to look
|
|
at how FlightGear is doing things now. In the future, we'll be adding
|
|
other animation types, including selecting among different versions of
|
|
the same object (such as a translucent propeller disk for high RPM),
|
|
non-rotational transformations, scaling, and conditionals (i.e. draw
|
|
engine exhaust only above a certain velocity).</p>
|
|
|
|
<p>It is often desired to apply several animations on the same object.
|
|
It is simply done by specifying multiple animations with the same
|
|
<var>object-name</var>. But you must be aware of the order of execution of
|
|
these specified animations. Every new animation takes precedence over previously
|
|
declared one. As we already seen, each new animation is inserted as the parent
|
|
of the object specified as the first <var>object-name</var>. That means that if
|
|
a rotation is already declared, and a new translation is to be inserted, it will
|
|
be between the rotation and the object, making the translation acting on the
|
|
object, and the rotation acting on the translated object.<br>
|
|
So, as a rule of thumb, remember that animations are executed from the
|
|
bottom of the animation file to its top.</p>
|
|
|
|
<p>Most animations can be conditioned by a boolean expression on
|
|
properties. A condition is introduced by the <var>condition</var> element,
|
|
like in this example :</p>
|
|
<blockquote><pre> <condition>
|
|
<greater-than>
|
|
<property>/sim/time/sun-angle-rad</property>
|
|
<value>1.57</value>
|
|
</greater-than>
|
|
</condition></pre></blockquote>
|
|
<p>Valid condition elements are :</p>
|
|
<blockquote><dl>
|
|
<dt><var>property</var></dt>
|
|
<dd>A valid property full path</dd>
|
|
<dt><var>not</var></dt>
|
|
<dt><var>and</var></dt>
|
|
<dt><var>or</var></dt>
|
|
<dd>Boolean operators</dd>
|
|
<dt><var>less-than</var></dt>
|
|
<dt><var>less-than-equals</var></dt>
|
|
<dt><var>greater-than</var></dt>
|
|
<dt><var>greater-than-equals</var></dt>
|
|
<dt><var>equals</var></dt>
|
|
<dt><var>not-equals</var></dt>
|
|
<dd>Comparison operators</dd>
|
|
<dt><var>value</var></dt>
|
|
<dd>A literal value</dd>
|
|
</dl></blockquote>
|
|
<p>These elements can be combined to build an arbitrary expression.</p>
|
|
<p>Animations without conditions are always executed. Animation with a condition
|
|
are only executed when the condition evaluated to <var>true</var>.</p>
|
|
|
|
<p>FlightGear sceneries use shared models. These models are loaded once and
|
|
displayed multiple times. If we apply a transformation on an object of the model,
|
|
every occurence of the model will show the same transformation, creating a
|
|
very unnatural unison. To solve this kind of problem, several animations
|
|
support the notion of personality. It means that a set of parameters are able
|
|
to randomly vary in a specified range if the <var>use-personality</var> boolean
|
|
property is set to <var>true</var>. For the moment, <var>spin</var> and <var>timed</var>
|
|
animations support personality.</p>
|
|
|
|
<h3><a name="select">"select" animation type</a></h3>
|
|
|
|
<p>The select animation is there to remove objects ( specified in the <var>object-name</var>
|
|
elements ) from the scene when the associated condition evaluated to <var>false</var>.</p>
|
|
<p>In the example below :</p>
|
|
<blockquote><pre> <animation>
|
|
<type>select</type>
|
|
<object-name>StrobesOn</object-name>
|
|
<object-name>StrobesOff</object-name>
|
|
<object-name>Fixed</object-name>
|
|
<condition>
|
|
<greater-than>
|
|
<property>/sim/time/sun-angle-rad</property>
|
|
<value>1.57</value>
|
|
</greater-than>
|
|
</condition>
|
|
</animation></pre></blockquote>
|
|
<p>Objects <var>StrobesOn</var>, <var>StrobesOff</var> and <var>Fixed</var> are only present
|
|
in the scene ( displayed ) when the sun is below the horizon ( the meaning of the condition).
|
|
In other words, these objects, that are already in the scene because they were added by the
|
|
designer of the model, are removed when the sun is above the horizon.</p>
|
|
|
|
<h3><a name="timed">"timed" animation type</a></h3>
|
|
|
|
<p>The timed animation selects only one object among those specified by <var>object-name</var>
|
|
for a specified duration. When the displayed time ends, the next object is selected for the
|
|
matching duration.</p>
|
|
<p>The simpler form is :</p>
|
|
<blockquote><pre> <animation>
|
|
<name>BeaconFlasher</name>
|
|
<type>timed</type>
|
|
<object-name>BeaconOff</object-name>
|
|
<object-name>BeaconOn</object-name>
|
|
<duration-sec>1.0</duration-sec>
|
|
</animation></pre></blockquote>
|
|
<p>In this example, each object is displayed during an equal time, specified in seconds.</p>
|
|
<p>This second example use personality :</p>
|
|
<blockquote><pre> <animation>
|
|
<type>timed</type>
|
|
<object-name>StrobesOn</object-name>
|
|
<object-name>StrobesOff</object-name>
|
|
<use-personality type="bool">true</use-personality>
|
|
<branch-duration-sec>
|
|
<random>
|
|
<min>0.9</min>
|
|
<max>1.1</max>
|
|
</random>
|
|
</branch-duration-sec>
|
|
<branch-duration-sec>
|
|
<random>
|
|
<min>0.9</min>
|
|
<max>1.1</max>
|
|
</random>
|
|
</branch-duration-sec>
|
|
</animation></pre></blockquote>
|
|
<p>In this case, there is a <var>branch-duration-sec</var> element for each
|
|
<var>object-name</var> that specify a duration for that object. The value of
|
|
<var>branch-duration-sec</var> could be a literal double value in seconds.<br>
|
|
Here, literals have been replaced by the <var>random</var> element. It means
|
|
that the duration is choosen randomly between <var>min</var> and <var>max</var>.
|
|
Because of the <var>use-personality</var> element set to true, durations are
|
|
allowed to be different for each occurence of this model, breaking the announced
|
|
unison.</p>
|
|
|
|
<h3><a name="scale">"scale" animation type</a></h3>
|
|
|
|
<p>Here is a contrived example of one way to use the "scale" animation
|
|
type. In this case a shadow map is placed below the aircraft and we
|
|
can control the size based on some property value (i.e. alitutude
|
|
above the ground.) In real life, the shadow size should stay pretty
|
|
much fixed, so this technique might ultimately be more useful for a
|
|
landing light.</p>
|
|
|
|
<blockquote><pre> <animation>
|
|
<type>scale</type>
|
|
<object-name>ShadowMap</object-name>
|
|
<property>/position/altitude-agl-ft</property>
|
|
<x-factor>0.05</x-factor>
|
|
<x-offset>1.0</x-offset>
|
|
<y-factor>0.05</y-factor>
|
|
<y-offset>1.0</y-offset>
|
|
<z-factor>0.0</z-factor>
|
|
<z-offset>1.0</z-offset>
|
|
<center>
|
|
<x-m>0.05</x-m>
|
|
<y-m>0.05</y-m>
|
|
<z-m>0.0</z-m>
|
|
</center>
|
|
</animation>
|
|
</pre></blockquote>
|
|
|
|
<p>As with the other animations, you need to specify an object-name and
|
|
the property that will drive this animation. And, as with other types
|
|
of transform animations, the order they are applied is important. For
|
|
a given object, you will probably want to put the scaling animation
|
|
after any other translate or rotate animations.</p>
|
|
|
|
<p>You have some individual control over the X, Y, and Z axis scaling.
|
|
For each dimension you can provide factors (x-factor, y-factor, and
|
|
z-factor) and also offsets (x-offset, y-offset, and z-offset.) You
|
|
can also specify minimum values (x-min, y-min, z-min) and maximum
|
|
values (x-max, y-max, and z-max) for scaling results.</p>
|
|
|
|
<p>You can set the center of scaling with the center tag. The center is
|
|
that point that does not ever change its position under any scaling.
|
|
If unset this defaults to the (0, 0, 0).</p>
|
|
|
|
<p>The amount of scaling for each dimension is computed by the
|
|
following formula (and then clamped if a min or max value is
|
|
specified.)</p>
|
|
|
|
<blockquote><pre> scale = property * factor + offset
|
|
</pre></blockquote>
|
|
|
|
<p>Specifying a factor of 0.0 and an offset of 1.0 is equivalent to no
|
|
scaling at all.</p>
|
|
|
|
<p>As you can see in the above example, at ground level (the property
|
|
value = 0.0) the scaling formula will evaluate to 1.0 (no scaling.)
|
|
As altitude above the ground increases, the scaling factor will
|
|
increase by agl * 0.05 + 1.0. Note that because a shadow has no depth
|
|
we use a z-factor of 0.0 and a z-offset of 1.0 so the formula always
|
|
evalutes to a scaling factor of 1.0 in the Z dimension.</p>
|
|
|
|
<h3><a name="blend">"blend" animation type</a></h3>
|
|
|
|
<p>The blend animation type can be used to adjust the transparency of
|
|
an object. To controll it's behavior it is possible to define:</p><p>
|
|
|
|
<table>
|
|
<tbody><tr>
|
|
<td><b>property</b></td>
|
|
<td><i>use the value of this property in the calculation</i></td>
|
|
</tr>
|
|
<tr>
|
|
<td><b>offset</b></td>
|
|
<td><i>offset, ranges from 0.0 to 1.0</i></td>
|
|
</tr>
|
|
<tr>
|
|
<td><b>factor</b></td>
|
|
<td><i>multiplication factor for the property</i></td>
|
|
</tr>
|
|
</tbody></table>
|
|
|
|
</p><p>The formula used is:
|
|
</p><blockquote><pre>alpha = property * factor + offset
|
|
</pre></blockquote>
|
|
|
|
<p>The result should be between 0.0 and 1.0 where 0.0 equals to a fully visible model and 1.0 equals to a fully transparent model.</p>
|
|
|
|
<p>To gain greater controll over the result it is possible to limit
|
|
the result by defining a <min> and/or a <max> parameter.
|
|
</p>
|
|
|
|
<p><strong>Note:</strong> This
|
|
effect will only work if there is already a transparent component in the
|
|
object, either in the vertex color or in the texture.
|
|
<!-- end of "Animating the Model" -->
|
|
|
|
|
|
<h3><a name="texrotate">"texrotate" texture rotation animation type</a></h3>
|
|
|
|
<p>This animation will adjust the texture mapping on an object
|
|
so that the texture image appears to rotate about
|
|
the specified center on the object. Note that when talking
|
|
about texture mapping, meaningful values are from
|
|
0.0 ~ 1.0. Texture coordinates are commonly specified as (u,v).
|
|
A square object's lower left corner would generally be
|
|
specified as (u=0,v=0) and the upper right corner as (u=1,v=1). The
|
|
center will be (u=0.5, v=0.5). These values
|
|
will be vary (within the 0.0 ~ 1.0 range) if only a portion of a texture is
|
|
mapped (see compass rose example below).</p>
|
|
|
|
<p>For the purpose of specifying the <center> tag
|
|
you need only use the x and y coordinates.
|
|
The <axis> tag usually only requires a value for z. It is possible to
|
|
obtain some unusual texture mapping effects, like as giving the illusion of
|
|
perspective on a flat stationary surface by using the other axes. Here is
|
|
an example of a rotating compass rose on the 747-400 PDF
|
|
(primary flight display):<p>
|
|
|
|
<blockquote><pre> <animation>
|
|
<type>texrotate</type>
|
|
<object-name>rose</object-name>
|
|
<property>/orientation/heading-magnetic-deg</property>
|
|
<center>
|
|
<x>0.75</x>
|
|
<y>0.75</y>
|
|
<z>0.0</z>
|
|
</center>
|
|
<axis>
|
|
<x>0</x>
|
|
<y>0</y>
|
|
<z>-1</z>
|
|
</axis>
|
|
</animation>
|
|
</pre></blockquote>
|
|
|
|
<p>The center in this example is (0.75, 0.75) because the compass
|
|
rose only occupies the upper right corner of the total
|
|
texture image that it is contained in. The other three quardrants
|
|
have other textures for the same model. As mentioned
|
|
before, the coordinates are (0,0) lower left to (1,1) upper right,
|
|
the center of the upper right quadrant is thus (0.75, 0.75).
|
|
|
|
<h3><a name="textranslate">"textranslate" texture translation animation type</a></h3>
|
|
|
|
<p>This animation will adjust the texture mapping on an object so
|
|
that the texture image appears to slides around
|
|
on the object. An <axis> tag is required to specify the axis
|
|
along which the texture is moved (the direction of movement). The
|
|
following example displays the right most digit in the altitude indicator
|
|
on the primary flight display:</p>
|
|
|
|
<blockquote><pre> <animation>
|
|
<type>textranslate</type>
|
|
<object-name>alt1</object-name>
|
|
<property>/position/altitude-ft</property>
|
|
<factor>0.01</factor>
|
|
<axis>
|
|
<x>0</x>
|
|
<y>1</y>
|
|
<z>0</z>
|
|
</axis>
|
|
</animation>
|
|
</pre></blockquote>
|
|
|
|
<p>There are also some special properties available for use in the texture animations. These are:</p>
|
|
|
|
<ol>
|
|
<li>step
|
|
<li>scroll</li>
|
|
</ol>
|
|
|
|
<p>The <step> property is useful if you want animations to
|
|
happen in steps rather than smoothly. It causes values that are
|
|
fractional (between) steps size to be ingnored. It can be used for
|
|
things like changing digits on nurmeric displays or a ticking second
|
|
hand on a clock. The <scroll> property works with the
|
|
<step> property. The scroll value specifies the distance the input
|
|
property value should be from a step when scrolling to the next
|
|
position begins. This type of scrolling is common on EFIS cockpit
|
|
displays. The following example gives an "odometer effect"
|
|
where the hundreds position digit doesn't move until the input value
|
|
is within is within 1 (e.g. > 99):</p>
|
|
|
|
<blockquote><pre><animation>
|
|
<type>textranslate</type>
|
|
<object-name>asi3</object-name>
|
|
<property>/velocities/airspeed-kt</property>
|
|
<factor>0.001</factor>
|
|
<step>100</step>
|
|
<scroll>1</scroll>
|
|
<axis>
|
|
<x>0</x>
|
|
<y>1</y>
|
|
<z>0</z>
|
|
</axis>
|
|
</animation>
|
|
</pre></blockquote>
|
|
|
|
<h3><a name="textmultiple">"textmultiple" type, combining texture animation types</a></h3>
|
|
|
|
<p>The textmultiple animation type isn't a real animation type, but
|
|
instead it is a method of combining multiple texture
|
|
tansform operations on the same object. Unlike object vertex
|
|
operations, texture operations can not be stacked,
|
|
which means that if you configure two or more texture animation tags
|
|
on the same object, only the first in the list will be used. By
|
|
listing operations using texmultiple they are combined together in
|
|
Simgear and then handled as a single operation.</p>
|
|
|
|
<p>If you need to combine together a translation and rotation
|
|
this is the only way to do it currently. Note that
|
|
transform operations are applied in the same order that they are
|
|
listed in the configuration file. The following
|
|
example for the horizon texture from the 747-400 primary flight
|
|
display explains the format clearly:</p>
|
|
|
|
<blockquote><pre><animation>
|
|
<type>texmultiple</type>
|
|
<object-name>horizon</object-name>
|
|
<transform>
|
|
<property>/orientation/pitch-deg</property>
|
|
<subtype>textranslate</subtype>
|
|
<factor>0.0045</factor>
|
|
<axis>
|
|
<x>0</x>
|
|
<y>1</y>
|
|
<z>0</z>
|
|
</axis>
|
|
</transform>
|
|
<transform>
|
|
<property>/orientation/roll-deg</property>
|
|
<subtype>texrotate</subtype>
|
|
<center>
|
|
<x>0.50</x>
|
|
<y>0.50</y>
|
|
</center>
|
|
<axis>
|
|
<x>0</x>
|
|
<y>0</y>
|
|
<z>-1</z>
|
|
</axis>
|
|
</transform>
|
|
</animation>
|
|
</pre></blockquote>
|
|
<h3><a name="range">"range" animation type</a></h3>
|
|
<p>The range type is used to select part of a model using its distance from the
|
|
viewer as the criterion. To be viewed, the model must be between a minimum
|
|
distance and a maximum one. Minimum distance can be specified either with the
|
|
<min-m> element or the <min-property> element that are exclusive.
|
|
The first one allow to specify a fixed distance in meters, the latter allow to
|
|
lookup the value from a property. Both can be multiplied by a fixed amount,
|
|
specified in the <min-factor> element. The same apply for the maximum
|
|
value with <max-m>, <max-property> and <max-factor> elements.
|
|
The example below shows how it can be used :</p>
|
|
<blockquote>
|
|
<pre><animation>
|
|
<type>range</type>
|
|
<object-name>Detailed</object-name>
|
|
<min-m>0</min-m>
|
|
<max-property>/sim/rendering/static-lod/detailed</max-property>
|
|
</animation>
|
|
</pre>
|
|
</blockquote>
|
|
<h3><a name="alphatest">"alpha-test" animation type</a></h3>
|
|
<p>This "animation" is a way to set an alpha test on a model branch. The effect
|
|
is to avoid depth buffer writing of pixel that are not seen because they are
|
|
transparent. This is particulary useful when modeling a metallic structure or a
|
|
tree with a billboard. The threshold of transparency is set with the
|
|
<alpha-factor> element like this :</p>
|
|
<blockquote>
|
|
<pre><animation>
|
|
<type>alpha-test</type>
|
|
<object-name>Detailed</object-name>
|
|
<alpha-factor>0.01</alpha-factor>
|
|
</animation>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<h3><a name="noshadow">"noshadow" animation type</a></h3>
|
|
<p>This "animation" prevents the shadow casting code to include this object,
|
|
which might be handy when it doesn't cast a shadow (exhaust flame) or when
|
|
it looks ugly.</p>
|
|
<blockquote>
|
|
<pre><animation>
|
|
<type>noshadow</type>
|
|
<object-name>Wires.1</object-name>
|
|
<object-name>Wires.2</object-name>
|
|
</animation>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<h3><a name="dist-scale">"dist-scale" animation type</h3>
|
|
<p>This animation enables to scale an object based on the distance of its
|
|
center to the viewer. It was designed to compensate the effect of fog on
|
|
emissive (light) sources that is too strong ( lights are hardly visible at distance )<br>
|
|
Parameters, with default values, are :</p>
|
|
<blockquote>
|
|
<pre><animation>
|
|
<type>dist-scale</type>
|
|
<object-name>RedLight.11</object-name>
|
|
<factor>1.0</factor>
|
|
<offset>0.0</offset>
|
|
<min>0.0</min>
|
|
<max>1.0</max>
|
|
<center>
|
|
<x-m>0.0</x-m>
|
|
<y-m>0.0</y-m>
|
|
<z-m>0.0</z-m>
|
|
</center>
|
|
</animation>
|
|
</pre>
|
|
</blockquote>
|
|
<p>Or, with an interpolation table :</p>
|
|
<blockquote>
|
|
<pre><animation>
|
|
<type>dist-scale</type>
|
|
<object-name>RedLight.11</object-name>
|
|
<interpolation>
|
|
<entry><ind>0</ind><dep>0.1</dep></entry>
|
|
<entry><ind>500</ind><dep>0.2</dep></entry>
|
|
<entry><ind>16000</ind><dep>3</dep></entry>
|
|
</interpolation>
|
|
<min>0.0</min>
|
|
<max>3.0</max>
|
|
<center>
|
|
<x-m>0.0</x-m>
|
|
<y-m>0.0</y-m>
|
|
<z-m>0.0</z-m>
|
|
</center>
|
|
</animation>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<h3><a name="flash">"flash" animation type</h3>
|
|
<p>This animation was designed to scale an object based on the angle between
|
|
an arbitrary axis and the axis that goes between the viewer and the center of
|
|
the object. The sought effect was the <i>flash</i> of a lighthouse or beacon,
|
|
or whatever intense narrow light beam, hence the name.<br>
|
|
Parameters, with default values, are :</p>
|
|
<blockquote>
|
|
<pre><animation>
|
|
<type>flash</type>
|
|
<object-name>WhiteFlash.2</object-name>
|
|
<offset>0.0</offset>
|
|
<factor>1.0</factor>
|
|
<power>1.0</power>
|
|
<two-sides type="boolean">false</two-sides>
|
|
<min>0.0</min>
|
|
<max>1.0</max>
|
|
<center>
|
|
<x-m>0.0</x-m>
|
|
<y-m>0.0</y-m>
|
|
<z-m>0.0</z-m>
|
|
</center>
|
|
<axis>
|
|
<x>0.0</x>
|
|
<y>0.0</y>
|
|
<z>1.0</z>
|
|
</axis>
|
|
</animation>
|
|
</pre>
|
|
</blockquote>
|
|
<p>The scale formulae is :<br>
|
|
<center>S = factor * pow( cos_angle, power ) + offset</center><br>
|
|
cos_angle being the cosine of the angle between the axis and the line
|
|
between the center and the viewer.<br>
|
|
The value S is clamped between min and max.<br>
|
|
No interpolation table is allowed in this animation.
|
|
</p>
|
|
|
|
<h3><a name="material">"material" animation type</a></h3>
|
|
<p>This "animation" can set any of the material properties on a model branch, including
|
|
the texture file path. The following minimalistic example animation allows to change the
|
|
"panel" object's emissive color from (0,0,0) to (1,.2,0) by setting the factor property
|
|
to values between 0.0 and 1.0.</p>
|
|
|
|
<blockquote>
|
|
<pre><animation>
|
|
<type>material</type>
|
|
<object-name>panel</object-name>
|
|
<emission>
|
|
<red>1.0</red>
|
|
<green>0.2</green>
|
|
<blue>0.0</blue>
|
|
<factor-prop>/controls/lighting/instruments-norm</factor-prop>
|
|
</emission>
|
|
</animation>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
|
|
<p>Changes made with this animation type are by default only effective for the objects listed in
|
|
<object-name> tags, whereby you can use more than one of those. The next example, however,
|
|
sets the optional <global> property, so that changes affect all objects that share
|
|
the same material. This is the preferred method and should be used whereever possible. It isn't
|
|
only faster, but also doesn't break other animations by forcing objects into the same branch.
|
|
Note that all material properties can be set to fixed values, for instance <red> or, by appending
|
|
"-prop", to the contents of another property node: <red-prop>. Because a "material" animation
|
|
can contain a lot of such property paths, which is a nuisance to write, hard to read, and a potential
|
|
source for typos, there's a <property-base> component. Its string value is prepended to
|
|
all material property names (but not to property paths in a <condition> statement!).
|
|
The following example shows all available elements:</p>
|
|
|
|
<blockquote>
|
|
<pre><animation>
|
|
<type>material</type>
|
|
<object-name>fuselage</object-name>
|
|
<condition>
|
|
<property>/sim/model/foo/animate-fuselage-material</property>
|
|
</condition>
|
|
<global type="bool">true</global>
|
|
<property-base>/sim/model/foo/material/fuselage</property-base>
|
|
<diffuse>
|
|
<red-prop>diffuse/red</red-prop>
|
|
<green-prop>diffuse/green</green-prop>
|
|
<blue-prop>diffuse/blue</blue-prop>
|
|
<factor-prop>diffuse/factor</factor-prop>
|
|
<offset-prop>diffuse/offset</offset-prop>
|
|
</diffuse>
|
|
<ambient>
|
|
<red-prop>ambient/red</red-prop>
|
|
<green-prop>ambient/green</green-prop>
|
|
<blue-prop>ambient/blue</blue-prop>
|
|
<factor-prop>ambient/factor</factor-prop>
|
|
<offset-prop>ambient/offset</offset-prop>
|
|
</ambient>
|
|
<emission>
|
|
<red-prop>emission/red</red-prop>
|
|
<green-prop>emission/green</green-prop>
|
|
<blue-prop>emission/blue</blue-prop>
|
|
<factor-prop>emission/factor</factor-prop>
|
|
<offset-prop>emission/offset</offset-prop>
|
|
</emission>
|
|
<specular>
|
|
<red-prop>specular/red</red-prop>
|
|
<green-prop>specular/green</green-prop>
|
|
<blue-prop>specular/blue</blue-prop>
|
|
<factor-prop>specular/factor</factor-prop>
|
|
<offset-prop>specular/offset</offset-prop>
|
|
</specular>
|
|
<shininess>
|
|
<transparency>
|
|
<alpha-prop>transparency/alpha</alpha-prop>
|
|
<factor-prop>transparency/factor</factor-prop>
|
|
<offset-prop>transparency/offset</offset-prop>
|
|
<min>0.0<min> <!-- no min-prop! -->
|
|
<max>1.0<max> <!-- no max-prop! -->
|
|
</transparency>
|
|
<texture>texture</texture>
|
|
<threshold>threshold</threshold>
|
|
</animation>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>A change to one of the components in each color group does always update
|
|
all three color components. Unset values default to zero. The <texture> path
|
|
is relative to the model's <texture-path> directory, or, if unset, to the model
|
|
directory. All numerical values are clamped to 0.0-1.0, except <shininess>, which is
|
|
clamped to 0.0-128.0. The <alpha> property (<transparency> group) makes an
|
|
object fully transparent (and thus invisible) with 0.0, and fully opaque with 1.0.
|
|
("alpha" could also be called "opaqueness".) The <threshold> property sets the
|
|
alpha/opaqueness threshold. It is only relevant for semitransparent textures. Only parts
|
|
of the texture that are more opaque than this are diplayed at all. If it is set
|
|
to 0.0, all parts of the texture will be shown. If it is 0.5, only parts with
|
|
opaqueness greater than 0.5 (or transparency less than 0.5) are shown.</p>
|
|
|
|
<p>Note that defining two or more of these animations for the same object,
|
|
or a mixture of "material" and "blend" animations, will probably not yield
|
|
the result that you expect. Try to put all state manipulations for one
|
|
object or material in one "material" animation, and use its "transparency"
|
|
property instead of an extra "blend" animation.</p>
|
|
|
|
<p>To make a texture replaceable at runtime, use a "material" animation
|
|
like this:</p>
|
|
|
|
<blockquote>
|
|
<pre><animation>
|
|
<type>material</type>
|
|
<object-name>tail-vert</object-name>
|
|
<texture-prop>/sim/model/foo/texture</texture-prop>
|
|
</animation>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>and put something like this into your aircraft's *-set.xml file:</p>
|
|
|
|
<blockquote>
|
|
<pre><sim>
|
|
<model>
|
|
<foo>
|
|
<texture>logos/tail-logo.rgb</texture>
|
|
</foo>
|
|
</model>
|
|
</sim>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
|
|
<p>You can explore the influence of material changes at runtime, if you use
|
|
a material animation like the above complete example, and call the material
|
|
dialog on it, like in the following Nasal example. Note, that the path is
|
|
the same that you would set in <property-base>.
|
|
</p>
|
|
|
|
<blockquote>
|
|
<pre>material.showDialog("/sim/model/foo/material/fuselage");</pre>
|
|
</blockquote>
|
|
|
|
<h3><a name="pick">"pick" animation type</h3>
|
|
<p>This animation type is used to execute a command binding when the mouse
|
|
is pressed on this particular object. The Commands are the usual bindings
|
|
like used elsewhere in flightgear.
|
|
<p>The visible property tells if the object should be visible as is. Setting
|
|
that to false make sense if you have small buttons on the instrument model
|
|
but you want to have huge active areas for interaction. It defaults to true.
|
|
<blockquote>
|
|
<pre><animation>
|
|
<type>pick</type>
|
|
<object-name>Button</object-name>
|
|
<visible>true</visible>
|
|
<action>
|
|
<button>0</button>
|
|
<repeatable>true</repeatable>
|
|
<interval-sec>0.1</interval-sec>
|
|
<binding>
|
|
<command>property-assign</command>
|
|
<property>instrumentation/button0-pressed</property>
|
|
<value>1</value>
|
|
</binding>
|
|
<mod-up>
|
|
<binding>
|
|
<command>property-assign</command>
|
|
<property>instrumentation/button0-pressed</property>
|
|
<value>0</value>
|
|
</binding>
|
|
</mod-up>
|
|
</action>
|
|
<action>
|
|
<button>1</button>
|
|
<repeatable>true</repeatable>
|
|
<interval-sec>0.1</interval-sec>
|
|
<binding>
|
|
<command>property-assign</command>
|
|
<property>instrumentation/button1-pressed</property>
|
|
<value>1</value>
|
|
</binding>
|
|
<mod-up>
|
|
<binding>
|
|
<command>property-assign</command>
|
|
<property>instrumentation/button1-pressed</property>
|
|
<value>0</value>
|
|
</binding>
|
|
</mod-up>
|
|
</action>
|
|
</animation></pre>
|
|
</blockquote>
|
|
</p>
|
|
|
|
<hr>
|
|
<address>David Megginson, 11 March 2002</address>
|
|
<address>Mathias Fröhlich, 3 Jan 2007</address>
|
|
|
|
<!-- Standard Footer Begin --></div>
|
|
</td></tr>
|
|
</tbody>
|
|
</table>
|
|
<br>
|
|
</body>
|
|
|
|
</html>
|
|
|
|
<!-- Standard Footer End -->
|