# UStunts3dedit

ustunts3dedit is a simple 3D editor that is supplied with Ultimate Stunts. It can be used for low-level polygon modification, simple 3D transformations and conversion from foreign file formats to the Ultimate Stunts .glt and .glb file formats.

### Before starting ustunts3dedit

In order to work properly, at least one file should exist in the root of either the datadir or the savedir: textures.dat. Also, a correct ultimatestunts.conf file should be somewhere at a location where Ultimate Stunts can find it (described elsewhere). In other words: you need a working Ultimate Stunts installation. The textures.dat file manages which textures are loaded.

### Preparing textures.dat

The first line of textures.dat should contain the text "TEDITFILE". If you are editing an existing file that does NOT contain this text on the first line, then it probably isn't a "textures.dat" suitable for ustunts3dedit.

After a line containing the text "BEGIN", textures.dat has a line containing the number of textures to be loaded. The next lines contain the filenames of the texture files.
Important: the number of texture files should ALWAYS match the number noted above!
The last line probably says "END", but that isn't really important.

### Starting ustunts3dedit

After starting ustunts3dedit, you have two important windows: the openGL window, and the console window. You can give commands by pressing keys in the openGL window, and most commands request some extra information, which can be entered in the console window. Because of this console window, it is important NOT to start ustunts3dedit in fullscreen mode. If it starts fullscreen (you get a black screen), exit it with Escape and edit ultimatestunts.conf to set it to windowed mode.

### Loading a file

After you've set textures.dat and started ustunts3dedit, it's time to enter your first command. press "h" in the openGL window. This gives you a list of all commands that are available (you can see the list in the console window). You can see that "F" means load a file, and "f" save a file. Capital characters are (of course) entered by pressing the shift-key (I don't think that Caps Lock will work). So, in order to load a file, press shift-F.

Now the program asks some questions in the console window. The program will not continue until you've answered these questions, even the openGL window won't be updated. The first question, something about LOD things, can normally be answered with "n". Then it asks for the file format, and the filename. The filename should be given relative to the datadir of Ultimate Stunts. I usually put the things I work on in the root of that directory, so that I only have to enter the filename, and not a long directory path.

For example: suppose that you want to load the body geometry of the Formula 1 car. Then the following describes exactly what you should type in the different windows. C: means "console window" and G: means openGL window. A capital charachter F means shift-F, [Esc] means the escape key, and so on.

    C: F
    G: n[enter]
    G: 2[enter]
    G: cars/f1/body.glb[enter]

Then press [PgUp] for some time in the openGL window to zoom in to the model, and use the arrow keys in the openGL window to view it from different angles.

### Keys

To do something with ustunts3dedit, just use your keyboard. Each key mentioned below should be used while the openGL graphics window has the keyboard focus.

The following keys work immediately, without user input on the console window:

- The arrow keys: used to rotate the camera view around the tile.
- PgUp/PgDn: Move towards/away from the tile
- Escape: used to exit the program (without saving!)
- End: to toggle between origin and tile center mode

Other keys, dealing with modifying and loading/saving, may or may not need console input. You always press the key in the openGL output window, and then switch to the console window to enter/view additional information. To check which functions are connected to which keys in your version of ustunts3dedit, press the 'h' key. Some of these keys are documented here:

- Load
- Save
- Settings
- help
- Change primitive
- Scale
- Mirror
- Clamp
- Split
- Set as collision object
- Generate normals, texture replacement colors or texture coordinates
- Rotate
- Translate
- Rotate texture
- Translate texture
- Select primitive
- Select vertex
- New primitive, vertex or triangle
- Delete primitive, vertex or triangle
- Change vertex or triangle
- Duplicate primitive

# Information about Ultimate Stunts 3D models

The 3D models that can be modified with ustunts3dedit have certain properties, and you need to understand these properties before working with ustunts3dedit.

First of all, a 3D model consists of several primitives. Every primitive has its own material properties, and many operations can be applied to individual primitives. Every primitive has certain vertices and triangles in it. Vertices define a point on the surface of the primitive: they have a position, a normal vector and texture coordinates. Triangles connect the vertices together. Every triangle has three vertex index numbers, that refer to elements of the vertex array. Position coordinates of vertices are all global: primitives don't have their own coordinate sysrtem.

Textures are teferred to with an index number. 0 is the first texture, 1 the second & so on. -1 means "no texture". Which texture file is actually used for a certain texture number, is defined in textures.dat. Ultimate Stunts itself gets this information from the track file or from the car configuration file.

Every primitive has a LODs parameter. The LODs, or "Levels Of Detail", are "layers" in the scene. The LODs parameter defines in which layers a primitive is "visible". There are currently 6 layers: 1, 2, 3, 4, c and s. 1 should contain the most detailed graphics model (for close view), and 4 the least detailed graphics model (for far away). c is used for collision models in cars and for collision models of models and walls in tiles. s is used for ground surfaces in tiles. The combination cs is used for water.

# Ustunts3dedit Command reference

### General functions

F: Load

    Do you want to merge the file as a LOD (y/n)? n
    Opening file. Choose from:
    1: *.glt / *.gl file
    2: *.glb file
    3: 3dto3d smooth *.raw file
    4: 3D Studio *.3ds file
    Your choice: 2
    Enter filename: tiles/tunnelin1.glb

Load a geometry file. Merge as a LOD means that you can merge the loaded file with the current scene, where the new file becomes one of the LODs of the model. If you just want to replace the current scene with the loaded file, then answer "n" on that first question. Old Ultimate Stunts *.gl files can be loaded with the *.glt loader.

f: Save

    Saving file. Choose from:
    1: *.glb file
    2: *.glt file
    Your choice: 1
    Saving *.glb file.
    Enter filename: tmp.glb

Just enter the filename. You can save as Ultimate Stunts *.glt or as *.glb file. *.glt is a text-based format, backward compatible with the old *.gl format, that allows editing with a text editor. *.glb is a binary file format that allows fast loading. Both formats can be loaded and saved by the ustunts3dedit program, but only the *.glb format can be loaded by the game.

S: Settings

    Set visible LODs: 1234sc

Currently you can only set the visible LODs here. Useful if you want to see what the LODs look like.

h: help

Display all the functions that are available in this version of ustunts3dedit.

### Tool functions

C: Change primitive

    Name: Weg
    Type: Vertex array
    Texture: 1
    LODs: 1234s
    Modulation color: 1.000000,1.000000,1.000000
    Texture replacement color: 0.615686,0.619608,0.588235
    Opacity: 1.000
    Reflectance: 0.000
    Emissivity: 0.000
    Static friction coefficient: 1.000
    Dynamic friction coefficient: 1.000
    Entering "-" will leave a property unchanged
    Enter new name: Road
    Which texture should be attached? 0
    In which LODs should it be visible? 123c
    Modulation color: 1,1,1
    Texture replacement color: 0.1,0.1,0.1
    Opacity: 1
    Reflectance: 0
    Emissivity: 0
    Static friction coefficient: 1
    Dynamic friction coefficient: 1

Change the properties of the currently selected primitive: name, type, LODs and several material properties. The friction coefficient are not (yet) used in Ultimate Stunts (version 0.5.4).

s: Scale

    Do you want to autoscale the entire scene (y/n)? y
    Do you want to scale around 1:the origin or 2:the CG? 1
    Enter new size: 40
    Scaling with scalefactor 1.000050

Scale the scene or the selected primitive to a desired size. If you want to scale with a certain scalefactor instead of scaling to a certain size, then you'd better have a look at the rotate-function (yes, the rotate-function!). Scaling can be done around the origin of the scene or around the "center of gravity" of the primitive.

m: Mirror

    Do you want to mirror the normals? y
    Do you want to mirror the vertices? y

Polygons in Ultimate Stunts are single-sided. If you want double-sided polygons, then you can duplicate a primitive, and use the mirror-function. Mirroring vertices inverts the direction from which the primitive is visible, by putting the vertices in the opposite direction in the vertex array. Mirroring normals can help to get the lighting right.

a: Clamp

    Clamp in value:30
    Clamp out value:30

This function selects all coordinates that are close to the in value, and sets them equal to the out value. This can be useful, for instance, to give the edges of a tile model exactly the right sizes, if importing and exporting has created roundoff errors.

P: Split

    Give axis (x, y or z):y
    Give limit value:12
    Do you want to keep everything above this value? (y/n):n

With this function you can split the scene into two parts, keep one part and delete the other. The splitting is done by looking at coordinates of vertices. Triangles that are partially in and partially out the selected area are deleted.

l: Set as collision object

    Do you want to apply the collision tool on the current primitive? y

If you have a primitive with a set of planes that define a bounding volume collision model (e.g. for cars) and you want to make it fit to the other LODs, then this function can be applied to that primitive. This function should NOT be used on tiles, as the tile collision model can simply consist of the same polygons that are used for graphics. To have a look at what kind of primitives this function should be used, load a car body model: We're talking about the blue translucent planes.

g: Generate normals, texture replacement colors or texture coordinates

    Generate normal vectors for this primitive (y/n)? y

This function contains some functions that generate some data automatically. While some of them are not yet implemented, the generate normals function is, and it is very useful if something has gone wrong with the importing of a smooth shape.

### Transform functions

r: Rotate

    Do you want to rotate the entire scene? y
    Do you want to rotate around the x-axis (y/n)? n
    Do you want to rotate around the y-axis (y/n)? n
    Do you want to rotate around the z-axis (y/n)? n
    Enter the new position of the x-axis: 1,0,0
    Enter the new position of the y-axis: 0,1,0
    Enter the new position of the z-axis: 0,0,1

Rotate a primitive or the entire scene. You can choose to rotate around the x, y or z axis. If you choose none of them, then you can enter a transformation matrix by giving the new positions of the coordinate axes. If you don't want to do this, then entering "1,0,0" for the x-axis, "0,1,0" for the y-axis and "0,0,1" for the z-axis will leave your model unchanged. You can also use this matrix tool for scaling. For example, giving "2,0,0" for the x-axis will scale the scene or primitive with a factor 2 in the x-direction.

t: Translate

    Do you want to translate the entire scene? y
    Enter translation vector: 0,0.5,0

Translate a primitive or the entire scene. You can enter the translation vector.

R: Rotate texture

    Enter the new position of the x-axis: 2,0
    Enter the new position of the y-axis: 0,2

Rotate the texture-coordinates of the selected primitive. This is done by entering a 2D transformation matrix (which contains the new 2D position of the old x-axis and the new 2D position of the y-axis). Of course, this can also be used for texture coordinate scaling. I apologise to all of you who never had matrix math at school. I know this is just easier for me as a programmer, but not to you as a user.

T: Translate texture

    Enter translation vector: 0.5,0

Translate the texture-coordinates of the selected primitive. You can just enter the 2D translation vector.

### Edit functions

p: Select primitive

Select a primitive

v: Select vertex

Select one of the vertices of the selected primitive

n: New primitive, vertex or triangle

    Do you want to add a new vertex (y/n)? n
    Do you want to add a new triangle (y/n)? n
    Do you want to add a new primitive (y/n)? y
    Enter the name: Test
    Which texture should be attached? 0
    In which LODs should it be visible? 1234s
    Modulation color: 1,1,1
    Texture replacement color: 0,1,0
    Opacity: 1
    Reflectance: 0
    Emissivity: 0
    Static friction coefficient: 1
    Dynamic friction coefficient: 1
    Deleting old model...
    Generating model...
    Do you want to add a new vertex (y/n)? y
    Give position: -20,0,-20
    Give normal: 0,1,0
    Give texcoord: 0,0
    Deleting old model...
    Generating model...
    Do you want to add a new vertex (y/n)? y
    Give position: -20,0,20
    Give normal: 0,1,0
    Give texcoord: 0,1
    Deleting old model...
    Generating model...
    Do you want to add a new vertex (y/n)? y
    Give position: 20,0,20
    Give normal: 0,1,0
    Give texcoord: 1,1
    Deleting old model...
    Generating model...
    Do you want to add a new vertex (y/n)? y
    Give position: 20,0,-20
    Give normal: 0,1,0
    Give texcoord: 1,0
    Deleting old model...
    Generating model...
    Do you want to add a new vertex (y/n)? n
    Do you want to add a new triangle (y/n)? y
            0: -20.000000,0.000000,-20.000000
            1: -20.000000,0.000000,20.000000
            2: 20.000000,0.000000,20.000000
            3: 20.000000,0.000000,-20.000000
    Enter the vertex indices: 0,1,2
    Deleting old model...
    Generating model...
    Do you want to add a new vertex (y/n)? n
    Do you want to add a new triangle (y/n)? y
            0: -20.000000,0.000000,-20.000000
            1: -20.000000,0.000000,20.000000
            2: 20.000000,0.000000,20.000000
            3: 20.000000,0.000000,-20.000000
    Enter the vertex indices: 0,2,3

Create a new primitive or a new vertex within the current primitive. The example that is given here creates a horizontal ground plane.

del: Delete a primitive, vertex or triangle

With this function, primitives, vertices or triangles can be deleted. After selecting whether a primitive, a vertex or a triangle needs to be deleted, one can choose the primitive, vertex or triangle that needs to be deleted.

c: Change vertex or triangle

    Do you want to change a vertex (y/n)? n
    Do you want to change the indices of a triangle (y/n)? y
    Triangle 0: 0  1  2
    Triangle 1: 0  2  3
    Select a triangle: 0
    Current indices are: 0  1  2
    Give new indices ("-" = no change): 0,1,2

Change the properties of the selected vertex, like position and normal, or the vertex indices of a triangle.

d: Duplicate primitive

Duplicate the selected primitive.