Hi Lefteris,
Unfortunately I cannot release the code in its current state. I am in the middle of making a lot of breaking changes in the code as I am in the process of integrating it into my MDLMagic tool (see here:
http://www.fsdeveloper.com/forum/showthread.php?t=151396). It is nowhere near a releasable state. The code as it existed when I released this does contain some proprietary code that I don't have the rights to release. I am in the process of refactoring all of this out.
I will gladly open up the code when MDLMagic and SimFramework (the bigger library that this code is a part of) ship. Hopefully not too much longer now, I am about to go into public beta.
I can tell you lots about the vertex limit though! I'm not sure how familiar you are with direct3d programming, so I'll try to give some relevant background. Direct3d uses data structures called vertex buffers and index buffers to store 3d geometry data. They are both simply linear arrays. The vertex buffer obviously contains an array of vertices, in the case of FSX it is a structure containing 3 floats for position, 3 floats a normal vector, 2 floats for UV's, etc. The index buffer is a list of offsets into the vertex buffer that define what points constitute a triangle. For example, if the index buffer is 6 elements long and contains the numbers 0, 3, 1, 1, 4, 2, then the first triangle would defined by the points VB[0], VB[3], and VB[1]. Likewise, triangle two would be defined by the points VB[1], VB[4], and VB[2], and these would be rendered in a clockwise fashion (since direct3d uses a left-handed coordinate system).
Now by default, D3D uses 16 bit shorts for each element of the index buffer. This means that theoretically the maximum element in the vertex buffer that could be indexed by the buffer would be 2^16-1: 65,535. This number limits the size of any one vertex buffer to 65,535 vertices. D3D will allow you to use 32-bit indices, but only newer, high-end cards support this (and supposedly there is some performance penalty associated with this). Since FSX was developed back in 2006 and had lots of legacy hardware to cope with, it is hard wired to only use 16 bit indices.
The mdl format supports multiple vertex buffers, so multiple parts can go into multiple buffers and thus there is not an overall vertex limit for the file. There are several cases that can cause a vertex buffer limit to be exceeded, though. The most obvious is having a single part that has greater than 65k vertices. XToMDL could just simply split this into several different vertex buffers, but
as stated here this was a feature that just simply didn't make it in. As part of the effort to reduce draw calls, parts with certain parameters that are the same are automatically merged together so they can be draw call batched together. The precise algorithm that determines this is given in this function: (sorry, a bit messy)
Code:
internal void MergeParts()
{
foreach (SceneGraphNode node in this.Children)
{
node.MergeParts();
}
for (int i = 0; i < (this.Parts.Count - 1); i++)
{
PartMesh mesh = this.Parts[i] as PartMesh;
for (int j = this.Parts.Count - 1; j > i; j--)
{
PartMesh other = this.m_Parts[j] as PartMesh;
if ((((mesh.Type == other.Type) && (mesh.MouseRectID == other.MouseRectID)) && ((mesh.VisibilityID == other.VisibilityID) && !mesh.HasSkinning)) &&
((!other.HasSkinning && mesh.IsVisible) && ((mesh.AssociatedMaterial.CompareTo(other.AssociatedMaterial) == 0) && (mesh.LOD == other.LOD))))
{
mesh.AbsorbPart(other);
this.Parts.RemoveAt(j);
}
}
}
}
This can cause parts to arbitrarily be merged that combined have a larger verts than can fit into a single vertex buffer, causing an error.
I hope that answers your question. There are several other quirks relating to vertices that are somewhat unrelated to this problem. I think I will give them a more in-depth treatment in a blog post in a few days, using this post as a starting point.
Let me know if you guys have any other xtomdl questions!