Howto:Creating 3D instruments
This tutorial describes the basic process of creating a 3D instrument for use in FlightGear. For now, we're assuming that you have created the actual 3d model to use and wish to include it in a cockpit and animate it. As an example, we will be animating the ITT gauge for the Fokker 50.
What you need
You will need:
- a text editor (even notepad will do, but one that does syntax highlighting might help you spot typos more easily; if you're on Windows, Notepad++ looks suitable.)
- your 3d modelling package
- and of course a copy of FlightGear
Creating the XML file
The first step is to create an XML file which will load the 3D model and animate it. There are no hard and fast rules about where these files should live or what they must be called, but we'll follow the fairly standard procedure of calling it itt.xml and placing it in the Models directory.
So, using your favourite text editor, create a file called itt.xml in the Aircraft/fokker50/Models directory (folder).
It should start like this (and please remember that case is ALWAYS important);
<?xml version="1.0"?> <PropertyList> </PropertyList>
Everything you will add to this file must go between the <PropertyList> tags.
Now, our file does nothing useful at this point. First of all, we want to tell FG to load the 3d model of our instrument. Add a section under <PropertyList> like this;
This is obviously the name of the 3d model file we wish to load. The model in question looks like this:
Adding an animation
See Howto:_Animate_models for the main article about this subject.
As you can see, the main item to animate is the temperature needle, and its name is "needle" (you can animate either AC3D "objects" or complete "groups"). We will want to use a "rotate" animation (for more details on available animation types, see "model-howto.html" which is provided with FG in the Docs directory.)
So, we add an <animation> section to our XML file.
<animation> <type>rotate</type> <object-name>needle</object-name>
Now, we need to specify a property which will determine the amount of rotation required; in other words, the property that provides the ITT value at any one time. To find the name of this property, we need to start FlightGear in the usual manner with the correct aircraft (fokker50 in this case). Once FG has started, open the property browser (file/browse internal properties). You will see the top level of the property tree. Click on "engines" and you will see a list of engines; click on the first one (engine) and you will see a long list of properties and their current values.
Now, we have a slight problem at this stage; the fokker50 was created before JSBSim could model turboprops, and so the ITT property is not available right now. For the purposes of this tutorial though, we'll just use the exhaust temperature instead; the process is what's important.
So, the next line in our XML file will specify the property to use;
Next we need to specify exactly how much that property moves the needle. There are several ways to do this, but we'll use a simple interpolation table since these are especially useful in more complicated situations. The ITT gauge is marked from 0 degC to 1200 degC; since we're having to use a value that's reported in degF for now, we'll just convert those two values. 0 degC is about 32 degF and 1200 degC is about 2192 degF. Two handy tips here; for Linux/unix users, the "units" program is truly invaluable; for everyone, google has a useful units converter; for example search for " 1200 degrees celsius in fahrenheit"
On to our table then.
<interpolation> <entry><ind>32</ind><dep>0</dep></entry> <entry><ind>2192</ind><dep>230</dep></entry> </interpolation>
The <ind> entries are the independent variables, or values read from the property tree; the <dep> entries are the dependent variables, or corresponding degrees the object will be rotated by. In this case I found that number by rotating the needle in AC3D from one end of the scale to the other and reading off the rotation value reported (see screenshot)
Having configured the type of animation, the controlling property, and specified the effect of that property, we need to describe an axis and centre for the animation.
In this case, the centre is easy, because the needle centre is at the origin of the 3d model. If you wanted the rotation centre to be somewhere else, you could use your modelling app to obtain these values.
<center> <x-m>0</x-m> <y-m>0</y-m> <z-m>0</z-m> </center>
The axis is also very simple in this case;
<axis> <x>-1</x> <y>0</y> <z>0</z> </axis>
The negative sign on the x axis means that the rotation will be clockwise when viewed from the -x direction (i.e. looking "forwards")
That concludes the rotation animation and so (as always) we need to add a suitable closing tag;
Our itt.xml file, as it stands, should now "work" in flightgear; that is, it will animate the needle object to display exhaust temperature on the first engine, in degC (despite the input property being in degF!)
However, the bottom half of the gauge contains a digital readout of the same information, and we haven't mentioned that yet. In order to only introduce one new aspect at a time, for the moment I am going to ignore the fact that our input property is in degF and simply display it using the digits; there are several ways we could display degC (or indeed any kind of value) instead, but those are probably best left to another tutorial.
Now, in order to give the illusion of a digital display, we are going to use a slightly less obvious technique than the simple rotation used for the needle. Our digits are going to come from this texture, freshly borrowed from another model in FlightGear (remember, this is open source software - don't reinvent the wheel unless it's absolutely necessary!).
Now, each "digit" in the 3d model is a separate rectangle, and each is mapped to the number zero on that texture. What we are going to do is use a "textranslate" animation to slide the texture along to the relevant number in each case. Here's the code for the first digit;
<!-- Digital Display --> <animation> <type>textranslate</type> <object-name>digit1</object-name> <property>engines/engine/egt_degf</property> <factor>0.0001</factor> <step>1000</step> <axis> <x>1</x> <y>0</y> <z>0</z> </axis> </animation>
As always, if you need more detailed explanations of any of these animations, remember to RTFM which in this case is the model-howto.html referred to previously.
Each subsequent digit is handled in the same way, though with the object-name, factor and step values modified accordingly.
For example, the next digit along, the "hundreds" digit;
<animation> <type>textranslate</type> <object-name>digit2</object-name> <property>engines/engine/egt_degf</property> <factor>0.001</factor> <step>100</step> <axis> <x>1</x> <y>0</y> <z>0</z> </axis> </animation>
And so on, for the remaining two. Now, your itt instrument should display the EGT in degC using the needle, and give a "digital" readout of the same in degF.
Level Of DetailTo prevent objects like this instrument being drawn when the aircraft is actually too far away for them to be seen anyway we use a Level Of Detail section (a "range" "animation".) Notice the
<!-- -->section; this is a comment, feel free to add them where you need a reminder of what's going on.
<!-- LoD --> <animation> <type>range</type> <min-m>0</min-m> <max-m>30</max-m> </animation>
Now, if you've managed to stay with us the whole way through, the file should look something like this one, which you can download and compare with. Media:itt.xml Notice that under each new opening xml tag (such as <animation>) the text is indented one more level. Sensible people(!) use one tab to indent each level, others try to use various numbers of spaces to indent; whatever you use, the single most important thing is to be consistent. Consistent indentation makes the file much easier to read.
Including the instrument in an aircraft
Now to the exciting bit, actually seeing the fruits of our labour in FlightGear! Including our itt.xml file in the fokker50 is actually an easy step. The "model" XML file controls the 3d model; this is often called aircraftname-model.xml and nearly always lives in the aircraftname/Models directory. However, FG is very flexible and in this case, the model XML file is fokker50/Models/fokker50.xml . To avoid confusion, it would be preferable for this to be called fokker50-model.xml, and if you're creating one from scratch, please use that convention.
If we open that file in a text editor, it should look quite familiar; you will recognise the way it specifies an ac3d file, and animates the various parts of it. However, we wish to include an instrument, and that is done very simply. Below the <offsets> section, add a section like this;
<!-- ITT Gauge --> <model> <path>Aircraft/fokker50/Models/itt.xml</path> <offsets> <x-m>-8.9088</x-m> <y-m>-0.0811</y-m> <z-m>-1.0722</z-m> <pitch-deg>-10</pitch-deg> </offsets> </model>
Those numbers can be easily obtained from your 3d modelling app; just open the aircraft model and place an object in the correct position, then use the distances here. The usual FG model coordinate system is used; x=back, y=right, z=up, from the pilot's perspective; the origin is the one in the 3d model (.ac file). The "pitch" entry is fairly obvious; pitch of zero is a completely vertical instrument, pitch of -90 is one tilted "top edge forwards" to lie flat.
Now, when you start FlightGear, you should see your fully-working instrument in all its glory, situated where it ought to be! If you need to move it later, it's trivial to tweak the numbers above to suit.