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

  1.  
  2. #include "precompile.h"
  3. #include "mmsystem.h"
  4. #include "model.h"
  5.  
  6.  
  7.  
  8. // 200:  382
  9. // 600:  366
  10. // 6000: 339
  11.  
  12. #define NUM_RANDOM_ORDERINGS    300
  13. #define NO_STRIP                0xFFFF
  14.  
  15.  
  16. class TempTri
  17. {
  18.     public:
  19.  
  20.         ModelTri    *m_pTri;
  21. };
  22.  
  23. class TriGroup
  24. {
  25.     public:
  26.  
  27.         CMoArray<TempTri>    m_Tris;
  28.         
  29.         CMoArray<DWORD>        m_BestOrder;
  30.         
  31.         // Tri start indices for the best ordering.  The triangles these reference
  32.         // are indexed by m_BestOrder (so m_StartIndices[0] means to start on that
  33.         // index for m_Tris[m_BestOrder[0]]).
  34.         CMoArray<DWORD>        m_StartIndices; 
  35.  
  36.         DWORD                m_BestNumStrips;
  37.         DWORD                m_WorstNumStrips;
  38. };
  39.  
  40.  
  41. class TestStrip
  42. {
  43.     public:
  44.  
  45.         CMoArray<DWORD>    m_Verts;        
  46. };
  47.  
  48. class TestVert
  49. {
  50.     public:
  51.  
  52.         DWORD    m_iStrip;    
  53. };
  54.  
  55.  
  56. void RandomFillTable(DWORD *pTable, DWORD size)
  57. {
  58.     CMoArray<BYTE> usedEntries;
  59.     DWORD nFilled, test;
  60.  
  61.     nFilled = 0;
  62.     usedEntries.SetSize(size);
  63.     memset(usedEntries.GetArray(), 0, size);
  64.  
  65.     while(nFilled < size)
  66.     {
  67.         test = rand() % size;
  68.         ASSERT(test < size);
  69.  
  70.         if(!usedEntries[test])
  71.         {
  72.             pTable[nFilled++] = test;
  73.         }
  74.     }
  75. }
  76.  
  77.  
  78. void OptimizeGroup(Model *pModel, TriGroup *pGroup)
  79. {
  80.     DWORD i, j, k, a, iNewVert;
  81.     CMoArray<TestVert> verts;
  82.     CMoArray<DWORD> testOrder;
  83.     CMoArray<DWORD> startIndices;
  84.     ModelTri *pTri;
  85.     CMoArray<TestStrip> strips;
  86.     TestStrip *pStrip, tempStrip;
  87.     BOOL bPutOnStrip;
  88.  
  89.     
  90.     pGroup->m_BestOrder.SetSize(pGroup->m_Tris);
  91.     pGroup->m_StartIndices.SetSize(pGroup->m_Tris);
  92.  
  93.     testOrder.SetSize(pGroup->m_Tris);
  94.     startIndices.SetSize(pGroup->m_Tris);
  95.     verts.SetSize(pModel->m_nVerts);
  96.  
  97.     pGroup->m_BestNumStrips = 1000000;
  98.     pGroup->m_WorstNumStrips = 0;
  99.  
  100.     for(i=0; i < NUM_RANDOM_ORDERINGS; i++)
  101.     {
  102.         RandomFillTable(testOrder.GetArray(), testOrder.GetSize());
  103.     
  104.         // Try 3 iterations thru this group starting on different tri verts.
  105.         for(j=0; j < 3; j++)
  106.         {
  107.             // Initialize everything.
  108.             strips.SetSize(0);
  109.             for(k=0; k < verts; k++)
  110.             {
  111.                 verts[k].m_iStrip = NO_STRIP;
  112.             }
  113.  
  114.             // Here's where we build the test tri strips.
  115.             for(k=0; k < pGroup->m_Tris; k++)
  116.             {
  117.                 pTri = pGroup->m_Tris[testOrder[k]].m_pTri;
  118.  
  119.                 // Can we stick this on a strip?
  120.                 bPutOnStrip = FALSE;
  121.                 for(a=0; a < 3; a++)
  122.                 {
  123.                     if(verts[pTri->m_Indices[a]].m_iStrip != NO_STRIP)
  124.                     {
  125.                         pStrip = &strips[verts[pTri->m_Indices[a]].m_iStrip];
  126.                         ASSERT(pStrip->m_Verts.Last() == pTri->m_Indices[a]);
  127.                         if(pStrip->m_Verts[pStrip->m_Verts.LastI()-1] == pTri->m_Indices[(a+1)%3])
  128.                         {
  129.                             // Add it on!
  130.                             iNewVert = pTri->m_Indices[(a+2)%3];
  131.                             verts[pTri->m_Indices[a]].m_iStrip = NO_STRIP;
  132.                             verts[iNewVert].m_iStrip = pStrip - strips.GetArray();
  133.                             pStrip->m_Verts.Append(iNewVert);
  134.                             startIndices[k] = a;
  135.                             
  136.                             bPutOnStrip = TRUE;
  137.                         }
  138.                     }
  139.                 }
  140.  
  141.                 // Make a new strip.
  142.                 if(!bPutOnStrip)
  143.                 {
  144.                     strips.Append(tempStrip);
  145.                     pStrip = &strips.Last();
  146.  
  147.                     pStrip->m_Verts.Append(pTri->m_Indices[j]);
  148.                     pStrip->m_Verts.Append(pTri->m_Indices[(j+1)%3]);
  149.                     pStrip->m_Verts.Append(pTri->m_Indices[(j+2)%3]);
  150.  
  151.                     startIndices[k] = j;
  152.                     verts[pTri->m_Indices[(j+2)%3]].m_iStrip = strips.LastI();
  153.                 }
  154.             }
  155.         
  156.             
  157.             // How good is this?
  158.             if(strips.GetSize() < pGroup->m_BestNumStrips)
  159.             {
  160.                 pGroup->m_BestNumStrips = strips.GetSize();
  161.                 memcpy(pGroup->m_BestOrder.GetArray(), testOrder.GetArray(), sizeof(long)*testOrder.GetSize());
  162.                 memcpy(pGroup->m_StartIndices.GetArray(), startIndices.GetArray(), sizeof(DWORD)*startIndices.GetSize());
  163.             }
  164.  
  165.             if(strips.GetSize() > pGroup->m_WorstNumStrips)
  166.                 pGroup->m_WorstNumStrips = strips.GetSize();
  167.         }
  168.     }
  169. }
  170.  
  171.  
  172.  
  173. void TriStripOptimize(Model *pModel)
  174. {
  175.     CMoArray<TriGroup> groups;
  176.     TempTri tempTri;
  177.     DWORD i;
  178.  
  179.  
  180.     srand(timeGetTime());
  181.  
  182.     // Make the initial groups.
  183.     groups.SetSize(pModel->m_nNodes);
  184.     for(i=0; i < pModel->m_nModelTris; i++)
  185.     {
  186.         tempTri.m_pTri = &pModel->m_ModelTris[i];
  187.         groups[pModel->m_ModelTris[i].m_TransformIndex].m_Tris.Append(tempTri);
  188.     }
  189.  
  190.     // Optimize each group.
  191.     for(i=0; i < groups; i++)
  192.     {
  193.         OptimizeGroup(pModel, &groups[i]);
  194.     }
  195. }
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.