furrycat's character conversion guide

This guide explains how to convert SWAT3 character types. The gsmhacking tool can convert suspect, hostage and kid models to SWAT, and SWAT to male suspect (can also be used as a hostage).

Hazmat dude to [furry] ops

These modified characters can be used as the base for mods such as the [furryclan] uniform mod, which features a "Hazardous Ops" skin derived from the dreaded Hazmat dudes.

You can't simply use suspect models for playable characters because they have a different number of bones. Each character class has its own unique set of animations for performing in-game actions such as aiming a weapon, deploying CS gas or dropping down dead. Animations for characters with a certain number of bones cannot be used for characters with a different number.

The solution is to edit the character GSM files directly and replace the skeleton structure with one that will work with the target animation. This is actually quite easy to do once you understand the GSM file format.

The progenitor of all GSMs is of course 3D Studio MAX. Let's take a look at an actual character mesh (released to the public by Sierra) to get an idea of how the skeletons work.

Skeletons in 3D Studio MAX

This is a character mesh as seen in 3D Studio MAX. The green lines are the triangles in the mesh and the coloured "boxes" represent the bones in the physique. Look at the purple thing on the right to see this: it's the guy's left upper arm.

Character mesh

The image below is a closeup of the character's right arm. This time the view is in vertex link mode. I've selected the right forearm bone (highlighted in red) and asked 3D Studio to show the vertices assigned to that bone (highlighted in green).

Vertex assignments

What does that mean?

By assigning vertices to bones you are basically saying "when the bone moves, these vertices move with it." Each vertex maintains its alignment relative to its assigned bone, wherever that bone goes.

To demonstrate this, I'll rotate the selected bone, making the character put his arm out by his side (rather awkwardly; hey, we're demonstrating a principle not posing for screenshots).

The bone, rotated

Notice how the vertices have moved along with the bone, thus preserving the form of the mesh. Vertices not assigned to the bone (for example those on the guy's chest) have not moved.

Animating characters, then, is all about knowing which bones to move and making sure the right vertices are mapped to the right bones.

Application of the theory

Now that you understand how 3D models are animated in SWAT3, you're probably starting to see just how we can remodel a character and allow it to use another set of animations.

If you've got the gsmhacking tool, you can check out a model's bones, "positions" (vertices) and vertex to bone "assignments" by running the command:

gsmhacking --describe --verbose --verbose FILENAME.GSM

Note the double use of --verbose. gsmhacking can print a LOT of information given the chance, so you need to tell it explicitly not to hold anything back.

Here's an extract from the output generated by telling gsmhacking to look at everyone's favourite baddy, Victor Getts, with the command gsmhacking --describe --verbose --verbose BG1_VIC_GET_HIGH.GSM

The bones:

Skeleton 00 at 0x0014: SwatGuy
  Bones in skeleton: 37

Bone 00 at 0x0021: Biped Pelvis
  Position: ( 0.0065, 37.3278, -0.8459)
  Rotation: -0.5000 about (-0.5000, -0.5000, 0.5000)
  Root bone
  Assigned vertices: 28, from 00 to 27

Bone 01 at 0x004f: Biped Spine
  Position: ( 2.8130, -0.0040, 0.0000)
  Rotation: 0.9997 about ( 0.0000, 0.0000, 0.0258)
  Links to: 00 Biped Pelvis
  Assigned vertices: 31, from 28 to 58

The vertices:

Vertices: 727
  Vertex 0000 at 0x0833: (-4.7792, -6.3574, 4.9922)
  Vertex 0001 at 0x083f: (-4.7792, -6.3574, 4.9922)
  Vertex 0002 at 0x084b: (-4.4505, -6.5753, 1.3197)
  Vertex 0003 at 0x0857: ( 3.8168, -3.9091, 3.2250)
  Vertex 0004 at 0x0863: (-0.2842, -6.5854, 4.8424)
  Vertex 0005 at 0x086f: (-10.9817, 4.0688, 2.1302)
  Vertex 0006 at 0x087b: ( 2.3331, 4.7584, 6.2943)
  Vertex 0007 at 0x0887: ( 2.3331, 4.7584, 6.2943)

As you can from looking at the first bone definition above, 28 vertices (those numbered 0 through 27) are assigned to bone 0, Biped Pelvis. This means that when the character's pelvis bone moves, those 28 vertices also move.

How the conversion actually works

Clunky but it works

When you use the command gsmhacking --make-swat, gsmhacking reads the suspect, hostage or kid GSM into memory and then forgets about the original bone data. It then constructs a SWAT skeleton using values obtained by making a raw dump of a SWAT model. The next part is the fun bit. gsmhacking needs to modify each entry in the vertex to bone assignments list.

The list is just a set of triples (f, n, b) where f is the index of the first vertex in the assignment, n is the number of vertices and b is the bone they are mapped to.

In the example above where 28 vertices (0 through 27) were mapped to bone 0, the assignment entry would be (0, 28, 0). The entry for the next next bone above would be (28, 31, 1), meaning 31 bones starting from 28 mapped to bone 1.

For each entry in the list, gsmhacking looks at the original bone identifier (remember we replaced the skeleton but we haven't edited anything else yet) and replaces it with its best guess as to the matching bone from the target skeleton. For example, if gsmhacking is converting a 37-bone TAC class model (male suspect) to SWAT and it finds the entry in the vertex to bone assignment list where the bone is 22, which is always Biped R Hand for suspects, it replaces the bone identifier with 28, the Biped R Hand bone for SWAT officers.

The code to do this is not elegant, it's basically a huge switch block with a case for each matching bone. To get it I laboriously listed each bone identifier from each character class and wrote the case statements to map them in the obvious order. Clunky but it works.


Unfortunately, that isn't the whole story. What should we do in the case where an assignment references a bone that isn't present in the target model? For example, SWAT models have no "ponytail" bones. Suspects have three. Kids have six. To get around this, gsmhacking ignores that assignment altogether and reassigns the affected vertices to the previous entry.

In our Victor Getts example, 60 vertices are assigned to Biped Head and 2 are assigned to Biped Ponytail1. The triples are: (143, 60, 4) and (203, 2, 5). gsmhacking thus removes both assignments and generates a new one: (143, 62, 4). Then it alters the bone identifier as usual and decreases the number of assignments, which is marked in the file.


There's one more thing to do before gsmhacking can write out the new GSM file. Grippers, the "helper" objects that tell the game engine where to make the character "hold" its weapon, are defined relative to the original skeleton. gsmhacking strips off the original grippers (if they exist; hostage models have none) and replaces them with the right grippers for the target class.

Source code

The gsmhacking source code is included in the gsmhacking package. Check out the function make_swt() in convert.c and take it from there.


Send any comments to swat3@furrycat.net.