Styxx's POF Conversion plugin for 3D Studio Max
Still a Work In progress, Styxx has created a plugin for 3d Studio Max versions 4 through 6. Available here: [[1]]
Despite being available for well over a year, not many people actually know how to make this plugin work correctly. To that end, the following is intended to be a complete walkthrough of using the plugin to create a simple ship that makes use of all of the plugin's features.
Contents
A Comprehensive 3dsMax->POF conversion tutorial
Please note that this is not a tutorial for actually creating models. There are plenty of Max tutorials out there that have far better information in them than what can be provided here. It is, however, a guide to getting a model out of 3ds Max and into the Freespace 2 object format, POF, with minimal complications.
This tutorial is for the current exporter version as of November 13, 2003.
To start off, load all of the components of your model into a single Max scene file, and make sure that everything is unlinked so that you have no heiararchy to start off with. If you have already set up a heirarchy, go back and unlink it, as having things grouped too early may cause trouble later. From here, preparing the geometry for conversion involves a specific sequence of actions.
Geometry Preperation
- Orient everything so that the front of the ship points towards the top of the screen in "top" view mode.
- One by one, select each subobject and assign it a conversion name. Certain subobjects require specific naming conventions. Level of detail (LOD) objects are named detail-0, detail-1, etc, where detail-0 is the parent geometry for LOD0, detail-1 is the parent for LOD1, and so on. Do not skip levels. Debris chunks are similarly named debris-0, debris-1, ... debris-n, where n is one less than the total number of debris chunks. Again, do not skip numbering, as the converter parses these in order and will break if a number is missed. For all other subsystems, any name is valid as long as Freespace can parse it from the POF chunk (so no Cylinder,3) but remember that what you name the subobject will be what it is called in the POF itself. The shield mesh should be named "shield" (and similarly, any and all geometry not supposed to be a sheild should not be named "shield"). Models should only have one shield.
As you pass through your list of objects assigning them names, also change them to editable poly mode, as the converter seems to work best with poly models.
The following is a personal convention for naming other objects:- Turrets are named turretXX, where XX is a number between 01 and 99 that corresponds to the turret number that this model represents.
- Live debris, the ugly chunks of stuff left over when a turret is destroyed, are specified by naming the subobject for the destroyed component the same as the healthy version but with an added "-destroyed" on the end.
- Geometry that's acting as a "standard" Freespace subsystem should be named according to the final subsystem name. A physical Comm system would be "communications", a physical hanger would be "fighterbay", and so on.
- Geometry representing non-standard displaying subsystems should be given the name you want them to appear with.
- Hidden subobjects should be given a name that's meaningful to their function, such as hangerdoor for a hanger door.
- No subobject should ever be converted with it's max-generated default name.
- Assign properties to physical subobjects. Turrets are the most common case, but rotating subobjects like radar dishes and geometry representing a game subsystem like engines also need some extra data. To assign text properties to an object, open the object properties dialogue (right-click on the object, and select properties) and go to the "User Defined" tab. All objects that will be subsystems will need "$special=subsystem" added to their user-defined properties tabs. Turrets (turret bases) should have "$fov=XXX" where XXX is the field of view for the turret (0-180) and "$name=gunturret" added at the end. Other subsystems also need the $name=somename" field, but only turrets require "gunturret". Rotating objects need "$rotate=X" where X is rotation time in seconds. Negative values indicate reverse rotation.
- Position the primary model where it is supposed to be in the converted file so that its pivot point is at the origin. If you were converting the colossus, you would put the model in such a location that the middle of its rear engines, the point about which it rotates in-game, at (0,0,0). When the ship is in the exact place you want it, select the Heirarchy tab, click "Affect Pivot Only" and make sure that the pivot is at location 0,0,0. The location of the pivot on the root geometry for a level of detail MUST be at the origin, and this is important, so do not skip this step.
- Position all turrets and other subobjects where you want them in relation to the detail-X object that they will be attached to (this will almost always be detail-0), making sure to follow Freespace conventions in terms of turret orientation. Topside multipart turrets should face forward with their barrels pointing straight up, multipart turrets on the bottom of the ship should face towards the ship's rear and their barrels should point straight down. Default resting positions can be assigned in tables, so don't try to do anything fancy with these in the model. Barrels (and any other object consisting of more than one connected element) should be one object, not several, so attach multiple barrels together with the attach tool.
- Glass, transparency-blended nameplates, and other transparent textures should come last in the model. An easy way to accomplish this is to select all faces that use the material of your glass texture and detach them from the model, select the original model and re-attach them with the attach tool, select the faces near the edge (all faces in the model may be appropriate) and perform a vertex weld with a threshold of 0.01. This will move the transparent faces to the end of the model's face list and will ensure proper rendering in-game. If you have a single map that is partially transparent, do this on the specific faces that will end up transparent. All transparent textures should be part of the root geometry (detail-0), without exception. Faces behind transparent textures, such as a pilot, are more likely to work correctly when it is a subobject.
- All faces on all geometry except the sheild must have a texture assigned to them. Missing this on as little as a single face will cause the plugin to crash.
Paths
Create your paths using the create line tool and modify the editable splines to suit each path you want in the model. Typically, the paths needed for a "complete" model are paths for each subsystem (main subsystems and turret subobjects) so it's usually a good idea to know in advance where things like the weapons subsystem will be defined. All editable splines will become paths on conversion, but name them according to the Freespace convention anyway. Subsystem paths should be named $pathXX (XX is a number) and fighterbay paths should be named $bayXX. The only exception is the dock paths, which must have "dock" in the name, so $dockXX is preferable. Paths are ALWAYS defined toward the ship, so the first point (where you first click when you start an editable spline with the create line tool) should be the most distant from the ship, and the last the closest. Turret and subsystem paths are fine with just two points, fighterbay and dock paths typically have more (docks should have at least 4). Dock paths should have $name=somename, where somename is the display name of the dock in FRED, added to their user-defined properties tab.
Reset X-Form
This is the step that has given people the most trouble. Now would be a good time to make a backup of the scene, so that you can restore to the un-rigged state if something goes wrong.
Select all objects in the scene and open the Utilities tab. Select the "Reset X-Form" tool in the rollout that appears. Click the button of the same name to reset the transforms on all objects in the scene. If something in the scene moves in a strange way when you perform this action, there was still heirarchy set up in the scene so load up the backup and unlink the object(s) that moved from whatever they are attached to with the schematic editor. Then update the backup and try Reset X-form again, repeating as necessary.
Turrets
Most turret issues have already been covered, but there is one additional step that must be done for each turret. To define a turret's firing points, place point helper objects in the scene at the desired location for these points. It's a good idea to name these points something meaningful (if it's a firepoint for turret03, perhaps call it "turret03fp") so that you can figure out what goes where when rigging. For now, just create the points, we'll put the turrets together shortly.
Rigging the Scene
Now that all geometry and paths are set up properly, it's time to start putting things together. Setting up the heirarchy is done through the Schematic view, so go ahead and open that up. If you can't make out anything, try zooming in; Max does a particularly poor job of initially displaying a large number of objects in this view.
Objects are connected in a heirarchy with the link tool. To link one object to another, select the link tool, click on the to-be child object and drag to the intended parent.
Turrets, again
It's usually a good idea to set up turret groups before linking the turret itself to its parent.
- The standard button turrets consist of the turret geometry, with the turret path and the firepoint(s) attached as children.
- Multipart turrets are assembled with the turret base as the parent and with the firepoint(s), path, and barrels all attached as children.
Heirarchy Matters
The connection heirarchy is essential to making the game display your model correctly. Child objects cannot be rendered if their parent is not rendered, so keep this in mind when setting up your heirarchy groupings. Child objects also rotate with their parents, so if you are setting up an animated model you must keep this in mind. In general, all subobjects that the game can access as a submodel get assigned as direct children of detail-0, unless it's some strange case involving rotation. Turret barrels, however, are always children of their base, even if you don't intend to use autogeneration to set the turret up for you.
Putting it All Together
- Using the link tool in heirarchy view, one by one attach each turret base, physical subsystem, and extra subobjects intended to be direct subobjects of detail-0 to their parent LOD.
- Additional LODs should be set up the same way, though in most cases all lower LODs will have no child objects. LODs should themselves be at the top level of the scene, not attached to any other piece of geometry or helper.
- Debris pieces be at the scene root as well, not attached to any parent object.
- The shield mesh (if one is being used) should also be at the top level of the scene.
- All paths not assigned to a turret or subobject (subsystem paths for non-geometry subsystems, fighterbay paths, and dock paths) should be at the root level of the scene.
It is recommended that you attempt an export with only "detail levels", "debris objects", and "glows" checked. "glows" will obviously not do anything yet, but for some reason the exporter seems to crash when it is not selected. If If it converts and everything is in the right place afterwards, then the geometry is sound and you can be sure that later errors were not caused by geometry issues. See the converting section for details and debugging info.
Of Points and Dummies
If you prefer editing all subsystem, turret, gun/missile point, dockpoint, engine glow, and glowpoint data in PCS, you can safely skip this section. However, as this is perhaps the greatest strength of the MAX converter, it is strongly recommended that you actually use these features.
All of the resulting structures should be left at the root level of the scene.
Weapon Banks
Two components are necessary for each gun and missile bank that you want to add. One is the points themselves; these are defined as point helper objects places where each specific firepoint should be. The other is a container dummy object. The location of the container dummy does not matter, so it can be dropped down anywhere. However, to prevent serious oddities in conversion, it is strongly recommended to define all dummy objects in either a top-down or perspective view. That rule applies to more than just weapon banks as well. To create a weapon bank, place all of the firepoints where they belong (naming them something representative of their bank is helpful if you do multiple banks at a time) and add a dummy helper to the scene. The dummy must take the name gunbank-X, if it is to be a gun bank, or missilebank-X if it is to be a missile bank. X in both of these is the number of the bank, so start with zero and work your way up for both. The count of gunbanks is not related to the count of missilebanks, so start both at 0 and don't skip numbers.
In the Schematic view, attach all firepoints for a particular bank to the container dummy helper as children.
Dock Points
Dockpoints are specified using a editable spline object and two point helpers. Place one point helper where you want the dockpoint, and place a second point helper a short distance away towards the "top" of the dock. If you want an argo to dock in a certain alignment, the second point should be above the first from the orientation of the argo. The spline should have been set up already and named $dockXX, and its final point should come very close to the first dockpoint. In the schematic view, attach the two dockpoints, in their creation order, to the dock path as children. The dock point normals will be set as the direction from the dockpoints to the first point in the path, which is often wrong, but this must be corrected after the fact.
Special Subsystems
To create the standard subsystems used in FS2, create a dummy object at the location and with the size of the special point you want to create. This point should have a name starting with '$' and should be named what you want the point to display as otherwise.
Engine Glows
Engine glows are created from dummy helpers attached to an engine subsystem. Place the dummies centered where the engine glows should be and set their size to the size of the glow. Glows associated with an engine subsystem should be linked to that subsystem as children.
Glowpoints
Glowpoints are very similar to gun/missile banks in setup, except that instead of point helpers for each point, they use dummys. The size of each individual dummy will determine the size of the glowpoint it creates. Glow banks are specified with a container dummy helper (which has multiple dummy helpers attached to it as children) with the name glow-X where X is the number of the glow bank (start with 0 and don't skip numbers). The string "$glow_texture=texturename" should be placed into the user properties tab for the parent helper.
Insignia
Insignia's don't work properly, so this tutorial will not address them.
Converting
Converting is a relatively simple process in comparison to actually setting everything up. It is, however, not foolproof and actually quite failure prone. It should be as simple as doing a file->export, choosing Freespace 2 POF as your export filetype, and selecting only the components that you actually have in your scene. The only exception is the glows box, which must always be checked or a crash will result.
What can go wrong
The simple answer is a lot. The converter will crash if you skipped a number in any sequence that requires a -X at the end. Debris is the most common place for this to occur now, though there are other places that it may also come up. The converter will crash if it encounters polygons on any mesh other than the shield that have no texture. The converter will also always crash if the glow box is unchecked, though there isn't any good reason for this. Finally, the converter will occasionally crash for no reason whatsoever, so always save before you convert and load it up and try again if it fails once. Failing twice in a row is usually indicative of a real problem.
Things that still need improvement
There are still some things that the POF converter cannot do properly. For one thing, it makes a mess out of the header; the mass values are about two orders of magnitude higher than they would be for an equivalent stock model. For another, the Moment of Inertia is a complete mess and doesn't output anything useful. Both of these values should be changed before the model is used in game. Unfortunately, if glowpoints were used, there is not a good mainstream way to correct the MoI data without losing the glow chunk, and PCS won't import glows, so you're sort of stuck unless you are willing to copy it by hand. There is a third issue that most people rarely notice; the converter miscalculates the radius of the model by approximately a factor of 2, which creates some strange behavior during subspace warps and when viewing externally from the model. Again, there is not a good way to correct this, so it may just be something you have to live with. If the radius problem becomes an issue, please contact the user StratComm through the HLP PM system for assistance.