Advanced model management

While working with Ultimate 3D you will come to appreciate the importance of model objects very quickly. In contrast to primitive objects, model objects are extremely flexible. But rendering model objects takes more computing time and models with high triangle counts can greatly slow down the performance of your games. For this reason this tutorial is going to deal with a couple of features that can be used to render models more efficiently.


Managing model files

Sometimes it happens that there are objects in your game that do not exist from the beginning but get created during game play. If these objects were loaded at the time they were needed, it would lead to a short lag. *.md2 files and *.an8 files can take especially large amounts of time to load. For this reason, you can preload models using the following function:

PreloadMesh(
File,
Password
)

File
The file that contains the model you want to preload.

Password
If File is an encrypted Ultimate 3D model file, you can enter the correct password for decryption to this parameter. Otherwise you can put either an empty string or nothing.


Once you have called this function for a model, creating a model object from it will not take any significant amount of time anymore. This way you can avoid a disturbing lag. When you load a model through LoadMesh() and destroy the object after that, you get the same effect. Ultimate 3D will never load the same model twice, because it keeps the model data in memory, even if the objects based on this model get destroyed. This way it avoids endless loading times in a reliable way. Of course, this behavior is not always appreciated. If you switch from one level to another, it would be a waste of memory to still have all models from the previous level loaded. For this reason Ultimate 3D allows you to release models explicitly.

The following function releases the given model file so that it does not take memory anymore and returns true if it succeeds. If there's still an object based on this model when you call this function, it will not release the model, to avoid conflicts. In this case it returns false.

ReleaseModel(
File
)

File
The file that contains the model you want to release.


Exporting to *.u3d files

This is an easy one. There's only one function to export model objects to Ultimate 3D model files and it takes only three parameters. So here you go:

This function exports the model object it's called by to the given file. The resulting Ultimate 3D model file will hold a representation of the model as it was at the time this function was called. The only information that will not be saved is the information that can be set up through variables.

ExportToU3DFile(
OutputFile,
Password,
ExportResources
)

OutputFile
The desired output file for the model object. If the call to the function finishes successfully, this file will contain the Ultimate 3D model file.

Password
The password that is to be used to encrypt the Ultimate 3D model file. If this is an empty string or null, the file will be exported unencrypted. The longer the password is, the more secure is the protection.

ExportResources
This parameter can take true or false. If you pass false the Ultimate 3D model file will not contain the textures and effects. These will be loaded from files as usual. Only the data of the *.ufx files will be exported. If you pass true the file will be a stand alone model file. It will not require any other files to be loaded. All textures and shaders will be included. Note that models that use a
render target texture as a texture for one of the materials cannot export their resources.

Of course, no guarantee can be given on the safety of the password encryption mechanism of Ultimate 3D. Specialists would probably be able to decrypt encrypted Ultimate 3D model files. However, it should be safe enough to keep away casual game developers or hackers. Even though I own the code that does the decrypting, I would not be able to decrypt an Ultimate 3D model file without the correct password.


Creating multiple levels of detail

Models can be extremely complex. Their complexity is directly connected to their triangle count. As such, models with a very high triangle count will reduce the performance of your game, so you'll get lower frame rates. For this reason it's important to always use as few triangles as possible. Often the fully detailed version of the model is not needed at a distance. If the object is farther away from the camera, its level of detail can be decreased. This technique is commonly referred to as LoD (level of detail). Ultimate 3D can create LoDs automatically and use them for given distances. The following picture shows an example of a model that has been simplified using the built-in LoD generator of Ultimate 3D.

Illustration not available

The difference between the first and the second version of the model is barely noticeable, but the triangle count has been decreased by 40%. The third version of the model has a triangle count that's decreased by 70%. However, the basic shape of the model is still recognizable. At a very long distance this low level of detail is perfectly suitable, even for high-graphics games. Using LoDs is extremely easy. You simply call one function in which you tell Ultimate 3D about the requested level of detail and the distance at which it is to be used. Here's the syntax:

This function creates LoDs with the given percentage triangle count for the model that calls the function and uses them for the given distance:

CreateLODChain(
CameraDistance1, LoD1,
CameraDistance2, LoD2,
CameraDistance3, LoD3,
CameraDistance4, LoD4,
CameraDistance5, LoD5
)

CameraDistance1, CameraDistance2, ..., CameraDistance5
The distances to the camera the LoD is to be used for. So the original LoD is used at distances from 0 to CameraDistance1, LoD1 is used at camera distances from CameraDistance1 to CameraDistance2 and so on.

LoD1, LoD2, LoD3, LoD4, LoD5
The levels of detail that are to be created. This is a percentage value so 100 means an unchanged triangle count and 0 means the lowest triangle count achievable (usually 3 triangles). The parameters have to fulfill LoD1>LoD2>=LoD3>=LoD4>=LoD5. If one of these values is zero this tells Ultimate 3D to stop creating additional LoDs.


LoDs can greatly increase the frame rate of your game, but they will also require memory and computing time (to be created). Remember that you must not create LoDs for *.md2 files. Creating them for every single frame can take a few minutes. Finally here is a small code example on how to create LoDs for a model. This code should be used at the end of the create event of a model object:

CreateLODChain(100,70,500,40,1000,20);


Creating animations from multiple model files

If you wish, you can create animations from multiple files instead of using file formats with support for skeleton animation (*.3ds, *.x or *.an8) or *.md2 files. To do this you have to add every single frame by calling the following function after creating the object with LoadMesh():

AddFrame(
File,
Password
)

File
The file that contains the frame that is to be added.

Password
If File is an encrypted Ultimate 3D model file, you can pass the correct password for decryption to this parameter. Otherwise you can pass either an empty string or nothing.


Since you would need a lot of frames to get a fluent animation, there's a possibility to enable vertex tweening for animations (vertex tweening is the technique that's enabled by default for *.md2 models). This will only work if all added frames have the same number of meshes, vertices and triangles. The function that enables vertex tweening is called EnableVertexTweening() and does not take any parameters.


Creating primitives from models

As I already said in the chapter about primitive objects, primitives get rendered extremely efficiently. All primitives that use the same material and the same texture get rendered simultaneously. This way the graphics device can process them much more efficiently. And in games it will often happen that you have simple objects that are too complex to be represented by the usual primitive objects, but appear very often. So usually you have to create them as model objects, but that would be inefficient. For that reason there's a function to create primitives from model files. Before creating the primitive object from the model you have to set up two variables:

file
The file that contains the model you want to create a primitive object from.

material
The index of the model material that is to be used for the primitive object.

password (optional)
If file refers to an encrypted Ultimate 3D model file, this variable has to be set to a string giving the password. Otherwise you do not need to set up this variable.


After setting up these variables you have to call CreatePrimitiveFromModel() once to create the primitive object. As with any other primitive object you have to put a call to Step() and Destroy() into the corresponding events. Primitive objects created from models also have the variable texture to set up the texture that is to be used. Note that only the first mesh of the model will be used to create the primitive object. It is useful to use *.an8 files with this function, because when loading *.an8 files Ultimate 3D creates only one mesh per object.


Creating custom backgrounds

The built in system for backgrounds of Ultimate 3D is nice, but it is very limited. If you want backgrounds that change over time or backgrounds, which use some special effects this can not be done with the built in system. In this case a more versatile technique is needed. Objects, which can be manipulated in complex ways are needed. Model objects are objects like this. For this reason Ultimate 3D gives you the possibility to use model objects as background objects.

Every model object can be set to be in background mode. Then this model object will not be effected by fog anymore and it will be covered by all other objects. This makes it seem to be in the background. To reach that it does not become obvious that it is not really in the background you should make it follow the camera, by setting its position to the position of the camera in every step. Enabling background mode is easy.

This function enables or disables background mode for the model object it is called by.

SwitchBackgroundMode(
EnableBackgroundMode
)

EnableBackgroundMode
If this parameter is true background mode will be enabled for the model object, otherwise it will be disabled.

Once the first model object gets set to background mode the built in system for backgrounds gets disabled completely. This will look very strange, since all objects will leave trails, so you should better make your model object in background mode so that it covers everything around the camera. You can also use multiple model objects in background mode, but you need to be careful then. Background objects are covered by everything, even by other background objects. Which background object covers which background object depends on the rendering order. For this reason you should make sure that the objects, which should have a lower depth, get created later. Also you should avoid that background objects cover parts of themselves, since this leads to the same problem. The best shapes for background models definitely are spheres and cubes.

If you keep these things in mind you can get very good results with this feature. You can have a sun, that travels over the sky, changing clouds, daytime changing effects, clouds, which are lit in realtime and a lot more. Good backgrounds are a key to impressive graphics. You should use this feature to its full potential.



© Christoph Peters. Some rights reserved.

Creative Commons License XHTML 1.0 Transitional