Model system
Contents
Overview
tl;dr: a simple scenegraph-based approach that has nothing to do with the old system or Lua, focus is on easy importing, supports some animation.
Importing models
The import system theoretically supports many different formats but you are expected to use only some:
- When node structure, node names and animations matter, use Collada (.dae)
- For static geometry, such as buildings, OBJ is recommended, this may allow for some optimizations
The only officially tested 3D modelling program at the moment is Blender 2.64.
The model viewer is supplied with the game. See Newmodelviewer.
Model definition file
Models must be placed under data/newmodels
To define a model, create a simple name_here.model
text file along with your exported meshes:
#Comments can be written like this #Define all used materials first Material some-material tex_diff some_texture.png diffuse 0.8 0.7 0.7 #Meshes to be imported into this model, should be in the current folder #Mixing different formats should be OK mesh part1.obj mesh part2.obj
Materials
Only material names are imported from 3D models, to set material properties use a small definition like this:
material CobraI_body tex_diff CobraI_diff.png tex_glow CobraI_emit.png tex_spec CobraI_spec.png diffuse 1.0 1.0 1.0 specular 1.0 1.0 1.0 shininess 150
Material properties
material | Name. Mandatory! Note, some exporters modify the names from what is visible in the modeling program, for example the Blender 2.6 Collada exporter adds "-material" to each name. You'll have to use this final name. |
diffuse | Diffuse colour RGB. Default white. |
specular | Colour of specular highlights, RGB. Default white. Set to black to disable highlights. |
emissive | Self-illumination colour, RGB. Default black. |
shininess | Sharpness/size of specular highlights, 0 - 200. Default 200. |
opacity | 0-100, controls transparency of the material. A node with a material opacity less than 100 is treated as transparent, otherwise opaque. |
tex_diff | Diffuse texture, file name (in the same folder). If you don't specify this, a white dummy texture is generated. |
tex_glow | Self-illumination texture, overrides emissive colour parameter. Default none. |
tex_spec | Specular highlight colour/intensity texture. Default none. Multiplied by specular colour parameter, so set it to white to leave control entirely to the texture. |
use_patterns | yes/no. This material will use the pattern/colour system. Read more below. Default no. |
Flat specular lighting improved by a specular map
A model lit only by the self-illumination texture
Patterns
A system to mark customizable color areas on a model without splitting it to separate materials.
Patterns are small grayscale textures placed in the model folder, named pattern*.png. Using gray or white colour you can mark the areas tinted by one of the customizable colours (black marks unaffected areas). The colours are set by the game (faction-specific ship colours, shipyard UI for the player).
The system has several limitations: it is not meant to do fine details, transitioning from one color to another is sharp and it works best with white/light textures. You'll have to experiment.
Detail levels
Meshes can be grouped into detail levels using the lod pixelsize
directive:
lod 100 mesh hull_low.dae lod 200 mesh hull_med.dae lod 1000 mesh hull_hi.dae mesh landing_gear.dae
A detail level will be picked if the approximate size of the model on screen is less than pixelsize
(for the highest level it does not matter as long as it's larger than the others). Use the modelviewer to find optimal sizes.
You may specify any number of detail levels in any order, they will be sorted according to size.
Animations
Position, rotation and scale keyframe animation is supported. Since the Blender 2.6 Collada exporter cannot export multiple animations in one file, you will have to put it all in one timeline and split it at the import stage (this is also the only reliable way to get named animations). An animation is defined after all the meshes in format anim name startframe endframe
:
anim gear_down 0 10 anim something_else 12 25
Note, Collada uses seconds instead of frame numbers. For the conversion to work, you should create the animations at 24FPS.
The game will recognize animations by name, the list of supported animations is to be decided.
There is no animation blending, so two animations shouldn't be directly controlling the same node.
Attachments
Models may have special "tag point" nodes where other models may be attached. You may define a tag point in Blender by placing an Empty object and giving it one of the predefined names.
The system is meant for attaching equipment: guns, cargo pods, turrets...
Example: A generic gun model attached to a point "tag_gun_right":
The actual list of available names has not been determined yet.
Collisions
By default, the collision mesh of a model is the bounding box of all the meshes. For more control, you can import a custom mesh using the collision
directive in the model definition:
collision collision.obj
This will be global for all detail levels.
Decals
Decals are meant for customizable insignia on spaceships and changing advertisements on space stations. Up to four unique decals are available for a model (multiple identical decals are allowed). Place a piece of geometry, usually a flat quad, with proper UV coordinates and name it decal_01, 02, 03 or 04. The game will then use a special material on the geometry, or make it invisible if no decal is to be used.
Labels
Dynamic 3D labels are meant for naming ships and space stations. Put an empty node in the model and give it a name beginning with "label". The text is set by the game at runtime if supported.
Node scale can be used as usual but the text is not constrained to the node bounds or anything like that, so some trial will be required.
You can use multiple label nodes but they will all show the same text.
Minor features
Billboard lights
Simple light sprites placed using empty nodes with special naming (navlight_*). Certain lights will blink when a ship's landing gear is down. This feature is not complete as it needs more support in the game.
Thrusters
Thrusters are marked with dummy objects. In Blender, create an "Empty" object and point its Z-axis (change the object display type to "arrows" or "single arrow" to visualize this) where the thruster should point. Thruster size is taken from the object scale. Begin the object name with either thruster
or thruster_linear
so the importer can recognize them (linear thrusters light up only when moving up/down/left/right/forward/backward, not when turning).
Internals
You can find some testcase models at git://github.com/Luomu/newmodels.git.
The internal scene graph consists of several of these nodes:
Node | Base class. A node can have a name and one or more parents. |
Group | A group is a Node that can have several children. |
MatrixTransform | A Group that applies a transformation to its child nodes when rendering. |
StaticGeometry | Contains one or more StaticMeshes. |
LOD | Detail level control node, picks one of the child nodes based on the approximate size of the model on screen. |
ModelNode | Can be used to attach another Model as a submodel. Use case: dynamic equipment on ships. |
More! | Some marginal nodes that exist at the moment are:
|
MatrixTransform nodes are the most commonly used, if a geometry is rotated or scaled it will be parented to a MatrixTransform. A simple form of instancing can be achieved by adding a geometry as the child of several separate MatrixTransforms.
During rendering, the graph is traversed twice. Once for opaque objects, and once for transparent objects (which includes decals, thrusters). The model system does not perform any depth sorting, this improvement job needs to be done elsewhere.
Animations
An animation consists of Channels. Each channel controls one node (always a MatrixTransform) and has a list of position and rotation Keys. Each key has a time and value. Keys are always linearly interpolated.
At first the animations had proper play/pause/loop functionality but right now it is not so. Animation progress (and fun things like serialization) needs to be controlled directly by whatever feature uses the animation (see: landing gear).
Graph dump
Below, an actual model test_meteor (two LODs, animated landing gear, several ship thrusters)
Group - test_meteor LOD Group - 10 MatrixTransform - Scene MatrixTransform - Meteor_Low StaticGeometry - Meteor_Low_mesh Group - 1000 Group MatrixTransform - Scene MatrixTransform - Meteor_Hi StaticGeometry - Meteor_Hi_mesh MatrixTransform Thruster - thruster_linear_rear_001 MatrixTransform Thruster - thruster_right_001 MatrixTransform Thruster - thruster_top_001 MatrixTransform Thruster - thruster_right_000 MatrixTransform Thruster - thruster_left_001 MatrixTransform Thruster - thruster_left_002 MatrixTransform Thruster - thruster_linear_rear_000 MatrixTransform Thruster - thruster_top_000 MatrixTransform Thruster - thruster_wing_001 MatrixTransform Thruster - thruster_wing_000 MatrixTransform Thruster - thruster_wing_002 MatrixTransform - decal_01 StaticGeometry - decal_01_mesh Group MatrixTransform - Root MatrixTransform - LandingGear StaticGeometry - LandingGear_mesh MatrixTransform - tag_gun_left MatrixTransform - tag_gun_right
Optimization potential: unanimated geometry should be pre-translated at loading phase to get rid of some MatrixTransforms.
Question: you might notice tag_gun_left and right are attached to the model root node. They have been pre-transformed to make the positions absolute. It's done this way since if a tag is defined on each LOD it can practically have several positions. This is a bit stupid since now they are outside of the LOD node. Should tags be kept in their original locations in the structure (then model->FindTag will potentially return more than one)?
New systems that need to be developed
Lots of them :)
- Model cache system so geometry is converted only once
- Lua API
- System to handle attachments
- Tag points may be rotated in code to implement target tracking guns
- System to handle spaceship logos, station advertisements and shipyard UI to customize your ship
- It should be possible to add ship insignia by dropping a .png in your user folder, without saves breaking if you later remove that .png
- UI to paint your ship and a system to give faction-appropriate colour schemes to NPC ships
- Building sets
- Update collision system to handle animation (just updating BB should be enough)
- Separate space station docking scripts from the old models
- There is no good way to define parameters for certain triangles (geomflags in LMR). The main use case is to mark landing pads, this will be doable with a named node.
- etc