コード例 #1
0
        public virtual void  gluTessVertex(double[] coords, int coords_offset, System.Object vertexData)
        {
            int    i;
            bool   tooLarge = false;
            double x;

            double[] clamped = new double[3];

            requireState(TessState.T_IN_CONTOUR);

            if (flushCacheOnNextVertex)
            {
                if (!flushCache())
                {
                    callErrorOrErrorData(GLU.GLU_OUT_OF_MEMORY);
                    return;
                }
                lastEdge = null;
            }
            for (i = 0; i < 3; ++i)
            {
                x = coords[i + coords_offset];
                if (x < -GLU.GLU_TESS_MAX_COORD)
                {
                    x        = -GLU.GLU_TESS_MAX_COORD;
                    tooLarge = true;
                }
                if (x > GLU.GLU_TESS_MAX_COORD)
                {
                    x        = GLU.GLU_TESS_MAX_COORD;
                    tooLarge = true;
                }
                clamped[i] = x;
            }
            if (tooLarge)
            {
                callErrorOrErrorData(GLU.GLU_TESS_COORD_TOO_LARGE);
            }

            if (mesh == null)
            {
                if (cacheCount < TESS_MAX_CACHE)
                {
                    cacheVertex(clamped, vertexData);
                    return;
                }
                if (!flushCache())
                {
                    callErrorOrErrorData(GLU.GLU_OUT_OF_MEMORY);
                    return;
                }
            }

            if (!addVertex(clamped, vertexData))
            {
                callErrorOrErrorData(GLU.GLU_OUT_OF_MEMORY);
            }
        }
コード例 #2
0
        private void  makeDormant()
        {
            /* Return the tessellator to its original dormant state. */

            if (mesh != null)
            {
                Mesh.__gl_meshDeleteMesh(mesh);
            }
            state    = TessState.T_DORMANT;
            lastEdge = null;
            mesh     = null;
        }
コード例 #3
0
        private bool addVertex(double[] coords, System.Object vertexData)
        {
            GLUhalfEdge e;

            e = lastEdge;
            if (e == null)
            {
                /* Make a self-loop (one vertex, one edge). */

                e = Mesh.__gl_meshMakeEdge(mesh);
                if (e == null)
                {
                    return(false);
                }
                if (!Mesh.__gl_meshSplice(e, e.Sym))
                {
                    return(false);
                }
            }
            else
            {
                /* Create a new vertex and edge which immediately follow e
                 * in the ordering around the left face.
                 */
                if (Mesh.__gl_meshSplitEdge(e) == null)
                {
                    return(false);
                }
                e = e.Lnext;
            }

            /* The new vertex is now e.Org. */
            e.Org.data      = vertexData;
            e.Org.coords[0] = coords[0];
            e.Org.coords[1] = coords[1];
            e.Org.coords[2] = coords[2];

            /* The winding of an edge says how the winding number changes as we
             * cross from the edge''s right face to its left face.  We add the
             * vertices in such an order that a CCW contour will add +1 to
             * the winding number of the region inside the contour.
             */
            e.winding     = 1;
            e.Sym.winding = -1;

            lastEdge = e;

            return(true);
        }
コード例 #4
0
        public virtual void  gluTessBeginContour()
        {
            requireState(TessState.T_IN_POLYGON);

            state    = TessState.T_IN_CONTOUR;
            lastEdge = null;
            if (cacheCount > 0)
            {
                /* Just set a flag so we don't get confused by empty contours
                 * -- these can be generated accidentally with the obsolete
                 * NextContour() interface.
                 */
                flushCacheOnNextVertex = true;
            }
        }
コード例 #5
0
        private void makeDormant()
        {
            /* Return the tessellator to its original dormant state. */

            if (mesh != null)
            {
                Mesh.__gl_meshDeleteMesh(mesh);
            }
            state = TessState.T_DORMANT;
            lastEdge = null;
            mesh = null;
        }
コード例 #6
0
ファイル: TessMono.cs プロジェクト: andyhebear/mogregis3d
        /* __gl_meshTessellateMonoRegion( face ) tessellates a monotone region
         * (what else would it do??)  The region must consist of a single
         * loop of half-edges (see mesh.h) oriented CCW.  "Monotone" in this
         * case means that any vertical line intersects the interior of the
         * region in a single interval.
         *
         * Tessellation consists of adding interior edges (actually pairs of
         * half-edges), to split the region into non-overlapping triangles.
         *
         * The basic idea is explained in Preparata and Shamos (which I don''t
         * have handy right now), although their implementation is more
         * complicated than this one.  The are two edge chains, an upper chain
         * and a lower chain.  We process all vertices from both chains in order,
         * from right to left.
         *
         * The algorithm ensures that the following invariant holds after each
         * vertex is processed: the untessellated region consists of two
         * chains, where one chain (say the upper) is a single edge, and
         * the other chain is concave.  The left vertex of the single edge
         * is always to the left of all vertices in the concave chain.
         *
         * Each step consists of adding the rightmost unprocessed vertex to one
         * of the two chains, and forming a fan of triangles from the rightmost
         * of two chain endpoints.  Determining whether we can add each triangle
         * to the fan is a simple orientation test.  By making the fan as large
         * as possible, we restore the invariant (check it yourself).
         */
        internal static bool __gl_meshTessellateMonoRegion(GLUface face)
        {
            GLUhalfEdge up, lo;

            /* All edges are oriented CCW around the boundary of the region.
             * First, find the half-edge whose origin vertex is rightmost.
             * Since the sweep goes from left to right, face->anEdge should
             * be close to the edge we want.
             */
            up = face.anEdge;
            //assert(up.Lnext != up && up.Lnext.Lnext != up);

            for (; Geom.VertLeq(up.Sym.Org, up.Org); up = up.Onext.Sym)
            {
                ;
            }
            for (; Geom.VertLeq(up.Org, up.Sym.Org); up = up.Lnext)
            {
                ;
            }
            lo = up.Onext.Sym;

            while (up.Lnext != lo)
            {
                if (Geom.VertLeq(up.Sym.Org, lo.Org))
                {
                    /* up.Sym.Org is on the left.  It is safe to form triangles from lo.Org.
                     * The EdgeGoesLeft test guarantees progress even when some triangles
                     * are CW, given that the upper and lower chains are truly monotone.
                     */
                    while (lo.Lnext != up && (Geom.EdgeGoesLeft(lo.Lnext) || Geom.EdgeSign(lo.Org, lo.Sym.Org, lo.Lnext.Sym.Org) <= 0))
                    {
                        GLUhalfEdge tempHalfEdge = Mesh.__gl_meshConnect(lo.Lnext, lo);
                        if (tempHalfEdge == null)
                        {
                            return(false);
                        }
                        lo = tempHalfEdge.Sym;
                    }
                    lo = lo.Onext.Sym;
                }
                else
                {
                    /* lo.Org is on the left.  We can make CCW triangles from up.Sym.Org. */
                    while (lo.Lnext != up && (Geom.EdgeGoesRight(up.Onext.Sym) || Geom.EdgeSign(up.Sym.Org, up.Org, up.Onext.Sym.Org) >= 0))
                    {
                        GLUhalfEdge tempHalfEdge = Mesh.__gl_meshConnect(up, up.Onext.Sym);
                        if (tempHalfEdge == null)
                        {
                            return(false);
                        }
                        up = tempHalfEdge.Sym;
                    }
                    up = up.Lnext;
                }
            }

            /* Now lo.Org == up.Sym.Org == the leftmost vertex.  The remaining region
             * can be tessellated in a fan from this leftmost vertex.
             */
            //assert(lo.Lnext != up);
            while (lo.Lnext.Lnext != up)
            {
                GLUhalfEdge tempHalfEdge = Mesh.__gl_meshConnect(lo.Lnext, lo);
                if (tempHalfEdge == null)
                {
                    return(false);
                }
                lo = tempHalfEdge.Sym;
            }

            return(true);
        }
コード例 #7
0
        private bool addVertex(double[] coords, System.Object vertexData)
        {
            GLUhalfEdge e;

            e = lastEdge;
            if (e == null)
            {
                /* Make a self-loop (one vertex, one edge). */

                e = Mesh.__gl_meshMakeEdge(mesh);
                if (e == null)
                    return false;
                if (!Mesh.__gl_meshSplice(e, e.Sym))
                    return false;
            }
            else
            {
                /* Create a new vertex and edge which immediately follow e
                * in the ordering around the left face.
                */
                if (Mesh.__gl_meshSplitEdge(e) == null)
                    return false;
                e = e.Lnext;
            }

            /* The new vertex is now e.Org. */
            e.Org.data = vertexData;
            e.Org.coords[0] = coords[0];
            e.Org.coords[1] = coords[1];
            e.Org.coords[2] = coords[2];

            /* The winding of an edge says how the winding number changes as we
            * cross from the edge''s right face to its left face.  We add the
            * vertices in such an order that a CCW contour will add +1 to
            * the winding number of the region inside the contour.
            */
            e.winding = 1;
            e.Sym.winding = - 1;

            lastEdge = e;

            return true;
        }
コード例 #8
0
        public virtual void gluTessVertex(double[] coords, int coords_offset, System.Object vertexData)
        {
            int i;
            bool tooLarge = false;
            double x;
            double[] clamped = new double[3];

            requireState(TessState.T_IN_CONTOUR);

            if (flushCacheOnNextVertex)
            {
                if (!flushCache())
                {
                    callErrorOrErrorData(GLU.GLU_OUT_OF_MEMORY);
                    return ;
                }
                lastEdge = null;
            }
            for (i = 0; i < 3; ++i)
            {
                x = coords[i + coords_offset];
                if (x < - GLU.GLU_TESS_MAX_COORD)
                {
                    x = - GLU.GLU_TESS_MAX_COORD;
                    tooLarge = true;
                }
                if (x > GLU.GLU_TESS_MAX_COORD)
                {
                    x = GLU.GLU_TESS_MAX_COORD;
                    tooLarge = true;
                }
                clamped[i] = x;
            }
            if (tooLarge)
            {
                callErrorOrErrorData(GLU.GLU_TESS_COORD_TOO_LARGE);
            }

            if (mesh == null)
            {
                if (cacheCount < TESS_MAX_CACHE)
                {
                    cacheVertex(clamped, vertexData);
                    return ;
                }
                if (!flushCache())
                {
                    callErrorOrErrorData(GLU.GLU_OUT_OF_MEMORY);
                    return ;
                }
            }

            if (!addVertex(clamped, vertexData))
            {
                callErrorOrErrorData(GLU.GLU_OUT_OF_MEMORY);
            }
        }
コード例 #9
0
        public virtual void gluTessBeginContour()
        {
            requireState(TessState.T_IN_POLYGON);

            state = TessState.T_IN_CONTOUR;
            lastEdge = null;
            if (cacheCount > 0)
            {
                /* Just set a flag so we don't get confused by empty contours
                * -- these can be generated accidentally with the obsolete
                * NextContour() interface.
                */
                flushCacheOnNextVertex = true;
            }
        }
コード例 #10
0
ファイル: Geom.cs プロジェクト: agustinsantos/mogregis3d
 internal static bool EdgeGoesRight(GLUhalfEdge e)
 {
     return VertLeq(e.Org, e.Sym.Org);
 }
コード例 #11
0
ファイル: Geom.cs プロジェクト: andyhebear/mogregis3d
 internal static bool EdgeGoesRight(GLUhalfEdge e)
 {
     return(VertLeq(e.Org, e.Sym.Org));
 }