示例#1
0
 // dot product (3D) which allows vector operations in arguments
 static float dot(Vector u, Vector v)
 {
     return(u.x * v.x + u.y * v.y + u.z * v.z);
 }
示例#2
0
        const float SMALL_NUM = 0.00000001F; // anything that avoids division overflow

        #endregion Fields

        #region Methods

        public static int intersect_RayTriangle(Ray R, Triangle T, ref Vector I)
        {
            Vector u, v, n;             // triangle vectors
            Vector dir, w0, w;          // ray vectors
            float r, a, b;             // params to calc ray-plane intersect

            // get triangle edge vectors and plane normal
            u = T.V1 - T.V0;
            v = T.V2 - T.V0;
            n = u * v;             // cross product

            Vector nullvec; nullvec.x = 0; nullvec.y = 0; nullvec.z = 0;
            if (n == nullvec)            // triangle is degenerate
                return -1;                 // do not deal with this case

            dir = R.P1 - R.P0;             // ray direction vector
            w0 = R.P0 - T.V0;
            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.P0 + 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.V0;
            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
        }