The LithTech(tm) Development System is
copyright 1998-2000 by LithTech, Inc., Kirkland, Washington, U.S.A. All rights
No One Lives Forever is copyright (c)2000 by Twentieth Century Fox Film Corporation. All rights reserved.
ModelEdit is the tool used by the No One Lives Forever 3D team to integrate models into the game. This guide covers the most frequently used and important features of ModelEdit. The ModelEdit UI is made up of several panels. The largest panel is the Model View panel, which previews the model mesh and its animations. Below this are the CD player-style buttons for controlling the animation. The Nodes panel lists the model's skeletal nodes. The Pieces panel displays all of the individual meshes that make up the current model. The Animations panel lists all animations that are loaded into the current model. The Child Models panel lists the sub-animations files that are loaded. An animation that comes from a child model cannot be edited and will have an empty box next to its name in the list. An animation that is part of the file you are looking at will have a check mark beside its name. The Sockets panel lists the model's sockets. All these panels are discussed in this document.
Use the Level of Detail (LOD) slider to select the level of detail you want to view. Use the Animation Edit control to manipulate animation data. Use the Transform Edit control to manipulate socket positions.
At the bottom of the display is the animation Time Bar. The Time Bar has a red mark for every key frame. Frame Strings are a way to tie an event or message to a keyframe so that it will be available to the game programmer. For example, if your character has a martial arts attack, you could hook a message onto his punch animation so that each time he throws a punch, a "whipping cloth" sound plays.
One of the best ways to optimize the rendering of models is to draw fewer of the model's polygons where appropriate. ModelEdit has a tool to create multiple levels of detail dependent upon a distance value. At lower levels of detail, ModelEdit creates a version of the model that uses fewer polygons to draw the same object. The game engine will take the distance from the rendering camera-whether that is the player's point of view or a cut scene camera-to the object seen and use the triangulation set for that distance.
To open the LOD creation dialog, in the Model menu, choose the Build LODs option. The Level of Detail Generation dialog, similar to the following, appears.
To create a new LOD point for the model, click the Add LOD button and then enter information in the LOD Edit dialog:
In this dialog, specify the LOD by distance and the percentage of model triangles to keep. The distance is the threshold for the LOD being created. In the game when the view camera is that distance from the object, the new detail level (the lower-polygon mesh) is used to render the model. The LOD operation affects the whole model, but the user can change how LOD affects different pieces of the model. Artists can make some important pieces stay detailed while other parts of the model become lower resolution.
To differentiate the pieces for the LOD operation, pick a piece from the Piece Weights list and a enter a value greater than one into the Piece Weights value box. The value represents the LOD priority for that piece. The larger the number, the later the piece will have LOD operations done on it. For example, if the value of one piece is three, it will take three vertex collapses before that piece's triangles start to collapse. This is useful for objects like heads or shields, where a small loss in detail can be very noticeable.
LOD 0 Reduced Triangle LOD
The images above are the result of an LOD operation. The image on the left (LOD 0) is the base model; the image on the right is the reduced triangle model. In the game, the renderer will automatically switch to the next LOD level when the distance associated with the LOD level has been reached.
Animations are part of the model's database. There are two methods for bringing new animation into a model. The first method adds it directly to the model's own data, and the second adds it by reference. A referenced animation's data is not included in the model file. Instead, the model file refers to another file that contains the actual animation data. This is useful when several models are going to share the same set of animations. All animations that are added must have the same hierarchy as the model being worked on. ModelEdit will signal an error when there is a hierarchy mismatch.
To add an animation directly, go to the File menu and select Import. A file dialog appears with check boxes at the bottom listing the import options. Select Animations and select the file you wish to load. The animation names appear in the animation list box when loading is done. You may want to do this if you know that no other models will need the animation. For example, an octopus's animation is only ever needed by the octopus model.
To add an animation by reference, in the Child Model menu select Add Child Model. Type the file name of the child model you want to load. ModelEdit checks the .abc file to see if the two models' hierarchies are the same, and then the animations will be available within ModelEdit. When the model is saved, a reference to that file is stored in the model data.
Below the Model View panel, there are CD player-style buttons that control animation playback. Below that is the animation bar. The red vertical lines are key frames. The four buttons in the Animation Edit area manipulate the ordering of the animations in the Animations list box. The red X button deletes the animation from the model. The # button renumbers the currently selected animation, and the arrows move the animation up and down in the list box. The other two choices, User Dimensions and Translation, work in conjunction with the six thumbwheel buttons below to adjust either the size of the bounding box of the animation or the base position of the animation.
In the Frame String text box, you can associate an arbitrary text string with each key frame in an animation. Use this association to indicate to the game code that a certain event has happened. This is most often used to associate a sound with an event. For example, you could associate footsteps with a "foot down" frame, gunshots with a model's "fire" frame, or a body hitting the floor with the last frames of a death animation. To add a Frame String, select a key frame by clicking on it and then type a word in the Frame String text field. When the animation runs, the frame string is sent to the game code as the tagged key frame passes.
The LithTech animation system supports two kinds of animation blending operations, consecutive and concurrent. The engine automatically blends between all consecutive animations. Additionally, you can create a custom blend between two concurrent animations using Animation Blending Weights.
Consecutive Animation Blending LithTech blends consecutive animations together by default. At the end of one animation the engine interpolates to the next animation in 200 milliseconds. This value can be changed per animation in ModelEdit.
Concurrent Weighted Animation Blending Use ModelEdit to blend from two to four animations concurrently by specifying Weighted Animation Blending values for nodes in the animations. When the game programmer sets up concurrent animations for the models in the game code, the Weighted Animation Blending can be swapped dynamically to produce new custom animations from existing animations.
To specify Weighted Animation Blending, open the ModelEdit Model menu and select Edit Weighted Animation Blending. The Weighted Animation Blending dialog box displays the available weight sets, a list of the model's nodes, and buttons to add or remove weight sets. Under the Nodes list is a Current Node Weight text box showing the value of the currently selected nodes. All nodes belong to the weight sets, and for each weight set the nodes can be weighted differently. For example, an upperbody weight set might have all the nodes belonging to the hips and above set to have a weight of one, while the nodes in a lowerbody weight set would have all the node's weights below the hips set to one and all the nodes above the hip node set to zero.
Creating a Weight Set
1. In the Model menu, select the Edit Weighted Animation Blending option.
2. In the Weighted Animation Blending dialog box, click Add Set.
3. In the New Weight Set dialog box, type a name for the new weight set you are creating and then click OK.
4. In the Weighted Animation Blending dialog box, select the new weight set you created.
5. In the Nodes list, select one or more nodes and then enter a new value in the Current Node Weight text box.
6. When you finish assigning weights to the nodes for the weight set, click Close.
Creating a Weighted Animation Blending
1. In the Animations list, click to select the first animation. Notice that the selected animation appears in the Animation Keyframes area.
2. Press and hold CTRL while you select a second animation. The second animation appears in the Animation Keyframes area, below the first animation.
3. In the Animation Keyframes area, click the button that displays the name of the first animation.
4. In the Select Animation Blending Weight Set dialog box, click the name of the weight set you created and then click OK.
5. Repeat steps 3 and 4 for each animation.
6. Click the Play button to see the results of your Weighted Animation Blending.
The order in which the animations are selected makes a difference. The animations linearly interpolate (LERP) per frame from the first to the next using the node's weight value. The formula is the resulting animation equals the first animation plus the difference between the first and the second animation times the second animation's weight value.
RES = FIRST + ((SECOND - FIRST) * SECOND's WEIGHT)
Be aware that when you blend more than two animations, this algorithm is recursive: the result from the previous evaluation becomes the FIRST value, and the SECOND parameter is the next animation in the list that has yet to be evaluated. For example, LERP (LERP (first, second, second-weight), third, third-weight) and so on.
The value of weight can be any numerical value. Typically, you will use values between 0 and 1 since 0 means no change and 1 gives full value to the second node.
If the weight set value is 2, the algorithm will simply add the two animations together. This can also be used to great effect. Generally the added animation should just modify the first, a walk and a run added together would result in a very strange animation.
To add concurrent animations to a model in game code use ILTModel::AddTracker. Be sure there is an Anim Blending Weight set associated with the second animation added in this fashion.
Because of the nature of the algorithm, getting things to look the way you want could be tricky, so as you experiment with various animations, try to make concurrent animations as similar to each other as possible. For example if you want to accentuate a walk, make sure the foot plants occur on the same key frame. If you are doing upper-lower body animations, have the weights at the fusion points ramp from one animation weight set to the other. With enough experimentation, you will develop good intuition as to what works.
Sockets are places in models where you can add attachments. Attachments are sub-models that do not deform with the main model. Also, attachments can be changed dynamically in the game. Usually attachments are guns, hats, and sometimes even armor pieces. The socket or attachment sites are normal transformations that are manipulated in the Transform Edit control or from the Sockets list.
To add a socket, from the nodes list pick a node where you want to create a socket. In the Sockets menu, select Add Socket. A socket will appear in the Sockets list. Double-click its name to open the Socket Properties dialog.
You can either browse for or type the name of the .abc file to add as an attachment. You can also change the socket's name, or explicitly change its position and orientation. The attachment .abc file will be kept in the model's data as a reference that can be changed during the game. This allows you to switch models on a socket while the game is going. For example, if a player picks up new power-ups, armor, or even clothing, you can add to it and modify it during the game.
Child Model is a term we use to describe animations that are shared across multiple models. A child model is a reference to another data file that contains animations to be used. The only constraint to this construct is that the child model's skeleton has to be organized exactly like the skeleton of the currently loaded model. ModelEdit will signify that an error has occurred if the child model skeleton is not the same as the base model.
This is broad overview of modeling for LithTech. This chapter will cover model creation as it pertains to LithTech in a very abstract terms.
Creating models for LithTech is conceptually pretty straightforward: First, use a modeling package to create a polygonal mesh model and "skin" it over a bone hierarchy. Skinning involves weighting each vertex of the mesh to one or more bones. Afterwards, select a texture for the model, apply UV texture coordinates to it, and animate its bones. The resulting model is ready to export.
The geometric center of the model should be at the origin. For human character models, for example, this would be the pelvis. The model can be made up of one or more meshes. Generally, splitting up models helps make UV mapping easier and can create reusable parts such as hands, feet and so on. The UV mapping of a model has to be done in the modeling package.
All textures in LithTech are 32-bit by default and their size must be a power of 2.
Textures and material values are not explicitly assigned in the modeler, except for UVW Mapping. LithTech uses a special mesh naming convention to associate a texture index to a mesh in the engine. This index will later be used in either game code or DEdit to assign a texture name to the models. The mesh name should take the form meshname_zTex#. The "#" represents the texture index and "_zTex" is the key that must be in the name. For example, a piece named "lower_body_zTex0" will be assigned texture map index 0, while "head_zTex1" will have index 1. Texture indexes correspond to the indexes on your model's different meshes. This way, the game programmer or the level designer controls explicit texture assignment for each mesh in a model. For the current release, there can be only two texture maps per model.
All surface material properties defined in the modeling package are ignored in the exporter. Vertex colors, lighting etc are lost in the conversion, except for UVW Mapping.
Use DEdit to convert images into the DTX format required for the game. DEdit can understand and import .PCX or .TGA files. The advantage to using a .TGA file is that since Targa files have a built-in alpha channel, DEdit can automatically generate an alpha mask for the texture without the need to import a second file as your alpha mask. .PCX files require a second file for their alpha mask, adding a second step and a second file to keep track of.
If you want models to share animations, then all models sharing a set of animations should have the exact same hierarchy. This is very important. Differently organized hierarchies cannot share animations. The skeleton offsets should be similar, but do not have to be exact. There are problems using animation from a short character on a tall character, but most things like walks, runs, and general hand movement work fine. The biggest problem is two characters with different shoulder/arm proportions sharing an animation that requires using two hands together, like holding a rifle, or even something like clapping hands. This will almost never work right, but LithTech supports overriding a shared animation on a per-character basis, so it can be worked around. Remember that you cannot scale bones.
An important concept to remember about the .abc file format is that it is a database that contains the model's geometry, bone hierarchy, level of detail information, and mode. The model database can refer to other files, especially if many models share the same set of animations.
All of the models in NOLF were created to be exported from Softimage 3.7 using our Softimage exporter.
Open: Opens a model (.ABC)
Import: Reads data from a model (.abc) into the current open model, such as new animations.
Save: Saves the model
Save As: Saves the model under a different filename
Exit: Quits ModelEdit
Model Info: Shows information about the model such as the amount of memory it uses and the number of triangles it contains.
Command String: Allows control over attributes of the model; See below for details.
Build LOD: Generates LOD information
Rename Node: Renames a node
Generate Vertex Normals: Recalculates the vertex normals based on neighboring polygons
Remove Node: Deletes the selected node
Set Texture: Changes the texture to be displayed on the model in the display window
Set Internal Radius: Sets the radius of the visibility-culling sphere.
Calc Internal Radius: Automatically sets internal radius based on all the animations used by the model. (Use this instead of 'Set Internal Radius for greater accuracy.)
Edit Weights: Dialog creating weight sets of nodes for animation blending.
Rename: Renames the selected animation
Duplicate: Makes a copy of the selected animation
Dimensions: Changes the dimensions of the selected animation
Reverse: Reverses the time direction of the selected animation
Make Continuous: Causes the selected animation to loop. This adds a length of time at the end of an animation so that it can interpolate back to the first keyframe.
Set Animation Rate: Changes the overall frame rate of the selected animation (or all animations) This does not directly set the animation's frame rate, but instead sets the number of stored keyframes per second. The engine then linearly interpolates to fill in the gaps.
Set Animation Length: Scales the length of the entire animation, making it faster or slower.
Set Animation Interpolation: Creates a dialog to set the interpolation time (in micro seconds) between two animations.
Create Single Frame: Creates a single-frame animation containing the current frame
Translation: Adds a translation to the selected animation
Rotate: Rotates the selected animation
Add Child Model: Adds a new child model. Any .abc file with an identical hierarchy to the current model can be used as its child model.
Remove Child Model: Removes the selected child model
Sockets are transforms for attachments.
Add Socket: Adds a new socket
Remove Socket: Removes the selected socket
Rename Socket: Renames the selected socket
Piece Info: Changes material attributes of the piece. The texture index can be changed and the specular attributes of the piece. The specular power represents the size of the reflected light on the surface of the model. The larger the power the larger the light source. The scale attributes represent how matte the surface is. With a value close 0.5 the surface will not reflect very well, but with a value of 1.0 the surface will look very smooth and shiny. ModelEdit will not show the specular highlight, only the engine will.
Merge Pieces: Select a group of pieces in the piece window and use this to combine them into one piece, based on texture map. If you select all the pieces, the result will be 1 piece for each texture map the model uses. Due to some bugs, don't use this on models with LODs. This is mostly very useful for prop objects which contain lots of pieces.
Lights Follow Camera: When toggled, the red/blue lights move along with the camera
Wireframe: Toggles wireframe rendering mode
Show User Dimensions: Draws a box that shows the size of the selected animation's dimensions graphically. User dimensions define the bounding shape around models for physics.
Show Internal Dimensions: Draws a box the size of the model's dimensions. The internal dimensions are used to determine the clipping state of a model. *The internal dimensions should always contain all of the model geometry as efficiently as possible.
Show Skeleton: Draws the location of the nodes in the model
Show Sockets: Draws the position and orientation of the sockets
Show Attachments: Draws the attached models in relation to their socket (See Command String/SocketModel)
Solid Attachments: Toggles Solid/wireframe mode for any attached models
Show Normals: Draws the vertex normals
Show NormalRef: If supported by the model, displays the vertex normal frame of reference
Profile: Shows performance information in the draw window
New Background Color: Change the color of the model view window.
Change Field of View: Change the camera angle in the model view window.
Mouse motion changes the camera position.
Left mouse rotates the camera around the model.
Right mouse dollies the camera in and out.
Right and left mouse combined pans the camera.
Shift left mouse restores the view.
Click to move to the nearest key frame, represented by red lines. Double-click to tag a key frame. Right-click on a frame to see a context menu for the frame.
Frame Time: Allows skipping to a given time in the animation
Frame String: Assigns a control string to the specified time in the animation
LOD slider: Changes the displayed LOD of the model
User Dimensions radio button: When selected, the +/- buttons control the size of the animation's dimensions
Translation radio button: When selected, the +/- buttons control the translation of the animation
X Deletes the animation
# Moves the animation to an index in the list
Up arrow: Moves the animation up in the list
Down arrow: Moves the animation down in the list
Global: Toggles whether adjustments are node-relative or global
Socket: Specifies that sockets will be adjusted by the adjustment color boxes
Relation: Specifies that nodes will be adjusted
Rotation: Click on the color (Red = X, Green = Y, Blue = Z) and drag left/right to rotate around that axis
Translation: Click on the color and drag left/right to move along that axis
If a node name has a check in its check box, the node will be placed relative to its parent, only the rotation will be used from the animation data. Not checking these where needed will cause bone lengths to be transferred from a child model to the parent, causing potentially strange looking scaling of a character
A checkbox here indicates that an animation is from this model and may therefore be changed/moved/etc.
The command string is a semicolon-delimited string defining the extra control settings for a model in ModelEdit, the engine, and in the final game. Most commands are game specific.
These are commands not ignored by ModelEdit:
ModelEditTexture: Specifies a texture filename to use for a texture channel. The command is specified in the form ModelEditTexture Channel Filename. (e.g. ModelEditTexture 0 C:\models\textures\player.dtx)
The steps below will walk through the character creation process for No One Lives Forever. All the characters in NOLF were created in Softimage. This is the only package for which we have a reliable NOLF exporter.
The player view (PV) hand guns, gadgets and vehicles for No One Lives Forever were modeled, UV textured and animated in Softimage. Each weapon PV model was exported from Softimage to an .abc file and could then be opened in ModelEdit for final additions needed for the game code as well as tweaks to the animations. The final thing needed to get player view weapons to work properly in the game are the attributes for the weapons that are outlined in the weapons.txt and the effects defined in the fx.txt.
The PV weapon/gadget/vehicle models in NOLF are somewhere between 1400 - 1800 triangles including the hand models (the hands are about 450 triangles each.)
Each PV weapon/gadget/vehicle has two textures associated with it:
1. The hand texture which is used is based on the model style; actionhands_pv.dtx is used with the player_action.abc.
2. The weapon/gadget/vehicle texture. The weapons.txt directs the game to the appropriate texture for this. An example would be: PVSkin = "Guns\Skins_PV\Contender_pv.dtx"
Each texture is 256x256. These should be saved as 32 bit .tga files and converted in DEdit to .dtx files by going to the textures tab and importing the tga files to nolf/guns/skins_pv/.
Chrome/environment mapping can be used on the texture using the alpha channel. In Dedit, in Textures/guns/skins_pv, double click on the texture and a new window will appear. Under Texture Format, check off Use 4444 in 16 bit mode. Darker values will use more chrome.
The exporters will keep the translation and rotation information but not the scaling. It is a good idea to keyframe at least one piece or null object for every frame of the entire animation because fcurve information is not something retained when exporting (the engine will interpolate between keyframes linearly) and the exporter will only export a key for every keyframe in the scene.
· Note: Some parts of the animations, such as the vehicle turning and the motorcycle tachometer and speedometer, are implemented in the game code.
In order for all of the geometry to be exported properly, all the pieces of the model and skeleton need to be part of the same hierarchy. Models should be exported to the folder nolf/guns/models_pv.
The animations for the weapons need to be very specific for the weapons to function properly in the game. Here is a list of the animation names and when this animation plays in the game:
· Idle_0: Idle animation played when the object is not being selected, deselected or interacted with in any way. (all NOLF weapons/gadgets had Idle_1 and Idle_2 animations as well which would play sporadically when idling.)
· Select: the animation played when an pv object is selected
· Fire: the firing animation. Fire1 and Fire2 are alternate animations that will play at random if they are part of the .abc file (these were used for the unarmed karate chops.)
· Deselect: the deselecting animation when putting away a gun/weapon/vehicle or switching to another
· Reload: the animation played when a weapon or gadget has run out of ammo or when the reload key is hit
Those are the most basic animations that would be required. For more complicated items that have two states, such as the lighter gadget in NOLF, these additional animations are required:
· AltSelect: switches the gadget from one state to another
· AltIdle_0: idle animation for the gadget in it's second state
· AltFire: the fire animation used in the alternate state of the gadget
· AltDeselect: this animation serves as the reload for the alternate gadget function
· AltSelect2: switches the gadget state back to the default state
After you export a PV weapon/gadget/vehicle, use ModelEdit to add attributes, such as user dims, internal dims, sockets, command strings, and frame strings.
User dims for all weapons in NOLF are the same: X: 1.5, Y: 2, Z: 1.5. Because the models are so small, these dimensions do not need to be exact but not setting dims results in a very long bounding box that will remind you that you didn't set them.
The internal radius must be set, and is most easily done using the Model menu Calc Internal Radius command. This is a rendering optimization that must be done.
Sockets are used to place attachments on guns for mods like the silencer and scope. To see how sockets are used, open a NOLF gun and go to the Select Options menu. Click Show Attachments and Show Attachments again. A multi colored axis will appear at each socket location. Double click on a socket name in the sockets window. Browse to the location of attachment .abc file and open it. Select Socket and then adjust its position and rotation using the colored buttons in the Transform Edit box. Any model can be used as an attachment.
The PV models all use to command strings to set the model FOV and to set how the model will be lit by model lights placed in DEdit. An example would be one of the lipstick gadgets which has this command string: FovXOffset 20;FovYOffset 50;NormalRef lsmiddle Select. The NormalRef command string has the name of a piece of the model that handles the model lighting well.
Frame strings are added to provide animation based cues to the game code. For weapons, the ones used are FIRE_KEY for the firing sound and creation of projectiles or sending out a fire vector depending on the weapon, SOUND_KEY # for any sounds played with other animations (selecting, deselecting, reloading, etc.) and FX_KEY for any effects that are turned on or off during animations (the light on the lipstick bomb gadgets for example.) These are entered by going to the frame of animation where the incident occurs and typing the appropriate string in the Frame String box.
The weapons.txt file found in the attributes file defines all weapon and ammo properties: interface artwork, model, skin, position, and much more. For a better explanation, look at the weapons.txt for examples (the weapons.txt also has a brief description for what everything does.)
The fx.txt file found in the attributes file defines all weapon effect properties: impact effects, muzzle flashes, and other effects like the flame on the lighter. For a better explanation, look at the fx.txt for examples (the weapons.txt also has a brief description for what everything does.)
The PV models are positioned in the engine by using the mppos command when you hit the key that has been mapped for 'talk.' From there you can manipulate the model position by using the move keys. When the model is in the desired position use the 'mppos' command again and the position for that specific model will be saved to the weapons.txt file.