Kevin Caccamo

Rear Admiral

I've created an import/export script for Blender (v2.65+) that can import and export VISION engine IFF 3D models. You can get it on GitHub here:

Most models from WC:SO mods are supported, as well as some models from the original game.
Installation guides and tutorials are available on GitHub.

Old post:
I've released a new tool for you aspiring modders out there... It's a converter that reads OBJ files and writes WCPPascal source code, which can then be compiled into an IFF using WCPPascal. The program is written in Java and the source code is included in the download.

It's still a beta version, so it may not work for some models. If you have any problems, post a description of the problem and a screenshot if necessary.

The converter is currently limited to 4096 polygons and 4096 vertices.

You can get it here:
Last edited:
Cool. On a tangent, is there a reason why people use exotic file packers? It seems like most files that come our way are rars, 7zips, zipz and so on, and so I have a battery of different programs to unpack everything. And then I uncompress these things and repackage them as plain zips to save everything else from having to do it, since modern computers have plain .zip compatibility built in these days. I hear reasons like how one format or another is 5-10% more efficient at compression, but most of these files are small (this one is only 11 kilobytes). Not trying to pick on this particular project, but I'm thinking that some curious people are just passing stuff over because they don't want to hassle with another file format.
Chris is right....I've found sometimes I do pass things over (Unless I really need to use it)... when it comes to certain compression styles...Although I do use 7zip for can compress .ZIP format with 7zip instead of the norm .7z or whatevers
7-Zip is fairly well known and supported now, and I use it all the time, personally. I use it to bypass e-mail servers that would otherwise strip legitimate EXEs from ZIPs when sending stuff at work, sometimes. Stupid false positives. Too, not everyone in the world has unlimited Internet transfer, so smaller files are always welcome for me.

That being said, I still use ZIPs for small stuff, for the compatibility factor. RARs are proprietary and old-school. :) Anything besides those three formats, I would call esoteric.

Even with the 7z format, I will usually use the self-extracting EXE option for the benefit of people who don't yet use 7-Zip - even with the added decompression code, things are often far, far smaller than the corresponding ZIP package.
7-Zip is fairly well known and supported now, and I use it all the time, personally. I use it to bypass e-mail servers that would otherwise strip legitimate EXEs from ZIPs when sending stuff at work, sometimes. Stupid false positives.

I jump between a number of different computers pretty regularly. For CIC updates these days, it's actually more likely that I'm writing them from a computer at a friend's house, (painstakingly and therefore quite rarely) from my cell phone, or from my work computer at lunch. I've got several zipz/7z/etc file-based updates in the queue right now, but they're on hold because I'm not on a machine where I can check them out. I posted this one yesterday because its technical nature makes it likely that the people who'd use it either have 7zip or would be willing to get it, and because it's a preliminary beta so I wasn't going to mirror it on the CIC server. Mainly because Windows automatically understands zips and I can't install anything else at work, if people posted and sent us normal zips, it'd make what I do easier.
I made some updates to the program, including cleaning up the code a little bit, using classes in The Java 3D API, and adding some code to calculate face normals.

The new version can be downloaded here.

The Java 3D API needs to be installed on your computer before the program can be used.
Thanks for all the hard work you did, I hope I can make use of your program.
Aside from just converting the model, Is there a link to a how-to on getting custom ships into the game?

I know you posted a limit of 4096, but would you know off hand how many polys the game ships were?

Do you have examples of imported ships, in obj or something I could use for scale when building the custom ship?

Thanks :D

Before the game can use the model, you'll have to open up the .pas file in WCPPascal and click Compile -> Compile and Build IFF, and then move the iff file to the Secret Ops\mesh folder. It may take a few minutes to compile the model.

You'll have to convert the textures to MAT format and place them in your Secret Ops\mat folder. Note that MAT files are in 8-bit (indexed) colour. I recommend converting the textures to 255 colours, using dithering, adding in an unused colour, and moving that colour to the first index of the palette (This is to prevent the texture from having unwanted transparent parts after conversion). Then, open up the texture using Texconv.exe and save it as an Origin MAT.

Depending on what starting MAT number you used, you'll have to name the converted textures according to the starting MAT number. The textures and their corresponding MAT numbers are listed in the <modelname>-info.txt file. As an example:
Texture1.bmp -> 22000.mat
Texture2.bmp -> 22001.mat
Texture3.bmp -> 22002.mat
This tells you that Texture1.bmp should be named 00022000.mat when it is converted, Texture2.bmp should be named 00022001.mat when it is converted, you get the idea.

To use the model in-game, you'll have to modify one of the existing ship files or create a new ship file to use the new model. You can use WCPPascal to decompile one of the ship files (in the Secret Ops\ships folder.) The mesh name that the ship file refers to is under this part of the ship file code:
  cstring "panther"
"panther" can simply be replaced with the filename of the new model (without extension)

At the bottom of the model source code, there are the hardpoints. The hardpoint positions are proportional to the model in 3D units, so if you want to change the hardpoints, you can place the hardpoints in your 3D program and then hand-copy the position to the hardpoint section in the model's "source code."

The thruster positions are in the ship file under CHUNK "CONS". Like the hardpoints, the thruster cone positions are proportional to the model in 3D units.

The default hardpoints (that OBJ2WCP uses) may not fit the model you are trying to convert, so I think you might want to play around with the hardpoints a little bit.

Most of the game models were (IIRC) lower than 800 polys. The base mesh of the superbase is about 1600 polys. I wouldn't recommend going any higher than that, since I once tried to import a 2000-poly model and the game crashed.

About scale, a good size for fighters would be around 18 3D units. Killerwave's site also has this:
for comparison purposes, the panther is: ‘x:8.0 y:1.7 z: 13.3’, the kilathi corvette is ‘x: 84.8 y: 11.0 z:110.0’ and the midway: ‘x:737.4 y: 282.4 z: 1841.6’
I do have an OBJ which I have converted before. Here it is.

If anyone else has any suggestions about generating the hardpoints, I'd like to hear them.
Update: Objects converted by OBJ2WCP now render properly in-game! I've finally been able to fix the problem which causes faces to mysteriously disappear.

Download the updated version here.

EDIT: The disappearing faces problem is still there, but it's a lot less noticeable. Here's a screenshot of my WCUE mod, featuring a Scimitar cockpit converted by OBJ2WCP.
Update 23/12/2010

I'm trying a bunch of different algorithms to calculate the unknown1 value. Let's see if this one doesn't totally eliminate the disappearing faces problem.

Hi Kevin,

The unknown1 value is a D-Plane equation. This is what you need:

Assume V is the first FVRT->VERT value called by FACE.
Assume N is the Surface Normal called by FACE.

D-Plane = -((N.i * V.x) + (N.j * V.y) + (N.k * V.z))

I'm not sure, but I think the Unknown2 value could be something to do with weapon/engine brightness effect, but I'm still looking at that.

Hope this helps :)

No problem at all :)

I've decided to teach myself C++. I'm actually in the process of making a converter of my own as my first C++ project. I did quite some investigation in to the mesh files. The D-Plane was probably the most awkward one to work out. Fortunately I had some help from the partial source code on the dev backup images to point me in the right direction.

The unknown2 value is definately not a true/false flag. I have done some investigation today and found this:

Bug "Green Globe" weapon polys had it set to 3
Bug Engine polys had it set to 2
Midway Engine was set to 10
Midway Engine surrounding polys had it set to 8. (i guess to mimic light reflection from engine)

I have also seen higher values in the medium and low poly versions for each mesh, I assume to make it stand out more in the distance.

It could be just a brightness value, but I think values 2 and 3 are special to bug engines and weapons. Bug weapons textures go dim when weapons are fired and engines change brightness dependant on speed.

I'll keep looking and let you know :)
So, I was originally thinking of making a new version of OBJ2WCP that works like PCS2, in that you load a model and rig it for the game, but now I'm thinking of making OBJ2WCP into an exporter script for Blender. It'll mean less work done in OBJ2WCP and more work done in Blender.

I'm trying to learn Python right now, and I've got a good head start on a .pas exporter.
Edit: I do plan to make it export .IFF files eventually. .pas is being used as an "in-between" format because it's easier to debug the script with test data in plain text format.
I got my first test model for the exporter script working ingame!

But there's still a lot of work to do, including support for models with multiple textures, support for fully lit faces, support for IFF format export, and optimizations such as deleting duplicate normals.

The script will be released before I begin working on IFF export.