Beispiel #1
0
        public static IEnumerable <Triangle3D> BoxTriangles(Vector3 a, Vector3 b)
        {
            float          x          = a.X;
            float          z          = a.Y;
            float          y          = a.Z;
            float          sx         = b.X - a.X;
            float          sz         = b.Y - a.Y;
            float          sy         = b.Z - a.Z;
            List <short>   myelements = new List <short>();
            List <Vector3> myvertices = new List <Vector3>();

            //top
            //if (drawtop)
            {
                short lastelement = (short)myvertices.Count;
                myvertices.Add(new Vector3(x + 0.0f * sx, z + 1.0f * sz, y + 0.0f * sy));
                myvertices.Add(new Vector3(x + 0.0f * sx, z + 1.0f * sz, y + 1.0f * sy));
                myvertices.Add(new Vector3(x + 1.0f * sx, z + 1.0f * sz, y + 0.0f * sy));
                myvertices.Add(new Vector3(x + 1.0f * sx, z + 1.0f * sz, y + 1.0f * sy));
                myelements.Add((short)(lastelement + 0));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
                myelements.Add((short)(lastelement + 3));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
            }
            //bottom - same as top, but z is 1 less.
            //if (drawbottom)
            {
                short lastelement = (short)myvertices.Count;
                myvertices.Add(new Vector3(x + 0.0f * sx, z + 0 * sz, y + 0.0f * sy));
                myvertices.Add(new Vector3(x + 0.0f * sx, z + 0 * sz, y + 1.0f * sy));
                myvertices.Add(new Vector3(x + 1.0f * sx, z + 0 * sz, y + 0.0f * sy));
                myvertices.Add(new Vector3(x + 1.0f * sx, z + 0 * sz, y + 1.0f * sy));
                myelements.Add((short)(lastelement + 0));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
                myelements.Add((short)(lastelement + 3));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
            }
            //front
            //if (drawfront)
            {
                short lastelement = (short)myvertices.Count;
                myvertices.Add(new Vector3(x + 0 * sx, z + 0 * sz, y + 0 * sy));
                myvertices.Add(new Vector3(x + 0 * sx, z + 0 * sz, y + 1 * sy));
                myvertices.Add(new Vector3(x + 0 * sx, z + 1 * sz, y + 0 * sy));
                myvertices.Add(new Vector3(x + 0 * sx, z + 1 * sz, y + 1 * sy));
                myelements.Add((short)(lastelement + 0));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
                myelements.Add((short)(lastelement + 3));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
            }
            //back - same as front, but x is 1 greater.
            //if (drawback)
            {
                short lastelement = (short)myvertices.Count;
                myvertices.Add(new Vector3(x + 1 * sx, z + 0 * sz, y + 0 * sy));
                myvertices.Add(new Vector3(x + 1 * sx, z + 0 * sz, y + 1 * sy));
                myvertices.Add(new Vector3(x + 1 * sx, z + 1 * sz, y + 0 * sy));
                myvertices.Add(new Vector3(x + 1 * sx, z + 1 * sz, y + 1 * sy));
                myelements.Add((short)(lastelement + 0));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
                myelements.Add((short)(lastelement + 3));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
            }
            //if (drawleft)
            {
                short lastelement = (short)myvertices.Count;
                myvertices.Add(new Vector3(x + 0 * sx, z + 0 * sz, y + 0 * sy));
                myvertices.Add(new Vector3(x + 0 * sx, z + 1 * sz, y + 0 * sy));
                myvertices.Add(new Vector3(x + 1 * sx, z + 0 * sz, y + 0 * sy));
                myvertices.Add(new Vector3(x + 1 * sx, z + 1 * sz, y + 0 * sy));
                myelements.Add((short)(lastelement + 0));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
                myelements.Add((short)(lastelement + 3));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
            }
            //right - same as left, but y is 1 greater.
            //if (drawright)
            {
                short lastelement = (short)myvertices.Count;
                myvertices.Add(new Vector3(x + 0 * sx, z + 0 * sz, y + 1 * sy));
                myvertices.Add(new Vector3(x + 0 * sx, z + 1 * sz, y + 1 * sy));
                myvertices.Add(new Vector3(x + 1 * sx, z + 0 * sz, y + 1 * sy));
                myvertices.Add(new Vector3(x + 1 * sx, z + 1 * sz, y + 1 * sy));
                myelements.Add((short)(lastelement + 0));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
                myelements.Add((short)(lastelement + 3));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
            }
            for (int i = 0; i < myelements.Count / 3; i++)
            {
                Triangle3D t = new Triangle3D();
                t.PointA = myvertices[myelements[i * 3 + 0]];
                t.PointB = myvertices[myelements[i * 3 + 1]];
                t.PointC = myvertices[myelements[i * 3 + 2]];
                yield return(t);
            }
        }
        // intersect_RayTriangle(): intersect a ray with a 3D triangle
        //    Input:  a ray R, and a triangle T
        //    Output: *I = intersection point (when it exists)
        //    Return: -1 = triangle is degenerate (a segment or point)
        //             0 = disjoint (no intersect)
        //             1 = intersect in unique point I1
        //             2 = are in the same plane
        public static int RayTriangle(Line3D R, Triangle3D T, out Vector3 I)
        {
            Vector3 u, v, n;             // triangle vectors
            Vector3 dir, w0, w;          // ray vectors
            float r, a, b;             // params to calc ray-plane intersect

            I = new Vector3();

            // get triangle edge vectors and plane normal
            u = T.PointB - T.PointA;
            v = T.PointC - T.PointA;
            //n = u.CrossProduct(v);             // cross product
            Vector3.Cross(ref u, ref v, out n);
            //if (n == (Vector3D)0)            // triangle is degenerate
            //    return -1;                 // do not deal with this case

            dir = R.End - R.Start;             // ray direction vector
            w0 = R.Start - T.PointA;
            a = -dot(n, w0);
            b = dot(n, dir);
            if (Math.Abs(b) < SMALL_NUM)
            {     // ray is parallel to triangle plane
                if (a == 0)                // ray lies in triangle plane
                    return 2;
                else return 0;             // ray disjoint from plane
            }

            // get intersect point of ray with triangle plane
            r = a / b;
            if (r < 0.0)                   // ray goes away from triangle
                return 0;                  // => no intersect
            // for a segment, also test if (r > 1.0) => no intersect

            I = R.Start + r * dir;           // intersect point of ray and plane

            // is I inside T?
            float uu, uv, vv, wu, wv, D;
            uu = dot(u, u);
            uv = dot(u, v);
            vv = dot(v, v);
            w = I - T.PointA;
            wu = dot(w, u);
            wv = dot(w, v);
            D = uv * uv - uu * vv;

            // get and test parametric coords
            float s, t;
            s = (uv * wv - vv * wu) / D;
            if (s < 0.0 || s > 1.0)        // I is outside T
                return 0;
            t = (uv * wu - uu * wv) / D;
            if (t < 0.0 || (s + t) > 1.0)  // I is outside T
                return 0;

            return 1;                      // I is in T
        }
Beispiel #3
0
        RayTriangle(Line3D R, Triangle3D T, out Vector3 I)
        {
            Vector3 u, v, n;           // triangle vectors
            Vector3 dir, w0, w;        // ray vectors
            float   r, a, b;           // params to calc ray-plane intersect

            I = new Vector3();

            // get triangle edge vectors and plane normal
            u = T.PointB - T.PointA;
            v = T.PointC - T.PointA;
            //n = u.CrossProduct(v);             // cross product
            Vector3.Cross(ref u, ref v, out n);
            //if (n == (Vector3D)0)            // triangle is degenerate
            //    return -1;                 // do not deal with this case

            dir = R.End - R.Start;             // ray direction vector
            w0  = R.Start - T.PointA;
            a   = -dot(n, w0);
            b   = dot(n, dir);
            if (Math.Abs(b) < SMALL_NUM)
            {               // ray is parallel to triangle plane
                if (a == 0) // ray lies in triangle plane
                {
                    return(2);
                }
                else
                {
                    return(0);             // ray disjoint from plane
                }
            }

            // get intersect point of ray with triangle plane
            r = a / b;
            if (r < 0.0)                   // ray goes away from triangle
            {
                return(0);                 // => no intersect
            }
            // for a segment, also test if (r > 1.0) => no intersect

            I = R.Start + r * dir;           // intersect point of ray and plane

            // is I inside T?
            float uu, uv, vv, wu, wv, D;

            uu = dot(u, u);
            uv = dot(u, v);
            vv = dot(v, v);
            w  = I - T.PointA;
            wu = dot(w, u);
            wv = dot(w, v);
            D  = uv * uv - uu * vv;

            // get and test parametric coords
            float s, t;

            s = (uv * wv - vv * wu) / D;
            if (s < 0.0 || s > 1.0)        // I is outside T
            {
                return(0);
            }
            t = (uv * wu - uu * wv) / D;
            if (t < 0.0 || (s + t) > 1.0)  // I is outside T
            {
                return(0);
            }

            return(1);                      // I is in T
        }
        static float SMALL_NUM = 0.00000001f; // anything that avoids division overflow

        #endregion Fields

        #region Methods

        public static IEnumerable<Triangle3D> BoxTriangles(Vector3 a, Vector3 b)
        {
            float x = a.X;
            float z = a.Y;
            float y = a.Z;
            float sx = b.X - a.X;
            float sz = b.Y - a.Y;
            float sy = b.Z - a.Z;
            List<short> myelements = new List<short>();
            List<Vector3> myvertices = new List<Vector3>();
            //top
            //if (drawtop)
            {
                short lastelement = (short)myvertices.Count;
                myvertices.Add(new Vector3(x + 0.0f * sx, z + 1.0f * sz, y + 0.0f * sy));
                myvertices.Add(new Vector3(x + 0.0f * sx, z + 1.0f * sz, y + 1.0f * sy));
                myvertices.Add(new Vector3(x + 1.0f * sx, z + 1.0f * sz, y + 0.0f * sy));
                myvertices.Add(new Vector3(x + 1.0f * sx, z + 1.0f * sz, y + 1.0f * sy));
                myelements.Add((short)(lastelement + 0));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
                myelements.Add((short)(lastelement + 3));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
            }
            //bottom - same as top, but z is 1 less.
            //if (drawbottom)
            {
                short lastelement = (short)myvertices.Count;
                myvertices.Add(new Vector3(x + 0.0f * sx, z + 0 * sz, y + 0.0f * sy));
                myvertices.Add(new Vector3(x + 0.0f * sx, z + 0 * sz, y + 1.0f * sy));
                myvertices.Add(new Vector3(x + 1.0f * sx, z + 0 * sz, y + 0.0f * sy));
                myvertices.Add(new Vector3(x + 1.0f * sx, z + 0 * sz, y + 1.0f * sy));
                myelements.Add((short)(lastelement + 0));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
                myelements.Add((short)(lastelement + 3));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
            }
            //front
            //if (drawfront)
            {
                short lastelement = (short)myvertices.Count;
                myvertices.Add(new Vector3(x + 0 * sx, z + 0 * sz, y + 0 * sy));
                myvertices.Add(new Vector3(x + 0 * sx, z + 0 * sz, y + 1 * sy));
                myvertices.Add(new Vector3(x + 0 * sx, z + 1 * sz, y + 0 * sy));
                myvertices.Add(new Vector3(x + 0 * sx, z + 1 * sz, y + 1 * sy));
                myelements.Add((short)(lastelement + 0));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
                myelements.Add((short)(lastelement + 3));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
            }
            //back - same as front, but x is 1 greater.
            //if (drawback)
            {
                short lastelement = (short)myvertices.Count;
                myvertices.Add(new Vector3(x + 1 * sx, z + 0 * sz, y + 0 * sy));
                myvertices.Add(new Vector3(x + 1 * sx, z + 0 * sz, y + 1 * sy));
                myvertices.Add(new Vector3(x + 1 * sx, z + 1 * sz, y + 0 * sy));
                myvertices.Add(new Vector3(x + 1 * sx, z + 1 * sz, y + 1 * sy));
                myelements.Add((short)(lastelement + 0));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
                myelements.Add((short)(lastelement + 3));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
            }
            //if (drawleft)
            {
                short lastelement = (short)myvertices.Count;
                myvertices.Add(new Vector3(x + 0 * sx, z + 0 * sz, y + 0 * sy));
                myvertices.Add(new Vector3(x + 0 * sx, z + 1 * sz, y + 0 * sy));
                myvertices.Add(new Vector3(x + 1 * sx, z + 0 * sz, y + 0 * sy));
                myvertices.Add(new Vector3(x + 1 * sx, z + 1 * sz, y + 0 * sy));
                myelements.Add((short)(lastelement + 0));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
                myelements.Add((short)(lastelement + 3));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
            }
            //right - same as left, but y is 1 greater.
            //if (drawright)
            {
                short lastelement = (short)myvertices.Count;
                myvertices.Add(new Vector3(x + 0 * sx, z + 0 * sz, y + 1 * sy));
                myvertices.Add(new Vector3(x + 0 * sx, z + 1 * sz, y + 1 * sy));
                myvertices.Add(new Vector3(x + 1 * sx, z + 0 * sz, y + 1 * sy));
                myvertices.Add(new Vector3(x + 1 * sx, z + 1 * sz, y + 1 * sy));
                myelements.Add((short)(lastelement + 0));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
                myelements.Add((short)(lastelement + 3));
                myelements.Add((short)(lastelement + 1));
                myelements.Add((short)(lastelement + 2));
            }
            for (int i = 0; i < myelements.Count / 3; i++)
            {
                Triangle3D t = new Triangle3D();
                t.PointA = myvertices[myelements[i * 3 + 0]];
                t.PointB = myvertices[myelements[i * 3 + 1]];
                t.PointC = myvertices[myelements[i * 3 + 2]];
                yield return t;
            }
        }