Example #1
0
 // Shadow ray test.  Returns true if shadowed, or false otherwise.
 // No other information is needed.
 public bool testShadowRay(double[] origin, double[] dir)
 {
     for (int objectIndex = 0; objectIndex < m_numObjects; objectIndex++)
     {
         BaseObject obj   = m_objects[objectIndex];
         double[]   coord = new double[3];
         if (!RayBox.RayAABB(obj.m_bounds, origin, dir, coord))                    // Trivial rejection of whole object
         {
             continue;
         }
         double[][] tri = new double[3][] { new double[3], new double[3], new double[3] };
         for (int i = 0; i < obj.m_numFaces; i++)
         {
             getTriangle(objectIndex, i, tri);
             double t, u, v;
             if (rayTriangleTest(tri, origin, dir, out t, out u, out v) && t < 1 - m_epsilon)                        // t < 1 will check the segment.
             {
                 return(false);
             }
         }
     }
     return(true);
 }
Example #2
0
        // Intersect a ray with the model.  The index of the object that is hit is returned (since this is
        // required to index into the relevant material data).  The intersection point is returned (since
        // the reflected/refracted ray will require this as an origin).  The normal is also returned (for computing
        // local illumination, and for generating the next ray in the path in accordance to the correct distribution).
        // The normal is interpolated using the barycentric coordinates of the intersection, if the hit object is smooth.
        // True is returned iff the ray does intersect an object.
        public bool rayIntersect(double[] origin, double[] dir, out int hitObjectIndex, double[] intersectionPoint, double[] normal)
        {
            double tMin = double.MaxValue;
            double uMin = double.MaxValue;
            double vMin = double.MaxValue;
            int    nearestObject = -1, nearestTriangle = -1;

            for (int objectIndex = 0; objectIndex < m_numObjects; objectIndex++)
            {
                BaseObject obj   = m_objects[objectIndex];
                double[]   coord = new double[3];
                if (!RayBox.RayAABB(obj.m_bounds, origin, dir, coord))                    // Trivial rejection of whole object (Bounding Box check)
                {
                    continue;
                }
                double[][] tri = new double[3][] { new double[3], new double[3], new double[3] };
                for (int i = 0; i < obj.m_numFaces; i++)
                {
                    getTriangle(objectIndex, i, tri);
                    double t, u, v;
                    if (rayTriangleTest(tri, origin, dir, out t, out u, out v))
                    {
                        if (tMin > t)
                        {
                            tMin            = t;
                            nearestObject   = objectIndex;
                            nearestTriangle = i;
                            uMin            = u;
                            vMin            = v;
                        }
                    }
                }
            }
            if (nearestObject != -1)                // Is there a nearest object, or did the ray just shoot off into infinity?
            {
                hitObjectIndex       = nearestObject;
                intersectionPoint[0] = origin[0] + tMin * dir[0];
                intersectionPoint[1] = origin[1] + tMin * dir[1];
                intersectionPoint[2] = origin[2] + tMin * dir[2];
                if (m_objects[nearestObject].m_smooth == false)
                {
                    Utils.setf3(normal, m_objects[nearestObject].m_normals[nearestTriangle]);                       // Triangle normal
                }
                else
                {
                    double[][] normals = new double[3][] { new double[3], new double[3], new double[3] };
                    getNormals(nearestObject, nearestTriangle, normals);
                    double a = 1 - uMin - vMin;
                    double b = uMin;
                    double c = vMin;
                    normal[0] = a * normals[0][0] + b * normals[1][0] + c * normals[2][0];
                    normal[1] = a * normals[0][1] + b * normals[1][1] + c * normals[2][1];
                    normal[2] = a * normals[0][2] + b * normals[1][2] + c * normals[2][2];
                    Utils.normalise(normal);                       // Interpolated normal
                }
                return(true);
            }
            else
            {
                hitObjectIndex = -1;
            }
            return(false);
        }