Exemplo n.º 1
0
        public bool IsLinkedEdge(apMeshEdge edge)
        {
            bool isORCond = (_vert1 == edge._vert1 || _vert1 == edge._vert2) ||
                            (_vert2 == edge._vert1 || _vert2 == edge._vert2);

            return(isORCond && !IsSameEdge(edge));           //
        }
Exemplo n.º 2
0
        public void UpdateSnapEdgeGUIOnly(Vector2 mousePos, bool isShift, bool isCtrl, bool isPressed)
        {
            if (Vector2.SqrMagnitude(_isTmpEdgeWire_SnapCheck_MousePos - mousePos) > 1.0f ||
                _isTmpEdgeWire_SnapCheck_PrevShift != isShift ||
                _isTmpEdgeWire_SnapCheck_PrevCtrl != isCtrl)
            {
                _isTmpEdgeWire_SnapToEdge = false;
                _tmpEdgeWire_SnapToEdge   = Vector2.zero;

                //if (isShift && _mesh != null && !isCtrl && _curVertex == null)
                if (isShift && _mesh != null && !isCtrl && !isPressed)
                {
                    //추가
                    //가장 가까운 Edge의 점을 찾는다.
                    apMeshEdge nearestEdge = GetMeshNearestEdge(mousePos, _mesh, 3.0f);                    //<<기본적인 5가 아닌 3이다. 제한적임
                    if (nearestEdge != null)
                    {
                        _isTmpEdgeWire_SnapToEdge = true;
                        _tmpEdgeWire_SnapToEdge   = nearestEdge.GetNearestPosOnEdge(apGL.GL2World(mousePos) + _mesh._offsetPos);
                    }
                }

                //Debug.Log("UpdateSnapEdgeGUIOnly >> " + _isTmpEdgeWire_SnapToEdge);

                _isTmpEdgeWire_SnapCheck_MousePos  = mousePos;
                _isTmpEdgeWire_SnapCheck_PrevShift = isShift;
                _isTmpEdgeWire_SnapCheck_PrevCtrl  = isCtrl;
            }
            //_tmpEdgeWire_MousePos = mousePos;
        }
Exemplo n.º 3
0
        private apMeshEdge GetMeshNearestEdge(Vector2 posGL, apMesh mesh, float offsetGL)
        {
            apMeshEdge curEdge = null;

            //Vector2 posW = apGL.GL2World(posGL) + mesh._offsetPos;

            Vector2 vPos1GL = Vector2.zero;
            Vector2 vPos2GL = Vector2.zero;
            float   minX    = 0.0f;
            float   maxX    = 0.0f;
            float   minY    = 0.0f;
            float   maxY    = 0.0f;
            float   curDist = 0.0f;

            float      minDist = 0.0f;
            apMeshEdge minEdge = null;

            for (int i = 0; i < mesh._edges.Count; i++)
            {
                curEdge = mesh._edges[i];

                if (curEdge._vert1 == null || curEdge._vert2 == null)
                {
                    continue;
                }

                //기본 사각 범위안에 있는지 확인
                vPos1GL = apGL.World2GL(curEdge._vert1._pos - mesh._offsetPos);
                vPos2GL = apGL.World2GL(curEdge._vert2._pos - mesh._offsetPos);

                minX = Mathf.Min(vPos1GL.x, vPos2GL.x);
                maxX = Mathf.Max(vPos1GL.x, vPos2GL.x);
                minY = Mathf.Min(vPos1GL.y, vPos2GL.y);
                maxY = Mathf.Max(vPos1GL.y, vPos2GL.y);

                if (posGL.x < minX || maxX < posGL.x ||
                    posGL.y < minY || maxY < posGL.y)
                {
                    continue;
                }

                curDist = apEditorUtil.DistanceFromLine(
                    vPos1GL,
                    vPos2GL,
                    posGL);

                if (curDist < offsetGL)
                {
                    if (minEdge == null || curDist < minDist)
                    {
                        minDist = curDist;
                        minEdge = curEdge;
                    }
                }
            }
            return(minEdge);
        }
Exemplo n.º 4
0
            public static CloneVertex MakeCrossPoint(Vector2 pos, apMeshEdge splitEdge)
            {
                CloneVertex newCVert = new CloneVertex();

                newCVert._pos             = pos;
                newCVert._isCrossOnAxis   = true;
                newCVert._srcSplitEdge    = splitEdge;
                newCVert._compareToMirror = 0;
                return(newCVert);
            }
Exemplo n.º 5
0
        public void DrawMeshEdgeOnly(apMesh mesh, apMatrix3x3 matrix)
        {
            try
            {
                //0. 메시, 텍스쳐가 없을 때
                //if (mesh == null || mesh._textureData == null || mesh._textureData._image == null)//이전 코드
                if (mesh == null || mesh.LinkedTextureData == null || mesh.LinkedTextureData._image == null)                //변경 코드
                {
                    return;
                }

                //1. 모든 메시를 보여줄때 (또는 클리핑된 메시가 없을 때) =>
                Color meshEdgeColor       = new Color(1.0f, 0.5f, 0.0f, 0.9f);
                Color meshHiddenEdgeColor = new Color(1.0f, 1.0f, 0.0f, 0.7f);

                matrix *= mesh.Matrix_VertToLocal;


                Vector2 pos0 = Vector2.zero, pos1 = Vector2.zero;
                if (mesh._edges.Count > 0)
                {
                    _matBatch.SetPass_Color();
                    _matBatch.SetClippingSize(_glScreenClippingSize);
                    GL.Begin(GL.LINES);
                    for (int i = 0; i < mesh._edges.Count; i++)
                    {
                        pos0 = matrix.MultiplyPoint(mesh._edges[i]._vert1._pos);
                        pos1 = matrix.MultiplyPoint(mesh._edges[i]._vert2._pos);

                        DrawLine(pos0, pos1, meshEdgeColor, false);
                    }

                    for (int iPoly = 0; iPoly < mesh._polygons.Count; iPoly++)
                    {
                        for (int iHE = 0; iHE < mesh._polygons[iPoly]._hidddenEdges.Count; iHE++)
                        {
                            apMeshEdge hiddenEdge = mesh._polygons[iPoly]._hidddenEdges[iHE];

                            pos0 = matrix.MultiplyPoint(hiddenEdge._vert1._pos);
                            pos1 = matrix.MultiplyPoint(hiddenEdge._vert2._pos);

                            DrawLine(pos0, pos1, meshHiddenEdgeColor, false);
                        }
                    }

                    GL.End();
                }
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);
            }
        }
Exemplo n.º 6
0
 public static apVertex GetSharedVertex(apMeshEdge edge1, apMeshEdge edge2)
 {
     if (edge1._vert1 == edge2._vert1 || edge1._vert1 == edge2._vert2)
     {
         return(edge1._vert1);
     }
     else if (edge1._vert2 == edge2._vert1 || edge1._vert2 == edge2._vert2)
     {
         return(edge1._vert2);
     }
     return(null);
 }
Exemplo n.º 7
0
        public static apVertex[] Get3VerticesOf2Edges(apMeshEdge edge1, apMeshEdge edge2)
        {
            apVertex[] verts = new apVertex[3];
            verts[0] = edge1._vert1;
            verts[1] = edge1._vert2;

            if (edge2._vert1 == edge1._vert1 || edge2._vert1 == edge1._vert2)
            {
                verts[2] = edge2._vert2;
            }
            else
            {
                verts[2] = edge2._vert1;
            }

            return(verts);
        }
Exemplo n.º 8
0
 public static apVertex[] GetNoSharedVertex(apMeshEdge edge1, apMeshEdge edge2)
 {
     if (edge1._vert1 == edge2._vert1)
     {
         return(new apVertex[] { edge1._vert2, edge2._vert2 });
     }
     if (edge1._vert1 == edge2._vert2)
     {
         return(new apVertex[] { edge1._vert2, edge2._vert1 });
     }
     if (edge1._vert2 == edge2._vert1)
     {
         return(new apVertex[] { edge1._vert1, edge2._vert2 });
     }
     if (edge1._vert2 == edge2._vert2)
     {
         return(new apVertex[] { edge1._vert1, edge2._vert1 });
     }
     return(null);
 }
Exemplo n.º 9
0
        public void RemoveMirrorEdge(apMeshEdge removedEdge, apMesh mesh)
        {
            ClearMovedVertex();
            //두개의 Vertex => Mirror 위치 각자 계산 => mesh에서 검색
            if (removedEdge == null)
            {
                return;
            }
            apVertex srcVert1 = removedEdge._vert1;
            apVertex srcVert2 = removedEdge._vert2;

            if (srcVert1 == null || srcVert2 == null)
            {
                return;
            }

            Vector2 mirrorPos1 = GetMirrorPosByMesh(srcVert1._pos, mesh);
            Vector2 mirrorPos2 = GetMirrorPosByMesh(srcVert2._pos, mesh);

            apVertex mirrorVert1 = FindNearestVertex(mirrorPos1, mesh, 2.0f, srcVert1);
            apVertex mirrorVert2 = FindNearestVertex(mirrorPos2, mesh, 2.0f, srcVert2);

            if (mirrorVert1 == null || mirrorVert2 == null || mirrorVert1 == mirrorVert2 ||
                (mirrorVert1 == srcVert1 && mirrorVert2 == srcVert2) ||
                (mirrorVert1 == srcVert2 && mirrorVert2 == srcVert1)
                )
            {
                return;
            }

            //이제 대상이 되는 Edge를 찾자
            apMeshEdge mirrorEdge = mesh._edges.Find(delegate(apMeshEdge a)
            {
                return(a.IsSameEdge(mirrorVert1, mirrorVert2));
            });

            if (mirrorEdge != null)
            {
                mesh.RemoveEdge(mirrorEdge);
            }
        }
Exemplo n.º 10
0
 public bool IsSameEdge(apMeshEdge edge)
 {
     return(IsSameEdge(edge._vert1, edge._vert2));
 }
Exemplo n.º 11
0
        private void MakeTriangles()
        {
            _tris.Clear();
            List <apMeshEdge> allEdges = new List <apMeshEdge>();

            for (int i = 0; i < _edges.Count; i++)
            {
                allEdges.Add(_edges[i]);
            }

            for (int i = 0; i < _hidddenEdges.Count; i++)
            {
                allEdges.Add(_hidddenEdges[i]);
            }


            for (int iEdge = 0; iEdge < allEdges.Count; iEdge++)
            {
                apMeshEdge baseEdge = allEdges[iEdge];

                if (!baseEdge._isHidden)
                {
                    //Hidden이 아닌 경우
                    //한개의 Edge는 한개의 Tri에만 들어간다.
                    bool isExistTri = _tris.Exists(delegate(apMeshTri a)
                    {
                        return(a.IsIncludeEdge(baseEdge));
                    });

                    if (isExistTri)
                    {
                        //이미 Tri 계산에 사용된 Edge이다.
                        continue;
                    }
                }

                //이제 여기에 연결된 Edge 하나를 찾는다. (두번째 Edge)
                //처음엔 "기본 Edge", 여기서 못찾으면 "Hidden Edge"에서 찾자

                //한개의 Edge에 대해서 최대 2개의 Tri만 나온다.
                //2개를 만들면 더이상 처리하지 말자
                int nCreatedTri = 0;

                for (int iNext = 0; iNext < allEdges.Count; iNext++)
                {
                    apMeshEdge nextEdge = allEdges[iNext];
                    if (baseEdge == nextEdge)
                    {
                        //같은거다
                        continue;
                    }

                    if (!nextEdge.IsLinkedEdge(baseEdge))
                    {
                        //연결되지 않았다.
                        continue;
                    }

                    //이 둘을 연결할 선분은 있는지 체크
                    //공유하고 있지 않은 버텍스 두개를 구하자
                    apVertex[] noSharedVerts = apMeshEdge.GetNoSharedVertex(baseEdge, nextEdge);
                    if (noSharedVerts == null)
                    {
                        continue;
                    }

                    //해당 Edge를 포함하는 Edge가 있는가
                    apMeshEdge thirdEdge = allEdges.Find(delegate(apMeshEdge a)
                    {
                        return(a.IsSameEdge(noSharedVerts[0], noSharedVerts[1]));
                    });

                    if (thirdEdge == null)
                    {
                        continue;
                    }

                    apVertex[] allVerts = apMeshEdge.Get3VerticesOf2Edges(baseEdge, nextEdge);

                    //base, next, third 완성
                    bool isExistTri = _tris.Exists(delegate(apMeshTri a)
                    {
                        return(a.IsSameTri(allVerts[0], allVerts[1], allVerts[2]));
                    });

                    if (!isExistTri)
                    {
                        //겹치는 Tri가 없다.
                        //만들자
                        apMeshTri newTri = new apMeshTri();
                        newTri.SetVertices(allVerts[0], allVerts[1], allVerts[2]);

                        _tris.Add(newTri);

                        nCreatedTri++;
                    }

                    if (nCreatedTri >= 2)
                    {
                        //처리 끝
                        break;
                    }
                }

                //if (_tris.Count >= nNeedTri)
                //{
                //	//이미 이 폴리곤에서 만들 수 있는 최대의 Tri를 만들었다.
                //	break;
                //}
            }

            //마지막에 Sort
            SortTriByDepth();
        }
Exemplo n.º 12
0
        //----------------------------------------------------------------
        public void AddMirrorVertex(apVertex prevVert, apVertex addedVert, apMesh mesh, bool isAddEdge, bool isShift, bool isNewVert, bool isAddVertexWithSplit)
        {
            apVertex mirrorVert_Prev = null;
            apVertex mirrorVert_Next = null;

            //float mirrorOffset = _editor._meshTRSOption_MirrorOffset;
            //float clickableOffset = Mathf.Max(6.0f, mirrorOffset);//6은 기본 클릭 범위
            float clickableOffset = 6.0f;

            if (isNewVert)
            {
                //새로운 버텍스를 생성했다면 미러쪽도 새로 만드는 방향으로 해야한다.
                clickableOffset = 2.0f;
            }

            bool isSnap = _editor._meshTRSOption_MirrorSnapVertOnRuler;

            //추가된 버텍스가 있다 (각각 Prev, Next에 대해서 동일한 처리)
            //=> 1) 축에 있다면
            //		=> Snap 옵션이 켜졌다면 Mirror대신 축으로 위치를 보정한다. (미러 생성 안하고 mirrorVert를 이걸로 설정)
            //		=> Snap 옵션이 꺼졌다면 처리하지 않는다. (Mirror가 안됨)
            //=> 2) 미러 위치를 계산한다.
            //		=> 근처에 버텍스가 있다면 그걸 선택하고, 위치를 보정한다. (Prev와 Next는 같은 점을 공유할 수 없다.)
            //		=> 근처에 버텍스가 없다면 새로 생성한다.
            //=> isAddEdge가 True일 때, mirrorVert Prev, Next가 모두 있다면 Edge 생성. 단, 서로 교차된 경우는 생략한다.



            if (prevVert != null)
            {
                if (IsOnAxisByMesh(prevVert._pos, mesh))
                {
                    //1) 축에 있는가
                    if (isSnap)
                    {
                        //=> 위치만 보정한다.
                        mirrorVert_Prev      = prevVert;
                        mirrorVert_Prev._pos = GetAxisPosToSnap(prevVert._pos, mesh);
                    }
                    else
                    {
                        //=> 위치 보정 없이 그냥 선택한다.
                        mirrorVert_Prev = prevVert;
                    }
                }
                else
                {
                    //2) 축 바깥이라면 미러 위치를 계산한다.
                    Vector2 mirrorPos = GetMirrorPosByMesh(prevVert._pos, mesh);

                    //근처에 Vertex가 있는가
                    apVertex nearestVert = FindNearestVertex(mirrorPos, mesh, clickableOffset);
                    if (nearestVert != null)
                    {
                        //=> 이걸 선택하고 위치만 보정한다.
                        mirrorVert_Prev      = nearestVert;
                        mirrorVert_Prev._pos = mirrorPos;
                    }
                    else
                    {
                        //=> 새로 생성하자
                        mirrorVert_Prev = mesh.AddVertexAutoUV(mirrorPos);
                    }
                }
            }

            if (addedVert != null && prevVert != addedVert)
            {
                if (IsOnAxisByMesh(addedVert._pos, mesh))
                {
                    //1) 축에 있는가
                    if (isSnap)
                    {
                        //=> 위치만 보정한다.
                        mirrorVert_Next      = addedVert;
                        mirrorVert_Next._pos = GetAxisPosToSnap(addedVert._pos, mesh);
                    }
                    else
                    {
                        //=> 위치 보정 없이 그냥 선택한다.
                        mirrorVert_Next = addedVert;
                    }
                }
                else
                {
                    //2) 축 바깥이라면 미러 위치를 계산한다.
                    Vector2 mirrorPos = GetMirrorPosByMesh(addedVert._pos, mesh);

                    //근처에 Vertex가 있는가 + Prev와 다른 Vertex인가
                    apVertex nearestVert = FindNearestVertex(mirrorPos, mesh, clickableOffset);
                    if (nearestVert != null && mirrorVert_Prev != nearestVert)
                    {
                        //=> 이걸 선택하고 위치만 보정한다.
                        mirrorVert_Next      = nearestVert;
                        mirrorVert_Next._pos = mirrorPos;
                    }
                    else
                    {
                        //=> 새로 생성하자
                        if (isAddVertexWithSplit)
                        {
                            //만약 원 소스가 Edge를 Split하고 Vertex를 만든 거라면,
                            //Mirror도 주변의 Edge를 Split해야한다.
                            apMeshEdge nearestEdge = GetMeshNearestEdge(mirrorPos, mesh, 3.0f);
                            if (nearestEdge != null)
                            {
                                Vector2 splitPos = nearestEdge.GetNearestPosOnEdge(mirrorPos);
                                if (Mathf.Abs(splitPos.x - nearestEdge._vert1._pos.x) < 1 && Mathf.Abs(splitPos.y - nearestEdge._vert1._pos.y) < 1)
                                {
                                    //Vert1과 겹친다.
                                    mirrorVert_Next = nearestEdge._vert1;
                                }
                                else if (Mathf.Abs(splitPos.x - nearestEdge._vert2._pos.x) < 1 && Mathf.Abs(splitPos.y - nearestEdge._vert2._pos.y) < 1)
                                {
                                    //Vert2와 겹친다.
                                    mirrorVert_Next = nearestEdge._vert2;
                                }
                                else
                                {
                                    //겹치는게 없다.
                                    mirrorVert_Next = mesh.SplitEdge(nearestEdge, splitPos);
                                }
                            }
                        }
                        else
                        {
                            mirrorVert_Next = mesh.AddVertexAutoUV(mirrorPos);
                        }
                    }
                }
            }

            //if(!isAddEdge)
            //{
            //	Debug.LogError("Add Edge => False");
            //}
            if (isAddEdge && mirrorVert_Prev != null && mirrorVert_Next != null)
            {
                //Edge를 추가하자
                //단, 두개가 서로 Mirror된게 아니라면 생략
                if ((mirrorVert_Prev == prevVert && mirrorVert_Next == addedVert) ||
                    (mirrorVert_Next == prevVert && mirrorVert_Prev == addedVert))                       //<<또는 그 반대
                {
                    //새로 만드는거 실패.
                    //서로 교차되고 있었다.
                    //Shift 키를 누른 상태라면 => Mirror 위치에 중점을 만들자.
                    if (isShift && mirrorVert_Prev != mirrorVert_Next)
                    {
                        //Mirror의 양쪽에 위치한 경우
                        bool    isCounterSize = false;
                        Vector2 centerPos     = (mirrorVert_Prev._pos + mirrorVert_Next._pos) * 0.5f;
                        if (mesh._isMirrorX)
                        {
                            if ((mirrorVert_Prev._pos.x - mesh._mirrorAxis.x) * (mirrorVert_Next._pos.x - mesh._mirrorAxis.x) < 0.0f)
                            {
                                //축으로부터 X 변화량의 곱이 -1인 경우
                                isCounterSize = true;
                                centerPos.x   = mesh._mirrorAxis.x;
                            }
                        }
                        else
                        {
                            if ((mirrorVert_Prev._pos.y - mesh._mirrorAxis.y) * (mirrorVert_Next._pos.y - mesh._mirrorAxis.y) < 0.0f)
                            {
                                //축으로부터 Y 변화량의 곱이 -1인 경우
                                isCounterSize = true;
                                centerPos.y   = mesh._mirrorAxis.y;
                            }
                        }
                        if (isCounterSize)
                        {
                            apMeshEdge existEdge = mesh._edges.Find(delegate(apMeshEdge a)
                            {
                                return(a.IsSameEdge(mirrorVert_Prev, mirrorVert_Next));
                            });

                            if (existEdge != null)
                            {
                                //분할하자
                                mesh.SplitEdge(existEdge, centerPos);
                                //apVertex centerVert = mesh.AddVertexAutoUV(centerPos);
                                //mesh.RemoveEdge(existEdge);

                                //if (centerVert != null)
                                //{
                                //	mesh.MakeNewEdge(mirrorVert_Prev, centerVert, false);
                                //	mesh.MakeNewEdge(mirrorVert_Next, centerVert, false);
                                //}

                                //Debug.Log("Split Edge");
                            }
                        }
                    }
                }
                else
                {
                    //새로운 Mirror Vertex를 만들자.
                    mesh.MakeNewEdge(mirrorVert_Prev, mirrorVert_Next, isShift);

                    //Debug.Log("Add Mirror Edge : " + isShift);
                }
            }

            if (mirrorVert_Prev != null)
            {
                mesh.RefreshVertexAutoUV(mirrorVert_Prev);
            }
            if (mirrorVert_Next != null)
            {
                mesh.RefreshVertexAutoUV(mirrorVert_Next);
            }


            ClearMovedVertex();
        }
Exemplo n.º 13
0
 public bool IsIncludeEdge(apMeshEdge edge)
 {
     return((edge._vert1 == _verts[0] || edge._vert1 == _verts[1] || edge._vert1 == _verts[2]) &&
            (edge._vert2 == _verts[0] || edge._vert2 == _verts[1] || edge._vert2 == _verts[2]));
 }
Exemplo n.º 14
0
        public void DrawMesh(apMesh mesh, apMatrix3x3 matrix, Color color2X, bool isShowAllTexture, bool isDrawOutline, bool isDrawEdge, bool isDrawToneOutline = false)
        {
            try
            {
                //0. 메시, 텍스쳐가 없을 때
                //if (mesh == null || mesh._textureData == null || mesh._textureData._image == null)//이전 코드
                if (mesh == null || mesh.LinkedTextureData == null || mesh.LinkedTextureData._image == null)                //변경 코드
                {
                    return;
                }

                //1. 모든 메시를 보여줄때 (또는 클리핑된 메시가 없을 때) =>
                Color textureColor = new Color(0.5f, 0.5f, 0.5f, 1.0f);
                //Color shadedTextureColor = new Color(0.3f, 0.3f, 0.3f, 1.0f);
                Color atlasBorderColor    = new Color(0.0f, 1.0f, 1.0f, 0.5f);
                Color meshEdgeColor       = new Color(1.0f, 0.5f, 0.0f, 0.9f);
                Color meshHiddenEdgeColor = new Color(1.0f, 1.0f, 0.0f, 0.7f);

                matrix *= mesh.Matrix_VertToLocal;

                if (isShowAllTexture)
                {
                    //DrawTexture(mesh._textureData._image, matrix, mesh._textureData._width, mesh._textureData._height, textureColor, -10);
                    DrawTexture(mesh.LinkedTextureData._image, matrix, mesh.LinkedTextureData._width, mesh.LinkedTextureData._height, textureColor, -10);
                }

                Vector2 pos2_0 = Vector2.zero;
                Vector2 pos2_1 = Vector2.zero;
                Vector2 pos2_2 = Vector2.zero;

                Vector3 pos_0 = Vector3.zero;
                Vector3 pos_1 = Vector3.zero;
                Vector3 pos_2 = Vector3.zero;

                Vector2 uv_0 = Vector2.zero;
                Vector2 uv_1 = Vector2.zero;
                Vector2 uv_2 = Vector2.zero;

                //2. 메시를 렌더링하자
                if (mesh._indexBuffer.Count >= 3)
                {
                    if (!isDrawToneOutline)
                    {
                        _matBatch.SetPass_Texture_Normal(color2X, mesh.LinkedTextureData._image, apPortrait.SHADER_TYPE.AlphaBlend);
                    }
                    else
                    {
                        _matBatch.SetPass_ToneColor_Custom(color2X, mesh.LinkedTextureData._image, 0.0f, 0.0f);
                    }

                    _matBatch.SetClippingSize(_glScreenClippingSize);

                    GL.Begin(GL.TRIANGLES);
                    //------------------------------------------
                    apVertex vert0, vert1, vert2;
                    //Color color0 = Color.black, color1 = Color.black, color2 = Color.black;
                    Color color0 = Color.white, color1 = Color.white, color2 = Color.white;


                    for (int i = 0; i < mesh._indexBuffer.Count; i += 3)
                    {
                        if (i + 2 >= mesh._indexBuffer.Count)
                        {
                            break;
                        }

                        if (mesh._indexBuffer[i + 0] >= mesh._vertexData.Count ||
                            mesh._indexBuffer[i + 1] >= mesh._vertexData.Count ||
                            mesh._indexBuffer[i + 2] >= mesh._vertexData.Count)
                        {
                            break;
                        }

                        vert0 = mesh._vertexData[mesh._indexBuffer[i + 0]];
                        vert1 = mesh._vertexData[mesh._indexBuffer[i + 1]];
                        vert2 = mesh._vertexData[mesh._indexBuffer[i + 2]];


                        pos2_0 = World2GL(matrix.MultiplyPoint(vert0._pos));
                        pos2_1 = World2GL(matrix.MultiplyPoint(vert1._pos));
                        pos2_2 = World2GL(matrix.MultiplyPoint(vert2._pos));

                        pos_0 = new Vector3(pos2_0.x, pos2_0.y, vert0._zDepth * 0.1f);
                        pos_1 = new Vector3(pos2_1.x, pos2_1.y, vert1._zDepth * 0.5f);
                        pos_2 = new Vector3(pos2_2.x, pos2_2.y, vert2._zDepth * 0.5f);                        //<<Z값이 반영되었다.

                        uv_0 = mesh._vertexData[mesh._indexBuffer[i + 0]]._uv;
                        uv_1 = mesh._vertexData[mesh._indexBuffer[i + 1]]._uv;
                        uv_2 = mesh._vertexData[mesh._indexBuffer[i + 2]]._uv;


                        GL.Color(color0); GL.TexCoord(uv_0); GL.Vertex(pos_0);                         // 0
                        GL.Color(color1); GL.TexCoord(uv_1); GL.Vertex(pos_1);                         // 1
                        GL.Color(color2); GL.TexCoord(uv_2); GL.Vertex(pos_2);                         // 2

                        //Back Side
                        GL.Color(color2); GL.TexCoord(uv_2); GL.Vertex(pos_2);                         // 2
                        GL.Color(color1); GL.TexCoord(uv_1); GL.Vertex(pos_1);                         // 1
                        GL.Color(color0); GL.TexCoord(uv_0); GL.Vertex(pos_0);                         // 0



                        ////------------------------------------------
                    }
                    GL.End();
                }

                if (mesh._isPSDParsed && isDrawOutline)
                {
                    Vector2 pos_LT = matrix.MultiplyPoint(new Vector2(mesh._atlasFromPSD_LT.x, mesh._atlasFromPSD_LT.y));
                    Vector2 pos_RT = matrix.MultiplyPoint(new Vector2(mesh._atlasFromPSD_RB.x, mesh._atlasFromPSD_LT.y));
                    Vector2 pos_LB = matrix.MultiplyPoint(new Vector2(mesh._atlasFromPSD_LT.x, mesh._atlasFromPSD_RB.y));
                    Vector2 pos_RB = matrix.MultiplyPoint(new Vector2(mesh._atlasFromPSD_RB.x, mesh._atlasFromPSD_RB.y));


                    _matBatch.SetPass_Color();
                    _matBatch.SetClippingSize(_glScreenClippingSize);
                    GL.Begin(GL.LINES);

                    DrawLine(pos_LT, pos_RT, atlasBorderColor, false);
                    DrawLine(pos_RT, pos_RB, atlasBorderColor, false);
                    DrawLine(pos_RB, pos_LB, atlasBorderColor, false);
                    DrawLine(pos_LB, pos_LT, atlasBorderColor, false);

                    GL.End();
                }

                //외곽선을 그려주자
                //float imageWidthHalf = mesh._textureData._width * 0.5f;
                //float imageHeightHalf = mesh._textureData._height * 0.5f;

                float imageWidthHalf  = mesh.LinkedTextureData._width * 0.5f;
                float imageHeightHalf = mesh.LinkedTextureData._height * 0.5f;

                Vector2 pos_TexOutline_LT = matrix.MultiplyPoint(new Vector2(-imageWidthHalf, -imageHeightHalf));
                Vector2 pos_TexOutline_RT = matrix.MultiplyPoint(new Vector2(imageWidthHalf, -imageHeightHalf));
                Vector2 pos_TexOutline_LB = matrix.MultiplyPoint(new Vector2(-imageWidthHalf, imageHeightHalf));
                Vector2 pos_TexOutline_RB = matrix.MultiplyPoint(new Vector2(imageWidthHalf, imageHeightHalf));


                _matBatch.SetPass_Color();
                _matBatch.SetClippingSize(_glScreenClippingSize);
                GL.Begin(GL.LINES);

                DrawLine(pos_TexOutline_LT, pos_TexOutline_RT, atlasBorderColor, false);
                DrawLine(pos_TexOutline_RT, pos_TexOutline_RB, atlasBorderColor, false);
                DrawLine(pos_TexOutline_RB, pos_TexOutline_LB, atlasBorderColor, false);
                DrawLine(pos_TexOutline_LB, pos_TexOutline_LT, atlasBorderColor, false);

                GL.End();


                //3. Edge를 렌더링하자 (전체 / Ouline)
                if (isDrawEdge)
                {
                    Vector2 pos0 = Vector2.zero, pos1 = Vector2.zero;
                    if (mesh._edges.Count > 0)
                    {
                        _matBatch.SetPass_Color();
                        _matBatch.SetClippingSize(_glScreenClippingSize);
                        GL.Begin(GL.LINES);
                        for (int i = 0; i < mesh._edges.Count; i++)
                        {
                            pos0 = matrix.MultiplyPoint(mesh._edges[i]._vert1._pos);
                            pos1 = matrix.MultiplyPoint(mesh._edges[i]._vert2._pos);

                            DrawLine(pos0, pos1, meshEdgeColor, false);
                        }

                        for (int iPoly = 0; iPoly < mesh._polygons.Count; iPoly++)
                        {
                            for (int iHE = 0; iHE < mesh._polygons[iPoly]._hidddenEdges.Count; iHE++)
                            {
                                apMeshEdge hiddenEdge = mesh._polygons[iPoly]._hidddenEdges[iHE];

                                pos0 = matrix.MultiplyPoint(hiddenEdge._vert1._pos);
                                pos1 = matrix.MultiplyPoint(hiddenEdge._vert2._pos);

                                DrawLine(pos0, pos1, meshHiddenEdgeColor, false);
                            }
                        }

                        GL.End();
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);
            }
        }
Exemplo n.º 15
0
        private void IsAnyCrossEdgeMultiple(apVertex vert1, apVertex vert2, Vector2 vert2PosIfNull)
        {
            if (_mesh == null)
            {
                return;
            }
            int nVert = _mesh._vertexData.Count;
            int nEdge = _mesh._edges.Count;

            Vector2 vert1Local = vert1._pos;
            Vector2 vert2Local = vert2PosIfNull;

            if (vert2 != null)
            {
                vert2Local = vert2._pos;
            }

            apMeshEdge edge      = null;
            apVertex   edgeVert1 = null;
            apVertex   edgeVert2 = null;

            //Vector2 crossPos = Vector2.zero;

            _tmpEdgeWireMultipleCrossPoints.Clear();

            for (int i = 0; i < nEdge; i++)
            {
                edge      = _mesh._edges[i];
                edgeVert1 = edge._vert1;
                edgeVert2 = edge._vert2;

                //if (vert2 != null)
                //{
                //	if ((vert1 == edgeVert1 && vert2 == edgeVert2) ||
                //		(vert1 == edgeVert2 && vert2 == edgeVert1))
                //	{
                //		//겹치면 : 같은 선분이 있네염
                //		//교차되었던거 다 무시
                //		_tmpEdgeWireMultipleCrossPoints.Clear();
                //		return;
                //	}
                //}
                //else
                //{
                //	if(vert1 == edgeVert1 || vert1 == edgeVert2)
                //	{
                //		//하나만 겹쳐도 해당 Edge와 교차되지는 않는다.
                //		//교차되었던거 다 무시
                //		_tmpEdgeWireMultipleCrossPoints.Clear();
                //		return;
                //	}
                //}

                CheckLineIntersetion(edgeVert1._pos, edgeVert2._pos, vert1Local, vert2Local);
                if (_crossPoint._isIntersetion)
                {
                    //교차되었다.
                    //단, 교차 포인트가 어느 점 근처라면 SameLine이 아닌 이상 일단 넘어간다.
                    if (_crossPoint._isAnyPointSame)
                    {
                        if (_crossPoint._isSameLine)
                        {
                            //return true;//<아예 겹친다.
                            if (Vector2.Distance(_crossPoint._pos, vert1Local) > 4.0f &&
                                Vector2.Distance(_crossPoint._pos, vert2Local) > 4.0f)
                            {
                                _tmpEdgeWireMultipleCrossPoints.Add(_crossPoint._pos);
                            }
                            //return;
                        }
                        //패스
                    }
                    else
                    {
                        //교차점이 선분 내부에 있다.
                        //만약 교차점이 어느 다른 점과 가까이 있다면 일단 무시할 수 있다.
                        if (_nextVertex != null)
                        {
                            if (Vector2.Distance(_nextVertex._pos, _crossPoint._pos) < nearBias)
                            {
                                continue;
                            }
                        }

                        //교차점이 목표한 선분 내부에 없다면 패스
                        Vector2 vec2Cross = _crossPoint._pos - vert1Local;
                        Vector2 vec2Req   = vert2Local - vert1Local;
                        if (vec2Req.sqrMagnitude > 1.0f && vec2Cross.sqrMagnitude > 1.0f)
                        {
                            float dotProduct = Vector2.Dot(vec2Req, vec2Cross);
                            //if(dotProduct < 0.0f || dotProduct > 1.0f)
                            //{
                            //	continue;//벡터 안에 있는게 아닌것 같다.
                            //}

                            float angle = Vector2.Angle(vec2Req, vec2Cross);

                            //if (dotProduct < 0.0f || angle > 5.0f)
                            //{
                            //	Debug.Log("Cross [Dot : " + dotProduct + " / Angle : " + angle + "]");
                            //}
                            if (dotProduct < 0.0f)
                            {
                                //Debug.LogError("Cross Out [Dot : " + dotProduct + "]");
                                continue;
                            }
                            if (vec2Cross.sqrMagnitude > vec2Req.sqrMagnitude)
                            {
                                //Debug.LogError("Cross Out [Length Over : " + vec2Req.magnitude + " >> " + vec2Cross.magnitude + "]");
                                continue;
                            }

                            //if(angle > 5.0f)
                            //{
                            //	//각도도 다르네요...
                            //	continue;
                            //}
                        }

                        if (Vector2.Distance(_crossPoint._pos, vert1Local) > 4.0f &&
                            Vector2.Distance(_crossPoint._pos, vert2Local) > 4.0f)
                        {
                            _tmpEdgeWireMultipleCrossPoints.Add(_crossPoint._pos);
                        }
                        //return true;
                    }
                }
                else
                {
                    //교차되지 않았다.
                    //다음 계산
                }
            }

            //return false;
        }
Exemplo n.º 16
0
        // Functions
        //-----------------------------------------------
        public void Refresh(apMesh mesh, bool isReset)
        {
            //리셋할지 말지 체크
            if (!isReset)
            {
                if (_mesh != mesh ||
                    mesh == null ||
                    _nSelectedVert != _editor.VertController.Vertices.Count ||
                    _nTotalVert != mesh._vertexData.Count ||
                    _nTotalEdge != mesh._edges.Count ||
                    !Mathf.Approximately(_offset, _editor._meshTRSOption_MirrorOffset) ||
                    _isAddOnRuler != _editor._meshTRSOption_MirrorSnapVertOnRuler
                    )
                {
                    isReset = true;
                }
                else
                {
                    if (mesh != null)
                    {
                        if (_isMirrorX != mesh._isMirrorX)
                        {
                            isReset = true;
                        }
                        else if ((mesh._isMirrorX && !Mathf.Approximately(_mirrorPos, mesh._mirrorAxis.x)) ||
                                 (!mesh._isMirrorX && !Mathf.Approximately(_mirrorPos, mesh._mirrorAxis.y)))
                        {
                            isReset = true;
                        }
                    }
                }
            }


            if (!isReset)
            {
                //리스트를 돌면서
                //SrcVert의 위치가 미러 축의 (+, -, 0) 중 어디에 들어가는지 확인하자
                //하나라도 변경된게 있다면 Reset이다.
                CloneVertex checkClone = null;
                for (int i = 0; i < _cloneVerts.Count; i++)
                {
                    checkClone = _cloneVerts[i];
                    if (checkClone._compareToMirror != GetMirrorCompare(checkClone._srcVert._pos, true))
                    {
                        //리셋을 해야할 만큼 위치가 바뀌었다.
                        //Debug.LogError("Mirror 변경됨");
                        isReset = true;
                        break;
                    }
                }
            }

            if (isReset)
            {
                Clear();

                if (mesh == null)
                {
                    return;
                }

                if (_editor.VertController.Vertices.Count == 0)
                {
                    return;
                }

                List <apVertex>   selectVerts = _editor.VertController.Vertices;
                List <apVertex>   verts       = mesh._vertexData;
                List <apMeshEdge> edges       = mesh._edges;


                _mesh          = mesh;
                _nSelectedVert = selectVerts.Count;
                _nTotalVert    = verts.Count;
                _nTotalEdge    = edges.Count;
                _offset        = _editor._meshTRSOption_MirrorOffset;
                _isAddOnRuler  = _editor._meshTRSOption_MirrorSnapVertOnRuler;
                _isMirrorX     = mesh._isMirrorX;
                _mirrorPos     = mesh._isMirrorX ? mesh._mirrorAxis.x : mesh._mirrorAxis.y;

                apMeshEdge curEdge  = null;
                apVertex   curVert1 = null;
                apVertex   curVert2 = null;
                for (int iEdge = 0; iEdge < edges.Count; iEdge++)
                {
                    curEdge  = edges[iEdge];
                    curVert1 = curEdge._vert1;
                    curVert2 = curEdge._vert2;

                    //하나라도 등록되어 있다면 "미러가 될 Edge"로 일단 등록
                    bool isVert1InList = selectVerts.Contains(curVert1);
                    bool isVert2InList = selectVerts.Contains(curVert2);

                    if (isVert1InList || isVert2InList)
                    {
                        _srcEdges.Add(curEdge);

                        if (isVert1InList)
                        {
                            if (!_srcVerts.Contains(curVert1))
                            {
                                _srcVerts.Add(curVert1);
                            }

                            if (!_vert2Verts.ContainsKey(curVert1))
                            {
                                _vert2Verts.Add(curVert1, new List <apVertex>());
                            }
                            if (!_vert2Verts[curVert1].Contains(curVert2))
                            {
                                _vert2Verts[curVert1].Add(curVert2);                                //<Vert1 -> Vert2가 이어져 있음을 등록
                            }
                        }
                        if (isVert2InList)
                        {
                            if (!_srcVerts.Contains(curVert2))
                            {
                                _srcVerts.Add(curVert2);
                            }
                            if (!_vert2Verts.ContainsKey(curVert2))
                            {
                                _vert2Verts.Add(curVert2, new List <apVertex>());
                            }
                            if (!_vert2Verts[curVert2].Contains(curVert1))
                            {
                                _vert2Verts[curVert2].Add(curVert1);                                //<Vert2 -> Vert1가 이어져 있음을 등록
                            }
                        }

                        //Edge중에서 축에 Cross되는 경우
                        if (IsCrossAxis(curEdge._vert1._pos, curEdge._vert2._pos))
                        {
                            Vector2 crossPos = GetCrossPos(curEdge._vert1._pos, curEdge._vert2._pos);
                            _crossVerts.Add(CloneVertex.MakeCrossPoint(crossPos, curEdge)
                                            .AddLinkedSrcVert(curEdge._vert1)
                                            .AddLinkedSrcVert(curEdge._vert2));
                        }
                    }
                }

                //등록된 Vertex 리스트를 바탕으로 Clone을 만들자
                //- 옵션에 따라 바뀐다.
                //- 일단 Clone간의 연결은 생략하고, Vert -> Clone만 만들자
                //- 위치 보정이 중요
                //- Cross가 되는 Clone은 여기서 만들지 않는다.
                apVertex        srcVert     = null;
                List <apVertex> linkedVerts = null;
                apVertex        linkedVert  = null;

                for (int iVert = 0; iVert < _srcVerts.Count; iVert++)
                {
                    srcVert = _srcVerts[iVert];
                    CloneVertex newCVert = null;
                    if (IsOnAxis(srcVert._pos))
                    {
                        //Axis 위에 있다면..
                        newCVert = CloneVertex.MakePointOnAxis(srcVert);
                    }
                    else
                    {
                        //그렇지 않다면
                        Vector2 mirrorPos = GetMirrorPos(srcVert._pos);
                        newCVert = CloneVertex.MakeMirrorPoint(srcVert, mirrorPos, GetMirrorCompare(srcVert._pos, false));
                    }

                    //이어진 Vertex 들을 입력하자
                    linkedVerts = _vert2Verts[srcVert];
                    for (int iLink = 0; iLink < linkedVerts.Count; iLink++)
                    {
                        linkedVert = linkedVerts[iLink];
                        newCVert.AddLinkedSrcVert(linkedVert);
                    }
                    _cloneVerts.Add(newCVert);
                    _clone2Vert.Add(newCVert, srcVert);
                    _vert2Clone.Add(srcVert, newCVert);
                }

                //CloneVert간에 연결을 하자
                CloneVertex cloneVert       = null;
                CloneVertex linkedCloneVert = null;
                for (int iClone = 0; iClone < _cloneVerts.Count; iClone++)
                {
                    cloneVert = _cloneVerts[iClone];
                    for (int iLinkedSrc = 0; iLinkedSrc < cloneVert._linkedSrcVerts.Count; iLinkedSrc++)
                    {
                        srcVert = cloneVert._linkedSrcVerts[iLinkedSrc];
                        if (_vert2Clone.ContainsKey(srcVert))
                        {
                            linkedCloneVert = _vert2Clone[srcVert];
                            cloneVert.AddLinkedCloneVert(linkedCloneVert);
                        }
                    }
                }

                //CrossVert를 이용해서 연결 관계를 바꾸자
                CloneVertex crossVert        = null;
                CloneVertex linkedCloneVert1 = null;
                CloneVertex linkedCloneVert2 = null;
                for (int iCross = 0; iCross < _crossVerts.Count; iCross++)
                {
                    crossVert = _crossVerts[iCross];
                    curVert1  = crossVert._srcSplitEdge._vert1;
                    curVert2  = crossVert._srcSplitEdge._vert2;

                    linkedCloneVert1 = null;
                    linkedCloneVert2 = null;
                    if (_vert2Clone.ContainsKey(curVert1))
                    {
                        linkedCloneVert1 = _vert2Clone[curVert1];
                        crossVert.AddLinkedCloneVert(linkedCloneVert1);
                    }
                    if (_vert2Clone.ContainsKey(curVert2))
                    {
                        linkedCloneVert2 = _vert2Clone[curVert2];
                        crossVert.AddLinkedCloneVert(linkedCloneVert2);
                    }

                    if (linkedCloneVert1 != null)
                    {
                        linkedCloneVert1.AddLinkedCloneVert(crossVert);
                        //만약 반대쪽이 연결된 상태라면 연결을 끊는다.
                        if (linkedCloneVert2 != null)
                        {
                            linkedCloneVert1.RemoveLinkedCloneVert(linkedCloneVert2);
                        }
                    }

                    if (linkedCloneVert2 != null)
                    {
                        linkedCloneVert2.AddLinkedCloneVert(crossVert);
                        //만약 반대쪽이 연결된 상태라면 연결을 끊는다.
                        if (linkedCloneVert1 != null)
                        {
                            linkedCloneVert2.RemoveLinkedCloneVert(linkedCloneVert1);
                        }
                    }
                }

                //CloneEdge를 완성한다. >> _cloneEdges
                //빠른 중복
                CloneVertex cloneVert1 = null;
                CloneVertex cloneVert2 = null;
                Dictionary <CloneVertex, List <CloneVertex> > edgedVertPairs = new Dictionary <CloneVertex, List <CloneVertex> >();
                for (int iClone = 0; iClone < _cloneVerts.Count; iClone++)
                {
                    cloneVert = _cloneVerts[iClone];
                    for (int iLinkClone = 0; iLinkClone < cloneVert._linkedCloneVerts.Count; iLinkClone++)
                    {
                        linkedCloneVert = cloneVert._linkedCloneVerts[iLinkClone];
                        if (cloneVert._index < linkedCloneVert._index)
                        {
                            cloneVert1 = cloneVert;
                            cloneVert2 = linkedCloneVert;
                        }
                        else
                        {
                            cloneVert1 = linkedCloneVert;
                            cloneVert2 = cloneVert;
                        }

                        bool isExisted = false;
                        if (edgedVertPairs.ContainsKey(cloneVert1))
                        {
                            if (edgedVertPairs[cloneVert1].Contains(cloneVert2))
                            {
                                isExisted = true;
                            }
                            else
                            {
                                edgedVertPairs[cloneVert1].Add(cloneVert2);
                            }
                        }
                        else
                        {
                            edgedVertPairs.Add(cloneVert1, new List <CloneVertex>());
                            edgedVertPairs[cloneVert1].Add(cloneVert2);
                        }
                        if (!isExisted)
                        {
                            _cloneEdges.Add(new CloneEdge(cloneVert1, cloneVert2));
                        }
                    }
                }
            }
            else
            {
                //위치만 갱신하자
                CloneVertex curCloneVert = null;
                for (int iClone = 0; iClone < _cloneVerts.Count; iClone++)
                {
                    curCloneVert = _cloneVerts[iClone];
                    if (!curCloneVert._isOnAxis)
                    {
                        curCloneVert._pos = GetMirrorPos(curCloneVert._srcVert._pos);
                    }
                    else
                    {
                        curCloneVert._pos = curCloneVert._srcVert._pos;
                    }
                }

                for (int iClone = 0; iClone < _crossVerts.Count; iClone++)
                {
                    curCloneVert = _crossVerts[iClone];
                    if (curCloneVert._linkedSrcVerts.Count < 2)
                    {
                        continue;
                    }

                    Vector2 crossPos = GetCrossPos(curCloneVert._linkedSrcVerts[0]._pos,
                                                   curCloneVert._linkedSrcVerts[1]._pos);
                    curCloneVert._pos = crossPos;
                }
            }
        }
Exemplo n.º 17
0
 public bool IsEdgeContain(apMeshEdge edge)
 {
     return(_edges.Contains(edge));
 }
Exemplo n.º 18
0
        public void Link(apMesh mesh)
        {
            //Mesh에 속한 Vert와 Edge는 초기화 후 ID와 연결해준다.
            //그 외에는 내부 Link를 호출한다.
            _verts.Clear();
            _edges.Clear();

            for (int i = 0; i < _vertIDs.Count; i++)
            {
                apVertex vert = mesh.GetVertexByUniqueID(_vertIDs[i]);
                if (vert != null)
                {
                    _verts.Add(vert);
                }
                else
                {
                    //?? 없는 Vert다.
                    _vertIDs[i] = -1;
                }
            }
            _vertIDs.RemoveAll(delegate(int a)
            {
                return(a < 0);
            });

            for (int i = 0; i < _edgeIDs.Count; i++)
            {
                apMeshEdge edge = mesh.GetEdgeByUniqueID(_edgeIDs[i]._ID1, _edgeIDs[i]._ID2);
                if (edge != null)
                {
                    _edges.Add(edge);
                }
                else
                {
                    _edgeIDs[i]._ID1 = -1;
                    _edgeIDs[i]._ID2 = -1;
                }
            }
            _edgeIDs.RemoveAll(delegate(IDPair a)
            {
                return(a._ID1 < 0 || a._ID2 < 0);
            });

            //나머지도 링크를 하자
            for (int i = 0; i < _hidddenEdges.Count; i++)
            {
                apMeshEdge hiddenEdge = _hidddenEdges[i];
                apVertex   vert1      = mesh.GetVertexByUniqueID(hiddenEdge._vertID_1);
                apVertex   vert2      = mesh.GetVertexByUniqueID(hiddenEdge._vertID_2);
                hiddenEdge.Link(vert1, vert2);
            }
            _hidddenEdges.RemoveAll(delegate(apMeshEdge a)
            {
                return(a._vert1 == null || a._vert2 == null);
            });

            for (int i = 0; i < _tris.Count; i++)
            {
                apMeshTri tri   = _tris[i];
                apVertex  vert1 = mesh.GetVertexByUniqueID(tri._vertIDs[0]);
                apVertex  vert2 = mesh.GetVertexByUniqueID(tri._vertIDs[1]);
                apVertex  vert3 = mesh.GetVertexByUniqueID(tri._vertIDs[2]);
                tri.Link(vert1, vert2, vert3);
            }
            _tris.RemoveAll(delegate(apMeshTri a)
            {
                return(a._verts[0] == null || a._verts[1] == null || a._verts[2] == null);
            });
        }
Exemplo n.º 19
0
 public static bool IsEdgeCross(apMeshEdge edge1, apMeshEdge edge2)
 {
     return(IsEdgeCross(edge1._vert1, edge1._vert2, edge2._vert1, edge2._vert2));
 }
Exemplo n.º 20
0
        public bool TurnHiddenEdge(apMeshEdge hiddenEdge)
        {
            if (!_hidddenEdges.Contains(hiddenEdge))
            {
                Debug.LogError("Not Contains Hidden Edge");
                return(false);
            }

            //List<apMeshEdge> allEdges = new List<apMeshEdge>();
            //for (int i = 0; i < _edges.Count; i++)
            //{
            //	allEdges.Add(_edges[i]);
            //}

            //for (int i = 0; i < _hidddenEdges.Count; i++)
            //{
            //	allEdges.Add(_hidddenEdges[i]);
            //}

            List <apMeshTri> containTris = _tris.FindAll(delegate(apMeshTri a)
            {
                return(a.IsIncludeEdge(hiddenEdge));
            });

            if (containTris.Count != 2)
            {
                //회전이 불가능하다
                Debug.LogError("Tri Count is Not 2 : " + containTris.Count);
                return(false);
            }

            apVertex[] newVerts = new apVertex[2];

            for (int i = 0; i < 2; i++)
            {
                apMeshTri curTri = containTris[i];

                if (curTri._verts[0] != hiddenEdge._vert1 && curTri._verts[0] != hiddenEdge._vert2)
                {
                    newVerts[i] = curTri._verts[0];
                }
                else if (curTri._verts[1] != hiddenEdge._vert1 && curTri._verts[1] != hiddenEdge._vert2)
                {
                    newVerts[i] = curTri._verts[1];
                }
                else if (curTri._verts[2] != hiddenEdge._vert1 && curTri._verts[2] != hiddenEdge._vert2)
                {
                    newVerts[i] = curTri._verts[2];
                }
                else
                {
                    newVerts[i] = null;
                }
            }


            if (newVerts[0] != null && newVerts[1] != null && newVerts[0] != newVerts[1])
            {
                //새로운 엣지를 넣고
                apMeshEdge newHidden = new apMeshEdge(newVerts[0], newVerts[1]);
                newHidden._isHidden = true;
                _hidddenEdges.Add(newHidden);

                //Debug.LogWarning("Vertex Turn ["
                //	+ hiddenEdge._vert1._index + ", " + hiddenEdge._vert2._index + "] -> ["
                //	+ newHidden._vert1._index + ", " + newHidden._vert2._index + "]");

                //현재 엣지를 지우자
                _hidddenEdges.Remove(hiddenEdge);

                MakeTriangles();
            }
            else
            {
                Debug.LogError("Vertex is Error");
            }


            return(true);
        }
Exemplo n.º 21
0
        public void MakeHiddenEdgeAndTri()
        {
            int nVert           = _verts.Count;
            int nNeedHiddenEdge = nVert - 3;
            int nNeedTri        = nVert - 2;

            if (_hidddenEdges.Count == nNeedHiddenEdge && _tris.Count == nNeedTri)
            {
                return;
            }

            _hidddenEdges.Clear();


            //Debug.Log("Verts : " + nVert + " / Hidden : " + nNeedHiddenEdge + " / Tri : " + nNeedTri);
            List <AutoHiddenEdgeData> hiddenData = new List <AutoHiddenEdgeData>();

            if (nNeedHiddenEdge > 0)
            {
                //Debug.Log("히든 엣지 필요 개수 : " + nNeedHiddenEdge);
                for (int iBaseVert = 0; iBaseVert < nVert; iBaseVert++)
                {
                    apVertex baseVert = _verts[iBaseVert];

                    //직접 연결되지 않은 Edge를 찾자
                    for (int iNext = 0; iNext < nVert; iNext++)
                    {
                        apVertex nextVert = _verts[iNext];
                        if (nextVert == baseVert)
                        {
                            continue;
                        }

                        //Edge가 있는가
                        bool isExistEdge = _edges.Exists(delegate(apMeshEdge a)
                        {
                            return(a.IsSameEdge(baseVert, nextVert));
                        });

                        if (isExistEdge)
                        {
                            continue;
                        }

                        if (hiddenData.Exists(delegate(AutoHiddenEdgeData a)
                        {
                            return((a._vert1 == baseVert && a._vert2 == nextVert) ||
                                   (a._vert2 == baseVert && a._vert1 == nextVert));
                        }))
                        {
                            continue;
                        }

                        //없다 -> HiddenEdge 대상이다.
                        //다른 HiddenEdge와 겹치지 않는지 체크한다.
                        bool isAnyCross = false;
                        for (int iHide = 0; iHide < _hidddenEdges.Count; iHide++)
                        {
                            apMeshEdge hiddenEdge = _hidddenEdges[iHide];

                            if (hiddenEdge.IsSameEdge(baseVert, nextVert))
                            {
                                isAnyCross = true;
                                break;
                            }
                            if (apMeshEdge.IsEdgeCross(hiddenEdge._vert1, hiddenEdge._vert2, baseVert, nextVert))
                            {
                                isAnyCross = true;
                                break;
                            }
                        }

                        if (!isAnyCross)
                        {
                            //교차되는 Hidden Edge가 없다.
                            //Hidden Edge를 만들쟈!
                            //수정 => 일단 Hidden Edge "대상"에 넣자

                            AutoHiddenEdgeData newHiddenData = new AutoHiddenEdgeData(baseVert, nextVert);

                            //다른 Edge와 비교하여 Angle을 넣어주자
                            for (int iEdge = 0; iEdge < _edges.Count; iEdge++)
                            {
                                apMeshEdge edge  = _edges[iEdge];
                                float      angle = Vector2.Angle(edge._vert2._pos - edge._vert1._pos, nextVert._pos - baseVert._pos);
                                if (angle > 90.0f)
                                {
                                    angle = 180.0f - angle;
                                }
                                newHiddenData.SetEdgeAngle(angle);
                            }

                            hiddenData.Add(newHiddenData);

                            //Debug.Log("Make Hidden Edge");
                        }
                    }
                }

                hiddenData.Sort(delegate(AutoHiddenEdgeData a, AutoHiddenEdgeData b)
                {
                    return(b.Score - a.Score);
                });

                for (int iData = 0; iData < hiddenData.Count; iData++)
                {
                    AutoHiddenEdgeData data = hiddenData[iData];

                    //다른 HiddenEdge와 겹치지 않는지 체크한다.
                    bool isAnyCross = false;
                    for (int iHide = 0; iHide < _hidddenEdges.Count; iHide++)
                    {
                        apMeshEdge hiddenEdge = _hidddenEdges[iHide];

                        if (hiddenEdge.IsSameEdge(data._vert1, data._vert2))
                        {
                            isAnyCross = true;
                            break;
                        }

                        if (apMeshEdge.IsEdgeCross(hiddenEdge._vert1, hiddenEdge._vert2, data._vert1, data._vert2))
                        {
                            isAnyCross = true;
                            break;
                        }
                    }
                    if (isAnyCross)
                    {
                        continue;
                    }

                    apMeshEdge newHiddenEdge = new apMeshEdge(data._vert1, data._vert2);
                    newHiddenEdge._isHidden = true;

                    _hidddenEdges.Add(newHiddenEdge);
                    if (_hidddenEdges.Count >= nNeedHiddenEdge)
                    {
                        break;
                    }
                }

                if (_hidddenEdges.Count < nNeedHiddenEdge)
                {
                    //오잉? 다 입력되지 않았네요. 그냥 한번 넣어봅시다.
                    for (int iBaseVert = 0; iBaseVert < nVert; iBaseVert++)
                    {
                        apVertex baseVert = _verts[iBaseVert];

                        //직접 연결되지 않은 Edge를 찾자
                        for (int iNext = 0; iNext < nVert; iNext++)
                        {
                            apVertex nextVert = _verts[iNext];
                            if (nextVert == baseVert)
                            {
                                continue;
                            }

                            //Edge가 있는가
                            bool isExistEdge = _edges.Exists(delegate(apMeshEdge a)
                            {
                                return(a.IsSameEdge(baseVert, nextVert));
                            });

                            if (isExistEdge)
                            {
                                continue;
                            }

                            //없다 -> HiddenEdge 대상이다.
                            //다른 HiddenEdge와 겹치지 않는지 체크한다.
                            bool isAnyCross = false;
                            for (int iHide = 0; iHide < _hidddenEdges.Count; iHide++)
                            {
                                apMeshEdge hiddenEdge = _hidddenEdges[iHide];

                                if (hiddenEdge.IsSameEdge(baseVert, nextVert))
                                {
                                    isAnyCross = true;
                                    break;
                                }

                                if (apMeshEdge.IsEdgeCross(hiddenEdge._vert1, hiddenEdge._vert2, baseVert, nextVert))
                                {
                                    isAnyCross = true;
                                    break;
                                }
                            }

                            if (isAnyCross)
                            {
                                continue;
                            }

                            apMeshEdge newHiddenEdge = new apMeshEdge(baseVert, nextVert);
                            newHiddenEdge._isHidden = true;

                            _hidddenEdges.Add(newHiddenEdge);
                            if (_hidddenEdges.Count >= nNeedHiddenEdge)
                            {
                                break;
                            }
                        }
                    }
                }



                //Debug.LogWarning("만들어진 히든 엣지 : " + _hidddenEdges.Count);
            }


            //Hidden Edge까지 추가했다면..
            //이제 내부에 Tri를 만들어주자
            //이건 겹치는건 체크하지 않는다.
            //Hidden을 제외하고는
            //1Edge -> 1Tri이며,
            //이미 Tri에 포함된 Edge는 제외한다.
            _tris.Clear();
            if (nNeedTri > 0)
            {
                MakeTriangles();
            }
        }
Exemplo n.º 22
0
        public static CrossCheckResult IsEdgeCrossWithResult(apMeshEdge edge, Vector2 edge2A, Vector2 edge2B)
        {
            CrossCheckResult.I.Init();

            Vector2 edge1A = edge._vert1._pos;
            Vector2 edge1B = edge._vert2._pos;

            //만약 어떤 점이 겹친 상태라면 일단 겹친 점에 대한 정보를 넣어준다.
            if (Vector2.Distance(edge1A, edge2A) < zeroBias || Vector2.Distance(edge1A, edge2B) < zeroBias)
            {
                //Vert1 에 겹친다.
                CrossCheckResult.I.SetSameVertexResult(edge._vert1);
                return(CrossCheckResult.I);
            }
            else if (Vector2.Distance(edge1B, edge2A) < zeroBias || Vector2.Distance(edge1B, edge2B) < zeroBias)
            {
                //Vert2 에 겹친다.
                CrossCheckResult.I.SetSameVertexResult(edge._vert2);
                return(CrossCheckResult.I);
            }



            float dX_1 = edge1B.x - edge1A.x;
            float dY_1 = edge1B.y - edge1A.y;
            float dX_2 = edge2B.x - edge2A.x;
            float dY_2 = edge2B.y - edge2A.y;

            float a1 = 0.0f;
            float a2 = 0.0f;
            float b1 = 0.0f;
            float b2 = 0.0f;

            float x1_Min = Mathf.Min(edge1A.x, edge1B.x);
            float x1_Max = Mathf.Max(edge1A.x, edge1B.x);
            float y1_Min = Mathf.Min(edge1A.y, edge1B.y);
            float y1_Max = Mathf.Max(edge1A.y, edge1B.y);

            float x2_Min = Mathf.Min(edge2A.x, edge2B.x);
            float x2_Max = Mathf.Max(edge2A.x, edge2B.x);
            float y2_Min = Mathf.Min(edge2A.y, edge2B.y);
            float y2_Max = Mathf.Max(edge2A.y, edge2B.y);

            //수직/수평에 따라 다르게 처리
            if (Mathf.Abs(dX_1) < zeroBias * 0.01f)
            {
                float X1 = (edge1A.x + edge1B.x) * 0.5f;

                //Line 1이 수직일 때
                if (Mathf.Abs(dX_2) < zeroBias * 0.01f)
                {
                    //Line 2도 같이 수직일 때
                    //수직 + 수직
                    //x가 같으면 [겹침] (y범위 비교)
                    //그 외에는 [평행]

                    float X2 = (edge2A.x + edge2B.x) * 0.5f;

                    if (Mathf.Abs(X1 - X2) < zeroBias * 0.01f)
                    {
                        //Y 영역이 겹치는가 [Y영역이 겹치면 겹침]
                        if (IsAreaIntersection(y1_Min, y1_Max, y2_Min, y2_Max))
                        {
                            CrossCheckResult.I.SetSameLine((edge1A + edge1B) * 0.5f);
                            return(CrossCheckResult.I);
                        }
                    }
                }
                else
                {
                    //Line 2는 수평이나 기울기가 있을 때
                    //Line1의 x 범위에서 y 안에 들면 [교차]
                    //Line1의 x 범위 밖이거나 y 범위 밖에 있으면 [교차하지 않음]
                    if (x2_Min <= X1 && X1 <= x2_Max)
                    {
                        a2 = dY_2 / dX_2;
                        b2 = edge2A.y - edge2A.x * a2;

                        float Yresult = a2 * X1 + b2;
                        if (y1_Min <= Yresult && Yresult <= y1_Max)
                        {
                            //[교차]
                            CrossCheckResult.I.SetCrossResult(new Vector2(X1, Yresult));
                            return(CrossCheckResult.I);
                        }
                    }
                }
            }
            else
            {
                //Line 1이 수평 또는 기울기가 있을 때
                if (Mathf.Abs(dX_2) < zeroBias * 0.01f)
                {
                    //Line 2가 수직일 때
                    //Line2를 기준으로 x, y범위 비교후 Y 체크 [교차]
                    //범위 밖이면 [교차하지 않음]

                    float X2 = (edge2A.x + edge2B.x) * 0.5f;

                    if (x1_Min <= X2 && X2 <= x1_Max)
                    {
                        a1 = dY_1 / dX_1;
                        b1 = edge1A.y - edge1A.x * a1;

                        float Yresult = a1 * X2 + b1;
                        if (y2_Min <= Yresult && Yresult <= y2_Max)
                        {
                            //[교차]
                            CrossCheckResult.I.SetCrossResult(new Vector2(X2, Yresult));
                            return(CrossCheckResult.I);
                        }
                    }
                }
                else
                {
                    //Line 2는 수평이나 기울기가 있을 때
                    //X 범위 비교후
                    //대입법 이용하여 체크하면 [교차]

                    if (IsAreaIntersection(x1_Min, x1_Max, x2_Min, x2_Max))
                    {
                        a1 = dY_1 / dX_1;
                        b1 = edge1A.y - edge1A.x * a1;

                        a2 = dY_2 / dX_2;
                        b2 = edge2A.y - edge2A.x * a2;

                        float Yparam1 = a2 - a1;
                        float Yparam2 = (a2 * b1) - (a1 * b2);

                        if (Mathf.Abs(Yparam1) < zeroBias * 0.01f)
                        {
                            //기울기가 같을때
                            //b도 같아야한다.
                            if (Mathf.Abs(Yparam2) < zeroBias * 0.01f)
                            {
                                //[일치]
                                CrossCheckResult.I.SetSameLine((edge1A + edge1B) * 0.5f);
                                return(CrossCheckResult.I);
                            }
                        }
                        else
                        {
                            //기울기가 다를때
                            float Yresult = Yparam2 / Yparam1;

                            //교차점의 위치를 확인한다.
                            if (y1_Min <= Yresult && Yresult <= y1_Max &&
                                y2_Min <= Yresult && Yresult <= y2_Max)
                            {
                                float Xresult = (Yresult - b1) / a1;

                                CrossCheckResult.I.SetCrossResult(new Vector2(Xresult, Yresult));
                                return(CrossCheckResult.I);
                            }
                        }
                    }
                }
            }


            //return _crossPoint;
            return(null);
        }