normal bug is not a bug, the normals you import are dynamic normals based on the skeleton pose, they are recalculated dynamicly by the engine ,differently than max do (they need to be rotated by the inverse matrix of the vertex associated joint and normalized after.
Then how do you explain the normals behaving correctly inside the edit mesh scope and vanishing outside, The skeleton pose doesn't have anything to do with this, even when I was experimenting without the skin modifier this problem was there!!
the vertex duplication can also be explain easily, when welding vertices, the weld is based on vertex pos and not on uv mapping, so if you weld only this way , the rendering using vertex arrays and indices will completly fuck up the model mapping, the only way to fix it is to add degenerated faces or to duplicate vertices
I don't think so ... I made a quick check on the head model and guess what: the head model uses only 2 base textures so UV mapping isn't that different from an object to another. Look at the pic below, even with welding the mapping looks great!!
even more so with multitexturing where it is not always possible for the textures mapped to use the same uv coordinates
In this case, as for the majority of the models of DMC4, the uv coords are the same for all the maps except for the lightmaps which are mainly found in stages.
even on today's hardware there are not any cards i know of that have a recommended vertex batch size of anywhere near 49000+ vertices
Just try to imagine a head model with 49000+ verts, this would be way too detailed, which isn't the case of nero head, ninja gaiden 2 models for example are more detailed than those of dmc4 without even reaching this amount of verts (check out the ninja gaiden 2 thread).
I made a tool to quickly check vertex duplication and here's what I got:
original nero head model:
verts: 49613
indices: 12184
when eliminating all the duplicate verts, taking into consideration the position, texture coords, normals, binormals, tangents, bone indices and weights, I get this:
verts: 4511
faces: 5804
In terms of memory loss:
49613 verts x 32 bytes per vertex = 1587616 bytes on the video card
4511 verts x 32 = 144352 bytes only !!!! this is less than 10%
The question now is: why waste 1.5Mb on the video card for a model which is only worth 0.2Mb!!!
Another remark is that this difference isn't that big on body models, for example in nero body there is 12269 verts and after optimization I get 10798 verts which is 88% but still ....
Will you please consider the removal of isolated vertices on your next version.
This is one of the flaws of this program, these vertices aren't considered degenerate by max and thus not deleted, max says a degenerate face is a face that has more than 2 identical indices, the converter exports the data per object basis and thus can't know if a face has some duplicate indices so it makes them unduplicate, I'll try to hack this in the future release.
Ok poly, continuing from the last messages, here's a little explanation on how to fix the bone indices:
MOD files have something called bone groups, each object in the model is influenced by one of these groups, the bone group count is at position 40 from file start.
As said earlier, after you read the bone transforms, you read a bone table, the size is 256 bytes no matter how many bone you have you always read 256.
Then after you read the bone groups, a bone group is something like this:
Code: Select all
struct cBoneGroup
{
unsigned int uiBoneNum; // bones in this group
BYTE *pBoneId;
};
// this part was already present in the code, I put it here to help you locate yourself in the human.cpp
// allocate memory for the bone tranforms and read them
m_pBoneTransform = new cBoneTransform[m_usBoneNum];
fread(m_pBoneTransform, sizeof(cBoneTransform), m_usBoneNum, pFile);
// read the bone table
fread(m_pBoneTable, 256, 1, pFile);
// read the bone groups
m_pBoneGroup = new cBoneGroup[m_uiBoneGroupNum];
for(unsigned int a = 0; a < m_uiBoneGroupNum; a++)
{
fread(&m_pBoneGroup[a].uiBoneNum, 4, 1, pFile);
m_pBoneGroup[a].pBoneId = new BYTE[m_pBoneGroup[a].uiBoneNum];
fread(m_pBoneGroup[a].pBoneId, 1, m_pBoneGroup[a].uiBoneNum, pFile);
// check if the bone count is greater than 32 in which case padding must be applied
// this is a stupid hack, must pad correctly to x32 later
if(m_pBoneGroup[a].uiBoneNum > 32)
{
// put a marker here
printf("Hey that can't be !!!\n");
return false;
}
fseek(pFile, 32 - m_pBoneGroup[a].uiBoneNum, SEEK_CUR);
}
For each object there is a bone group id, this id byte is located at position 45 for each cObject struct.
Now all is left is this:
for every object
for every vertex in this object
do this 4 times since we have 4 bones per vertex
BYTE cId = m_pVertex[the current vertex].bone[0 .. 3];
BYTE cTrueId = m_pBoneGroup[bone group to use].pBoneId[cId]
Notice that the bone table isn't used here!!! I'm too lazy to tell why so I'll leave this to you
I hope this helps you out