Exemplo n.º 1
0
        /* MakeVertex( newVertex, eOrig, vNext ) attaches a new vertex and makes it the
         * origin of all edges in the vertex loop to which eOrig belongs. "vNext" gives
         * a place to insert the new vertex in the global vertex list.  We insert
         * the new vertex *before* vNext so that algorithms which walk the vertex
         * list will not see the newly created vertices.
         */
        internal static void  MakeVertex(Mogre.Utils.GluTesselator.GLUvertex newVertex, Mogre.Utils.GluTesselator.GLUhalfEdge eOrig, Mogre.Utils.GluTesselator.GLUvertex vNext)
        {
            Mogre.Utils.GluTesselator.GLUhalfEdge e;
            Mogre.Utils.GluTesselator.GLUvertex   vPrev;
            Mogre.Utils.GluTesselator.GLUvertex   vNew = newVertex;

            //assert(vNew != null);

            /* insert in circular doubly-linked list before vNext */
            vPrev      = vNext.prev;
            vNew.prev  = vPrev;
            vPrev.next = vNew;
            vNew.next  = vNext;
            vNext.prev = vNew;

            vNew.anEdge = eOrig;
            vNew.data   = null;
            /* leave coords, s, t undefined */

            /* fix other edges on this vertex loop */
            e = eOrig;
            do
            {
                e.Org = vNew;
                e     = e.Onext;
            }while (e != eOrig);
        }
Exemplo n.º 2
0
        /* __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency.
         */
        public static void  __gl_meshCheckMesh(Mogre.Utils.GluTesselator.GLUmesh mesh)
        {
            Mogre.Utils.GluTesselator.GLUface     fHead = mesh.fHead;
            Mogre.Utils.GluTesselator.GLUvertex   vHead = mesh.vHead;
            Mogre.Utils.GluTesselator.GLUhalfEdge eHead = mesh.eHead;
            Mogre.Utils.GluTesselator.GLUface     f, fPrev;
            Mogre.Utils.GluTesselator.GLUvertex   v, vPrev;
            Mogre.Utils.GluTesselator.GLUhalfEdge e, ePrev;

            fPrev = fHead;
            for (fPrev = fHead; (f = fPrev.next) != fHead; fPrev = f)
            {
                //assert(f.prev == fPrev);
                e = f.anEdge;
                do
                {
                    //assert(e.Sym != e);
                    //assert(e.Sym.Sym == e);
                    //assert(e.Lnext.Onext.Sym == e);
                    //assert(e.Onext.Sym.Lnext == e);
                    //assert(e.Lface == f);
                    e = e.Lnext;
                }while (e != f.anEdge);
            }
            //assert(f.prev == fPrev && f.anEdge == null && f.data == null);

            vPrev = vHead;
            for (vPrev = vHead; (v = vPrev.next) != vHead; vPrev = v)
            {
                //assert(v.prev == vPrev);
                e = v.anEdge;
                do
                {
                    //assert(e.Sym != e);
                    //assert(e.Sym.Sym == e);
                    //assert(e.Lnext.Onext.Sym == e);
                    //assert(e.Onext.Sym.Lnext == e);
                    //assert(e.Org == v);
                    e = e.Onext;
                }while (e != v.anEdge);
            }
            //assert(v.prev == vPrev && v.anEdge == null && v.data == null);

            ePrev = eHead;
            for (ePrev = eHead; (e = ePrev.next) != eHead; ePrev = e)
            {
                //assert(e.Sym.next == ePrev.Sym);
                //assert(e.Sym != e);
                //assert(e.Sym.Sym == e);
                //assert(e.Org != null);
                //assert(e.Sym.Org != null);
                //assert(e.Lnext.Onext.Sym == e);
                //assert(e.Onext.Sym.Lnext == e);
            }
            //assert(e.Sym.next == ePrev.Sym && e.Sym == mesh.eHeadSym && e.Sym.Sym == e && e.Org == null && e.Sym.Org == null && e.Lface == null && e.Sym.Lface == null);
        }
Exemplo n.º 3
0
        /* __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the
         * mesh connectivity and topology.  It changes the mesh so that
         *	eOrg->Onext <- OLD( eDst->Onext )
         *	eDst->Onext <- OLD( eOrg->Onext )
         * where OLD(...) means the value before the meshSplice operation.
         *
         * This can have two effects on the vertex structure:
         *  - if eOrg->Org != eDst->Org, the two vertices are merged together
         *  - if eOrg->Org == eDst->Org, the origin is split into two vertices
         * In both cases, eDst->Org is changed and eOrg->Org is untouched.
         *
         * Similarly (and independently) for the face structure,
         *  - if eOrg->Lface == eDst->Lface, one loop is split into two
         *  - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one
         * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.
         *
         * Some special cases:
         * If eDst == eOrg, the operation has no effect.
         * If eDst == eOrg->Lnext, the new face will have a single edge.
         * If eDst == eOrg->Lprev, the old face will have a single edge.
         * If eDst == eOrg->Onext, the new vertex will have a single edge.
         * If eDst == eOrg->Oprev, the old vertex will have a single edge.
         */
        public static bool __gl_meshSplice(Mogre.Utils.GluTesselator.GLUhalfEdge eOrg, Mogre.Utils.GluTesselator.GLUhalfEdge eDst)
        {
            bool joiningLoops    = false;
            bool joiningVertices = false;

            if (eOrg == eDst)
            {
                return(true);
            }

            if (eDst.Org != eOrg.Org)
            {
                /* We are merging two disjoint vertices -- destroy eDst->Org */
                joiningVertices = true;
                KillVertex(eDst.Org, eOrg.Org);
            }
            if (eDst.Lface != eOrg.Lface)
            {
                /* We are connecting two disjoint loops -- destroy eDst.Lface */
                joiningLoops = true;
                KillFace(eDst.Lface, eOrg.Lface);
            }

            /* Change the edge structure */
            Splice(eDst, eOrg);

            if (!joiningVertices)
            {
                Mogre.Utils.GluTesselator.GLUvertex newVertex = new Mogre.Utils.GluTesselator.GLUvertex();

                /* We split one vertex into two -- the new vertex is eDst.Org.
                 * Make sure the old vertex points to a valid half-edge.
                 */
                MakeVertex(newVertex, eDst, eOrg.Org);
                eOrg.Org.anEdge = eOrg;
            }
            if (!joiningLoops)
            {
                Mogre.Utils.GluTesselator.GLUface newFace = new Mogre.Utils.GluTesselator.GLUface();

                /* We split one loop into two -- the new loop is eDst.Lface.
                 * Make sure the old face points to a valid half-edge.
                 */
                MakeFace(newFace, eDst, eOrg.Lface);
                eOrg.Lface.anEdge = eOrg;
            }

            return(true);
        }
Exemplo n.º 4
0
        /// <summary>*************** Basic Edge Operations *********************</summary>

        /* __gl_meshMakeEdge creates one edge, two vertices, and a loop (face).
         * The loop consists of the two new half-edges.
         */
        public static Mogre.Utils.GluTesselator.GLUhalfEdge __gl_meshMakeEdge(Mogre.Utils.GluTesselator.GLUmesh mesh)
        {
            Mogre.Utils.GluTesselator.GLUvertex   newVertex1 = new Mogre.Utils.GluTesselator.GLUvertex();
            Mogre.Utils.GluTesselator.GLUvertex   newVertex2 = new Mogre.Utils.GluTesselator.GLUvertex();
            Mogre.Utils.GluTesselator.GLUface     newFace    = new Mogre.Utils.GluTesselator.GLUface();
            Mogre.Utils.GluTesselator.GLUhalfEdge e;

            e = MakeEdge(mesh.eHead);
            if (e == null)
            {
                return(null);
            }

            MakeVertex(newVertex1, e, mesh.vHead);
            MakeVertex(newVertex2, e.Sym, mesh.vHead);
            MakeFace(newFace, e, mesh.fHead);
            return(e);
        }
Exemplo n.º 5
0
        /* KillVertex( vDel ) destroys a vertex and removes it from the global
         * vertex list.  It updates the vertex loop to point to a given new vertex.
         */
        internal static void  KillVertex(Mogre.Utils.GluTesselator.GLUvertex vDel, Mogre.Utils.GluTesselator.GLUvertex newOrg)
        {
            Mogre.Utils.GluTesselator.GLUhalfEdge e, eStart = vDel.anEdge;
            Mogre.Utils.GluTesselator.GLUvertex   vPrev, vNext;

            /* change the origin of all affected edges */
            e = eStart;
            do
            {
                e.Org = newOrg;
                e     = e.Onext;
            }while (e != eStart);

            /* delete from circular doubly-linked list */
            vPrev      = vDel.prev;
            vNext      = vDel.next;
            vNext.prev = vPrev;
            vPrev.next = vNext;
        }
Exemplo n.º 6
0
        /// <summary>***************** Other Edge Operations *********************</summary>

        /* All these routines can be implemented with the basic edge
         * operations above.  They are provided for convenience and efficiency.
         */


        /* __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that
         * eNew == eOrg.Lnext, and eNew.Dst is a newly created vertex.
         * eOrg and eNew will have the same left face.
         */
        internal static Mogre.Utils.GluTesselator.GLUhalfEdge __gl_meshAddEdgeVertex(Mogre.Utils.GluTesselator.GLUhalfEdge eOrg)
        {
            Mogre.Utils.GluTesselator.GLUhalfEdge eNewSym;
            Mogre.Utils.GluTesselator.GLUhalfEdge eNew = MakeEdge(eOrg);

            eNewSym = eNew.Sym;

            /* Connect the new edge appropriately */
            Splice(eNew, eOrg.Lnext);

            /* Set the vertex and face information */
            eNew.Org = eOrg.Sym.Org;
            {
                Mogre.Utils.GluTesselator.GLUvertex newVertex = new Mogre.Utils.GluTesselator.GLUvertex();

                MakeVertex(newVertex, eNewSym, eNew.Org);
            }
            eNew.Lface = eNewSym.Lface = eOrg.Lface;

            return(eNew);
        }
Exemplo n.º 7
0
        internal static void  CheckOrientation(GLUtessellatorImpl tess)
        {
            double area;

            Mogre.Utils.GluTesselator.GLUface     f, fHead = tess.mesh.fHead;
            Mogre.Utils.GluTesselator.GLUvertex   v, vHead = tess.mesh.vHead;
            Mogre.Utils.GluTesselator.GLUhalfEdge e;

            /* When we compute the normal automatically, we choose the orientation
             * so that the the sum of the signed areas of all contours is non-negative.
             */
            area = 0;
            for (f = fHead.next; f != fHead; f = f.next)
            {
                e = f.anEdge;
                if (e.winding <= 0)
                {
                    continue;
                }
                do
                {
                    area += (e.Org.s - e.Sym.Org.s) * (e.Org.t + e.Sym.Org.t);
                    e     = e.Lnext;
                }while (e != f.anEdge);
            }
            if (area < 0)
            {
                /* Reverse the orientation by flipping all the t-coordinates */
                for (v = vHead.next; v != vHead; v = v.next)
                {
                    v.t = -v.t;
                }
                tess.tUnit[0] = -tess.tUnit[0];
                tess.tUnit[1] = -tess.tUnit[1];
                tess.tUnit[2] = -tess.tUnit[2];
            }
        }
Exemplo n.º 8
0
        /* __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in
         * both meshes, and returns the new mesh (the old meshes are destroyed).
         */
        internal static Mogre.Utils.GluTesselator.GLUmesh __gl_meshUnion(Mogre.Utils.GluTesselator.GLUmesh mesh1, Mogre.Utils.GluTesselator.GLUmesh mesh2)
        {
            Mogre.Utils.GluTesselator.GLUface     f1 = mesh1.fHead;
            Mogre.Utils.GluTesselator.GLUvertex   v1 = mesh1.vHead;
            Mogre.Utils.GluTesselator.GLUhalfEdge e1 = mesh1.eHead;
            Mogre.Utils.GluTesselator.GLUface     f2 = mesh2.fHead;
            Mogre.Utils.GluTesselator.GLUvertex   v2 = mesh2.vHead;
            Mogre.Utils.GluTesselator.GLUhalfEdge e2 = mesh2.eHead;

            /* Add the faces, vertices, and edges of mesh2 to those of mesh1 */
            if (f2.next != f2)
            {
                f1.prev.next = f2.next;
                f2.next.prev = f1.prev;
                f2.prev.next = f1;
                f1.prev      = f2.prev;
            }

            if (v2.next != v2)
            {
                v1.prev.next = v2.next;
                v2.next.prev = v1.prev;
                v2.prev.next = v1;
                v1.prev      = v2.prev;
            }

            if (e2.next != e2)
            {
                e1.Sym.next.Sym.next = e2.next;
                e2.next.Sym.next     = e1.Sym.next;
                e2.Sym.next.Sym.next = e1;
                e1.Sym.next          = e2.Sym.next;
            }

            return(mesh1);
        }
Exemplo n.º 9
0
        internal static void ComputeNormal(GLUtessellatorImpl tess, double[] norm)
        {
            Mogre.Utils.GluTesselator.GLUvertex v, v1, v2;
            double c, tLen2, maxLen2;
            double[] maxVal, minVal, d1, d2, tNorm;
            Mogre.Utils.GluTesselator.GLUvertex[] maxVert, minVert;
            Mogre.Utils.GluTesselator.GLUvertex vHead = tess.mesh.vHead;
            int i;

            maxVal = new double[3];
            minVal = new double[3];
            minVert = new Mogre.Utils.GluTesselator.GLUvertex[3];
            maxVert = new Mogre.Utils.GluTesselator.GLUvertex[3];
            d1 = new double[3];
            d2 = new double[3];
            tNorm = new double[3];

            maxVal[0] = maxVal[1] = maxVal[2] = (- 2) * GLU.GLU_TESS_MAX_COORD;
            minVal[0] = minVal[1] = minVal[2] = 2 * GLU.GLU_TESS_MAX_COORD;

            for (v = vHead.next; v != vHead; v = v.next)
            {
                for (i = 0; i < 3; ++i)
                {
                    c = v.coords[i];
                    if (c < minVal[i])
                    {
                        minVal[i] = c;
                        minVert[i] = v;
                    }
                    if (c > maxVal[i])
                    {
                        maxVal[i] = c;
                        maxVert[i] = v;
                    }
                }
            }

            /* Find two vertices separated by at least 1/sqrt(3) of the maximum
            * distance between any two vertices
            */
            i = 0;
            if (maxVal[1] - minVal[1] > maxVal[0] - minVal[0])
            {
                i = 1;
            }
            if (maxVal[2] - minVal[2] > maxVal[i] - minVal[i])
            {
                i = 2;
            }
            if (minVal[i] >= maxVal[i])
            {
                /* All vertices are the same -- normal doesn't matter */
                norm[0] = 0;
                norm[1] = 0;
                norm[2] = 1;
                return ;
            }

            /* Look for a third vertex which forms the triangle with maximum area
            * (Length of normal == twice the triangle area)
            */
            maxLen2 = 0;
            v1 = minVert[i];
            v2 = maxVert[i];
            d1[0] = v1.coords[0] - v2.coords[0];
            d1[1] = v1.coords[1] - v2.coords[1];
            d1[2] = v1.coords[2] - v2.coords[2];
            for (v = vHead.next; v != vHead; v = v.next)
            {
                d2[0] = v.coords[0] - v2.coords[0];
                d2[1] = v.coords[1] - v2.coords[1];
                d2[2] = v.coords[2] - v2.coords[2];
                tNorm[0] = d1[1] * d2[2] - d1[2] * d2[1];
                tNorm[1] = d1[2] * d2[0] - d1[0] * d2[2];
                tNorm[2] = d1[0] * d2[1] - d1[1] * d2[0];
                tLen2 = tNorm[0] * tNorm[0] + tNorm[1] * tNorm[1] + tNorm[2] * tNorm[2];
                if (tLen2 > maxLen2)
                {
                    maxLen2 = tLen2;
                    norm[0] = tNorm[0];
                    norm[1] = tNorm[1];
                    norm[2] = tNorm[2];
                }
            }

            if (maxLen2 <= 0)
            {
                /* All points lie on a single line -- any decent normal will do */
                norm[0] = norm[1] = norm[2] = 0;
                norm[LongAxis(d1)] = 1;
            }
        }
Exemplo n.º 10
0
        /// <summary>***************** Other Edge Operations *********************</summary>
        /* All these routines can be implemented with the basic edge
        * operations above.  They are provided for convenience and efficiency.
        */
        /* __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that
        * eNew == eOrg.Lnext, and eNew.Dst is a newly created vertex.
        * eOrg and eNew will have the same left face.
        */
        internal static Mogre.Utils.GluTesselator.GLUhalfEdge __gl_meshAddEdgeVertex(Mogre.Utils.GluTesselator.GLUhalfEdge eOrg)
        {
            Mogre.Utils.GluTesselator.GLUhalfEdge eNewSym;
            Mogre.Utils.GluTesselator.GLUhalfEdge eNew = MakeEdge(eOrg);

            eNewSym = eNew.Sym;

            /* Connect the new edge appropriately */
            Splice(eNew, eOrg.Lnext);

            /* Set the vertex and face information */
            eNew.Org = eOrg.Sym.Org;
            {
                Mogre.Utils.GluTesselator.GLUvertex newVertex = new Mogre.Utils.GluTesselator.GLUvertex();

                MakeVertex(newVertex, eNewSym, eNew.Org);
            }
            eNew.Lface = eNewSym.Lface = eOrg.Lface;

            return eNew;
        }
Exemplo n.º 11
0
        /* __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the
        * mesh connectivity and topology.  It changes the mesh so that
        *	eOrg->Onext <- OLD( eDst->Onext )
        *	eDst->Onext <- OLD( eOrg->Onext )
        * where OLD(...) means the value before the meshSplice operation.
        *
        * This can have two effects on the vertex structure:
        *  - if eOrg->Org != eDst->Org, the two vertices are merged together
        *  - if eOrg->Org == eDst->Org, the origin is split into two vertices
        * In both cases, eDst->Org is changed and eOrg->Org is untouched.
        *
        * Similarly (and independently) for the face structure,
        *  - if eOrg->Lface == eDst->Lface, one loop is split into two
        *  - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one
        * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.
        *
        * Some special cases:
        * If eDst == eOrg, the operation has no effect.
        * If eDst == eOrg->Lnext, the new face will have a single edge.
        * If eDst == eOrg->Lprev, the old face will have a single edge.
        * If eDst == eOrg->Onext, the new vertex will have a single edge.
        * If eDst == eOrg->Oprev, the old vertex will have a single edge.
        */
        public static bool __gl_meshSplice(Mogre.Utils.GluTesselator.GLUhalfEdge eOrg, Mogre.Utils.GluTesselator.GLUhalfEdge eDst)
        {
            bool joiningLoops = false;
            bool joiningVertices = false;

            if (eOrg == eDst)
                return true;

            if (eDst.Org != eOrg.Org)
            {
                /* We are merging two disjoint vertices -- destroy eDst->Org */
                joiningVertices = true;
                KillVertex(eDst.Org, eOrg.Org);
            }
            if (eDst.Lface != eOrg.Lface)
            {
                /* We are connecting two disjoint loops -- destroy eDst.Lface */
                joiningLoops = true;
                KillFace(eDst.Lface, eOrg.Lface);
            }

            /* Change the edge structure */
            Splice(eDst, eOrg);

            if (!joiningVertices)
            {
                Mogre.Utils.GluTesselator.GLUvertex newVertex = new Mogre.Utils.GluTesselator.GLUvertex();

                /* We split one vertex into two -- the new vertex is eDst.Org.
                * Make sure the old vertex points to a valid half-edge.
                */
                MakeVertex(newVertex, eDst, eOrg.Org);
                eOrg.Org.anEdge = eOrg;
            }
            if (!joiningLoops)
            {
                Mogre.Utils.GluTesselator.GLUface newFace = new Mogre.Utils.GluTesselator.GLUface();

                /* We split one loop into two -- the new loop is eDst.Lface.
                * Make sure the old face points to a valid half-edge.
                */
                MakeFace(newFace, eDst, eOrg.Lface);
                eOrg.Lface.anEdge = eOrg;
            }

            return true;
        }
Exemplo n.º 12
0
        /// <summary>*************** Basic Edge Operations *********************</summary>
        /* __gl_meshMakeEdge creates one edge, two vertices, and a loop (face).
        * The loop consists of the two new half-edges.
        */
        public static Mogre.Utils.GluTesselator.GLUhalfEdge __gl_meshMakeEdge(Mogre.Utils.GluTesselator.GLUmesh mesh)
        {
            Mogre.Utils.GluTesselator.GLUvertex newVertex1 = new Mogre.Utils.GluTesselator.GLUvertex();
            Mogre.Utils.GluTesselator.GLUvertex newVertex2 = new Mogre.Utils.GluTesselator.GLUvertex();
            Mogre.Utils.GluTesselator.GLUface newFace = new Mogre.Utils.GluTesselator.GLUface();
            Mogre.Utils.GluTesselator.GLUhalfEdge e;

            e = MakeEdge(mesh.eHead);
            if (e == null)
                return null;

            MakeVertex(newVertex1, e, mesh.vHead);
            MakeVertex(newVertex2, e.Sym, mesh.vHead);
            MakeFace(newFace, e, mesh.fHead);
            return e;
        }
Exemplo n.º 13
0
        internal static void  ComputeNormal(GLUtessellatorImpl tess, double[] norm)
        {
            Mogre.Utils.GluTesselator.GLUvertex v, v1, v2;
            double c, tLen2, maxLen2;

            double[] maxVal, minVal, d1, d2, tNorm;
            Mogre.Utils.GluTesselator.GLUvertex[] maxVert, minVert;
            Mogre.Utils.GluTesselator.GLUvertex   vHead = tess.mesh.vHead;
            int i;

            maxVal  = new double[3];
            minVal  = new double[3];
            minVert = new Mogre.Utils.GluTesselator.GLUvertex[3];
            maxVert = new Mogre.Utils.GluTesselator.GLUvertex[3];
            d1      = new double[3];
            d2      = new double[3];
            tNorm   = new double[3];

            maxVal[0] = maxVal[1] = maxVal[2] = (-2) * GLU.GLU_TESS_MAX_COORD;
            minVal[0] = minVal[1] = minVal[2] = 2 * GLU.GLU_TESS_MAX_COORD;

            for (v = vHead.next; v != vHead; v = v.next)
            {
                for (i = 0; i < 3; ++i)
                {
                    c = v.coords[i];
                    if (c < minVal[i])
                    {
                        minVal[i]  = c;
                        minVert[i] = v;
                    }
                    if (c > maxVal[i])
                    {
                        maxVal[i]  = c;
                        maxVert[i] = v;
                    }
                }
            }

            /* Find two vertices separated by at least 1/sqrt(3) of the maximum
             * distance between any two vertices
             */
            i = 0;
            if (maxVal[1] - minVal[1] > maxVal[0] - minVal[0])
            {
                i = 1;
            }
            if (maxVal[2] - minVal[2] > maxVal[i] - minVal[i])
            {
                i = 2;
            }
            if (minVal[i] >= maxVal[i])
            {
                /* All vertices are the same -- normal doesn't matter */
                norm[0] = 0;
                norm[1] = 0;
                norm[2] = 1;
                return;
            }

            /* Look for a third vertex which forms the triangle with maximum area
             * (Length of normal == twice the triangle area)
             */
            maxLen2 = 0;
            v1      = minVert[i];
            v2      = maxVert[i];
            d1[0]   = v1.coords[0] - v2.coords[0];
            d1[1]   = v1.coords[1] - v2.coords[1];
            d1[2]   = v1.coords[2] - v2.coords[2];
            for (v = vHead.next; v != vHead; v = v.next)
            {
                d2[0]    = v.coords[0] - v2.coords[0];
                d2[1]    = v.coords[1] - v2.coords[1];
                d2[2]    = v.coords[2] - v2.coords[2];
                tNorm[0] = d1[1] * d2[2] - d1[2] * d2[1];
                tNorm[1] = d1[2] * d2[0] - d1[0] * d2[2];
                tNorm[2] = d1[0] * d2[1] - d1[1] * d2[0];
                tLen2    = tNorm[0] * tNorm[0] + tNorm[1] * tNorm[1] + tNorm[2] * tNorm[2];
                if (tLen2 > maxLen2)
                {
                    maxLen2 = tLen2;
                    norm[0] = tNorm[0];
                    norm[1] = tNorm[1];
                    norm[2] = tNorm[2];
                }
            }

            if (maxLen2 <= 0)
            {
                /* All points lie on a single line -- any decent normal will do */
                norm[0]            = norm[1] = norm[2] = 0;
                norm[LongAxis(d1)] = 1;
            }
        }
Exemplo n.º 14
0
        /* Determine the polygon normal and project vertices onto the plane
         * of the polygon.
         */
        public static void  __gl_projectPolygon(GLUtessellatorImpl tess)
        {
            Mogre.Utils.GluTesselator.GLUvertex v, vHead = tess.mesh.vHead;
            double w;

            double[] norm = new double[3];
            double[] sUnit, tUnit;
            int      i;
            bool     computedNormal = false;

            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);
                computedNormal = true;
            }
            sUnit = tess.sUnit;
            tUnit = tess.tUnit;
            i     = LongAxis(norm);

            if (TRUE_PROJECT)
            {
                /* Choose the initial sUnit vector to be approximately perpendicular
                 * to the normal.
                 */
                Normalize(norm);

                sUnit[i]           = 0;
                sUnit[(i + 1) % 3] = S_UNIT_X;
                sUnit[(i + 2) % 3] = S_UNIT_Y;

                /* Now make it exactly perpendicular */
                w         = Dot(sUnit, norm);
                sUnit[0] -= w * norm[0];
                sUnit[1] -= w * norm[1];
                sUnit[2] -= w * norm[2];
                Normalize(sUnit);

                /* Choose tUnit so that (sUnit,tUnit,norm) form a right-handed frame */
                tUnit[0] = norm[1] * sUnit[2] - norm[2] * sUnit[1];
                tUnit[1] = norm[2] * sUnit[0] - norm[0] * sUnit[2];
                tUnit[2] = norm[0] * sUnit[1] - norm[1] * sUnit[0];
                Normalize(tUnit);
            }
            else
            {
                /* Project perpendicular to a coordinate axis -- better numerically */
                sUnit[i]           = 0;
                sUnit[(i + 1) % 3] = S_UNIT_X;
                sUnit[(i + 2) % 3] = S_UNIT_Y;

                tUnit[i]           = 0;
                tUnit[(i + 1) % 3] = (norm[i] > 0)?-S_UNIT_Y:S_UNIT_Y;
                tUnit[(i + 2) % 3] = (norm[i] > 0)?S_UNIT_X:-S_UNIT_X;
            }

            /* Project the vertices onto the sweep plane */
            for (v = vHead.next; v != vHead; v = v.next)
            {
                v.s = Dot(v.coords, sUnit);
                v.t = Dot(v.coords, tUnit);
            }
            if (computedNormal)
            {
                CheckOrientation(tess);
            }
        }