Exemple #1
0
        static void Swap(ref MeshUtils.Vertex a, ref MeshUtils.Vertex b)
        {
            var tmp = a;

            a = b;
            b = tmp;
        }
Exemple #2
0
        public static float TransSign(MeshUtils.Vertex u, MeshUtils.Vertex v, MeshUtils.Vertex w)
        {
            Debug.Assert(TransLeq(u, v) && TransLeq(v, w));

            float gapL = v._t - u._t;
            float gapR = w._t - v._t;

            if (gapL + gapR > 0.0f)
            {
                return((v._s - w._s) * gapL + (v._s - u._s) * gapR);
            }
            /* vertical line */
            return(0.0f);
        }
Exemple #3
0
        /// <summary>
        /// Returns a number whose sign matches EdgeEval(u,v,w) but which
        /// is cheaper to evaluate. Returns > 0, == 0 , or less than 0
        /// as v is above, on, or below the edge uw.
        /// </summary>
        public static float EdgeSign(MeshUtils.Vertex u, MeshUtils.Vertex v, MeshUtils.Vertex w)
        {
            //  Debug.Assert(VertLeq(u, v) && VertLeq(v, w));

            float gapL = v._s - u._s;
            float gapR = w._s - v._s;

            if (gapL + gapR > 0.0f)
            {
                return((v._t - w._t) * gapL + (v._t - u._t) * gapR);
            }
            /* vertical line */
            return(0.0f);
        }
Exemple #4
0
        /// <summary>
        /// Given three vertices u,v,w such that VertLeq(u,v) .and. VertLeq(v,w),
        /// evaluates the t-coord of the edge uw at the s-coord of the vertex v.
        /// Returns v->t - (uw)(v->s), ie. the signed distance from uw to v.
        /// If uw is vertical (and thus passes thru v), the result is zero.
        ///
        /// The calculation is extremely accurate and stable, even when v
        /// is very close to u or w.  In particular if we set v->t = 0 and
        /// let r be the negated result (this evaluates (uw)(v->s)), then
        /// r is guaranteed to satisfy MIN(u->t,w->t) less than or equal r less than or equal MAX(u->t,w->t).
        /// </summary>
        public static float EdgeEval(MeshUtils.Vertex u, MeshUtils.Vertex v, MeshUtils.Vertex w)
        {
            Debug.Assert(VertLeq(u, v) && VertLeq(v, w));

            float gapL = v._s - u._s;
            float gapR = w._s - v._s;

            if (gapL + gapR > 0.0f)
            {
                if (gapL < gapR)
                {
                    return((v._t - u._t) + (u._t - w._t) * (gapL / (gapL + gapR)));
                }
                return((v._t - w._t) + (w._t - u._t) * (gapR / (gapL + gapR)));
            }
            /* vertical line */
            return(0.0f);
        }
Exemple #5
0
        public static float TransEval(MeshUtils.Vertex u, MeshUtils.Vertex v, MeshUtils.Vertex w)
        {
            Debug.Assert(TransLeq(u, v) && TransLeq(v, w));

            float gapL = v._t - u._t;
            float gapR = w._t - v._t;

            if (gapL + gapR > 0.0f)
            {
                if (gapL < gapR)
                {
                    return((v._s - u._s) + (u._s - w._s) * (gapL / (gapL + gapR)));
                }
                return((v._s - w._s) + (w._s - u._s) * (gapR / (gapL + gapR)));
            }
            /* vertical line */
            return(0.0f);
        }
Exemple #6
0
// ReSharper restore InconsistentNaming
        public Mesh()
        {
            var v = _vHead = new MeshUtils.Vertex();
            var f = _fHead = new MeshUtils.Face();

            var pair = MeshUtils.EdgePair.Create();
            var e    = _eHead = pair._e;
            var eSym = _eHeadSym = pair._eSym;

            v._next   = v._prev = v;
            v._anEdge = null;

            f._next   = f._prev = f;
            f._anEdge = null;
            f._trail  = null;
            f._marked = false;
            f._inside = false;

            e._next         = e;
            e._Sym          = eSym;
            e._Onext        = null;
            e._Lnext        = null;
            e._Org          = null;
            e._Lface        = null;
            e._winding      = 0;
            e._activeRegion = null;

            eSym._next         = eSym;
            eSym._Sym          = e;
            eSym._Onext        = null;
            eSym._Lnext        = null;
            eSym._Org          = null;
            eSym._Lface        = null;
            eSym._winding      = 0;
            eSym._activeRegion = null;
        }
Exemple #7
0
        public static bool VertLeq(MeshUtils.Vertex lhs, MeshUtils.Vertex rhs)
        {
// ReSharper disable CompareOfFloatsByEqualityOperator
            return((lhs._s < rhs._s) || (lhs._s == rhs._s && lhs._t <= rhs._t));
// ReSharper restore CompareOfFloatsByEqualityOperator
        }
Exemple #8
0
 public static bool VertCcw(MeshUtils.Vertex u, MeshUtils.Vertex v, MeshUtils.Vertex w)
 {
     return((u._s * (v._t - w._t) + v._s * (w._t - u._t) + w._s * (u._t - v._t)) >= 0.0f);
 }
Exemple #9
0
        /// <summary>
        /// Given edges (o1,d1) and (o2,d2), compute their point of intersection.
        /// The computed point is guaranteed to lie in the intersection of the
        /// bounding rectangles defined by each edge.
        /// </summary>
        public static void EdgeIntersect(MeshUtils.Vertex o1, MeshUtils.Vertex d1, MeshUtils.Vertex o2, MeshUtils.Vertex d2, MeshUtils.Vertex v)
        {
            float z1, z2;

            // This is certainly not the most efficient way to find the intersection
            // of two line segments, but it is very numerically stable.
            //
            // Strategy: find the two middle vertices in the VertLeq ordering,
            // and interpolate the intersection s-value from these.  Then repeat
            // using the TransLeq ordering to find the intersection t-value.

            if (!VertLeq(o1, d1))
            {
                Swap(ref o1, ref d1);
            }
            if (!VertLeq(o2, d2))
            {
                Swap(ref o2, ref d2);
            }
            if (!VertLeq(o1, o2))
            {
                Swap(ref o1, ref o2); Swap(ref d1, ref d2);
            }

            if (!VertLeq(o2, d1))
            {
                // Technically, no intersection -- do our best
                v._s = (o2._s + d1._s) / 2.0f;
            }
            else if (VertLeq(d1, d2))
            {
                // Interpolate between o2 and d1
                z1 = EdgeEval(o1, o2, d1);
                z2 = EdgeEval(o2, d1, d2);
                if (z1 + z2 < 0.0f)
                {
                    z1 = -z1;
                    z2 = -z2;
                }
                v._s = Interpolate(z1, o2._s, z2, d1._s);
            }
            else
            {
                // Interpolate between o2 and d2
                z1 = EdgeSign(o1, o2, d1);
                z2 = -EdgeSign(o1, d2, d1);
                if (z1 + z2 < 0.0f)
                {
                    z1 = -z1;
                    z2 = -z2;
                }
                v._s = Interpolate(z1, o2._s, z2, d2._s);
            }

            // Now repeat the process for t

            if (!TransLeq(o1, d1))
            {
                Swap(ref o1, ref d1);
            }
            if (!TransLeq(o2, d2))
            {
                Swap(ref o2, ref d2);
            }
            if (!TransLeq(o1, o2))
            {
                Swap(ref o1, ref o2); Swap(ref d1, ref d2);
            }

            if (!TransLeq(o2, d1))
            {
                // Technically, no intersection -- do our best
                v._t = (o2._t + d1._t) / 2.0f;
            }
            else if (TransLeq(d1, d2))
            {
                // Interpolate between o2 and d1
                z1 = TransEval(o1, o2, d1);
                z2 = TransEval(o2, d1, d2);
                if (z1 + z2 < 0.0f)
                {
                    z1 = -z1;
                    z2 = -z2;
                }
                v._t = Interpolate(z1, o2._t, z2, d1._t);
            }
            else
            {
                // Interpolate between o2 and d2
                z1 = TransSign(o1, o2, d1);
                z2 = -TransSign(o1, d2, d1);
                if (z1 + z2 < 0.0f)
                {
                    z1 = -z1;
                    z2 = -z2;
                }
                v._t = Interpolate(z1, o2._t, z2, d2._t);
            }
        }
Exemple #10
0
 public static float VertL1Dist(MeshUtils.Vertex u, MeshUtils.Vertex v)
 {
     return(Math.Abs(u._s - v._s) + Math.Abs(u._t - v._t));
 }