Beispiel #1
0
        // MouseToWorldRay
        //
        // This takes the view matricies, and a window-local mouse coordinate, and returns a ray in world space.

        public static SSRay MouseToWorldRay(
            Matrix4 projection,
            Matrix4 view,
            System.Drawing.Size viewport,
            Vector2 mouse)
        {
            // these mouse.Z values are NOT scientific.
            // Near plane needs to be < -1.5f or we have trouble selecting objects right in front of the camera. (why?)
            Vector3 pos1 = UnProject(ref projection, view, viewport, new Vector3(mouse.X, mouse.Y, -1.5f)); // near
            Vector3 pos2 = UnProject(ref projection, view, viewport, new Vector3(mouse.X, mouse.Y, 1.0f));  // far

            return(SSRay.FromTwoPoints(pos1, pos2));
        }
Beispiel #2
0
        /// <summary>
        /// Distance from a ray to a point at the closest spot. The ray is assumed to be infinite length.
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public static float DistanceToLine(SSRay ray, Vector3 point, out float distanceAlongRay)
        {
            // http://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line

            Vector3 a = ray.pos;
            Vector3 n = ray.dir;
            Vector3 p = point;

            var t = Vector3.Dot((a - p), n);

            distanceAlongRay = -t;
            return(((a - p) - t * n).Length);
        }
Beispiel #3
0
        // Ray to AABB (AxisAlignedBoundingBox)
        // http://gamedev.stackexchange.com/questions/18436/most-efficient-aabb-vs-ray-collision-algorithms

        public static bool intersectRayAABox2(SSRay ray, SSAABB box, ref float tnear, ref float tfar)
        {
            Vector3d T_1    = new Vector3d();
            Vector3d T_2    = new Vector3d();  // vectors to hold the T-values for every direction
            double   t_near = double.MinValue; // maximums defined in float.h
            double   t_far  = double.MaxValue;

            for (int i = 0; i < 3; i++)
            {     //we test slabs in every direction
                if (ray.dir[i] == 0)
                { // ray parallel to planes in this direction
                    if ((ray.pos[i] < box.Min[i]) || (ray.pos[i] > box.Max[i]))
                    {
                        return(false); // parallel AND outside box : no intersection possible
                    }
                }
                else
                { // ray not parallel to planes in this direction
                    T_1[i] = (box.Min[i] - ray.pos[i]) / ray.dir[i];
                    T_2[i] = (box.Max[i] - ray.pos[i]) / ray.dir[i];

                    if (T_1[i] > T_2[i])
                    {                  // we want T_1 to hold values for intersection with near plane
                        var swp = T_2; // swap
                        T_1 = swp; T_2 = T_1;
                    }
                    if (T_1[i] > t_near)
                    {
                        t_near = T_1[i];
                    }
                    if (T_2[i] < t_far)
                    {
                        t_far = T_2[i];
                    }
                    if ((t_near > t_far) || (t_far < 0))
                    {
                        return(false);
                    }
                }
            }
            tnear = (float)t_near; tfar = (float)t_far; // put return values in place
            return(true);                               // if we made it here, there was an intersection - YAY
        }
Beispiel #4
0
        } // fn

        public static bool intersectRayAABox1(SSRay ray, SSAABB box, ref float tnear, ref float tfar)
        {
            // r.dir is unit direction vector of ray
            Vector3 dirfrac = new Vector3();
            float   t;

            dirfrac.X = 1.0f / ray.dir.X;
            dirfrac.Y = 1.0f / ray.dir.Y;
            dirfrac.Z = 1.0f / ray.dir.Z;
            // lb is the corner of AABB with minimal coordinates - left bottom, rt is maximal corner
            // r.org is origin of ray
            float t1 = (box.Min.X - ray.pos.X) * dirfrac.X;
            float t2 = (box.Max.X - ray.pos.X) * dirfrac.X;
            float t3 = (box.Min.Y - ray.pos.Y) * dirfrac.Y;
            float t4 = (box.Max.Y - ray.pos.Y) * dirfrac.Y;
            float t5 = (box.Min.Z - ray.pos.Z) * dirfrac.Z;
            float t6 = (box.Max.Z - ray.pos.Z) * dirfrac.Z;

            float tmin = Math.Max(Math.Max(Math.Min(t1, t2), Math.Min(t3, t4)), Math.Min(t5, t6));
            float tmax = Math.Min(Math.Min(Math.Max(t1, t2), Math.Max(t3, t4)), Math.Max(t5, t6));

            // if tmax < 0, ray (line) is intersecting AABB, but whole AABB is behing us
            if (tmax < 0)
            {
                t = tmax;
                return(false);
            }

            // if tmin > tmax, ray doesn't intersect AABB
            if (tmin > tmax)
            {
                t = tmax;
                return(false);
            }

            t = tmin;
            return(true);
        }
Beispiel #5
0
 public static float DistanceToLine_2(SSRay ray, Vector3 point)
 {
     return(Vector3.Cross(ray.dir, point - ray.pos).Length);
 }