Jump to content


* - - - - 1 votes

Placing MDL Objects from LibObj File


  • Please log in to reply
1 reply to this topic

#1 IBtheSarge

IBtheSarge

    First Class Member

  • Moderator
  • PipPipPipPipPipPipPipPip
  • 10,718 posts
  • Location:Central Florida

Posted 07 April 2006 - 10:18 AM

First things first -- there will be no tutorial describing how to make a LibraryObjects file for MDL objects.  If you make your own MDL objects (GMAX or FSDS3), the best thing you can do is get Arno Gerretsen's Library Creator XML (get the one that has "runtime installer" in the title).  It IS possible to create it by hand, but Arno's program is faster than anything I can think of, is EXTREMELY accurate, and creates the object GUID on the fly.  It also saves the library as an XML file and compiles the XML to a BGL file.  Arno has already done the work, all you have to do is download it, install it, and reap the rewards.  This process, by the way, works with any LibObj file of MDL objects, be it your personal LibObj file made with Arno's program or libraries from EZ-Scenery, Runway 12, or SBuilder.

To place MDL objects from a LibraryObjects file, you need the LibObj file (of course), the XML version of the library (or a TXT file that lists the objects and their associated GUIDs), a pic of the objects (so you can see which object you're trying to place), and something that gives you the texture files that go with the object(s).  Some designers provide all of that with their libraries, some don't.  My MDLs reside in two directories (military objects and civilian objects) and have a screenshot of the object, onto which I've placed text identifying the scale (invariably 1.0), the name and footprint (width, depth, height) of the object, and the GUID that Arno's program assigned to the object.  Since they're my creations, I also have the raw file which contains the texture list for the objects.  Some designers will include an MS-Word document, containing the pics and GUID information, in the zip file.

That being said, and presuming (not assuming) that you have a LibObj file, it's associated XML file, pics for the objects in the library, and the texture files for the objects in the library, let's get on with creating an XML placement file and compiling it to BGL.  Your work will be done in the BGLCOMP work directory, which should contain the previous listed items and both blgcomp.exe and bglcomp.xsd files.

=====================================================

Step 1:  Open Wordpad and type in the following lines of code:
<?xml version="1.0" encoding="ISO-8859-1"?>
<FSData
version="9.0"
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:noNamespaceSchemaLocation="bglcomp.xsd" >

<!-- ILS RWY 27L -->
<SceneryObject
            lat="41.679755"
            lon="-116.74338"
            alt="0"
            altitudeIsAgl="TRUE"
            pitch="0"
            bank="0"
            heading="090.0"
            imageComplexity="NORMAL">
            <LibraryObject
                      name="5025B8654F0146D7AE20DD5CE5C0A955"
                      scale="1.0"/>
</SceneryObject>
<Airport
          region="North America"
          country="United States"
          state="Nevada"
          city="Hidden Springs"
          name="Hidden Springs AB"
          lat="41.6578733"
          lon="-116.7560566"
          alt="1645.92"
          magvar="15.9"
          ident="KHSX">
</Airport>
</FSData>
Step 2:  Modify the data to reflect the object(s) you wish to place from the LibObj file.  This is done in two stages and we'll do the second one first -- the airport data.  Open your airport in AFCAD, right-click on any unused screen area, select PROPERTIES in the pop-up that appears.  Change these lines
          region="North America"
          country="United States"
          state="Nevada"
          city="Hidden Springs"
          name="Hidden Springs AB"
          lat="41.6578733"
          lon="-116.7560566"
          alt="1645.92"
          magvar="15.9"
          ident="KHSX">
to reflect the location/name of your airport.  Notice that you will have to convert AFCAD's dd:mm.mmmm format coordinates to the dd.ddddddd format.  It's simple math; let's use N41 26.37 as an example.  We can readily plug in the 41 and dd of dd.ddddddd in the new format.  To get the numbers to the right of the decimal place, we need to convert mm.mmmm (26.37) to degrees and add it to the 41.  First step:  .37 divided by 60 = .0061666.  Now add the whole minutes (26) and do the math again -- 26.0061666 divided by 60 = .4334361, and if we add the whole degrees (41), we have the new format -- 41.4334361 degrees.  (Just remember that southern latitudes are negative numbers; S41 26.37 would be written as -41.4334361.  The same holds true for longitudes -- east longitude is positive, west longitude is negative.)

Heads-up -- (1)  You will need to convert your airport's elevation to meters, again simple math.  If your airport elevation is in feet (for example, 700 feet), simply divide feet by 3.28084 (the number of feet in a meter).  So 700 feet divided by 3.28084 would give you an elevation of 213.35999 meters for your airport.  Heads-up -- (2)  Remember that an east magnetic variance is a positive number and a west magnetic variance is a negative number.

With all of the above in mind, change the above lines of code to reflect your airport.

NOTE:  There are two sides to the use of this data in the XML file, one being that the airport data is not needed.  I can only offer this advice -- having more than one project in work at any given time, I find the airport data VERY useful in confirming exactly which XML file I am working with, and having it in the file -- even if it isn't needed -- is certainly harmless.  Leave it out if you so desire; it shouldn't have any impact on compiliation to BGL.

Step 3:  Place an object from the LibObj file.  To do this, you will need to change the information in these lines:
<!-- ILS RWY 27L -->
<SceneryObject
            lat="41.679755"
            lon="-116.74338"
            alt="0"
            altitudeIsAgl="TRUE"
            pitch="0"
            bank="0"
            heading="090.0"
            imageComplexity="NORMAL">
            <LibraryObject
                      name="5025B8654F0146D7AE20DD5CE5C0A955"
                      scale="1.0"/>
</SceneryObject>
The first line (<!-- ILS RWY 27L -->) is an information line.  Use of the exclamation mark in that position tells bglcomp.exe to ignore what follows and go to the next line of code.  This line, however, is also VERY useful in keeping track of what you have placed in the scenery, and even how many times you've placed a particular object.  Let's leave it in for the moment and change it to identify the object you are going to place.

The latitude and longitude,
            lat="41.679755"
            lon="-116.74338"
as with the lat/lon in the Airport Data section, has to be converted to the dd.ddddddd format.  This is the point on your AFCAD screen where you want the center of the object to be located.  Use your mouse pointer to locate where you want the center of the object to be placed, copy the lat/lon from the bottom bar of the AFCAD screen, convert to dd.ddddddd format, and replace the lat/lon in your XML file with the real location.

The next two lines
            alt="0"
            altitudeIsAgl="TRUE"
establish the elevation of the object with regard to the airport elevation.  Unless you want your object suspended in the air, leave alt="0" alone; this represents zero feet above the ground.  If you want the object 25 feet above the ground, change the zero to 25.  Do not add 25 to the airport elevation; if your airport is 700 feet MSL and you enter 725 as the elevation of the object, FS9 is going to draw the object 725 feet up in the air.

The lines dealing with pitch and bank can be ignored for now.  These are quite useful in adjusting the position of jetways you may place later to make them match the hatches of airliners more precise.  For now, they can be left at zero (unless you want a horizontal and/or lateral tilt to your object).
If you have to, refer back to the AFCAD of your airport and determine which way you want your object to face.  Change heading="090.0" to whatever heading you've decided to use.  Notice that the heading is three digits left of the decimal place and one digit right of the decimal place.  Always use this format; 360 degrees would be 000.0, 45.7 degrees would be 045.7 degrees.

And now it is time to identify the specific object.  Open the XML (or TXT) file that is associated with the object you wish to place, and locate the GUID of that object.  Change
                      name="5025B8654F0146D7AE20DD5CE5C0A955"
the GUID of the sample code to the GUID of the object you wish to place.  The next line (scale="1.0"/>) you can leave alone.  If you later find that the object is too small or too large, you can come back and change this value to a greater or lesser scale.  It is recommended that you do in increments of one-tenth until the object appears to be correctly sized ("0.9" to make it smaller, or "1.1" to make it bigger, etc.).

Step 4:  On Wordpad's top toolbar, select FILE then SAVE AS and give the file a unique name with the file extension XML.  My method is to use the ICAO of the airport in the filename (i.e., KPSM_MDL.XML).  Save the file into the work directory and close Wordpad.  Now, drag-and-drop the XML file onto bglcomp.exe and wait a few seconds.  If your lines of code are correct, and the coordinates are entered correctly and in the correct sequence, within 10 - 15 seconds you should see a BGL file with the same name as the XML file appear (i.e., KPSM_MDL.BGL).  If it doesn't, you've mistyped something; recheck your code, make the necessary changes, and do the drag-and-drop again.
Place this BGL in your airport's scenery folder.  You're almost finished.

You also need to place the LibObj BGL file in your airport's scenery folder, and the textures for the object in your airport's texture folder.  Once those actions have been done, you should be able to create a flight at your airport and see your object positioned exactly where you told FS9 to put it, facing the direction you indicated for it to face.
=====================================================

Of course you'll be placing more than one object per scenery; keep repeating the block
<SceneryObject
            lat="41.679755"
            lon="-116.74338"
            alt="0"
            altitudeIsAgl="TRUE"
            pitch="0"
            bank="0"
            heading="090.0"
            imageComplexity="NORMAL">
            <LibraryObject
                      name="5025B8654F0146D7AE20DD5CE5C0A955"
                      scale="1.0"/>
</SceneryObject>
over and over, in sequence, changing the data to reflect each object you place, until they're all entered.

For those of you who create your own MDL objects in FSDS3, the default (regardless of which program you use) is for the object to cast a ground shadow.  This is a framerate KILLER! and is compounded depending on how many objects you place in a particular scenery.  For you folks who design in FSDS3, I have an extra document on how to get rid of the ground shadow when creating MDL objects.  (I'm not that familiar with GMAX, so if you use GMAX to design your MDL objects, you may want to look, too, and see if anything is familiar and can be used.)

In your main FSDS3 directory, there are two files -- MakeMdlAircraftParms.txt and MakeMdlSceneryParms.txt -- that need a filename extension change.  Change the extension from .txt to .ORG.

Now, open Wordpad and copy/paste the below lines, exactly as is (it's rather long, so make sure you get the whole thing).  Once you have verified that you have everything, on Wordpad's toolbar select FILE then SAVE AS.  Point Wordpad to your main FSDS3 directory, give it the name KillShadow_shadow.x and save it.  I also have a copy of the file in my makeMDL directory, just for insurance.  When you export your object from FSDS3, this file will kick-in as an add-on "x" file and result in your object NOT casting a ground shadow.
xof 0302txt 0032
// Direct3D .x file translation of Scene_Root
// Generated by 3DSMax FSModelExp Plug-in, Version 1.00
// Thu Jan 06 09:50:39 2005


template Header {
 <3D82AB43-62DA-11cf-AB39-0020AF71E433>
 WORD major;
 WORD minor;
 DWORD flags;
}

template Vector {
 <3D82AB5E-62DA-11cf-AB39-0020AF71E433>
 FLOAT x;
 FLOAT y;
 FLOAT z;
}

template Coords2d {
 <F6F23F44-7686-11cf-8F52-0040333594A3>
 FLOAT u;
 FLOAT v;
}

template Matrix4x4 {
 <F6F23F45-7686-11cf-8F52-0040333594A3>
 array FLOAT matrix[16];
}

template ColorRGBA {
 <35FF44E0-6C7C-11cf-8F52-0040333594A3>
 FLOAT red;
 FLOAT green;
 FLOAT blue;
 FLOAT alpha;
}

template ColorRGB {
 <D3E16E81-7835-11cf-8F52-0040333594A3>
 FLOAT red;
 FLOAT green;
 FLOAT blue;
}

template TextureFilename {
 <A42790E1-7810-11cf-8F52-0040333594A3>
 STRING filename;
}

template Material {
 <3D82AB4D-62DA-11cf-AB39-0020AF71E433>
 ColorRGBA faceColor;
 FLOAT power;
 ColorRGB specularColor;
 ColorRGB emissiveColor;
 [...]
}

template MeshFace {
 <3D82AB5F-62DA-11cf-AB39-0020AF71E433>
 DWORD nFaceVertexIndices;
 array DWORD faceVertexIndices[nFaceVertexIndices];
}

template MeshTextureCoords {
 <F6F23F40-7686-11cf-8F52-0040333594A3>
 DWORD nTextureCoords;
 array Coords2d textureCoords[nTextureCoords];
}

template MeshMaterialList {
 <F6F23F42-7686-11cf-8F52-0040333594A3>
 DWORD nMaterials;
 DWORD nFaceIndexes;
 array DWORD faceIndexes[nFaceIndexes];
 [Material]
}

template MeshNormals {
 <F6F23F43-7686-11cf-8F52-0040333594A3>
 DWORD nNormals;
 array Vector normals[nNormals];
 DWORD nFaceNormals;
 array MeshFace faceNormals[nFaceNormals];
}

template Mesh {
 <3D82AB44-62DA-11cf-AB39-0020AF71E433>
 DWORD nVertices;
 array Vector vertices[nVertices];
 DWORD nFaces;
 array MeshFace faces[nFaces];
 [...]
}

template FrameTransformMatrix {
 <F6F23F41-7686-11cf-8F52-0040333594A3>
 Matrix4x4 frameMatrix;
}

template Frame {
 <3D82AB46-62DA-11cf-AB39-0020AF71E433>
 [...]
}
template FloatKeys {
 <10DD46A9-775B-11cf-8F52-0040333594A3>
 DWORD nValues;
 array FLOAT values[nValues];
}

template TimedFloatKeys {
 <F406B180-7B3B-11cf-8F52-0040333594A3>
 DWORD time;
 FloatKeys tfkeys;
}

template AnimationKey {
 <10DD46A8-775B-11cf-8F52-0040333594A3>
 DWORD keyType;
 DWORD nKeys;
 array TimedFloatKeys keys[nKeys];
}

template AnimationOptions {
 <E2BF56C0-840F-11cf-8F52-0040333594A3>
 DWORD openclosed;
 DWORD positionquality;
}

template Animation {
 <3D82AB4F-62DA-11cf-AB39-0020AF71E433>
 [...]
}

template AnimationSet {
 <3D82AB50-62DA-11cf-AB39-0020AF71E433>
 [Animation]
}

template DiffuseTextureFileName {
 <E00200E2-D4AB-481a-9B85-E20F9AE07401>
 STRING filename;
}

template AmbientTextureFileName {
 <E00200E2-D4AB-481a-9B85-E20F9AE07402>
 STRING filename;
}

template EmissiveTextureFileName {
 <E00200E2-D4AB-481a-9B85-E20F9AE07403>
 STRING filename;
}

template ReflectionTextureFileName {
 <E00200E2-D4AB-481a-9B85-E20F9AE07404>
 STRING filename;
}

template ShininessTextureFileName {
 <E00200E2-D4AB-481a-9B85-E20F9AE07405>
 STRING filename;
}

template BumpTextureFileName {
 <E00200E2-D4AB-481a-9B85-E20F9AE07406>
 STRING filename;
}

template DisplacementTextureFileName {
 <E00200E2-D4AB-481a-9B85-E20F9AE07407>
 STRING filename;
}

template PartData {
 <79B183BA-7E70-44d1-914A-23B304CA91E5>
 DWORD nByteCount;
 array BYTE XMLData[ nByteCount ];
}

Header {
 1;
 0;
 1;
 }

//=====================
// FILE NODE HEIRARCHY
//=====================
// Scene_Root (1 Children)
//   Plane01 (0 Children)

Frame frm-MasterScale {
FrameTransformMatrix {
   0.000977, 0.0, 0.0, 0.0,
   0.0, 0.000977, 0.0, 0.0,
   0.0, 0.0, 0.000977, 0.0,
   0.0, 0.0, 0.0, 1.0;;
}  // End frm-MasterScale FrameTransformMatrix
Frame frm-MasterUnitConversion {
FrameTransformMatrix {
   1024.000000, 0.0, 0.0, 0.0,
   0.0, 1024.000000, 0.0, 0.0,
   0.0, 0.0, 1024.000000, 0.0,
   0.0, 0.0, 0.0, 1.0;;
}  // End frm-MasterUnitConversion FrameTransformMatrix
Frame RotateAroundX {
FrameTransformMatrix {
   1.0, 0.0, 0.0, 0.0,
   0.0, 0.0, 1.0, 0.0,
   0.0, -1.0, 0.0, 0.0,
   0.0, 0.0, 0.0, 1.0;;
}  // End Frame RotateAroundX FrameTransformMatrix
Frame frm-Plane01 {
FrameTransformMatrix {
  1.000000, 0.000000, 0.000000, 0.0,
  0.000000, 1.000000, 0.000000, 0.0,
  0.000000, 0.000000, 1.000000, 0.0,
  0.000000, 0.000000, 0.000000, 1.0;;
}  // End FrameTransformMatrix

Mesh Plane01 {
4;  // Mesh 'Plane01' contains 4 vertices
  -0.500000; -0.500000; 0.000000;,
  0.500000; -0.500000; 0.000000;,
  -0.500000; 0.500000; 0.000000;,
  0.500000; 0.500000; 0.000000;;

2;  // Mesh 'Plane01' contains 2 Faces
  3; 3, 0, 2;,
  3; 0, 3, 1;;
MeshMaterialList {
  1; // 1 Materials
  2; // 2 Faces have materials specified
  0,
  0;
  Material Mtl__10 {
  0.000000; 0.000000; 0.000000; 0.000000;;
  0.000000;
  0.000000; 0.000000; 0.000000;;
  0.000000; 0.000000; 0.000000;;
}  // End Material 'Mtl__10'
}  // End MaterialList for 'Plane01'
MeshNormals {  // Mesh normals for Plane01
1;  // 1 vertex normals
  0.000000; 0.000000; -1.000000;;
2;  // 2 faces with normals
  3; 0, 0, 0;,
  3; 0, 0, 0;;
}  // End Mesh normals for Plane01
}  // End of Mesh 'Plane01'
}   // End of frame frm-Plane01

}   // End of RotateAroundX frame

}   // End of frm-MasterUnitConversion frame

}   // End of frm-MasterScale frame


AnimationSet {  // Collection of Animations
}  // End of AnimationSet
This little goody was passed on to me by (who else) Jeff Stanyer.  The file's author is Richard Ludowise (aka Rhumbaflappy).  Enjoy.

Edited by sarge, 07 April 2006 - 10:34 AM.


#2 Jon

Jon

    Administrator

  • Admin
  • PipPipPipPipPipPip
  • 3,140 posts
  • Location:South Carolina, USA

Posted 14 April 2006 - 02:35 PM

Good stuff - added to Knowledge Base.  Thanks again!