Esempio n. 1
0
        static STSpace AvgTSpace(ref STSpace pTS0, ref STSpace pTS1)
        {
            STSpace ts_res = new STSpace();

            if (pTS0.fMagS == pTS1.fMagS && pTS0.fMagT == pTS1.fMagT &&
                pTS0.vOs.Equals(pTS1.vOs) && pTS1.vOt.Equals(pTS1.vOt))
            {
                ts_res.fMagS = pTS0.fMagS;
                ts_res.fMagT = pTS0.fMagT;
                ts_res.vOs   = pTS0.vOs;
                ts_res.vOt   = pTS0.vOt;
            }
            else
            {
                ts_res.fMagS = 0.5f * (pTS0.fMagS + pTS1.fMagS);
                ts_res.fMagT = 0.5f * (pTS0.fMagT + pTS1.fMagT);
                ts_res.vOs   = pTS0.vOs + pTS0.vOs;
                ts_res.vOt   = pTS0.vOt + pTS0.vOt;

                if (VNotZero(ref ts_res.vOs))
                {
                    ts_res.vOs.Normalize();
                }
                if (VNotZero(ref ts_res.vOt))
                {
                    ts_res.vOt.Normalize();
                }
            }

            return(ts_res);
        }
Esempio n. 2
0
        static bool GenerateTSpaces(ref STSpace[] psTspace, ref STriInfo[] pTriInfos, SGroup[] pGroups, int iNrActiveGroups, int[] piTriListIn, int[] pGroupTriangleBuffer, float fThresCos, ref SMikkTSpaceContext context)
        {
            STSpace[]   pSubGroupTSpace = null;
            SSubGroup[] pUniSubGroups = null;
            int[]       pTmpMembers = null;
            int         iMaxNrFaces = 0, iUniqueTSpaces = 0, g = 0, i = 0;

            for (g = 0; g < iNrActiveGroups; ++g)
            {
                if (iMaxNrFaces < pGroups[g].iNrFaces)
                {
                    iMaxNrFaces = pGroups[g].iNrFaces;
                }
            }

            if (iMaxNrFaces == 0)
            {
                return(true);
            }

            pSubGroupTSpace = new STSpace[iMaxNrFaces];
            pUniSubGroups   = new SSubGroup[iMaxNrFaces];
            pTmpMembers     = new int[iMaxNrFaces];

            iUniqueTSpaces = 0;
            for (g = 0; g < iNrActiveGroups; ++g)
            {
                int iUniqueSubGroups = 0;

                for (i = 0; i < pGroups[g].iNrFaces; ++i)
                {
                    int       f = pGroupTriangleBuffer[pGroups[g].faceOffset];
                    int       index = -1, iVertIndex = -1, iOF_1 = -1, iMembers = 0, j = 0, l = 0;
                    SSubGroup tmp_group;
                    bool      bFound = false;
                    Vector3   n = Vector3.Zero, vOs = Vector3.Zero, vOt = Vector3.Zero;
                    if (pTriInfos[f].AssignedGroup[0] == pGroups[g])
                    {
                        index = 0;
                    }
                    else if (pTriInfos[f].AssignedGroup[1] == pGroups[g])
                    {
                        index = 1;
                    }
                    else if (pTriInfos[f].AssignedGroup[2] == pGroups[g])
                    {
                        index = 2;
                    }

                    iVertIndex = piTriListIn[f * 3 + index];

                    n = GetNormal(ref context, iVertIndex);

                    vOs = pTriInfos[f].vOs - (Vector3.Dot(n, pTriInfos[f].vOs) * n);
                    vOt = pTriInfos[f].vOt - (Vector3.Dot(n, pTriInfos[f].vOt) * n);
                    if (VNotZero(ref vOs))
                    {
                        vOs.Normalize();
                    }
                    if (VNotZero(ref vOt))
                    {
                        vOt.Normalize();
                    }

                    iOF_1 = pTriInfos[f].iOrgFaceNumber;

                    iMembers = 0;
                    for (j = 0; j < pGroups[g].iNrFaces; ++j)
                    {
                        int t     = pGroupTriangleBuffer[pGroups[g].faceOffset + j];
                        int iOf_2 = pTriInfos[t].iOrgFaceNumber;

                        Vector3 vOs2 = (pTriInfos[t].vOs - (Vector3.Dot(n, pTriInfos[t].vOs) * n));
                        Vector3 vOt2 = (pTriInfos[t].vOt - (Vector3.Dot(n, pTriInfos[t].vOt) * n));

                        if (VNotZero(ref vOs2))
                        {
                            vOs2.Normalize();
                        }
                        if (VNotZero(ref vOt2))
                        {
                            vOt2.Normalize();
                        }

                        {
                            bool bAny         = ((pTriInfos[f].iFlag | pTriInfos[t].iFlag) & GROUP_WITH_ANY) != 0;
                            bool bSameOrgFace = iOF_1 == iOf_2;

                            float fCosS = Vector3.Dot(vOs, vOs2);
                            float fCosT = Vector3.Dot(vOt, vOt2);

                            if (bAny || bSameOrgFace || (fCosS > fThresCos && fCosT > fThresCos))
                            {
                                pTmpMembers[iMembers++] = t;
                            }
                        }
                    }

                    tmp_group.iNrFaces   = iMembers;
                    tmp_group.triMembers = new List <int>(pTmpMembers);
                    if (iMembers > 1)
                    {
                        tmp_group.triMembers.Sort();
                    }

                    bFound = false;
                    l      = 0;
                    while (l < iUniqueSubGroups && !bFound)
                    {
                        bFound = CompareSubGroups(ref tmp_group, ref pUniSubGroups[l]);
                        if (!bFound)
                        {
                            ++l;
                        }
                    }

                    if (!bFound)
                    {
                        pUniSubGroups[iUniqueSubGroups].iNrFaces   = iMembers;
                        pUniSubGroups[iUniqueSubGroups].triMembers = new List <int>(tmp_group.triMembers);
                        pSubGroupTSpace[iUniqueSubGroups]          = EvalTspace(tmp_group.triMembers, iMembers, piTriListIn, ref pTriInfos, ref context, pGroups[g].iVertex);
                        iUniqueSubGroups++;
                    }


                    {
                        int iOffs = pTriInfos[f].iTSpacesOffs;
                        int iVert = pTriInfos[f].vert_num[index];
                        if (psTspace[iOffs + iVert].iCounter == 1)
                        {
                            psTspace[iOffs + iVert]          = AvgTSpace(ref psTspace[iOffs + iVert], ref pSubGroupTSpace[l]);
                            psTspace[iOffs + iVert].iCounter = 2;
                            psTspace[iOffs + iVert].bOrient  = pGroups[g].bOrientPreservering;
                        }
                        else
                        {
                            psTspace[iOffs + iVert]          = pSubGroupTSpace[l];
                            psTspace[iOffs + iVert].iCounter = 1;
                            psTspace[iOffs + iVert].bOrient  = pGroups[g].bOrientPreservering;
                        }
                    }
                }

                iUniqueTSpaces += iUniqueSubGroups;
            }

            return(true);
        }
Esempio n. 3
0
        /// <summary>
        /// this version of Mikktspace only deals with triangles
        /// in order to save sometime in moving the code over to c#
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static bool genTangSpace(ref SMikkTSpaceContext context, float fAngularThreshold)
        {
            int[]      piTriListIn            = null;
            int[]      piGroupTrianglesBuffer = null;
            STriInfo[] pTriInfos = null;
            SGroup[]   pGroups   = null;
            STSpace[]  psTspace  = null;

            int   iNrTrianglesIn = 0, f = 0, t = 0, i = 0;
            int   iNrTSPaces = 0, iNrMaxGroups = 0;
            int   iNrActiveGroups = 0, index = 0;
            int   iNrFaces  = context.m_pInterface.m_getNumFaces(ref context);
            float fThresCos = (float)Math.Cos((fAngularThreshold * ((float)Math.PI / 180.0f)));

            for (f = 0; f < iNrFaces; f++)
            {
                int verts = context.m_pInterface.m_getNumVerticesOfFace(ref context, f);
                if (verts == 3)
                {
                    iNrTrianglesIn++;
                }
            }
            if (iNrTrianglesIn <= 0)
            {
                return(false);
            }

            piTriListIn = new int[3 * iNrTrianglesIn];
            pTriInfos   = new STriInfo[iNrTrianglesIn];

            iNrTSPaces = GenerateInitialVerticesIndexList(ref pTriInfos, piTriListIn, ref context, iNrTrianglesIn);

            GenerateSharedVerticesIndexList(piTriListIn, ref context, iNrTrianglesIn);

            InitTriInfo(ref pTriInfos, piTriListIn, ref context, iNrTrianglesIn);

            iNrMaxGroups = iNrTrianglesIn * 3;
            pGroups      = new SGroup[iNrMaxGroups];

            for (f = 0; f < iNrMaxGroups; f++)
            {
                pGroups[f] = new SGroup();
            }

            piGroupTrianglesBuffer = new int[iNrTrianglesIn * 3];

            try
            {
                iNrActiveGroups = Build4RuleGroups(ref pTriInfos, ref pGroups, piGroupTrianglesBuffer, piTriListIn, iNrTrianglesIn);

                psTspace = new STSpace[iNrTSPaces];
                for (t = 0; t < iNrTSPaces; t++)
                {
                    psTspace[t].vOs.X = 1.0f;
                    psTspace[t].fMagS = 1.0f;
                    psTspace[t].vOt.Y = 1.0f;
                    psTspace[t].fMagT = 1.0f;
                }

                GenerateTSpaces(ref psTspace, ref pTriInfos, pGroups, iNrActiveGroups, piTriListIn, piGroupTrianglesBuffer, fThresCos, ref context);

                index = 0;
                for (f = 0; f < iNrFaces; f++)
                {
                    int verts = context.m_pInterface.m_getNumVerticesOfFace(ref context, f);
                    if (verts != 3)
                    {
                        continue;
                    }

                    for (i = 0; i < verts; ++i)
                    {
                        var     pSpace = psTspace[index];
                        float[] tang   = new float[] { pSpace.vOs.X, pSpace.vOs.Y, pSpace.vOs.Z };
                        float[] bitang = new float[] { pSpace.vOt.X, pSpace.vOt.Y, pSpace.vOt.Z };
                        context.m_pInterface.m_setTSpace(ref context, tang, bitang, pSpace.fMagS, pSpace.fMagT, pSpace.bOrient, f, i);
                        context.m_pInterface.m_setTSpaceBasic(ref context, tang, pSpace.bOrient ? 1 : -1, f, i);
                        ++index;
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.StackTrace);
            }

            return(true);
        }
Esempio n. 4
0
        static STSpace EvalTspace(List <int> face_indices, int iFaces, int[] piTriListIn, ref STriInfo[] pTriInfos, ref SMikkTSpaceContext context, int iVertexRepresentitive)
        {
            STSpace res       = new STSpace();
            float   fAngleSum = 0;
            int     face      = 0;

            res.vOs   = Vector3.Zero;
            res.vOt   = Vector3.Zero;
            res.fMagS = 0; res.fMagT = 0;

            for (face = 0; face < iFaces; face++)
            {
                int f = face_indices[face];

                if ((pTriInfos[f].iFlag & GROUP_WITH_ANY) == 0)
                {
                    Vector3 n, vOs, vOt, p0, p1, p2, v1, v2;
                    float   fCos, fAngle, fMagS, fMagT;
                    int     i = -1, index = -1, i0 = -1, i1 = -1, i2 = -1;
                    if (piTriListIn[3 * f] == iVertexRepresentitive)
                    {
                        i = 0;
                    }
                    else if (piTriListIn[3 * f + 1] == iVertexRepresentitive)
                    {
                        i = 1;
                    }
                    else if (piTriListIn[3 * f + 2] == iVertexRepresentitive)
                    {
                        i = 2;
                    }

                    index = piTriListIn[3 * f + i];

                    n   = GetNormal(ref context, index);
                    vOs = pTriInfos[f].vOs - (Vector3.Dot(n, pTriInfos[f].vOs) * n);
                    vOt = pTriInfos[f].vOt - (Vector3.Dot(n, pTriInfos[f].vOt) * n);
                    if (VNotZero(ref vOs))
                    {
                        vOs.Normalize();
                    }
                    if (VNotZero(ref vOt))
                    {
                        vOt.Normalize();
                    }

                    i2 = piTriListIn[3 * f + (i < 2 ? (i + 1) : 0)];
                    i1 = piTriListIn[3 * f + i];
                    i0 = piTriListIn[3 * f + (i > 0 ? (i - 1) : 2)];

                    p0 = GetPosition(ref context, i0);
                    p1 = GetPosition(ref context, i1);
                    p2 = GetPosition(ref context, i2);

                    v1 = p0 - p1;
                    v2 = p2 - p1;

                    v1 = v1 - Vector3.Dot(n, v1) * n;
                    v2 = v2 - Vector3.Dot(n, v2) * n;
                    if (VNotZero(ref v1))
                    {
                        v1.Normalize();
                    }
                    if (VNotZero(ref v2))
                    {
                        v2.Normalize();
                    }

                    fCos   = Vector3.Dot(v1, v2); fCos = fCos > 1 ? 1 : (fCos < -1 ? -1 : fCos);
                    fAngle = (float)Math.Acos(fCos);
                    fMagS  = pTriInfos[f].fMagS;
                    fMagT  = pTriInfos[f].fMagT;

                    res.vOs    = res.vOs + vOs * fAngle;
                    res.vOt    = res.vOt + vOt * fAngle;
                    res.fMagS += (fAngle * fMagS);
                    res.fMagT += (fAngle * fMagT);

                    fAngleSum += fAngle;
                }
            }

            if (VNotZero(ref res.vOs))
            {
                res.vOs.Normalize();
            }
            if (VNotZero(ref res.vOt))
            {
                res.vOt.Normalize();
            }

            if (fAngleSum > 0)
            {
                res.fMagS /= fAngleSum;
                res.fMagT /= fAngleSum;
            }

            return(res);
        }