The OpenCTM file format for compressed triangle meshes looks very promising. To celebrate my gigasecond birthday, I wrote a .x to .ctm converter that exports positions and normals. It currently discards texture coordinates, but it shouldn’t be hard to extend it. I can’t guarantee that this tool is super robust, but it worked well enough for the test cases that I ran across.

I simply used ID3DXMesh to load in the .x file and the OpenCTM API to write out the .ctm file. Unfortunately, the usage of ID3DXMesh makes this tool Windows-only.

It’s a command line tool that works like this:

Usage: x2ctm [sourcefile] [sourcefile] ...

To form a destination filename, it simply replaces the existing file extension with .ctm and preserves the folder path.

At a high level, here’s how it works: (if you want, skip to the downloads section)

void ExportCTM(ID3DXMesh* pMesh, const char* destFile)
{
// 1. Find where the positions, normals, and texture coordinates live.
// 2. Check that we support the format of the data.
// 3. Obtain vertex & index counts from the D3D mesh; allocate memory for the CTM mesh.
// 4. Lock down the verts and pluck out the positions and normals.
// 5. Lock down the indices and convert them to unsigned 32-bit integers.
// 6. Instance the OpenCTM mesh and save it to disk.
// 7. Free the OpenCTM buffers.
}