Пример #1
0
        static void MergeVertsFast(int[] piTriList_in_and_out, ref STmpVert[] pTmpVert, ref SMikkTSpaceContext context, int iL_in, int iR_in)
        {
            int c = 0, l = 0, channel = 0;

            float[] fvMin = new float[3], fvMax = new float[3];
            float   dx = 0, dy = 0, dz = 0, fSep = 0;

            for (c = 0; c < 3; c++)
            {
                fvMin[c] = pTmpVert[iL_in].vert[c]; fvMax[c] = fvMin[c];
            }
            for (l = (iL_in + 1); l <= iR_in; l++)
            {
                for (c = 0; c < 3; c++)
                {
                    if (fvMin[c] > pTmpVert[l].vert[c])
                    {
                        fvMin[c] = pTmpVert[l].vert[c];
                    }
                    else if (fvMax[c] < pTmpVert[l].vert[c])
                    {
                        fvMax[c] = pTmpVert[l].vert[c];
                    }
                }
            }

            dx = fvMax[0] - fvMin[0];
            dy = fvMax[1] - fvMin[1];
            dz = fvMax[2] - fvMin[2];

            channel = 0;
            if (dy > dx && dy > dz)
            {
                channel = 1;
            }
            else if (dz > dx)
            {
                channel = 2;
            }

            fSep = 0.5f * (fvMax[channel] + fvMin[channel]);

            if (fSep >= fvMax[channel] || fSep <= fvMin[channel])
            {
                for (l = iL_in; l <= iR_in; l++)
                {
                    int     i     = pTmpVert[l].index;
                    int     index = piTriList_in_and_out[i];
                    Vector3 vP    = GetPosition(ref context, index);
                    Vector3 vN    = GetNormal(ref context, index);
                    Vector2 vT    = GetTexCoord(ref context, index);

                    bool bNotFound = true;
                    int  l2 = iL_in, i2rec = -1;

                    while (l2 < l && bNotFound)
                    {
                        int     i2     = pTmpVert[l2].index;
                        int     index2 = piTriList_in_and_out[i2];
                        Vector3 vP2    = GetPosition(ref context, index2);
                        Vector3 vN2    = GetNormal(ref context, index2);
                        Vector2 vT2    = GetTexCoord(ref context, index2);
                        i2rec = i2;

                        if (vP.Equals(vP2) && vN.Equals(vN2) && vT.Equals(vT2))
                        {
                            bNotFound = false;
                        }
                        else
                        {
                            l2++;
                        }
                    }

                    if (!bNotFound)
                    {
                        piTriList_in_and_out[i] = piTriList_in_and_out[i2rec];
                    }
                }
            }
            else
            {
                int iL = iL_in, iR = iR = iR_in;

                while (iL < iR)
                {
                    bool bReadyLeftSwap = false, bReadyRightSwap = false;
                    while ((!bReadyLeftSwap) && iL < iR)
                    {
                        bReadyLeftSwap = !(pTmpVert[iL].vert[channel] < fSep);
                        if (!bReadyLeftSwap)
                        {
                            ++iL;
                        }
                    }
                    while ((!bReadyRightSwap) && iL < iR)
                    {
                        bReadyRightSwap = pTmpVert[iR].vert[channel] < fSep;
                        if (!bReadyRightSwap)
                        {
                            --iR;
                        }
                    }

                    if (bReadyLeftSwap && bReadyRightSwap)
                    {
                        STmpVert sTmp = pTmpVert[iL];
                        pTmpVert[iL] = pTmpVert[iR];
                        pTmpVert[iR] = sTmp;
                        ++iL; --iR;
                    }
                }

                if (iL == iR)
                {
                    bool bReadyRightSwap = pTmpVert[iR].vert[channel] < fSep;
                    if (bReadyRightSwap)
                    {
                        ++iL;
                    }
                    else
                    {
                        --iR;
                    }
                }

                if (iL_in < iR)
                {
                    MergeVertsFast(piTriList_in_and_out, ref pTmpVert, ref context, iL_in, iR);
                }
                if (iL < iR_in)
                {
                    MergeVertsFast(piTriList_in_and_out, ref pTmpVert, ref context, iL, iR_in);
                }
            }
        }
Пример #2
0
        static void GenerateSharedVerticesIndexList(int[] piTriList_in_and_out, ref SMikkTSpaceContext pContext, int iNrTrianglesIn)
        {
            int[]      piHashTable = null, piHashCount = null, piHashOffsets = null, piHashCount2 = null;
            STmpVert[] pTmpVer = null;
            int        i = 0, iChannel = 0, k = 0, e = 0;
            int        iMaxCount = 0;
            Vector3    vMin = GetPosition(ref pContext, 0), vMax = vMin, vDim = new Vector3();
            float      fMin, fMax;

            for (i = 1; i < (iNrTrianglesIn * 3); ++i)
            {
                int     index = piTriList_in_and_out[i];
                Vector3 vP    = GetPosition(ref pContext, index);
                if (vMin.X > vP.X)
                {
                    vMin.X = vP.X;
                }
                else if (vMax.X < vP.X)
                {
                    vMax.X = vP.X;
                }
                if (vMin.Y > vP.Y)
                {
                    vMin.Y = vP.Y;
                }
                else if (vMax.Y < vP.Y)
                {
                    vMax.Y = vP.Y;
                }
                if (vMin.Z > vP.Z)
                {
                    vMin.Z = vP.Z;
                }
                else if (vMax.Z < vP.Z)
                {
                    vMax.Z = vP.Z;
                }
            }

            vDim     = vMax - vMin;
            iChannel = 0;
            fMin     = vMin.X; fMax = vMax.X;
            if (vDim.Y > vDim.X && vDim.Y > vDim.Z)
            {
                iChannel = 1;
                fMin     = vMin.Y; fMax = vMax.Y;
            }
            else if (vDim.Z > vDim.X)
            {
                iChannel = 2;
                fMin     = vMin.Z; fMax = vMax.Z;
            }

            piHashTable   = new int[iNrTrianglesIn * 3];
            piHashCount   = new int[g_iCells];
            piHashOffsets = new int[g_iCells];
            piHashCount2  = new int[g_iCells];

            try
            {
                for (i = 0; i < iNrTrianglesIn * 3; ++i)
                {
                    int     index = piTriList_in_and_out[i];
                    Vector3 vP    = GetPosition(ref pContext, index);
                    float   fVal  = iChannel == 0 ? vP.X : (iChannel == 1) ? vP.Y : vP.Z;
                    int     iCell = FindGridCell(fMin, fMax, fVal);
                    piHashCount[iCell]++;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
            }

            piHashOffsets[0] = 0;
            for (k = 1; k < g_iCells; ++k)
            {
                piHashOffsets[k] = piHashOffsets[k - 1] + piHashCount[k - 1];
            }

            try
            {
                for (i = 0; i < iNrTrianglesIn * 3; ++i)
                {
                    int     index = piTriList_in_and_out[i];
                    Vector3 vP    = GetPosition(ref pContext, index);
                    float   fVal  = iChannel == 0 ? vP.X : (iChannel == 1) ? vP.Y : vP.Z;
                    int     iCell = FindGridCell(fMin, fMax, fVal);

                    piHashTable[piHashOffsets[iCell] + piHashCount2[iCell]] = i;
                    piHashCount2[iCell]++;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
            }

            piHashCount2 = null;

            iMaxCount = piHashCount[0];
            for (k = 1; k < g_iCells; ++k)
            {
                if (iMaxCount < piHashCount[k])
                {
                    iMaxCount = piHashCount[k];
                }
            }

            pTmpVer = new STmpVert[iMaxCount];

            try
            {
                for (k = 0; k < g_iCells; ++k)
                {
                    int entries = piHashCount[k];
                    if (entries < 2)
                    {
                        continue;
                    }

                    for (e = 0; e < entries; e++)
                    {
                        pTmpVer[e].vert = new float[3];
                        int     iv = piHashTable[piHashOffsets[k] + e];
                        Vector3 vP = GetPosition(ref pContext, piTriList_in_and_out[iv]);
                        pTmpVer[e].vert[0] = vP.X; pTmpVer[e].vert[1] = vP.Y; pTmpVer[e].vert[2] = vP.Z;
                        pTmpVer[e].index   = iv;
                    }

                    //merge verts fast here
                    MergeVertsFast(piTriList_in_and_out, ref pTmpVer, ref pContext, 0, entries - 1);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
            }

            pTmpVer = null;
        }