Example #1
0
            public virtual void  render(GLUtessellatorImpl tess, Mogre.Utils.GluTesselator.GLUhalfEdge e, long size)
            {
                /* Render as many CCW triangles as possible in a strip starting from
                 * edge "e".  The strip *should* contain exactly "size" triangles
                 * (otherwise we've goofed up somewhere).
                 */
                tess.callBeginOrBeginData(GL.GL_TRIANGLE_STRIP);
                tess.callVertexOrVertexData(e.Org.data);
                tess.callVertexOrVertexData(e.Sym.Org.data);

                while (!Mogre.Utils.GluTesselator.Render.Marked(e.Lface))
                {
                    e.Lface.marked = true;
                    --size;
                    e = e.Lnext.Sym;
                    tess.callVertexOrVertexData(e.Org.data);
                    if (Mogre.Utils.GluTesselator.Render.Marked(e.Lface))
                    {
                        break;
                    }

                    e.Lface.marked = true;
                    --size;
                    e = e.Onext;
                    tess.callVertexOrVertexData(e.Sym.Org.data);
                }

                //assert(size == 0);
                tess.callEndOrEndData();
            }
Example #2
0
        /// <summary>********************* Strips and Fans decomposition *****************</summary>

        /* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle
         * fans, strips, and separate triangles.  A substantial effort is made
         * to use as few rendering primitives as possible (ie. to make the fans
         * and strips as large as possible).
         *
         * The rendering output is provided as callbacks (see the api).
         */
        public static void  __gl_renderMesh(GLUtessellatorImpl tess, Mogre.Utils.GluTesselator.GLUmesh mesh)
        {
            Mogre.Utils.GluTesselator.GLUface f;

            /* Make a list of separate triangles so we can render them all at once */
            tess.lonelyTriList = null;

            for (f = mesh.fHead.next; f != mesh.fHead; f = f.next)
            {
                f.marked = false;
            }
            for (f = mesh.fHead.next; f != mesh.fHead; f = f.next)
            {
                /* We examine all faces in an arbitrary order.  Whenever we find
                 * an unprocessed face F, we output a group of faces including F
                 * whose size is maximum.
                 */
                if (f.inside && !f.marked)
                {
                    RenderMaximumFaceGroup(tess, f);
                    //assert(f.marked);
                }
            }
            if (tess.lonelyTriList != null)
            {
                RenderLonelyTriangles(tess, tess.lonelyTriList);
                tess.lonelyTriList = null;
            }
        }
Example #3
0
 public virtual void  render(GLUtessellatorImpl tess, Mogre.Utils.GluTesselator.GLUhalfEdge e, long size)
 {
     /* Just add the triangle to a triangle list, so we can render all
      * the separate triangles at once.
      */
     //assert(size == 1);
     tess.lonelyTriList = Mogre.Utils.GluTesselator.Render.AddToTrail(e.Lface, tess.lonelyTriList);
 }
Example #4
0
        internal static void  RenderMaximumFaceGroup(GLUtessellatorImpl tess, Mogre.Utils.GluTesselator.GLUface fOrig)
        {
            /* We want to find the largest triangle fan or strip of unmarked faces
             * which includes the given face fOrig.  There are 3 possible fans
             * passing through fOrig (one centered at each vertex), and 3 possible
             * strips (one for each CCW permutation of the vertices).  Our strategy
             * is to try all of these, and take the primitive which uses the most
             * triangles (a greedy approach).
             */
            Mogre.Utils.GluTesselator.GLUhalfEdge e = fOrig.anEdge;
            FaceCount max     = new FaceCount();
            FaceCount newFace = new FaceCount();

            max.size   = 1;
            max.eStart = e;
            max.render = renderTriangle;

            if (!tess.flagBoundary)
            {
                newFace = MaximumFan(e);
                if (newFace.size > max.size)
                {
                    max = newFace;
                }
                newFace = MaximumFan(e.Lnext);
                if (newFace.size > max.size)
                {
                    max = newFace;
                }
                newFace = MaximumFan(e.Onext.Sym);
                if (newFace.size > max.size)
                {
                    max = newFace;
                }

                newFace = MaximumStrip(e);
                if (newFace.size > max.size)
                {
                    max = newFace;
                }
                newFace = MaximumStrip(e.Lnext);
                if (newFace.size > max.size)
                {
                    max = newFace;
                }
                newFace = MaximumStrip(e.Onext.Sym);
                if (newFace.size > max.size)
                {
                    max = newFace;
                }
            }
            max.render.render(tess, max.eStart, max.size);
        }
Example #5
0
        // Tesselerator
        public void tessBegin(int context)
        {
            Render.Context cntxt = getContext(context);
            cntxt.vertexRenderer.BeginBlock();
            GLUtessellatorCallback callback = new MogreTessellationCallbacks(null);

            Glu = (GLUtessellatorImpl)GLUtessellatorImpl.gluNewTess();
            Glu.gluTessCallback(GLU.GLU_TESS_VERTEX, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_BEGIN, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_END, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_ERROR, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_COMBINE, callback);
            Glu.gluTessBeginPolygon(null);
        }
Example #6
0
        /// <summary>********************* Boundary contour decomposition *****************</summary>

        /* __gl_renderBoundary( tess, mesh ) takes a mesh, and outputs one
         * contour for each face marked "inside".  The rendering output is
         * provided as callbacks (see the api).
         */
        public static void  __gl_renderBoundary(GLUtessellatorImpl tess, Mogre.Utils.GluTesselator.GLUmesh mesh)
        {
            Mogre.Utils.GluTesselator.GLUface     f;
            Mogre.Utils.GluTesselator.GLUhalfEdge e;

            for (f = mesh.fHead.next; f != mesh.fHead; f = f.next)
            {
                if (f.inside)
                {
                    tess.callBeginOrBeginData(GL.GL_LINE_LOOP);
                    e = f.anEdge;
                    do
                    {
                        tess.callVertexOrVertexData(e.Org.data);
                        e = e.Lnext;
                    }while (e != f.anEdge);
                    tess.callEndOrEndData();
                }
            }
        }
Example #7
0
        private void Tesselate(double[][] data)
        {
            MogreTessellationCallbacks callback = new MogreTessellationCallbacks(polygon);

            GLUtessellatorImpl Glu = (GLUtessellatorImpl)GLUtessellatorImpl.gluNewTess();

            Glu.gluTessCallback(GLU.GLU_TESS_VERTEX, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_BEGIN, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_END, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_ERROR, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_COMBINE, callback);
            Glu.gluTessBeginPolygon(null);
            Glu.gluTessBeginContour();
            for (int i = 0; i < data.GetLength(0); i++)
            {
                Glu.gluTessVertex(data[i], 0, new Vector3((float)data[i][0], (float)data[i][1], (float)data[i][2]));
            }
            Glu.gluTessEndContour();
            Glu.gluTessNormal(0, 0, 1);
            Glu.gluTessEndPolygon();
        }
Example #8
0
        private void TesselateComplex(double[][] data, Area[] holes)
        {
            MogreTessellationCallbacks callback = new MogreTessellationCallbacks(polygon);

            GLUtessellatorImpl Glu = (GLUtessellatorImpl)GLUtessellatorImpl.gluNewTess();

            Glu.gluTessCallback(GLU.GLU_TESS_VERTEX, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_BEGIN, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_END, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_ERROR, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_COMBINE, callback);
            Glu.gluTessBeginPolygon(null);
            for (int area = 0; area < holes.Length; area++)
            {
                Glu.gluTessBeginContour();
                for (int i = holes[area].first; i <= holes[area].last; i++)
                {
                    Glu.gluTessVertex(data[i], 0, new Vector3((float)data[i][0], (float)data[i][1], (float)data[i][2]));
                }
                Glu.gluTessEndContour();
            }
            Glu.gluTessEndPolygon();
        }
Example #9
0
        private void Tesselate(ICoordinateSequence coords)
        {
            MogreTessellationCallbacks callback = new MogreTessellationCallbacks(lineNode);

            GLUtessellatorImpl Glu = (GLUtessellatorImpl)GLUtessellatorImpl.gluNewTess();

            Glu.gluTessCallback(GLU.GLU_TESS_VERTEX, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_BEGIN, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_END, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_ERROR, callback);
            Glu.gluTessCallback(GLU.GLU_TESS_COMBINE, callback);
            Glu.gluTessBeginPolygon(null);
            Glu.gluTessBeginContour();
            foreach (Coord coord in coords)
            {
                double[] data = new double[] { coord.X, coord.Y, (double.IsNaN(coord.Z) ? 0 : coord.Z) };

                Glu.gluTessVertex(data, 0, new Vector3((float)data[0], (float)data[1], (float)data[2]));
            }
            Glu.gluTessEndContour();
            Glu.gluTessNormal(0, 0, 1);
            Glu.gluTessEndPolygon();
        }
Example #10
0
        internal static void  RenderLonelyTriangles(GLUtessellatorImpl tess, Mogre.Utils.GluTesselator.GLUface f)
        {
            /* Now we render all the separate triangles which could not be
             * grouped into a triangle fan or strip.
             */
            Mogre.Utils.GluTesselator.GLUhalfEdge e;
            int newState;
            int edgeState = -1;              /* force edge state output for first vertex */

            tess.callBeginOrBeginData(GL.GL_TRIANGLES);

            for (; f != null; f = f.trail)
            {
                /* Loop once for each edge (there will always be 3 edges) */

                e = f.anEdge;
                do
                {
                    if (tess.flagBoundary)
                    {
                        /* Set the "edge state" to true just before we output the
                         * first vertex of each edge on the polygon boundary.
                         */
                        newState = (!e.Sym.Lface.inside)?1:0;
                        if (edgeState != newState)
                        {
                            edgeState = newState;
                            tess.callEdgeFlagOrEdgeFlagData(edgeState != 0);
                        }
                    }
                    tess.callVertexOrVertexData(e.Org.data);

                    e = e.Lnext;
                }while (e != f.anEdge);
            }
            tess.callEndOrEndData();
        }
Example #11
0
        /* __gl_renderCache( tess ) takes a single contour and tries to render it
        * as a triangle fan.  This handles convex polygons, as well as some
        * non-convex polygons if we get lucky.
        *
        * Returns true if the polygon was successfully rendered.  The rendering
        * output is provided as callbacks (see the api).
        */
        public static bool __gl_renderCache(GLUtessellatorImpl tess)
        {
            Mogre.Utils.GluTesselator.CachedVertex[] v = tess.cache;
            //            CachedVertex vn = v0 + tess.cacheCount;
            int vn = tess.cacheCount;
            //            CachedVertex vc;
            int vc;
            double[] norm = new double[3];
            int sign;

            if (tess.cacheCount < 3)
            {
                /* Degenerate contour -- no output */
                return true;
            }

            norm[0] = tess.normal[0];
            norm[1] = tess.normal[1];
            norm[2] = tess.normal[2];
            if (norm[0] == 0 && norm[1] == 0 && norm[2] == 0)
            {
                ComputeNormal(tess, norm, false);
            }

            sign = ComputeNormal(tess, norm, true);
            if (sign == SIGN_INCONSISTENT)
            {
                /* Fan triangles did not have a consistent orientation */
                return false;
            }
            if (sign == 0)
            {
                /* All triangles were degenerate */
                return true;
            }

            if (!USE_OPTIMIZED_CODE_PATH)
            {
                return false;
            }
            else
            {
                /* Make sure we do the right thing for each winding rule */
                switch (tess.windingRule)
                {

                    case GLU.GLU_TESS_WINDING_ODD:
                    case GLU.GLU_TESS_WINDING_NONZERO:
                        break;

                    case GLU.GLU_TESS_WINDING_POSITIVE:
                        if (sign < 0)
                            return true;
                        break;

                    case GLU.GLU_TESS_WINDING_NEGATIVE:
                        if (sign > 0)
                            return true;
                        break;

                    case GLU.GLU_TESS_WINDING_ABS_GEQ_TWO:
                        return true;
                    }

                tess.callBeginOrBeginData(tess.boundaryOnly?GL.GL_LINE_LOOP:((tess.cacheCount > 3)?GL.GL_TRIANGLE_FAN:GL.GL_TRIANGLES));

                tess.callVertexOrVertexData(v[0].data);
                if (sign > 0)
                {
                    for (vc = 1; vc < vn; ++vc)
                    {
                        tess.callVertexOrVertexData(v[vc].data);
                    }
                }
                else
                {
                    for (vc = vn - 1; vc > 0; --vc)
                    {
                        tess.callVertexOrVertexData(v[vc].data);
                    }
                }
                tess.callEndOrEndData();
                return true;
            }
        }
Example #12
0
        /// <summary>********************* Boundary contour decomposition *****************</summary>
        /* __gl_renderBoundary( tess, mesh ) takes a mesh, and outputs one
        * contour for each face marked "inside".  The rendering output is
        * provided as callbacks (see the api).
        */
        public static void __gl_renderBoundary(GLUtessellatorImpl tess, Mogre.Utils.GluTesselator.GLUmesh mesh)
        {
            Mogre.Utils.GluTesselator.GLUface f;
            Mogre.Utils.GluTesselator.GLUhalfEdge e;

            for (f = mesh.fHead.next; f != mesh.fHead; f = f.next)
            {
                if (f.inside)
                {
                    tess.callBeginOrBeginData(GL.GL_LINE_LOOP);
                    e = f.anEdge;
                    do
                    {
                        tess.callVertexOrVertexData(e.Org.data);
                        e = e.Lnext;
                    }
                    while (e != f.anEdge);
                    tess.callEndOrEndData();
                }
            }
        }
Example #13
0
 public virtual void render(GLUtessellatorImpl tess, Mogre.Utils.GluTesselator.GLUhalfEdge e, long size)
 {
     /* Just add the triangle to a triangle list, so we can render all
     * the separate triangles at once.
     */
     //assert(size == 1);
     tess.lonelyTriList = Mogre.Utils.GluTesselator.Render.AddToTrail(e.Lface, tess.lonelyTriList);
 }
Example #14
0
            public virtual void render(GLUtessellatorImpl tess, Mogre.Utils.GluTesselator.GLUhalfEdge e, long size)
            {
                /* Render as many CCW triangles as possible in a strip starting from
                * edge "e".  The strip *should* contain exactly "size" triangles
                * (otherwise we've goofed up somewhere).
                */
                tess.callBeginOrBeginData(GL.GL_TRIANGLE_STRIP);
                tess.callVertexOrVertexData(e.Org.data);
                tess.callVertexOrVertexData(e.Sym.Org.data);

                while (!Mogre.Utils.GluTesselator.Render.Marked(e.Lface))
                {
                    e.Lface.marked = true;
                    --size;
                    e = e.Lnext.Sym;
                    tess.callVertexOrVertexData(e.Org.data);
                    if (Mogre.Utils.GluTesselator.Render.Marked(e.Lface))
                        break;

                    e.Lface.marked = true;
                    --size;
                    e = e.Onext;
                    tess.callVertexOrVertexData(e.Sym.Org.data);
                }

                //assert(size == 0);
                tess.callEndOrEndData();
            }
Example #15
0
        internal static void RenderMaximumFaceGroup(GLUtessellatorImpl tess, Mogre.Utils.GluTesselator.GLUface fOrig)
        {
            /* We want to find the largest triangle fan or strip of unmarked faces
            * which includes the given face fOrig.  There are 3 possible fans
            * passing through fOrig (one centered at each vertex), and 3 possible
            * strips (one for each CCW permutation of the vertices).  Our strategy
            * is to try all of these, and take the primitive which uses the most
            * triangles (a greedy approach).
            */
            Mogre.Utils.GluTesselator.GLUhalfEdge e = fOrig.anEdge;
            FaceCount max = new FaceCount();
            FaceCount newFace = new FaceCount();

            max.size = 1;
            max.eStart = e;
            max.render = renderTriangle;

            if (!tess.flagBoundary)
            {
                newFace = MaximumFan(e);
                if (newFace.size > max.size)
                {
                    max = newFace;
                }
                newFace = MaximumFan(e.Lnext);
                if (newFace.size > max.size)
                {
                    max = newFace;
                }
                newFace = MaximumFan(e.Onext.Sym);
                if (newFace.size > max.size)
                {
                    max = newFace;
                }

                newFace = MaximumStrip(e);
                if (newFace.size > max.size)
                {
                    max = newFace;
                }
                newFace = MaximumStrip(e.Lnext);
                if (newFace.size > max.size)
                {
                    max = newFace;
                }
                newFace = MaximumStrip(e.Onext.Sym);
                if (newFace.size > max.size)
                {
                    max = newFace;
                }
            }
            max.render.render(tess, max.eStart, max.size);
        }
Example #16
0
        internal static void RenderLonelyTriangles(GLUtessellatorImpl tess, Mogre.Utils.GluTesselator.GLUface f)
        {
            /* Now we render all the separate triangles which could not be
            * grouped into a triangle fan or strip.
            */
            Mogre.Utils.GluTesselator.GLUhalfEdge e;
            int newState;
            int edgeState = - 1; /* force edge state output for first vertex */

            tess.callBeginOrBeginData(GL.GL_TRIANGLES);

            for (; f != null; f = f.trail)
            {
                /* Loop once for each edge (there will always be 3 edges) */

                e = f.anEdge;
                do
                {
                    if (tess.flagBoundary)
                    {
                        /* Set the "edge state" to true just before we output the
                        * first vertex of each edge on the polygon boundary.
                        */
                        newState = (!e.Sym.Lface.inside)?1:0;
                        if (edgeState != newState)
                        {
                            edgeState = newState;
                            tess.callEdgeFlagOrEdgeFlagData(edgeState != 0);
                        }
                    }
                    tess.callVertexOrVertexData(e.Org.data);

                    e = e.Lnext;
                }
                while (e != f.anEdge);
            }
            tess.callEndOrEndData();
        }
Example #17
0
        /*
        * If check==false, we compute the polygon normal and place it in norm[].
        * If check==true, we check that each triangle in the fan from v0 has a
        * consistent orientation with respect to norm[].  If triangles are
        * consistently oriented CCW, return 1; if CW, return -1; if all triangles
        * are degenerate return 0; otherwise (no consistent orientation) return
        * SIGN_INCONSISTENT.
        */
        internal static int ComputeNormal(GLUtessellatorImpl tess, double[] norm, bool check)
        {
            Mogre.Utils.GluTesselator.CachedVertex[] v = tess.cache;
            //            CachedVertex vn = v0 + tess.cacheCount;
            int vn = tess.cacheCount;
            //            CachedVertex vc;
            int vc;
            double dot, xc, yc, zc, xp, yp, zp;
            double[] n = new double[3];
            int sign = 0;

            /* Find the polygon normal.  It is important to get a reasonable
            * normal even when the polygon is self-intersecting (eg. a bowtie).
            * Otherwise, the computed normal could be very tiny, but perpendicular
            * to the true plane of the polygon due to numerical noise.  Then all
            * the triangles would appear to be degenerate and we would incorrectly
            * decompose the polygon as a fan (or simply not render it at all).
            *
            * We use a sum-of-triangles normal algorithm rather than the more
            * efficient sum-of-trapezoids method (used in CheckOrientation()
            * in normal.c).  This lets us explicitly reverse the signed area
            * of some triangles to get a reasonable normal in the self-intersecting
            * case.
            */
            if (!check)
            {
                norm[0] = norm[1] = norm[2] = 0.0;
            }

            vc = 1;
            xc = v[vc].coords[0] - v[0].coords[0];
            yc = v[vc].coords[1] - v[0].coords[1];
            zc = v[vc].coords[2] - v[0].coords[2];
            while (++vc < vn)
            {
                xp = xc;
                yp = yc;
                zp = zc;
                xc = v[vc].coords[0] - v[0].coords[0];
                yc = v[vc].coords[1] - v[0].coords[1];
                zc = v[vc].coords[2] - v[0].coords[2];

                /* Compute (vp - v0) cross (vc - v0) */
                n[0] = yp * zc - zp * yc;
                n[1] = zp * xc - xp * zc;
                n[2] = xp * yc - yp * xc;

                dot = n[0] * norm[0] + n[1] * norm[1] + n[2] * norm[2];
                if (!check)
                {
                    /* Reverse the contribution of back-facing triangles to get
                    * a reasonable normal for self-intersecting polygons (see above)
                    */
                    if (dot >= 0)
                    {
                        norm[0] += n[0];
                        norm[1] += n[1];
                        norm[2] += n[2];
                    }
                    else
                    {
                        norm[0] -= n[0];
                        norm[1] -= n[1];
                        norm[2] -= n[2];
                    }
                }
                else if (dot != 0)
                {
                    /* Check the new orientation for consistency with previous triangles */
                    if (dot > 0)
                    {
                        if (sign < 0)
                            return SIGN_INCONSISTENT;
                        sign = 1;
                    }
                    else
                    {
                        if (sign > 0)
                            return SIGN_INCONSISTENT;
                        sign = - 1;
                    }
                }
            }
            return sign;
        }
Example #18
0
        internal static int ComputeNormal(GLUtessellatorImpl tess, double[] norm, bool check)

        /*
         * If check==false, we compute the polygon normal and place it in norm[].
         * If check==true, we check that each triangle in the fan from v0 has a
         * consistent orientation with respect to norm[].  If triangles are
         * consistently oriented CCW, return 1; if CW, return -1; if all triangles
         * are degenerate return 0; otherwise (no consistent orientation) return
         * SIGN_INCONSISTENT.
         */
        {
            Mogre.Utils.GluTesselator.CachedVertex[] v = tess.cache;
            //            CachedVertex vn = v0 + tess.cacheCount;
            int vn = tess.cacheCount;
            //            CachedVertex vc;
            int    vc;
            double dot, xc, yc, zc, xp, yp, zp;

            double[] n    = new double[3];
            int      sign = 0;

            /* Find the polygon normal.  It is important to get a reasonable
             * normal even when the polygon is self-intersecting (eg. a bowtie).
             * Otherwise, the computed normal could be very tiny, but perpendicular
             * to the true plane of the polygon due to numerical noise.  Then all
             * the triangles would appear to be degenerate and we would incorrectly
             * decompose the polygon as a fan (or simply not render it at all).
             *
             * We use a sum-of-triangles normal algorithm rather than the more
             * efficient sum-of-trapezoids method (used in CheckOrientation()
             * in normal.c).  This lets us explicitly reverse the signed area
             * of some triangles to get a reasonable normal in the self-intersecting
             * case.
             */
            if (!check)
            {
                norm[0] = norm[1] = norm[2] = 0.0;
            }

            vc = 1;
            xc = v[vc].coords[0] - v[0].coords[0];
            yc = v[vc].coords[1] - v[0].coords[1];
            zc = v[vc].coords[2] - v[0].coords[2];
            while (++vc < vn)
            {
                xp = xc;
                yp = yc;
                zp = zc;
                xc = v[vc].coords[0] - v[0].coords[0];
                yc = v[vc].coords[1] - v[0].coords[1];
                zc = v[vc].coords[2] - v[0].coords[2];

                /* Compute (vp - v0) cross (vc - v0) */
                n[0] = yp * zc - zp * yc;
                n[1] = zp * xc - xp * zc;
                n[2] = xp * yc - yp * xc;

                dot = n[0] * norm[0] + n[1] * norm[1] + n[2] * norm[2];
                if (!check)
                {
                    /* Reverse the contribution of back-facing triangles to get
                     * a reasonable normal for self-intersecting polygons (see above)
                     */
                    if (dot >= 0)
                    {
                        norm[0] += n[0];
                        norm[1] += n[1];
                        norm[2] += n[2];
                    }
                    else
                    {
                        norm[0] -= n[0];
                        norm[1] -= n[1];
                        norm[2] -= n[2];
                    }
                }
                else if (dot != 0)
                {
                    /* Check the new orientation for consistency with previous triangles */
                    if (dot > 0)
                    {
                        if (sign < 0)
                        {
                            return(SIGN_INCONSISTENT);
                        }
                        sign = 1;
                    }
                    else
                    {
                        if (sign > 0)
                        {
                            return(SIGN_INCONSISTENT);
                        }
                        sign = -1;
                    }
                }
            }
            return(sign);
        }
Example #19
0
        /* __gl_renderCache( tess ) takes a single contour and tries to render it
         * as a triangle fan.  This handles convex polygons, as well as some
         * non-convex polygons if we get lucky.
         *
         * Returns true if the polygon was successfully rendered.  The rendering
         * output is provided as callbacks (see the api).
         */
        public static bool __gl_renderCache(GLUtessellatorImpl tess)
        {
            Mogre.Utils.GluTesselator.CachedVertex[] v = tess.cache;
            //            CachedVertex vn = v0 + tess.cacheCount;
            int vn = tess.cacheCount;
            //            CachedVertex vc;
            int vc;

            double[] norm = new double[3];
            int      sign;

            if (tess.cacheCount < 3)
            {
                /* Degenerate contour -- no output */
                return(true);
            }

            norm[0] = tess.normal[0];
            norm[1] = tess.normal[1];
            norm[2] = tess.normal[2];
            if (norm[0] == 0 && norm[1] == 0 && norm[2] == 0)
            {
                ComputeNormal(tess, norm, false);
            }

            sign = ComputeNormal(tess, norm, true);
            if (sign == SIGN_INCONSISTENT)
            {
                /* Fan triangles did not have a consistent orientation */
                return(false);
            }
            if (sign == 0)
            {
                /* All triangles were degenerate */
                return(true);
            }

            if (!USE_OPTIMIZED_CODE_PATH)
            {
                return(false);
            }
            else
            {
                /* Make sure we do the right thing for each winding rule */
                switch (tess.windingRule)
                {
                case GLU.GLU_TESS_WINDING_ODD:
                case GLU.GLU_TESS_WINDING_NONZERO:
                    break;

                case GLU.GLU_TESS_WINDING_POSITIVE:
                    if (sign < 0)
                    {
                        return(true);
                    }
                    break;

                case GLU.GLU_TESS_WINDING_NEGATIVE:
                    if (sign > 0)
                    {
                        return(true);
                    }
                    break;

                case GLU.GLU_TESS_WINDING_ABS_GEQ_TWO:
                    return(true);
                }

                tess.callBeginOrBeginData(tess.boundaryOnly?GL.GL_LINE_LOOP:((tess.cacheCount > 3)?GL.GL_TRIANGLE_FAN:GL.GL_TRIANGLES));

                tess.callVertexOrVertexData(v[0].data);
                if (sign > 0)
                {
                    for (vc = 1; vc < vn; ++vc)
                    {
                        tess.callVertexOrVertexData(v[vc].data);
                    }
                }
                else
                {
                    for (vc = vn - 1; vc > 0; --vc)
                    {
                        tess.callVertexOrVertexData(v[vc].data);
                    }
                }
                tess.callEndOrEndData();
                return(true);
            }
        }
Example #20
0
        // FragmentFilter overrides
        public override FragmentList process(FeatureList input, FilterEnv env)
        {
            FragmentList output = new FragmentList();

            //cuidado con las entidades dentro del for

            int     i = 0;
            Vector3 scale;
            Vector3 distanceScale;
            Vector3 mScale = new Vector3(1, 1, 1);
            float   lWidth = 1;

            if (Scale != null)
            {
                scale = Registry.instance().GetEngine("Python").run(Scale).asVec3();
            }
            else
            {
                scale = new Vector3(1, 1, 1);
            }

            if (CoordScale != null)
            {
                distanceScale = Registry.instance().GetEngine("Python").run(CoordScale).asVec3();
            }
            else
            {
                distanceScale = new Vector3(1, 1, 1);
            }
            if (LineWidth != null)
            {
                lWidth = Registry.instance().GetEngine("Python").run(LineWidth).asFloat();
            }
            if (MaterialScale != null)
            {
                mScale = Registry.instance().GetEngine("Python").run(MaterialScale).asVec3();
            }

            SceneNode nodeIni = point3d(env.getName(), i, 0, 0, 0, null, env.getSceneMgr());

#if ESCALA_NODO_INICIAL
            if (Scale != null)
            {
                nodeIni.SetScale(Registry.instance().GetEngine("Python").run(Scale).asVec3());
            }
            if (coordScale != null)
            {
                Vector3 vec3 = Registry.instance().GetEngine("Python").run(Scale).asVec3();
                nodeIni.SetPosition(nodeIni.Position.x * vec3.x, nodeIni.Position.y * vec3.y, nodeIni.Position.z * vec3.z);
#if TRACE_BUILDGEOMFILTER
                System.Console.WriteLine("(" + n.Position.x + "," + n.Position.y + ")");
#endif
            }
#endif
            Fragment fIni = new Fragment(nodeIni);
            output.Add(fIni);

            foreach (Feature feature in input)
            {
                //if type of features is Point
                if (feature.row.Geometry is SharpMap.Geometries.Point)
                {
                    SharpMap.Geometries.Point p = (SharpMap.Geometries.Point)feature.row.Geometry;

                    i++;
                    SceneNode n = point3d(env.getName(), i, (float)p.X, (float)p.Y, 0, nodeIni, env.getSceneMgr());

                    n.SetScale(scale);
                    n.SetPosition(n.Position.x * distanceScale.x, n.Position.y * distanceScale.y, n.Position.z * distanceScale.z);

                    Fragment f = new Fragment(n);
                    output.Add(f);
                }

                //if type of features is Polygon
                else if (feature.row.Geometry is SharpMap.Geometries.Polygon)
                {
                    SharpMap.Geometries.Polygon polygon = (SharpMap.Geometries.Polygon)feature.row.Geometry;

                    ManualObject polygonNode = null;

                    if (polygonNode == null)
                    {
                        polygonNode = env.getSceneMgr().CreateManualObject(env.getName() + "Node_" + i);
                        MaterialPtr material = MaterialManager.Singleton.Create("Test/ColourPolygon",
                                                                                ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME);
                        material.GetTechnique(0).GetPass(0).VertexColourTracking =
                            (int)TrackVertexColourEnum.TVC_AMBIENT;

                        //Vector3 v = Registry.instance().GetEngine("Python").run(Color, feature, null).asVec3();
                        MogreTessellationCallbacks callback = new MogreTessellationCallbacks(polygonNode, Color, feature);

                        if (nameMaterial != null)
                        {
                            callback.Material      = nameMaterial; // "Test/ColourPolygon2";
                            callback.MaterialScale = mScale;
                        }

                        GLUtessellatorImpl Glu = (GLUtessellatorImpl)GLUtessellatorImpl.gluNewTess();
                        Glu.gluTessCallback(GLU.GLU_TESS_VERTEX, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_BEGIN, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_END, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_ERROR, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_COMBINE, callback);
                        Glu.gluTessBeginPolygon(null);
                        Glu.gluTessBeginContour();

                        int        numVertices = polygon.ExteriorRing.NumPoints /*/10+1*/;
                        int        numValores  = 3;
                        double[][] data        = new double[numVertices][];

                        for (int j = 0; j < numVertices; j++)
                        {
                            data[j] = new double[numValores];
                        }

                        int k = 0;
                        //1 polygon = N vertices
                        foreach (SharpMap.Geometries.Point point in polygon.ExteriorRing.Vertices)
                        {
                            //if (k % 10 == 0)
                            {
                                data[k /*/10*/][0] = point.X;
                                data[k /*/10*/][1] = point.Y;
                                data[k /*/10*/][2] = 0;
                            }
                            k++;

                            //SceneNode n = point3d(env.getName()+i+k, k + 10, (float)point.X * 10.0f, (float)point.Y * 10.0f, 0, nodeIni, env.getSceneMgr());
                        }
                        for (int j = 0; j < data.GetLength(0); j++)
                        {
                            Glu.gluTessVertex(data[j], 0, new Vector3((float)(data[j][1] * distanceScale.y), (float)(data[j][2] * distanceScale.z), (float)(data[j][0] * distanceScale.x)));
                        }

                        Glu.gluTessEndContour();
                        Glu.gluTessNormal(0, 0, 1);
                        Glu.gluTessEndPolygon();

                        nodeIni.AttachObject(polygonNode);
                    }
                    i++;
                }

                //if type of features is MultiPolygon
                else if (feature.row.Geometry is SharpMap.Geometries.MultiPolygon)
                {
                    SharpMap.Geometries.MultiPolygon mp = (SharpMap.Geometries.MultiPolygon)feature.row.Geometry;

                    // 1 MultiPolygon = N polygon
                    foreach (SharpMap.Geometries.Polygon polygon in mp.Polygons)
                    {
                        ManualObject polygonNode = null;

                        if (polygonNode == null)
                        {
                            polygonNode = env.getSceneMgr().CreateManualObject(env.getName() + "Node_" + i);
                            MaterialPtr material = MaterialManager.Singleton.Create("Test/ColourPolygon",
                                                                                    ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME);
                            material.GetTechnique(0).GetPass(0).VertexColourTracking =
                                (int)TrackVertexColourEnum.TVC_AMBIENT;


                            //Vector3 v = Registry.instance().GetEngine("Python").run(Color, feature, null).asVec3();
                            MogreTessellationCallbacks callback = new MogreTessellationCallbacks(polygonNode, Color, feature);

                            if (nameMaterial != null)
                            {
                                callback.Material      = nameMaterial; // "Test/ColourPolygon2";
                                callback.MaterialScale = mScale;
                            }

                            GLUtessellatorImpl Glu = (GLUtessellatorImpl)GLUtessellatorImpl.gluNewTess();
                            Glu.gluTessCallback(GLU.GLU_TESS_VERTEX, callback);
                            Glu.gluTessCallback(GLU.GLU_TESS_BEGIN, callback);
                            Glu.gluTessCallback(GLU.GLU_TESS_END, callback);
                            Glu.gluTessCallback(GLU.GLU_TESS_ERROR, callback);
                            Glu.gluTessCallback(GLU.GLU_TESS_COMBINE, callback);
                            Glu.gluTessBeginPolygon(null);
                            Glu.gluTessBeginContour();

                            int        numVertices = polygon.ExteriorRing.NumPoints;
                            int        numValores  = 3;
                            double[][] data        = new double[numVertices][];

                            for (int j = 0; j < numVertices; j++)
                            {
                                data[j] = new double[numValores];
                            }

                            int k = 0;
                            //1 polygon = N vertices
                            foreach (SharpMap.Geometries.Point point in polygon.ExteriorRing.Vertices)
                            {
                                data[k][0] = point.X;
                                data[k][1] = point.Y;
                                data[k][2] = 0;

                                k++;

                                //SceneNode n = point3d(env.getName(), i, (float)point.X, (float)point.Y, 0, nodeIni, env.getSceneMgr());
                            }
                            for (int j = 0; j < data.GetLength(0); j++)
                            {
                                Glu.gluTessVertex(data[j], 0, new Vector3(((float)data[j][1]) * distanceScale.y, ((float)data[j][2]) * distanceScale.z, ((float)data[j][0]) * distanceScale.x));
                            }

                            Glu.gluTessEndContour();
                            Glu.gluTessNormal(0, 0, 1);
                            Glu.gluTessEndPolygon();

                            nodeIni.AttachObject(polygonNode);
                        }
                        i++;
                    }
                }

                //if type of features is Line
                else if (feature.row.Geometry is SharpMap.Geometries.ILineal /*SharpMap.Geometries.LineString*/)
                {
                    System.Collections.Generic.List <SharpMap.Geometries.ILineal> lineas = new System.Collections.Generic.List <SharpMap.Geometries.ILineal>();
                    if (feature.row.Geometry is SharpMap.Geometries.MultiLineString)
                    {
                        foreach (SharpMap.Geometries.LineString l in ((SharpMap.Geometries.MultiLineString)(feature.row.Geometry)).LineStrings)
                        {
                            lineas.Add(l);
                        }
                    }
                    else
                    {
                        lineas.Add((SharpMap.Geometries.ILineal)(feature.row.Geometry));
                    }
                    foreach (SharpMap.Geometries.ILineal line in lineas)
                    {
                        ManualObject lineNode = env.getSceneMgr().CreateManualObject("line" + i);

                        //MaterialPtr material = MaterialManager.Singleton.Create(nameMaterial,
                        //ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME);
                        //material.GetTechnique(0).GetPass(0).VertexColourTracking =
                        //               (int)TrackVertexColourEnum.TVC_AMBIENT;
                        //material.GetTechnique(0).GetPass(0).SetDepthBias(100);
                        //material.GetTechnique(0).GetPass(0).LightingEnabled = false;

                        int nSeg = 5; // Number of segments on the cap or join pieces
                        BufferParameters         param           = new BufferParameters(nSeg, BufferParameters.BufferEndCapStyle.CapRound, BufferParameters.BufferJoinStyle.JoinRound, 2);
                        IGeometryFactory <Coord> geometryFactory = new GeometryFactory <Coord>(new CoordSeqFac(new CoordFac(PrecisionModelType.DoubleFloating)));
                        //IWktGeometryReader<Coord> reader = geometryFactory.WktReader;
                        //string txt = feature.row.Geometry.AsText();
                        ILineString         line1       = (ILineString)GeometryConverter.ToNTSGeometry((SharpMap.Geometries.LineString)line, geometryFactory); // (ILineString<Coord>)reader.Read(txt);
                        IGeometry           coordBuffer = line1.Buffer(lWidth, param);
                        ICoordinateSequence coords      = coordBuffer.Coordinates;
                        //Vector3 v = Registry.instance().GetEngine("Python").run(Color, feature, null).asVec3();
                        MogreTessellationCallbacks callback = new MogreTessellationCallbacks(lineNode, Color, feature);
                        if (nameMaterial != null)
                        {
                            callback.Material      = nameMaterial; // "Test/ColourPolygon2";
                            callback.MaterialScale = mScale;
                        }

                        GLUtessellatorImpl Glu = (GLUtessellatorImpl)GLUtessellatorImpl.gluNewTess();
                        Glu.gluTessCallback(GLU.GLU_TESS_VERTEX, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_BEGIN, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_END, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_ERROR, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_COMBINE, callback);
                        Glu.gluTessBeginPolygon(null);
                        Glu.gluTessBeginContour();
                        foreach (Coord coord in coords)
                        {
                            double[] data = new double[] { coord.X *distanceScale.x, coord.Y *distanceScale.y, (double.IsNaN(coord.Z) ? 0 : coord.Z) * distanceScale.z };

                            Glu.gluTessVertex(data, 0, new Vector3((float)data[1], (float)data[2], (float)data[0]));
                        }
                        Glu.gluTessEndContour();
                        Glu.gluTessNormal(0, 0, 1);
                        Glu.gluTessEndPolygon();
                        i++;
                        nodeIni.AttachObject(lineNode);
                    }
                    if ((feature.row.Geometry is SharpMap.Geometries.Polygon) | (feature.row.Geometry is SharpMap.Geometries.MultiPolygon))
                    {
                        Fragment f = new Fragment(nodeIni);
                        output.Add(f);
                    }
                }
            }
            i = 0;//breakpoint

            /*foreach (Fragment fragment in output)
             * {
             *  fragment.Node.Scale(0,0,0);
             * }*/

#if TODO
            // if features are arriving in batch, resolve the color here.
            // otherwise we will resolve it later in process(feature,env).
            is_batch            = input.Count > 1;
            batch_feature_color = overall_color;
            if (is_batch && getColorScript() != null)
            {
                ScriptResult r = env.getScriptEngine().run(getColorScript(), env);
                if (r.isValid())
                {
                    batch_feature_color = r.asVec4();
                }
                else
                {
                    env.getReport().error(r.asString());
                }
            }

            return(base.process(input, env));
#endif
            //throw new NotImplementedException();

            if (successor != null)
            {
                if (successor is FeatureFilter)
                {
                    FeatureFilter filter = (FeatureFilter)successor;
                    FeatureList   l      = filter.process(input, env);
                    //FeatureList l = successor.process(input, env);
                }
                else if (successor is FragmentFilter)
                {
                    FragmentFilter filter = (FragmentFilter)successor;
                    FragmentList   l      = filter.process(output, env);
                }
            }

            return(output);
        }
Example #21
0
        /// <summary>********************* Strips and Fans decomposition *****************</summary>
        /* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle
        * fans, strips, and separate triangles.  A substantial effort is made
        * to use as few rendering primitives as possible (ie. to make the fans
        * and strips as large as possible).
        *
        * The rendering output is provided as callbacks (see the api).
        */
        public static void __gl_renderMesh(GLUtessellatorImpl tess, Mogre.Utils.GluTesselator.GLUmesh mesh)
        {
            Mogre.Utils.GluTesselator.GLUface f;

            /* Make a list of separate triangles so we can render them all at once */
            tess.lonelyTriList = null;

            for (f = mesh.fHead.next; f != mesh.fHead; f = f.next)
            {
                f.marked = false;
            }
            for (f = mesh.fHead.next; f != mesh.fHead; f = f.next)
            {

                /* We examine all faces in an arbitrary order.  Whenever we find
                * an unprocessed face F, we output a group of faces including F
                * whose size is maximum.
                */
                if (f.inside && !f.marked)
                {
                    RenderMaximumFaceGroup(tess, f);
                    //assert(f.marked);
                }
            }
            if (tess.lonelyTriList != null)
            {
                RenderLonelyTriangles(tess, tess.lonelyTriList);
                tess.lonelyTriList = null;
            }
        }