コード例 #1
0
        private void CheckOnEdge(Cell cell, int x, int y, HandleEdge workOnEdge)
        {
            var neighbours = Neighbour.None;

            if (x == 0)
            {
                neighbours |= Neighbour.Left;
            }
            if (x == _map.NumberOfTiles)
            {
                neighbours |= Neighbour.Right;
            }
            if (y == 0)
            {
                neighbours |= Neighbour.Top;
            }
            if (y == _map.NumberOfTiles)
            {
                neighbours |= Neighbour.Bottom;
            }

            if ((neighbours & Neighbour.Left) == Neighbour.Left)
            {
                workOnEdge(cell, x, y, -1, 0);
            }
            if ((neighbours & Neighbour.Top) == Neighbour.Top)
            {
                workOnEdge(cell, x, y, 0, -1);
            }
            if ((neighbours & Neighbour.Right) == Neighbour.Right)
            {
                workOnEdge(cell, x, y, 1, 0);
            }
            if ((neighbours & Neighbour.Bottom) == Neighbour.Bottom)
            {
                workOnEdge(cell, x, y, 0, 1);
            }
            if ((neighbours & Neighbour.LeftTop) == Neighbour.LeftTop)
            {
                workOnEdge(cell, x, y, -1, -1);
            }
            if ((neighbours & Neighbour.RightTop) == Neighbour.RightTop)
            {
                workOnEdge(cell, x, y, 1, -1);
            }
            if ((neighbours & Neighbour.LeftBottom) == Neighbour.LeftBottom)
            {
                workOnEdge(cell, x, y, -1, 1);
            }
            if ((neighbours & Neighbour.RightBottom) == Neighbour.RightBottom)
            {
                workOnEdge(cell, x, y, 1, 1);
            }
        }
コード例 #2
0
        /// <summary>
        /// Establishes a connection between two vertices.
        /// 1) Creates two half-edges
        /// 2) Fills them with information
        /// 3) Creates an edge pointer container and adds it to the geo container.
        /// 4) returns a handle to an edge
        /// </summary>
        /// <param name="fromVert">HandleVertex from which vertex</param>
        /// <param name="toVert">Handlevertex to which vertex</param>
        /// <returns>Returns a handle to the half-edge that has just been inserted</returns>
        public HandleHalfEdge CreateConnection(HandleVertex fromVert, HandleVertex toVert)
        {
            // Check if the connection does already exist.
            HandleEdge existingEdge = DoesConnectionExist(fromVert, toVert);

            if (existingEdge != -1)
            {
                return(ReuseExistingConnection(existingEdge, fromVert, toVert));
            }
            else
            {
                return(CreateAllNewConnection(fromVert, toVert));
            }
        }
コード例 #3
0
        /// <summary>
        /// For testing only now.
        /// </summary>
        /// <param name="existingEdge"></param>
        /// <param name="fromVert"></param>
        /// <param name="toVert"></param>
        /// <returns></returns>
        private HandleHalfEdge ReuseExistingConnection(HandleEdge existingEdge, HandleVertex fromVert, HandleVertex toVert)
        {
            // Check half-edge 1 and 2 if one points to the actual face. This is the one we use for our face then. If no one we build a new connection.
            HEdgePtrCont hedge1 = _LhedgePtrCont[_LedgePtrCont[existingEdge]._he1];
            HEdgePtrCont hedge2 = _LhedgePtrCont[_LedgePtrCont[existingEdge]._he2];

            HandleHalfEdge hedgeToUse = new HandleHalfEdge(-1);

            if (hedge2._f == -1)
            {
                // It is hedge 2 that is free. We should use it.
                hedgeToUse = _LedgePtrCont[existingEdge]._he2;
            }
            else if (hedge1._f == -1)
            {
                // It is hedge 1 that is free. We should use it. Should never happen. TODO: Exception throw?
                hedgeToUse = _LedgePtrCont[existingEdge]._he1;
            }
            else
            {
                // Neither one of the faces of the existing half-edges was free so we build a new edge.
                return(CreateAllNewConnection(fromVert, toVert));
            }
            // Updating the face pointer.
            HEdgePtrCont hedge = _LhedgePtrCont[hedgeToUse];

            hedge._f = new HandleFace(_LfacePtrCont.Count - 1);

            _LhedgePtrCont[hedgeToUse] = new HEdgePtrCont()
            {
                _f   = hedge._f,
                _he  = hedge._he,
                _nhe = hedge._nhe,
                _v   = hedge._v,
                _vn  = hedge._vn,
                _vuv = hedge._vuv
            };

            return(hedgeToUse);
        }
コード例 #4
0
        /// <summary>
        /// This method converts a quad based 'Geometry' object to a triangle based one.
        /// </summary>
        private void TriangulateGeometry()
        {
            List <HandleFace> LtmpFaces = new List <HandleFace>();

            foreach (HandleFace currentFace in _LfaceHndl)
            {
                // Pruefe zuerst ob man das face triangulaten sollte oder nicht.
                if (EnFaceAdjacentHalfEdges(currentFace).Count() == 3)
                {
                    continue;
                }

                // Hole aktuelles face und merke den index.
                FacePtrCont currentFaceCont = _LfacePtrCont[currentFace];
                // Merke erste hedge h0.
                HandleHalfEdge h0H    = currentFaceCont._h;
                HEdgePtrCont   h0Cont = _LhedgePtrCont[h0H];
                // Merke ersten vert v0.
                HandleVertex v0H = _LhedgePtrCont[h0Cont._he]._v;
                // Merke die letzte hedge im face hl.
                //HandleHalfEdge hlH = RetLastHalfEdgeInFaceCw(currentFace);

                var temp = EnFaceAdjacentHalfEdges(currentFace);


                HandleHalfEdge hlH    = temp.ElementAt(temp.Count() - 1);
                HEdgePtrCont   hlCont = _LhedgePtrCont[hlH];
                // Lege zwei neue hedges an und fülle sie korrekt.
                int            hedgeCount = _LhedgePtrCont.Count;
                HandleHalfEdge hedge0H    = new HandleHalfEdge()
                {
                    _DataIndex = hedgeCount
                };
                HandleHalfEdge hedge1H = new HandleHalfEdge()
                {
                    _DataIndex = hedgeCount + 1
                };
                HandleEdge edgeHNew = new HandleEdge()
                {
                    _DataIndex = _LedgeHndl.Count
                };
                EdgePtrCont edgeContNew = new EdgePtrCont()
                {
                    _he1 = hedge0H, _he2 = hedge1H
                };

                HEdgePtrCont newhedge0 = new HEdgePtrCont()
                {
                    _nhe = h0H,
                    _v   = v0H,
                    _he  = hedge1H,
                    _f   = currentFace,
                    _vn  = hlCont._vn,
                    _vuv = hlCont._vuv
                };
                // Hole h1 und h2 zum Merken.
                HandleHalfEdge h1H    = h0Cont._nhe;
                HEdgePtrCont   h1Cont = _LhedgePtrCont[h1H];
                HandleHalfEdge h2H    = h1Cont._nhe;
                HEdgePtrCont   h2Cont = _LhedgePtrCont[h2H];

                HEdgePtrCont newhedge1 = new HEdgePtrCont()
                {
                    _nhe = h1Cont._nhe,
                    _v   = h1Cont._v,
                    _he  = hedge0H,
                    _f   = new HandleFace(-1),
                    _vn  = h1Cont._vn,
                    _vuv = h1Cont._vuv,
                };
                // Update die jeweiligen next pointer der angrenzenden hedges.
                h1Cont._nhe = hedge0H;
                hlCont._nhe = hedge1H;
                // Lege ein neues face an für das triangle 2.
                HandleFace f1H = new HandleFace()
                {
                    _DataIndex = (_LfaceHndl.Count - 1) + LtmpFaces.Count + 1
                };
                FacePtrCont f1Cont = new FacePtrCont()
                {
                    _fn = currentFaceCont._fn, _h = hlH
                };
                // Update das neue triangle bezüglich des neuen faces. Dazu erstmal h2 holen noch.
                newhedge1._f = f1H;
                h2Cont._f    = f1H;
                hlCont._f    = f1H;
                // Sichere die Änderungen in den listen.
                _LedgeHndl.Add(edgeHNew);
                _LedgePtrCont.Add(edgeContNew);
                _LhedgePtrCont.Add(newhedge0);
                _LhedgePtrCont.Add(newhedge1);

                // Speichere das face handle erstmal in tmp faces wegen der iteration.
                LtmpFaces.Add(f1H);
                _LfacePtrCont.Add(f1Cont);

                _LhedgePtrCont[h1H] = new HEdgePtrCont()
                {
                    _f   = h1Cont._f,
                    _he  = h1Cont._he,
                    _nhe = h1Cont._nhe,
                    _v   = h1Cont._v,
                    _vn  = h1Cont._vn,
                    _vuv = h1Cont._vuv
                };

                _LhedgePtrCont[h2H] = new HEdgePtrCont()
                {
                    _f   = h2Cont._f,
                    _he  = h2Cont._he,
                    _nhe = h2Cont._nhe,
                    _v   = h2Cont._v,
                    _vn  = h2Cont._vn,
                    _vuv = h2Cont._vuv
                };

                _LhedgePtrCont[hlH] = new HEdgePtrCont()
                {
                    _f   = hlCont._f,
                    _he  = hlCont._he,
                    _nhe = hlCont._nhe,
                    _v   = hlCont._v,
                    _vn  = hlCont._vn,
                    _vuv = hlCont._vuv
                };
            }

            foreach (HandleFace handleFace in LtmpFaces)
            {
                _LfaceHndl.Add(handleFace);
            }
            LtmpFaces.Clear();
        }
コード例 #5
0
ファイル: MapEditing.cs プロジェクト: jtabG/Alone
        private void CheckOnEdge(Cell cell, int x, int y, HandleEdge workOnEdge)
        {
            var neighbours = Neighbour.None;

            if (x == 0) neighbours |= Neighbour.Left;
            if (x == _map.NumberOfTiles) neighbours |= Neighbour.Right;
            if (y == 0) neighbours |= Neighbour.Top;
            if (y == _map.NumberOfTiles) neighbours |= Neighbour.Bottom;

            if ((neighbours & Neighbour.Left) == Neighbour.Left)
            {
                workOnEdge(cell, x, y, -1, 0);
            }
            if ((neighbours & Neighbour.Top) == Neighbour.Top)
            {
                workOnEdge(cell, x, y, 0, -1);
            }
            if ((neighbours & Neighbour.Right) == Neighbour.Right)
            {
                workOnEdge(cell, x, y, 1, 0);
            }
            if ((neighbours & Neighbour.Bottom) == Neighbour.Bottom)
            {
                workOnEdge(cell, x, y, 0, 1);
            }
            if ((neighbours & Neighbour.LeftTop) == Neighbour.LeftTop)
            {
                workOnEdge(cell, x, y, -1, -1);
            }
            if ((neighbours & Neighbour.RightTop) == Neighbour.RightTop)
            {
                workOnEdge(cell, x, y, 1, -1);
            }
            if ((neighbours & Neighbour.LeftBottom) == Neighbour.LeftBottom)
            {
                workOnEdge(cell, x, y, -1, 1);
            }
            if ((neighbours & Neighbour.RightBottom) == Neighbour.RightBottom)
            {
                workOnEdge(cell, x, y, 1, 1);
            }
        }