Dynamic Texture Swapping
How to use multiple textures to get your model to reflect combat damage.

If you already have a fully textured model, you're off to a good start. If you haven't created the texture bitmaps, or "paint scheme," for your model, you have to do this first. There are plenty of great tutorials available on the net to help you do that.

"How many of these texture files do I need?"

Fair question. If you are using a single texture file that contains the upper, lower, left and right side of every part you want to display bullet holes, you could do this with as few as two bitmaps: your normal paint scheme and a maximum damage paint scheme.

If you want to show different degrees of damage to the upper and lower or left and right side of parts however, you're going to need a larger number of bitmaps, one for each side of each part.

In addition, you'll need a different bitmap for each level of damage you want to show for each side. Four levels of damage to each surface could result in upwards of 50 bitmaps!

NOTE
Remember ... it's not the texture files that cause frame-rate problems, but the complexity of your model. CFS2 has to go through the process of assigning a texture file to every textured part before it's rendered. Dynamic texture swapping simply gives CFS2 another texture filename to use in the assignment.

Okay, assuming you have your normal paint scheme completed, let's set up the right wing of a model to show two levels of battle damage and a maximum damage level.

Start with the texture bitmap containing the normal paint scheme for the right wing upper surface. Save a new copy of this bitmap with the name RWingT.bmp.

Next, using RWingT.bmp as your template, add 3-5 bullet holes and save it as RWing_d01T.bmp. This is the first damage level for the upper surface of the right wing.

Using RWing_d01T.bmp as your new template, add 3-5 more bullet holes and maybe a large tear in the skin. Save this texture as RWing_d02T.bmp. This is the second damage level for the upper surface of the right wing.

Finally, using RWing_d02T.bmp as your new template, add a large gaping hole in the upper wing surface and save this texture as RWing_dT.bmp, your "maximum damage" texture for the upper surface of the right wing.

You now have a normal paint scheme and three damage textures.

FSDS uses only the normal texture you assigned to the upper right wing in the model file.

The FSDS-generated SCA file for this model will show only your normal texture file in the texture list ...

TextureList( 0
1 FF 255 255 255 0 15.240000 "RWingT.bmp"
)

You have to manually add your new textures into the object source code file (.sca) for your model.

Since each of your damage textures is the same size as the normal texture and you haven't changed the physical size or location of the texture for the upper wing surface, each of these texture files are identical except for the filename.

To add your damage textures to the SCA file, copy the entire line from TextureList( .. ) containing the normal texture filename and paste it back in place, once for each damage texture, changing only the file name. For this example your new texture list would look like this ...

TextureList( 0
1 FF 255 255 255 0 15.240000 "RWingT.bmp"
1 FF 255 255 255 0 15.240000 "RWing_d01T.bmp"
1 FF 255 255 255 0 15.240000 "RWing_d02T.bmp"
1 FF 255 255 255 0 15.240000 "RWing_dT.bmp"
)

Now comes the fun part.

When editing the object source code (.sca) to create texture swapping for the upper surface of the right wing, add a series of tests on the bullets0 variable to check how many hits the upper right wing surface has taken. The result of each test is the triggering event that determines which damage texture is applied to the upper right wing.

Here is an example to show you the testing logic applied to texture swapping.

The bullets0 variable uses 16 index bits to track hits on the damage box containing the upper right wing: 12 for the upper right wing and 4 for the upper right wingtip.

Since you have only two damage textures aside from your maximum damage texture, you need only test two of these index bits for hits ... but which two? I suggest testing index 4 and index 8 (that's one-third and two-thirds of the difference between 1 hit and 12 hits on the upper wing damage box.

First, test to determine if the right wing is actually visible.

If the right wing is NOT visible, it has already sustained maximum damage. Therefore, set the maximum damage texture "RWing_dT.bmp" in the SetMaterial ( ... ) command and jump to draw the part.

If the right wing is visible, then test for various levels of damage.

DESIGN

TIP
Always test the highest index value first, followed by the next highest value, etc..

This technique will ensure you don't get a false test results.

If the test on index 8 is true, set damage texture "RWing_d02T.bmp" in the SetMaterial ( ... ) command and jump to draw the part. If it's false, test index 4.

If the test on index 4 is true, then set damage texture "RWing_d01T.bmp" in the SetMaterial ( ... ) command and jump to draw the part.

If the test on index 4 is false, then set the normal texture "RWingT.bmp" in the SetMaterial ( ... ) command and draw the part.

The visual result of this bit of magic is pretty impressive.

As long as your model has not taken a hit through the upper surface of the right wing, it will always show your normal paint scheme.

The instant the right wing gets hit 4 times, it will "dynamically" swap textures and show an increased level of damage.

As the wing takes more hits, it will again "dynamically" swap textures to show even more damage. Finally, when the right wing fails, it will reveal the major damage you created for it in your maximum damage texture.

Here is the SCASM code testing sequence for the upper right wing from a model that uses four damage textures in addition to the normal and maximum damage textures.

:R_STUBWING_DAMAGE_T
IfVarAnd(:R_STUBWING_MAX_DAMAGE_T 0x90 0x0001) ;Right Wing Visible?
Jump(:R_STUBWING_HIT_16T) ;Yes

:R_STUBWING_MAX_DAMAGE_T
SetMaterial( 0 40) ;"F4U-4F_Rwing_dT.bmp" ;Set maximum damage bitmap
Jump(:DRAW_R_STUBWING_T)

:R_STUBWING_HIT_16T
IfVarAnd(:R_STUBWING_HIT_12T 0x0100 0x0800) ;Check bullets0- upper right wing
SetMaterial( 0 48) ;"F4U-4F_Rwing_d16T.bmp" ;Set level 4 damage bitmap
Jump(:DRAW_R_STUBWING_T)

:R_STUBWING_HIT_12T
IfVarAnd(:R_STUBWING_HIT_08T 0x0100 0x0100) ;Check bullets0- upper right wing
SetMaterial( 0 46) ;"F4U-4F_Rwing_d12T.bmp" ;Set level 3 damage bitmap
Jump(:DRAW_R_STUBWING_T)

:R_STUBWING_HIT_08T
IfVarAnd(:R_STUBWING_HIT_04T 0x0100 0x0020) ;Check bullets0- upper right wing
SetMaterial( 0 44) ;"F4U-4F_Rwing_d08T.bmp" ;Set level 2 damage bitmap
Jump(:DRAW_R_STUBWING_T)

:R_STUBWING_HIT_04T
IfVarAnd(:NOHITS_R_STUBWING_T 0x0100 0x0004) ;Check bullets0- upper right wing
SetMaterial( 0 42) ;"F4U-4F_Rwing_d04T.bmp" ;Set level 1 damage bitmap
Jump(:DRAW_R_STUBWING_T)

:NOHITS_R_STUBWING_T
SetMaterial( 0 12 ) ;"F4U-4F_RwingT.bmp" ;Set normal bitmap

:DRAW_R_STUBWING_T
DrawTriList( 0

Does it really work? You betcha ... judge for yourself.

Right Wing with bullet hole damage

Setting up your MDL file