3ca20ad9ef
here is the promised material animation. It looks a bit longish, but that wasn't avoidable -- there are simply too many parameters to consider. I tried hard, though, to make the animation fast by only doing the necessary stuff. It doesn't affect the frame rate here with my test model. The animation is heavily based on Jim's "material-emission" animation. * implementation of the "material" animation (this required to make the texture path available) + documentation update ($FG_ROOT/Docs/) * fix some more return values (texture animations, and select) for the shadow problem (and some in anticipation of other problems :-) * fix compiler warning
988 lines
36 KiB
HTML
988 lines
36 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>
|
|
<li>angles are in degrees</li>
|
|
<li>the x-axis runs lengthwise, towards the back</li>
|
|
<li>the y-axis runs sideways, towards the right</li>
|
|
<li>the z-axis runs upwards</li>
|
|
<li>heading is a rotation around the z-axis, where positive is
|
|
clockwise viewed from above</li>
|
|
<li>pitch is a rotation around the y-axis, where positive is clockwise
|
|
viewed from the left</li>
|
|
<li>roll is a rotation around the x-axis, where positive is clockwise
|
|
viewed from behind</li>
|
|
</ul>
|
|
|
|
<p>[[TODO: will someone volunteer to draw diagrams?]]</p>
|
|
|
|
<p>This mini-HOWTO contains three parts:</p>
|
|
|
|
<ol>
|
|
<li><a href="#loading">Loading the model</a></li>
|
|
<li><a href="#repositioning">Repositioning the model</a></li>
|
|
<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://plib.sourceforge.net/">plib</a>, FlightGear
|
|
supports many different 3D file formats, including VRML1, AC3D, DXF,
|
|
MDL (from <cite>Microsoft Flight Simulator</cite>), and many others.
|
|
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="compact"><dt><strong>/offsets/x-m</strong></dt><dd>The distance to reposition the model along the x-axis.</dd><dt><strong>/offsets/y-m</strong></dt><dd>The distance to reposition the model along the y-axis.</dd><dt><strong>/offsets/z-m</strong></dt><dd>The distance to reposition the model along the z-axis.</dd><dt><strong>/offsets/heading-deg</strong></dt><dd>The angle by which to rotate the model around the z-axis.</dd><dt><strong>/offsets/roll-deg</strong></dt><dd>The angle by which to rotate the model around the x-axis.</dd><dt><strong>/offsets/pitch-deg</strong></dt><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-offset-deg>270</heading-offset-deg>
|
|
<z-offset-m>-1.5</z-offset-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>
|
|
<li>billboard</li>
|
|
<li>rotate</li>
|
|
<li><a href="#scale">scale</a></li>
|
|
<li><a href="#blend">blend</a></li>
|
|
<li>select</li>
|
|
<li>spin</li>
|
|
<li>timed</li>
|
|
<li>translate</li>
|
|
<li><a href="#texrotate">texrotate</a></li>
|
|
<li><a href="#textranslate">textranslate</a></li>
|
|
<li><a href="#textmultiple">textmultiple</a></li>
|
|
<li><a href="#material">material</a></li>
|
|
<li><a href="#range">range</a></li>
|
|
<li><a href="#alphatest">alpha-test</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>none</var> is a no-op; <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>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>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</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>-0.01</offset>
|
|
<factor>18</factor>
|
|
</animation>
|
|
</pre></blockquote>
|
|
|
|
<p>The offset is applied <em>before</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>-1</offset>
|
|
<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>
|
|
|
|
<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>
|
|
</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>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 = offset + property * factor
|
|
</pre></blockquote>
|
|
|
|
<p>Specifying an offset of 1.0 and a factor of 0.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 1.0 + agl * 0.05. 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>
|
|
|
|
<p>There is still a plib issue to be aware of when using scale
|
|
animation. When rendering an object, the plib bounding sphere culling
|
|
system isn't aware of the scale transformation so it will do the cull
|
|
based on the object's original size. If you have made the object
|
|
bigger, it will disappear if the space occupied by the original size
|
|
of the object goes out of the view frustum. If you make the object
|
|
smaller then this won't be a problem because the larger original
|
|
object will always contain it's currently smaller version. So one
|
|
work around would be to build the object at it's maximum size and then
|
|
use the scaling transform to always make it smaller.</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>
|
|
<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 (a plib limitation),
|
|
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="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. A simple case for such an animation can look like this:</p>
|
|
|
|
<blockquote>
|
|
<pre><animation>
|
|
<type>material</type>
|
|
<object-name>fuselage</object-name>
|
|
<global type="bool">true</global>
|
|
<emission-red>1.0</emission-red>
|
|
<emission-green>0.8</emission-green>
|
|
<emission-blue>0.3</emission-blue>
|
|
<emission-factor-prop>/controls/lighting/instruments-norm</emission-factor-prop>
|
|
<emission-offset>0.3</emission-offset>
|
|
</animation>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>The change is only effective for the objects listed in "object-name" tags,
|
|
whereby you can use more than one of those. The above example, however,
|
|
sets the optional "global" property, so that the changes affect all objects that share
|
|
the same material. Note that all material properties can be set to fixed
|
|
values or, by appending "-prop", to the contents of another property node.</p>
|
|
|
|
<p>The "emission" group is only one of four available groups: "diffuse,
|
|
"ambient", "specular, and "emission". A change to one of the components
|
|
in each group does always update all three color components. Unset values
|
|
default to zero. In addition to the color groups there are three properties
|
|
"shininess", "transparency", "threshold", and "texture". The "texture" path
|
|
is relative to the "texture-path" target or, if unset, the model directory.
|
|
All numerical values are clamped to 0.0-1.0, except "shininess", which is
|
|
clamped to 0.0-128.0. The "transparency" property makes an object fully
|
|
transparent (and thus invisible) with 0.0, and fully opaque with 1.0. The
|
|
"threshold" property sets the 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 do 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>
|
|
|
|
<hr>
|
|
<address>David Megginson, 11 March 2002</address>
|
|
|
|
<!-- Standard Footer Begin -->
|
|
</td></tr>
|
|
</tbody>
|
|
</table>
|
|
<br>
|
|
</body>
|
|
|
|
</html>
|
|
|
|
<!-- Standard Footer End -->
|