Пример #1
0
            /// <summary>
            /// merge two VFaces into lhs,
            /// modify other related data-structures as well
            /// </summary>
            private void _MergeVFace(VFace lhs, VFace rhs)
            {
                //int lhsTriIdx = lhs.GetRTriIdx(0);
                int rhsTriIdx = rhs.GetRTriIdx(0);

                m_VFaceCont[rhsTriIdx] = lhs; //link rhs's rTri to lhs

                // merge the data from rhs to lhs
                lhs.AddRTri(rhsTriIdx);
            }
Пример #2
0
 private bool _HasIntersect(VFLst lhs, VFLst rhs)
 {
     for (int i = 0; i < rhs.Count; ++i)
     {
         VFace vf = rhs[i];
         if (lhs.Contains(vf))
         {
             return(true);
         }
     }
     return(false);
 }
Пример #3
0
            /// <summary>
            /// assume the rTriIdx is not degraded
            /// </summary>
            public VFace GetVFaceFromRTri(int rTriIdx)
            {
                VFace vf = null;

                if (m_VFaceCont.TryGetValue(rTriIdx, out vf))
                {
                    return(vf);
                }
                else
                {
                    Dbg.LogErr("VMesh.GetVFaceFromRTri: the rTriIdx is not found in m_VFaceCont, {0}", rTriIdx);
                    return(null);
                }
            }
Пример #4
0
            /// <summary>
            /// get VFaces that containing this VEdge
            /// </summary>
            public void GetVFaces(List <VFace> vFaces)
            {
                vFaces.Clear();
                VMesh vmesh = VMesh.Instance;

                for (int i = 0; i < m_TriCont.Count; ++i)
                {
                    int   triIdx = m_TriCont[i];
                    VFace vf     = vmesh.GetVFaceFromRTri(triIdx);
                    if (!vFaces.Contains(vf))
                    {
                        vFaces.Add(vf);
                    }
                }
            }
Пример #5
0
            /// <summary>
            /// tell each VVert which VFace it's in
            /// </summary>
            private void _MapVVertToVFaces()
            {
                //
                HashSet <VFace> faces = new HashSet <VFace>();

                for (var ie = m_VFaceCont.GetEnumerator(); ie.MoveNext();)
                {
                    VFace f = ie.Current.Value;
                    faces.Add(f);
                }

                for (var ie = faces.GetEnumerator(); ie.MoveNext();)
                {
                    VFace        f     = ie.Current;
                    List <VVert> vvLst = f.GetVVerts();
                    foreach (VVert vv in vvLst)
                    {
                        vv.AddVFace(f);
                    }
                }
            }
Пример #6
0
            /// <summary>
            /// rTriIdx might be degraded rtri, but we can get the VFace to which it belongs anyway
            /// </summary>
            public VFace GetVFaceFromRTri(int rTriIdx, RaycastHit hit)
            {
                VFace vf = null;

                if (m_VFaceCont.TryGetValue(rTriIdx, out vf))
                {
                    return(vf);
                }
                else
                {
                    Dbg.Assert(m_DegRTriCont.Contains(rTriIdx), "VMesh.GetVFaceFromRTri: not in m_VFaceCont or degradedTriCont!?");

                    m_tmpVVLst.Clear();
                    GetVVertsFromRTri(rTriIdx, m_tmpVVLst);

                    float minDist = float.MaxValue;
                    VVert retVV   = null;
                    for (int i = 0; i < m_tmpVVLst.Count; ++i)
                    {
                        VVert vv   = m_tmpVVLst[i];
                        float dist = Vector3.Distance(hit.point, vv.GetWorldPos());
                        if (dist < minDist)
                        {
                            minDist = dist;
                            retVV   = vv;
                        }
                    }

                    Dbg.Assert(retVV != null, "VMesh.GetVFaceFromRTri: no VVert for given rtri!? {0}", rTriIdx);

                    VFLst vfLst = retVV.GetAllVFaces();
                    Dbg.Assert(vfLst.Count > 0, "VMesh.GetVFaceFromRTri: the vvert has no VFace, {0}", retVV);

                    return(vfLst[0]);
                }
            }
Пример #7
0
            // "VQuad table init"

            /// <summary>
            /// this method will try to make VMesh from tri-mesh into hybrid tri-quad-mesh,
            /// it will mark some vedges as "ActiveEdge" which will be used,
            ///
            /// the result will be used in:
            /// * edge marker,
            /// * edge loop
            /// * etc
            ///
            /// [BE WARNED]:
            /// </summary>
            private void _InitVFaceTable()
            {
                //////////////////////////////////////////////////
                // 1. foreach vedge of the vmesh
                //       if vedge has and only has 2 tris
                //          calc a score and store in sorted_vEdges
                // 2. foreach vedge in sorted_vEdges
                //       if the 2 tris not be 'marked' yet, then
                //          take it as the 'non-quad' edge;
                //          mark the 2 tris;
                // 3. get all active-edge into m_VActiveEdgeArr
                //   3.1 call all vvert, to make activeVEdge
                // 4. prepare the VFaceCont:
                //        create the rTriIdx <=> VFace first;
                //        merge VFace with those markedTris;
                // 5. process the degraded r-tris, assign them to some good VFace (so we can handle click-selection)
                //////////////////////////////////////////////////

                int totalTriCnt = MeshCache.Instance.triangles.Length / 3;

                VVert[] tmpVertArr = new VVert[4];

                // step 1
                SortedDictionary <_ScoredEdge, bool> sortedVEdges = new SortedDictionary <_ScoredEdge, bool>();

                foreach (var vedge in m_VEdgeCont)
                {
                    if (vedge.GetRTriCount() != 2)
                    {
                        continue;
                    }

                    RTriCont rtris = vedge.GetRTris();
                    _GetAsQuadVerts(rtris[0], rtris[1], vedge, tmpVertArr);

                    float score = _CalcQuadScore(tmpVertArr); // calc score for the quad-to-be
                    sortedVEdges.Add(new _ScoredEdge(score, vedge), false);
                }

                // step 2
                //int cnt = 0;
                Dictionary <int, int> markedTris = new Dictionary <int, int>();

                for (var ie = sortedVEdges.GetEnumerator(); ie.MoveNext();)
                {
                    var vedge = ie.Current.Key.vEdge;
                    //if (cnt < 100)
                    //Dbg.Log("sortedVEdges: {0}: {1}, score:{2}", cnt++, vedge, ie.Current.Key.score);
                    RTriCont triCont = vedge.GetRTris();
                    Dbg.Assert(triCont.Count == 2, "VMesh._InitVFaceTable: the tri-cont count of vEdge != 2");
                    if (!markedTris.ContainsKey(triCont[0]) && !markedTris.ContainsKey(triCont[1]))
                    {
                        //Dbg.Log("Add markedTris: {0}<=>{1}", triCont[0], triCont[1]);
                        markedTris.Add(triCont[0], triCont[1]);
                        markedTris.Add(triCont[1], triCont[0]);
                        vedge.IsActiveEdge = false;

                        if (markedTris.Count >= totalTriCnt)
                        {
                            break; // all tris covered, no need to loop on
                        }
                    }
                }

                // step 3
                List <VEdge> quadEdges = new List <VEdge>();

                for (int i = 0; i < m_VEdgeArr.Length; ++i)
                {
                    if (m_VEdgeArr[i].IsActiveEdge)
                    {
                        quadEdges.Add(m_VEdgeArr[i]);
                    }
                }
                m_VActiveEdgeArr = quadEdges.ToArray();

                //step 3.1
                for (int i = 0; i < m_VVertArr.Length; ++i)
                {
                    m_VVertArr[i].CreateActiveVEdgesList();
                }

                // step 4
                int[] rTriIdxs = MeshCache.Instance.triangles;
                int   rTriCnt  = rTriIdxs.Length / 3;

                for (int i = 0; i < rTriCnt; ++i)
                {
                    VFace vFace = new VFace();
                    vFace.AddRTri(i);

                    m_VFaceCont.Add(i, vFace);
                }

                for (var ie = markedTris.GetEnumerator(); ie.MoveNext();)
                {
                    int rTriIdx0 = ie.Current.Key;
                    int rTriIdx1 = ie.Current.Value;

                    if (rTriIdx0 > rTriIdx1)
                    {
                        continue;
                    }

                    VFace vf0 = m_VFaceCont[rTriIdx0];
                    VFace vf1 = m_VFaceCont[rTriIdx1];

                    _MergeVFace(vf0, vf1);
                }
                markedTris.Clear();

                // step 5
                _MapVVertToVFaces();
            }
Пример #8
0
 public override void Awake()
 {
     base.Awake();
     vFace = GetComponent <VFace>();
 }
Пример #9
0
            // "vface"

            public void AddVFace(VFace vf)
            {
                m_vfLst.Add(vf);
            }