home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 8090 / ModelEdit.7z / model_cleanup.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-03-08  |  8.5 KB  |  375 lines

  1.  
  2. #include "precompile.h"
  3. #include "model_ops.h"
  4. #include "model_cleanup.h"
  5.  
  6.  
  7. typedef struct VertPolyAdjacency_t
  8. {
  9.     CMoArray<ModelTri*>    m_Tris;
  10. } VertPolyAdjacency;
  11.  
  12.  
  13.  
  14. void gn_SetModelUVs(CMoArray<UVTriple> &theArray, Model *pModel)
  15. {
  16.     DWORD i, j;
  17.     UVPair *pCur;
  18.     
  19.     if(pModel->m_UVCoords)
  20.         free(pModel->m_UVCoords);
  21.  
  22.     pModel->m_UVCoords = (UVPair*)malloc(sizeof(UVPair) * theArray.GetSize() * 3);
  23.     pCur = pModel->m_UVCoords;
  24.     for(i=0; i < theArray; i++)
  25.     {
  26.         for(j=0; j < 3; j++)
  27.         {
  28.             pCur->tu = theArray[i].pairs[j].tu;
  29.             pCur->tv = theArray[i].pairs[j].tv;
  30.             ++pCur;
  31.         }
  32.     }
  33. }
  34.  
  35.  
  36. void gn_SetupUVTriples(CMoArray<UVTriple> &theArray, Model *pModel)
  37. {
  38.     DWORD i, j;
  39.     UVPair *pCur;
  40.  
  41.     theArray.SetSize(pModel->m_nModelTris);
  42.     pCur = pModel->m_UVCoords;
  43.     for(i=0; i < pModel->m_nModelTris; i++)
  44.     {
  45.         for(j=0; j < 3; j++)
  46.         {
  47.             theArray[i].pairs[j].tu = pCur->tu;
  48.             theArray[i].pairs[j].tv = pCur->tv;
  49.             ++pCur;
  50.         }
  51.     }
  52. }
  53.  
  54.  
  55. static void gn_SlideVertsDown(DWORD index, Model *pModel)
  56. {
  57.     ModelTri *pCurTri, *pEndTri;
  58.     ModelNode *pNode;
  59.     DWORD i, j;
  60.  
  61.     pCurTri = pModel->m_ModelTris;
  62.     pEndTri = pModel->m_ModelTris + pModel->m_nModelTris;
  63.     while(pCurTri < pEndTri)
  64.     {
  65.         for(i=0; i < 3; i++)
  66.         {
  67.             ASSERT(pCurTri->m_Indices[i] != index);
  68.  
  69.             if(pCurTri->m_Indices[i] > index)
  70.                 --pCurTri->m_Indices[i];
  71.         }
  72.     
  73.         ++pCurTri;
  74.     }
  75.  
  76.     for(i=0; i < pModel->m_nNodes; i++)
  77.     {
  78.         pNode = pModel->m_FlatNodeList[i];
  79.     
  80.         for(j=0; j < pNode->m_nIndices; j++)
  81.         {
  82.             if(pNode->m_Indices[j] > index)
  83.                 pNode->m_Indices[j]--;
  84.         }
  85.     }
  86. }
  87.  
  88.  
  89. static void gn_ChangeVertexReferences(DWORD from, DWORD to, Model *pModel)
  90. {
  91.     ModelTri *pCurTri, *pEndTri;
  92.     ModelNode *pNode;
  93.     DWORD i, j;
  94.  
  95.     pCurTri = pModel->m_ModelTris;
  96.     pEndTri = pModel->m_ModelTris + pModel->m_nModelTris;
  97.     while(pCurTri < pEndTri)
  98.     {
  99.         for(i=0; i < 3; i++)
  100.             if(pCurTri->m_Indices[i] == from)
  101.                 pCurTri->m_Indices[i] = (WORD)to;
  102.     
  103.         ++pCurTri;
  104.     }
  105.  
  106.     for(i=0; i < pModel->m_nNodes; i++)
  107.     {
  108.         pNode = pModel->m_FlatNodeList[i];
  109.     
  110.         for(j=0; j < pNode->m_nIndices; j++)
  111.         {
  112.             if(pNode->m_Indices[j] == from)
  113.                 pNode->m_Indices[j] = (WORD)to;
  114.         }
  115.     }
  116. }
  117.  
  118.  
  119.  
  120. // Removes references to the vertex in all the AnimNodes on the ModelNode specified.
  121. static void gn_RemoveFromDAnimData(Model *pModel, ModelNode *pNode, DWORD index)
  122. {
  123.     DWORD i, j, a, b, curOut, size;
  124.     ModelAnim *pAnim;
  125.     AnimNode *pAnimNode;
  126.     DefVertex *pInRow, *pOutRow, *pNewVerts;
  127.  
  128.     for(i=0; i < pModel->m_Anims; i++)
  129.     {
  130.         pAnim = pModel->m_Anims[i];
  131.     
  132.         for(j=0; j < pModel->m_nDNodes; j++)
  133.         {
  134.             pAnimNode = pAnim->m_DNodes[j];
  135.             
  136.             if(pAnimNode->m_pNode == pNode)
  137.             {
  138.                 size = sizeof(DefVertex) * pAnim->m_KeyFrames * (pNode->m_nIndices-1);
  139.                 pNewVerts = (DefVertex*)dalloc(size);
  140.  
  141.                 for(a=0; a < pAnim->m_KeyFrames; a++)
  142.                 {
  143.                     pInRow = &pAnimNode->m_DefVertices[a * pNode->m_nIndices];
  144.                     pOutRow = &pNewVerts[a * (pNode->m_nIndices-1)];
  145.                     
  146.                     curOut = 0;
  147.                     for(b=0; b < pNode->m_nIndices; b++)
  148.                     {
  149.                         if(pNode->m_Indices[b] == index)
  150.                         {
  151.                         }
  152.                         else
  153.                         {
  154.                             pOutRow[curOut++] = pInRow[b];
  155.                         }
  156.                     }
  157.  
  158.                     ASSERT(curOut == pNode->m_nIndices-1);
  159.                 }
  160.  
  161.                 dfree(pAnimNode->m_DefVertices);
  162.                 pAnimNode->m_DefVertices = pNewVerts;
  163.             }
  164.         }
  165.     }
  166. }
  167.  
  168.  
  169. // Gets rid of references to the vertex in all the deformation animation and indices.
  170. static void gn_RemoveVertexFromDeformation(Model *pModel, DWORD index)
  171. {
  172.     DWORD i, j, k;
  173.     ModelAnim *pAnim;
  174.     ModelNode *pNode;
  175.  
  176.     for(i=0; i < pModel->m_Anims; i++)
  177.     {
  178.         pAnim = pModel->m_Anims[i];
  179.  
  180.         for(j=0; j < pModel->m_nDNodes; j++)
  181.         {
  182.             pNode = pModel->m_DNodes[j];
  183.  
  184.             for(k=0; k < pNode->m_nIndices; k++)
  185.             {
  186.                 if(pNode->m_Indices[k] == index)
  187.                 {
  188.                     // Remove this index from all the animations.
  189.                     gn_RemoveFromDAnimData(pModel, pNode, index);
  190.                     GENERIC_REMOVE(pNode->m_Indices, k, pNode->m_nIndices);
  191.                     --k;
  192.                 }
  193.             }
  194.         }
  195.     }
  196. }
  197.  
  198.  
  199. // Finds duplicate vertices and removes them.  Note: this routine has potential for error
  200. // if the tolerance is too large because vertices could 'slide' around and move really far.
  201. // The preprocessor does it correctly, but it was a total pain in the ass.
  202. static void gn_RemoveDuplicateVertices(Model *pModel)
  203. {
  204.     DWORD i, j;
  205.     float dist;
  206.     CMoArray<ModelVert> vertList;
  207.     DVector vTemp;
  208.  
  209.     vertList.SetSize(pModel->m_nVerts);
  210.     memcpy(vertList.GetArray(), pModel->m_Verts, pModel->m_nVerts*sizeof(pModel->m_Verts[0]));
  211.  
  212.     // For each vertex, find any other ones close enough.
  213.     for(i=0; i < vertList; i++)
  214.     {
  215.         for(j=0; j < vertList; j++)
  216.         {
  217.             if(i == j)
  218.                 continue;
  219.  
  220.             // Only vertices from the same node can be joined!
  221.             if(vertList[i].m_TransformIndex == vertList[j].m_TransformIndex)
  222.             {
  223.                 VEC_SUB(vTemp, vertList[i].m_Vec, vertList[j].m_Vec);
  224.                 dist = VEC_MAGSQR(vTemp);
  225.                 if(dist < 0.00001f)
  226.                 {
  227.                     // Remove vertex I.
  228.                     vertList.Remove(i);
  229.                     gn_RemoveVertexFromDeformation(pModel, i);
  230.                     gn_ChangeVertexReferences(i, j, pModel);
  231.                     gn_SlideVertsDown(i, pModel);
  232.                     
  233.                     --i;
  234.                     break;
  235.                 }
  236.             }
  237.         }
  238.     }
  239.  
  240.     // Set the new vertex list..
  241.     if(pModel->m_Verts)
  242.     {
  243.         delete pModel->m_Verts;
  244.         pModel->m_Verts = new ModelVert[vertList.GetSize()];
  245.         memcpy(pModel->m_Verts, vertList.GetArray(), sizeof(ModelVert)*vertList.GetSize());
  246.         pModel->m_nVerts = pModel->m_nNormalVerts = vertList.GetSize();
  247.     }
  248. }
  249.  
  250.  
  251. static void gn_RemoveFuckedUpTriangles(Model *pModel)
  252. {
  253.     CMoArray<ModelTri> newTris;
  254.     DWORD i;
  255.     ModelTri *pTri;
  256.     CMoArray<UVTriple> uvTriples;
  257.  
  258.     if(pModel->m_ModelTris)
  259.     {
  260.         newTris.SetSize(pModel->m_nModelTris);
  261.         memcpy(newTris.GetArray(), pModel->m_ModelTris, pModel->m_nModelTris*sizeof(ModelTri));
  262.         
  263.         gn_SetupUVTriples(uvTriples, pModel);
  264.  
  265.         for(i=0; i < newTris; i++)
  266.         {
  267.             pTri = &newTris[i];
  268.         
  269.             if(pTri->m_Indices[0] == pTri->m_Indices[1] || pTri->m_Indices[0] == pTri->m_Indices[2] ||
  270.                 pTri->m_Indices[1] == pTri->m_Indices[2])
  271.             {
  272.                 uvTriples.Remove(i);
  273.                 newTris.Remove(i);
  274.                 --i;
  275.             }
  276.         }
  277.  
  278.         // Set the new array..
  279.         gn_SetModelUVs(uvTriples, pModel);
  280.  
  281.         delete[] pModel->m_ModelTris;
  282.         pModel->m_ModelTris = new ModelTri[newTris.GetSize()];
  283.         memcpy(pModel->m_ModelTris, newTris.GetArray(), newTris.GetSize()*sizeof(ModelTri));
  284.         pModel->m_nModelTris = newTris.GetSize();
  285.     }
  286. }
  287.  
  288.  
  289. void gn_BuildModelVertexNormals(Model *pModel)
  290. {
  291.     DWORD i, j;
  292.     VertPolyAdjacency *pAdjacent;
  293.     ModelTri *pCurTri;
  294.     ModelVert *pCurVert;
  295.     CVector normal;
  296.  
  297.     // compute the vertex normals
  298.     pAdjacent = new VertPolyAdjacency[pModel->m_nVerts];
  299.  
  300.     pCurTri = pModel->m_ModelTris;
  301.     for (i = 0; i < pModel->m_nModelTris; i++)
  302.     {
  303.         pAdjacent[pCurTri->m_Indices[0]].m_Tris.Append(pCurTri);
  304.         pAdjacent[pCurTri->m_Indices[1]].m_Tris.Append(pCurTri);
  305.         pAdjacent[pCurTri->m_Indices[2]].m_Tris.Append(pCurTri);
  306.         ++pCurTri;
  307.     }
  308.  
  309.     pCurVert = pModel->m_Verts;    
  310.     for (i = 0; i < pModel->m_nVerts; i++)
  311.     {
  312.         normal.x = normal.y = normal.z = 0.0f;
  313.  
  314.         for(j = 0; j < pAdjacent[i].m_Tris; j++)
  315.         {
  316.             normal.x += (float)pAdjacent[i].m_Tris[j]->m_Normal[0] / 127.0f;
  317.             normal.y += (float)pAdjacent[i].m_Tris[j]->m_Normal[1] / 127.0f;
  318.             normal.z += (float)pAdjacent[i].m_Tris[j]->m_Normal[2] / 127.0f;
  319.         }
  320.  
  321.         normal.x /= (float)pAdjacent[i].m_Tris;
  322.         normal.y /= (float)pAdjacent[i].m_Tris;
  323.         normal.z /= (float)pAdjacent[i].m_Tris;
  324.         normal.Norm();
  325.  
  326.         // Compress it into bytes..
  327.         pCurVert->m_Normal[0] = (char)(normal.x * 127.0f);
  328.         pCurVert->m_Normal[1] = (char)(normal.y * 127.0f);
  329.         pCurVert->m_Normal[2] = (char)(normal.z * 127.0f);
  330.  
  331.         ++pCurVert;
  332.     }
  333.  
  334.     delete [] pAdjacent;
  335. }
  336.  
  337.  
  338. void gn_BuildModelPolygonNormals(Model *pModel)
  339. {
  340.     DWORD i;
  341.     ModelTri *pCurTri;
  342.     CVector normal;
  343.     DVector v1, v2;
  344.  
  345.     // compute the polygon normals
  346.     pCurTri = pModel->m_ModelTris;
  347.     for(i=0; i < pModel->m_nModelTris; i++)
  348.     {
  349.         ModelVert    &p0 = pModel->m_Verts[pCurTri->m_Indices[0]];
  350.         ModelVert    &p1 = pModel->m_Verts[pCurTri->m_Indices[1]];
  351.         ModelVert    &p2 = pModel->m_Verts[pCurTri->m_Indices[2]];
  352.  
  353.         VEC_SUB(v1, p2.m_Vec, p0.m_Vec);
  354.         VEC_SUB(v2, p1.m_Vec, p0.m_Vec);
  355.         VEC_CROSS(normal, v2, v1);
  356.         VEC_NORM(normal);
  357.  
  358.         pCurTri->m_Normal[0] = (char)(normal.x * 127.0f);
  359.         pCurTri->m_Normal[1] = (char)(normal.y * 127.0f);
  360.         pCurTri->m_Normal[2] = (char)(normal.z * 127.0f);
  361.  
  362.         ++pCurTri;
  363.     }
  364. }
  365.  
  366. void gn_CleanupGeometry(Model *pModel)
  367. {
  368.     model_ClearLODInfo(pModel);
  369.     gn_RemoveDuplicateVertices(pModel);
  370.     gn_RemoveFuckedUpTriangles(pModel);
  371. }
  372.  
  373.  
  374.  
  375.