コード例 #1
0
ファイル: Perspective.cs プロジェクト: Kintaro/Hyperion
        public override double GenerateRay(CameraSample sample, ref Ray ray)
        {
            ++NumberOfRays;
            // Generate raster and camera samples
            Point pRas = new Point (sample.ImageX, sample.ImageY, 0);
            Point pCam = new Point ();
            RasterToCamera.Apply (pRas, ref pCam);
            ray = new Ray (new Point (), new Vector (pCam), 0.0, double.PositiveInfinity);

            if (LensRadius > 0.0)
            {
                double lensU = 0.0, lensV = 0.0;
                MonteCarlo.ConcentricSampleDisk (sample.LensU, sample.LensV, ref lensU, ref lensV);
                lensU *= LensRadius;
                lensV *= LensRadius;

                double ft = FocalDistance / ray.Direction.z;
                Point pFocus = ray.Apply (ft);

                ray.Origin = new Point (lensU, lensV, 0.0);
                ray.Direction = (pFocus - ray.Origin).Normalized;
            }

            ray.Time = Util.Lerp (sample.Time, ShutterOpen, ShutterClose);
            CameraToWorld.Apply (ray, ref ray);

            return 1.0;
        }
コード例 #2
0
ファイル: ICamera.cs プロジェクト: Kintaro/Hyperion
        public virtual double GenerateRayDifferential(CameraSample sample, ref RayDifferential rd)
        {
            Ray r = new Ray (rd.Origin, rd.Direction, rd.MinT, rd.MaxT, rd.Time);
            double wt = GenerateRay (sample, ref r);
            rd.Origin = r.Origin;
            rd.Direction = r.Direction;
            rd.MinT = r.MinT;
            rd.MaxT = r.MaxT;
            rd.Time = r.Time;

            CameraSample sshift = sample;
            ++sshift.ImageX;

            Ray rx = new Ray ();
            double wtx = GenerateRay (sshift, ref rx);
            rd.RxOrigin = rx.Origin;
            rd.RxDirection = rx.Direction;

            --sshift.ImageX;
            ++sshift.ImageY;

            Ray ry = new Ray ();
            double wty = GenerateRay (sshift, ref ry);
            rd.RyOrigin = ry.Origin;
            rd.RyDirection = ry.Direction;

            if (wtx == 0.0 || wty == 0.0)
                return 0.0;

            rd.HasDifferentials = true;

            return wt;
        }
コード例 #3
0
ファイル: DiffuseAreaLight.cs プロジェクト: Kintaro/Hyperion
 public override Spectrum SampleL(Scene scene, LightSample ls, double u1, double u2, double time, ref Ray ray, ref Normal Ns, ref double pdf)
 {
     Point org = ShapeSet.Sample (ls, ref Ns);
     Vector dir = MonteCarlo.UniformSampleSphere (u1, u2);
     if ((dir ^ Ns) < 0.0)
         dir *= -1.0;
     ray = new Ray (org, dir, 0.001, double.PositiveInfinity, time);
     pdf = ShapeSet.Pdf (org) * Util.InvTwoPi;
     Spectrum Ls = L (org, Ns, dir);
     return Ls;
 }
コード例 #4
0
        public override bool Intersect(Ray ray, ref Intersection isect)
        {
            double thit = 0.0, rayEpsilon = 0.0;
            if (!Shape.Intersect (ray, ref thit, ref rayEpsilon, ref isect.dg))
                return false;

            isect.Primitive = this;
            isect.WorldToObject = Shape.WorldToObject;
            isect.ObjectToWorld = Shape.ObjectToWorld;
            isect.ShapeID = Shape.ShapeID;
            isect.PrimitiveID = PrimitiveID;
            isect.RayEpsilon = rayEpsilon;
            ray.MaxT = thit;

            return true;
        }
コード例 #5
0
ファイル: ShapeSet.cs プロジェクト: Kintaro/Hyperion
 public Point Sample(Point p, LightSample lightSample, ref Normal Ns)
 {
     double temp = 0.0;
     int sn = AreaDistribution.SampleDiscrete (lightSample.uComponent, ref temp);
     Point pt = Shapes[sn].Sample (p, lightSample.uPos[0], lightSample.uPos[1], ref Ns);
     // Find closest intersection of ray with shapes in _ShapeSet_
     Ray r = new Ray (p, pt - p, 0.001, double.PositiveInfinity);
     double rayEps = 0.0, thit = 1.0;
     bool anyHit = false;
     DifferentialGeometry dg = new DifferentialGeometry ();
     foreach (IShape shape in Shapes)
         anyHit |= shape.Intersect (r, ref thit, ref rayEps, ref dg);
     if (anyHit)
         Ns = new Normal (dg.n);
     return r.Apply (thit);
 }
コード例 #6
0
ファイル: Disk.cs プロジェクト: Kintaro/Hyperion
        public override bool Intersect(Ray r, ref double tHit, ref double rayEpsilon, ref DifferentialGeometry dg)
        {
            // Transform _Ray_ to object space
            Ray ray = new Ray ();
            WorldToObject.Apply (r, ref ray);

            // Compute plane intersection for disk
            if (Math.Abs (ray.Direction.z) < 1E-07)
                return false;
            double thit = (Height - ray.Origin.z) / ray.Direction.z;
            if (thit < ray.MinT || thit > ray.MaxT)
                return false;

            // See if hit point is inside disk radii and $\phimax$
            Point phit = ray.Apply (thit);
            double dist2 = phit.x * phit.x + phit.y * phit.y;
            if (dist2 > Radius * Radius || dist2 < InnerRadius * InnerRadius)
                return false;

            // Test disk $\phi$ value against $\phimax$
            double phi = Math.Atan2 (phit.y, phit.x);
            if (phi < 0)
                phi += 2.0 * Util.Pi;
            if (phi > PhiMax)
                return false;

            // Find parametric representation of disk hit
            double u = phi / PhiMax;
            double v = 1.0 - ((Math.Sqrt (dist2) - InnerRadius) / (Radius - InnerRadius));
            Vector dpdu = new Vector (-PhiMax * phit.y, PhiMax * phit.x, 0.0);
            Vector dpdv = new Vector (-phit.x / (1 - v), -phit.y / (1 - v), 0.0);
            dpdu *= PhiMax * Util.InvTwoPi;
            dpdv *= (Radius - InnerRadius) / Radius;
            Normal dndu = new Normal (0, 0, 0), dndv = new Normal (0, 0, 0);

            // Initialize _DifferentialGeometry_ from parametric information
            dg = new DifferentialGeometry (ObjectToWorld.Apply (phit), ObjectToWorld.Apply (dpdu), ObjectToWorld.Apply (dpdv), ObjectToWorld.Apply (dndu), ObjectToWorld.Apply (dndv), u, v, this);

            // Update _tHit_ for quadric intersection
            tHit = thit;

            // Compute _rayEpsilon_ for quadric intersection
            rayEpsilon = 0.0005 * tHit;
            return true;
        }
コード例 #7
0
ファイル: Distant.cs プロジェクト: Kintaro/Hyperion
        public override Spectrum SampleL(Scene scene, LightSample ls, double u1, double u2, double time, ref Ray ray, ref Normal Ns, ref double pdf)
        {
            // Choose point on disk oriented toward infinite light direction
            Point worldCenter;
            double worldRadius;
            scene.WorldBound.BoundingSphere (out worldCenter, out worldRadius);
            Vector v1, v2;
            Util.CoordinateSystem (LightDir, out v1, out v2);
            double d1 = 0.0, d2 = 0.0;
            MonteCarlo.ConcentricSampleDisk (ls.uPos[0], ls.uPos[1], ref d1, ref d2);
            Point Pdisk = worldCenter + worldRadius * (d1 * v1 + d2 * v2);

            // Set ray origin and direction for infinite light ray
            ray = new Ray (Pdisk + worldRadius * LightDir, -LightDir, 0.0, double.PositiveInfinity, time);
            Ns = new Normal (ray.Direction);
            pdf = 1.0 / (Util.Pi * worldRadius * worldRadius);
            return L;
        }
コード例 #8
0
ファイル: IPrimitive.cs プロジェクト: Kintaro/Hyperion
 public abstract bool IntersectP(Ray ray);
コード例 #9
0
ファイル: IPrimitive.cs プロジェクト: Kintaro/Hyperion
 public abstract bool Intersect(Ray ray, ref Intersection isect);
コード例 #10
0
ファイル: Ray.cs プロジェクト: Kintaro/Hyperion
 public Ray(Point origin, Vector direction, Ray parent, double start, double end)
     : this(origin, direction, start, end, parent.Time, parent.Depth + 1)
 {
 }
コード例 #11
0
ファイル: Sphere.cs プロジェクト: Kintaro/Hyperion
        public override bool IntersectP(Ray r)
        {
            double phi;
            Point phit;
            // Transform _Ray_ to object space
            Ray ray = new Ray ();
            WorldToObject.Apply (r, ref ray);

            // Compute quadratic sphere coefficients
            double A = ray.Direction.x * ray.Direction.x + ray.Direction.y * ray.Direction.y + ray.Direction.z * ray.Direction.z;
            double B = 2 * (ray.Direction.x * ray.Origin.x + ray.Direction.y * ray.Origin.y + ray.Direction.z * ray.Origin.z);
            double C = ray.Origin.x * ray.Origin.x + ray.Origin.y * ray.Origin.y + ray.Origin.z * ray.Origin.z - Radius * Radius;

            // Solve quadratic equation for _t_ values
            double t0 = 0.0, t1 = 0.0;
            if (!Util.Quadratic (A, B, C, ref t0, ref t1))
                return false;

            // Compute intersection distance along ray
            if (t0 > ray.MaxT || t1 < ray.MinT)
                return false;
            double thit = t0;
            if (t0 < ray.MinT)
            {
                thit = t1;
                if (thit > ray.MaxT)
                    return false;
            }

            // Compute sphere hit position and $\phi$
            phit = ray.Apply (thit);
            if (phit.x == 0.0 && phit.y == 0.0)
                phit.x = 1E-5 * Radius;
            phi = Math.Atan2 (phit.y, phit.x);
            if (phi < 0.0)
                phi += 2.0 * Util.Pi;

            // Test sphere intersection against clipping parameters
            if ((zMin > -Radius && phit.z < zMin) || (zMax < Radius && phit.z > zMax) || phi > PhiMax)
            {
                if (thit == t1)
                    return false;
                if (t1 > ray.MaxT)
                    return false;
                thit = t1;
                // Compute sphere hit position and $\phi$
                phit = ray.Apply (thit);
                if (phit.x == 0.0 && phit.y == 0.0)
                    phit.x = 1E-5 * Radius;
                phi = Math.Atan2 (phit.y, phit.x);
                if (phi < 0.0)
                    phi += 2.0 * Util.Pi;
                if ((zMin > -Radius && phit.z < zMin) || (zMax < Radius && phit.z > zMax) || phi > PhiMax)
                    return false;
            }
            return true;
        }
コード例 #12
0
ファイル: Triangle.cs プロジェクト: Kintaro/Hyperion
        public override bool IntersectP(Ray ray)
        {
            Point p1 = Mesh.Points[Vertices[0]];
            Point p2 = Mesh.Points[Vertices[1]];
            Point p3 = Mesh.Points[Vertices[2]];

            Vector e1 = p2 - p1;
            Vector e2 = p3 - p1;
            Vector s1 = ray.Direction % e2;

            double divisor = s1 ^ e1;
            if (divisor == 0.0)
                return false;
            double invDivisor = 1.0 / divisor;

            Vector d = ray.Origin - p1;
            double b1 = (d ^ s1) * invDivisor;
            if (b1 < 0.0 || b1 > 1.0)
                return false;

            Vector s2 = d % e1;
            double b2 = (ray.Direction ^ s2) * invDivisor;
            if (b2 < 0.0 || b1 + b2 > 1.0)
                return false;

            double t = (e2 ^ s2) * invDivisor;
            if (t < ray.MinT || t > ray.MaxT)
                return false;

            if (ray.Depth != -1)
            {
                Vector dpdu = new Vector (), dpdv = new Vector ();
                double[] uvs = new double[6];
                GetUVs (uvs);

                double du1 = uvs[0] - uvs[4];
                double du2 = uvs[2] - uvs[4];
                double dv1 = uvs[1] - uvs[5];
                double dv2 = uvs[3] - uvs[5];
                Vector dp1 = p1 - p3, dp2 = p2 - p3;
                double determinant = du1 * dv2 - dv1 * du2;
                if (determinant == 0.0)
                    Util.CoordinateSystem ((e2 % e1).Normalized, out dpdu, out dpdv);
                else
                {
                    double invdet = 1.0 / determinant;
                    dpdu = (dv2 * dp1 - dv1 * dp2) * invdet;
                    dpdv = (-du2 * dp1 - du1 * dp2) * invdet;
                }

                double b0 = 1 - b1 - b2;
                double tu = b0 * uvs[0] + b1 * uvs[2] + b2 * uvs[4];
                double tv = b0 * uvs[1] + b1 * uvs[3] + b2 * uvs[5];

                DifferentialGeometry dgLocal = new DifferentialGeometry (ray.Apply (t), dpdu, dpdv, new Normal (), new Normal (), tu, tv, this);
                if (Mesh.AlphaTexture != null && Mesh.AlphaTexture.Evaluate (dgLocal) == 0.0)
                    return false;
            }

            return true;
        }
コード例 #13
0
ファイル: IShape.cs プロジェクト: Kintaro/Hyperion
 public virtual bool IntersectP(Ray ray)
 {
     return false;
 }
コード例 #14
0
ファイル: VisibilityTester.cs プロジェクト: Kintaro/Hyperion
 public void SetRay(Point p, double eps, Vector w, double time)
 {
     Ray = new Ray (p, w, eps, double.PositiveInfinity, time);
 }
コード例 #15
0
ファイル: VisibilityTester.cs プロジェクト: Kintaro/Hyperion
 public void SetSegment(Point p1, double eps1, Point p2, double eps2, double time)
 {
     double dist = Util.Distance (p1, p2);
     Ray = new Ray (p1, (p2 - p1) / dist, eps1, dist * (1.0 - eps2), time);
 }
コード例 #16
0
ファイル: ILight.cs プロジェクト: Kintaro/Hyperion
 public abstract Spectrum SampleL(Scene scene, LightSample ls, double u1, double u2, double time, ref Ray ray, ref Normal Ns, ref double pdf);
コード例 #17
0
 public override bool IntersectP(Ray ray)
 {
     return Shape.IntersectP (ray);
 }
コード例 #18
0
ファイル: Scene.cs プロジェクト: Kintaro/Hyperion
 public bool Intersect(Ray ray, ref Intersection isect)
 {
     return Aggregate.Intersect (ray, ref isect);
 }
コード例 #19
0
ファイル: Sphere.cs プロジェクト: Kintaro/Hyperion
        public override bool Intersect(Ray r, ref double tHit, ref double rayEpsilon, ref DifferentialGeometry dg)
        {
            double phi;
            Point phit;
            // Transform _Ray_ to object space
            Ray ray = new Ray ();
            WorldToObject.Apply (r, ref ray);

            // Compute quadratic sphere coefficients
            double A = ray.Direction.x * ray.Direction.x + ray.Direction.y * ray.Direction.y + ray.Direction.z * ray.Direction.z;
            double B = 2 * (ray.Direction.x * ray.Origin.x + ray.Direction.y * ray.Origin.y + ray.Direction.z * ray.Origin.z);
            double C = ray.Origin.x * ray.Origin.x + ray.Origin.y * ray.Origin.y + ray.Origin.z * ray.Origin.z - Radius * Radius;

            // Solve quadratic equation for _t_ values
            double t0 = 0.0, t1 = 0.0;
            if (!Util.Quadratic (A, B, C, ref t0, ref t1))
                return false;

            // Compute intersection distance along ray
            if (t0 > ray.MaxT || t1 < ray.MinT)
                return false;
            double thit = t0;
            if (t0 < ray.MinT)
            {
                thit = t1;
                if (thit > ray.MaxT)
                    return false;
            }

            // Compute sphere hit position and $\phi$
            phit = ray.Apply (thit);
            if (phit.x == 0.0 && phit.y == 0.0)
                phit.x = 1E-5 * Radius;
            phi = Math.Atan2 (phit.y, phit.x);
            if (phi < 0.0)
                phi += 2.0 * Util.Pi;

            // Test sphere intersection against clipping parameters
            if ((zMin > -Radius && phit.z < zMin) || (zMax < Radius && phit.z > zMax) || phi > PhiMax)
            {
                if (thit == t1)
                    return false;
                if (t1 > ray.MaxT)
                    return false;
                thit = t1;
                // Compute sphere hit position and $\phi$
                phit = ray.Apply (thit);
                if (phit.x == 0.0 && phit.y == 0.0)
                    phit.x = 1E-5f * Radius;
                phi = Math.Atan2 (phit.y, phit.x);
                if (phi < 0.0)
                    phi += 2.0 * Util.Pi;
                if ((zMin > -Radius && phit.z < zMin) || (zMax < Radius && phit.z > zMax) || phi > PhiMax)
                    return false;
            }

            // Find parametric representation of sphere hit
            double u = phi / PhiMax;
            double theta = Math.Acos (Util.Clamp (phit.z / Radius, -1.0, 1.0));
            double v = (theta - ThetaMin) / (ThetaMax - ThetaMin);

            // Compute sphere $\dpdu$ and $\dpdv$
            double zRadius = Math.Sqrt (phit.x * phit.x + phit.y * phit.y);
            double invzRadius = 1.0 / zRadius;
            double cosphi = phit.x * invzRadius;
            double sinphi = phit.y * invzRadius;
            Vector dpdu = new Vector (-PhiMax * phit.y, PhiMax * phit.x, 0);
            Vector dpdv = (ThetaMax - ThetaMin) * new Vector (phit.z * cosphi, phit.z * sinphi, -Radius * Math.Sin (theta));

            // Compute sphere $\dndu$ and $\dndv$
            Vector d2Pduu = -PhiMax * PhiMax * new Vector (phit.x, phit.y, 0);
            Vector d2Pduv = (ThetaMax - ThetaMin) * phit.z * PhiMax * new Vector (-sinphi, cosphi, 0.0);
            Vector d2Pdvv = -(ThetaMax - ThetaMin) * (ThetaMax - ThetaMin) * new Vector (phit.x, phit.y, phit.z);

            // Compute coefficients for fundamental forms
            double E = (dpdu ^ dpdu);
            double F = (dpdu ^ dpdv);
            double G = (dpdv ^ dpdv);
            Vector N = (dpdu % dpdv).Normalized;
            double e = (N ^ d2Pduu);
            double f = (N ^ d2Pduv);
            double g = (N ^ d2Pdvv);

            // Compute $\dndu$ and $\dndv$ from fundamental form coefficients
            double invEGF2 = 1.0 / (E * G - F * F);
            Normal dndu = new Normal ((f * F - e * G) * invEGF2 * dpdu + (e * F - f * E) * invEGF2 * dpdv);
            Normal dndv = new Normal ((g * F - f * G) * invEGF2 * dpdu + (f * F - g * E) * invEGF2 * dpdv);

            // Initialize _DifferentialGeometry_ from parametric information
            dg = new DifferentialGeometry (ObjectToWorld.Apply (phit), ObjectToWorld.Apply (dpdu), ObjectToWorld.Apply (dpdv), ObjectToWorld.Apply (dndu), ObjectToWorld.Apply (dndv), u, v, this);

            // Update _tHit_ for quadric intersection
            tHit = thit;

            // Compute _rayEpsilon_ for quadric intersection
            rayEpsilon = 0.0005 * tHit;

            return true;
        }
コード例 #20
0
ファイル: Sphere.cs プロジェクト: Kintaro/Hyperion
        public override Point Sample(Point p, double u1, double u2, ref Normal Ns)
        {
            // Compute coordinate system for sphere sampling
            Point Pcenter = ObjectToWorld.Apply (new Point ());
            Vector wc = (Pcenter - p).Normalized;
            Vector wcX, wcY;
            Util.CoordinateSystem (wc, out wcX, out wcY);

            // Sample uniformly on sphere if $\pt{}$ is inside it
            if (Util.DistanceSquared (p, Pcenter) - Radius * Radius < 0.0001)
                return Sample (u1, u2, ref Ns);

            // Sample sphere uniformly inside subtended cone
            double sinThetaMax2 = Radius * Radius / Util.DistanceSquared (p, Pcenter);
            double cosThetaMax = Math.Sqrt (Math.Max (0.0, 1.0 - sinThetaMax2));
            DifferentialGeometry dgSphere = new DifferentialGeometry ();
            double thit = 0.0, rayEpsilon = 0.0;
            Point ps;
            Ray r = new Ray (p, MonteCarlo.UniformSampleCone (u1, u2, cosThetaMax, wcX, wcY, wc), 0.001);
            if (!Intersect (r, ref thit, ref rayEpsilon, ref dgSphere))
                thit = ((Pcenter - p) ^ r.Direction.Normalized);
            ps = r.Apply (thit);
            Ns = new Normal ((ps - Pcenter).Normalized);
            if (ReverseOrientation)
                Ns *= -1.0;
            return ps;
        }
コード例 #21
0
ファイル: KdTreeAccelerator.cs プロジェクト: Kintaro/Hyperion
        /// <summary>
        ///     Checks if the given ray intersects the primitive.
        /// </summary>
        /// <param name="ray">
        ///     The ray to test for
        /// </param>
        /// <param name="intersection">
        ///     A pointer to an Intersection structure that'll hold
        ///     the intersection information.
        /// </param>
        /// <returns>
        ///     True if the ray intersects the primitive. False otherwise.
        /// </returns>
        public override bool Intersect(Ray ray, ref Intersection intersection)
        {
            int index = 0;

            double tMin = 0.0, tMax = 0.0;

            if (!_bounds.IntersectP (ray, out tMin, out tMax))
            {
                return false;
            }

            Vector inverseDirection = new Vector (1.0 / ray.Direction.x, 1.0 / ray.Direction.y, 1.0 / ray.Direction.z);

            int todoPosition = 0;
            bool hit = false;

            KdToDo[] todo = ToDoPool.Get ();

            while (index >= 0 && index < _nodes.Length)
            {
                if (ray.MaxT < tMin)
                    break;

                if (!_nodes[index].IsLeaf)
                {
                    int axis = _nodes[index].SplitAxis;
                    double tPlane = (_nodes[index].Split - ray.Origin[axis]) * inverseDirection[axis];
                    int firstIndex, secondIndex;
                    bool belowFirst = (ray.Origin[axis] < _nodes[index].Split) || (ray.Origin[axis] == _nodes[index].Split && ray.Direction[axis] >= 0);

                    if (belowFirst)
                    {
                        firstIndex = index + 1;
                        secondIndex = _nodes[index].AboveChild;
                    }
                    else
                    {
                        firstIndex = _nodes[index].AboveChild;
                        secondIndex = index + 1;
                    }

                    if (tPlane > tMax || tPlane <= 0)
                    {
                        index = firstIndex;
                    }
                    else if (tPlane < tMin)
                    {
                        index = secondIndex;
                    }
                    else
                    {
                        todo[todoPosition].tMax = tMax;
                        todo[todoPosition].tMin = tPlane;
                        todo[todoPosition].Index = secondIndex;
                        ++todoPosition;
                        index = firstIndex;
                        tMax = tPlane;
                    }
                }
                else
                {
                    if (_nodes[index].NumberOfPrimitives == 1)
                    {
                        IPrimitive prim = _primitives[_nodes[index].OnePrimitive];
                        if (prim.Intersect (ray, ref intersection))
                        {
                            hit = true;
                        }
                    }
                    else
                    {
                        for (int i = 0; i < _nodes[index].NumberOfPrimitives; ++i)
                        {
                            IPrimitive prim = _primitives[_nodes[index].Primitives[i]];
                            if (prim.Intersect (ray, ref intersection))
                            {
                                hit = true;
                            }
                        }
                    }

                    if (todoPosition > 0)
                    {
                        --todoPosition;
                        tMin = todo[todoPosition].tMin;
                        tMax = todo[todoPosition].tMax;
                        index = todo[todoPosition].Index;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            ToDoPool.Free (todo);

            return hit;
        }
コード例 #22
0
ファイル: IShape.cs プロジェクト: Kintaro/Hyperion
        public virtual double Pdf(Point p, Vector wi)
        {
            DifferentialGeometry dgLight = new DifferentialGeometry ();
            Ray ray = new Ray (p, wi, 1e-3);
            ray.Depth = - 1;
            double thit = 0.0, rayEpsilon = 0.0;

            if (!Intersect (ray, ref thit, ref rayEpsilon, ref dgLight))
                return 0.0;

            double pdf = Util.DistanceSquared (p, ray.Apply (thit)) / Util.AbsDot (dgLight.n, -wi) * Area;

            if (double.IsInfinity (pdf))
                pdf = 0.0;

            return pdf;
        }
コード例 #23
0
ファイル: KdTreeAccelerator.cs プロジェクト: Kintaro/Hyperion
        /// <summary>
        ///     A quick check just to test if the ray intersects the primitive.
        ///     This method doesn't fill in Intersection information,
        ///     so this method is obviously faster for pure testing.
        /// </summary>
        /// <param name="ray">
        ///     The ray to test for
        /// </param>
        /// <returns>
        ///     True if the ray intersects the primitive. False otherwise.
        /// </returns>
        public override bool IntersectP(Ray ray)
        {
            int index = 0;

            double tMin = 0.0, tMax = 0.0;
            if (!_bounds.IntersectP (ray, out tMin, out tMax))
                return false;

            Vector inverseDirection = new Vector (1.0 / ray.Direction.x, 1.0 / ray.Direction.y, 1.0 / ray.Direction.z);

            KdToDo[] todo = ToDoPool.Get ();
            int todoPosition = 0;

            while (index >= 0 && index < _nodes.Length)
            {
                if (_nodes[index].IsLeaf)
                {
                    int numberOfPrimitives = _nodes[index].NumberOfPrimitives;
                    if (numberOfPrimitives == 1)
                    {
                        IPrimitive primitive = _primitives[_nodes[index].OnePrimitive];
                        if (primitive.IntersectP (ray))
                        {
                            ToDoPool.Free (todo);
                            return true;
                        }
                    }
                    else
                    {
                        for (int i = 0; i < numberOfPrimitives; ++i)
                        {
                            IPrimitive primitive = _primitives[_nodes[index].Primitives[i]];
                            if (primitive.IntersectP (ray))
                            {
                                ToDoPool.Free (todo);
                                return true;
                            }
                        }
                    }

                    // Grab next node to process from todo list
                    if (todoPosition > 0)
                    {
                        --todoPosition;
                        tMin = todo[todoPosition].tMin;
                        tMax = todo[todoPosition].tMax;
                        index = todo[todoPosition].Index;
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    // Process kd-Tree interior node
                    // Compute parametric distance along ray to split plane
                    int axis = _nodes[index].SplitAxis;
                    double tPlane = (_nodes[index].Split - ray.Origin[axis]) * inverseDirection[axis];

                    // Get node children for ray
                    bool belowFirst = (ray.Origin[axis] < _nodes[index].Split) || (ray.Origin[axis] == _nodes[index].Split && ray.Direction[axis] >= 0);

                    int firstIndex, secondIndex;
                    if (belowFirst)
                    {
                        firstIndex = index + 1;
                        secondIndex = _nodes[index].AboveChild;
                    }
                    else
                    {
                        firstIndex = _nodes[index].AboveChild;
                        secondIndex = index + 1;
                    }

                    // Advance to next child node, possibly enqueue other child
                    if (tPlane > tMax || tPlane <= 0)
                    {
                        index = firstIndex;
                    }

                    else if (tPlane < tMin)
                    {
                        index = secondIndex;
                    }
                    else
                    {
                        todo[todoPosition].tMin = tPlane;
                        todo[todoPosition].tMax = tMax;
                        todo[todoPosition].Index = secondIndex;
                        ++todoPosition;
                        tMax = tPlane;
                        index = firstIndex;
                    }
                }
            }
            ToDoPool.Free (todo);
            return false;
        }
コード例 #24
0
ファイル: RayDifferential.cs プロジェクト: Kintaro/Hyperion
 public RayDifferential(Ray ray)
     : this(ray.Origin, ray.Direction, ray.MinT, ray.MaxT, ray.Time, ray.Depth)
 {
 }
コード例 #25
0
ファイル: ICamera.cs プロジェクト: Kintaro/Hyperion
 public abstract double GenerateRay(CameraSample sample, ref Ray ray);
コード例 #26
0
ファイル: RayDifferential.cs プロジェクト: Kintaro/Hyperion
 public RayDifferential(Point origin, Vector direction, Ray parent, double start)
     : this(origin, direction, parent, start, double.PositiveInfinity)
 {
 }
コード例 #27
0
ファイル: Grid.cs プロジェクト: Kintaro/Hyperion
        public override bool IntersectP(Ray ray)
        {
            double rayT = 0.0, t = 0.0;
            if (Bounds.Inside (ray.Apply (ray.MinT)))
                rayT = ray.MinT;
            else if (!Bounds.IntersectP (ray, out rayT, out t))
                return false;
            Point gridIntersect = ray.Apply (rayT);

            double[] nextCrossing = new double[3];
            double[] delta = new double[3];
            int[] Step = new int[3];
            int[] Out = new int[3];
            int[] Pos = new int[3];

            for (int axis = 0; axis < 3; ++axis)
            {
                Pos[axis] = PositionToVoxel (gridIntersect, axis);
                if (ray.Direction[axis] >= 0)
                {
                    nextCrossing[axis] = rayT + (VoxelToPos (Pos[axis] + 1, axis) - gridIntersect[axis]) / ray.Direction[axis];
                    delta[axis] = Width[axis] / ray.Direction[axis];
                    Step[axis] = 1;
                    Out[axis] = nVoxels[axis];
                }

                else
                {
                    nextCrossing[axis] = rayT + (VoxelToPos (Pos[axis], axis) - gridIntersect[axis]) / ray.Direction[axis];
                    delta[axis] = -Width[axis] / ray.Direction[axis];
                    Step[axis] = -1;
                    Out[axis] = -1;
                }
            }

            while (true)
            {
                Voxel voxel = Voxels[Offset (Pos[0], Pos[1], Pos[2])];
                if (voxel != null)
                {
                    if (voxel.IntersectP (ray))
                        return true;
                }

                int bits = (((nextCrossing[0] < nextCrossing[1]) ? 1 : 0) << 2) + (((nextCrossing[0] < nextCrossing[2]) ? 1 : 0) << 1) + (((nextCrossing[1] < nextCrossing[2]) ? 1 : 0));
                int[] cmpTpAxis = new int[] { 2, 1, 2, 1, 2, 2, 0, 0 };
                int stepAxis = cmpTpAxis[bits];
                if (ray.MaxT < nextCrossing[stepAxis])
                {
                    break;
                }
                Pos[stepAxis] += Step[stepAxis];
                if (Pos[stepAxis] == Out[stepAxis])
                    break;
                nextCrossing[stepAxis] += delta[stepAxis];
            }
            return false;
        }
コード例 #28
0
ファイル: RayDifferential.cs プロジェクト: Kintaro/Hyperion
 public RayDifferential(Point origin, Vector direction, Ray parent, double start, double end)
     : base(origin, direction, start, end, parent.Time, parent.Depth + 1)
 {
     HasDifferentials = false;
 }
コード例 #29
0
ファイル: AnimatedTransform.cs プロジェクト: Kintaro/Hyperion
 public void Apply(Ray r, ref Ray tr)
 {
     if (!ActuallyAnimated || r.Time <= StartTime)
         StartTransform.Apply (r, ref tr);
     else if (r.Time >= EndTime)
         EndTransform.Apply (r, ref tr);
     else
     {
         Transform t = new Transform ();
         Interpolate (r.Time, ref t);
         t.Apply (r, ref tr);
     }
     tr.Time = r.Time;
 }
コード例 #30
0
ファイル: Scene.cs プロジェクト: Kintaro/Hyperion
 public bool IntersectP(Ray ray)
 {
     return Aggregate.IntersectP (ray);
 }