Beispiel #1
0
 public Sphere(Transform objectToWorld, bool reverseOrientation,
               float radius, float z0, float z1, float phiMax)
     : base(objectToWorld, reverseOrientation)
 {
     _radius   = radius;
     _zMin     = MathUtility.Clamp(Math.Min(z0, z1), -radius, radius);
     _zMax     = MathUtility.Clamp(Math.Max(z0, z1), -radius, radius);
     _thetaMin = MathUtility.Acos(MathUtility.Clamp(_zMin / radius, -1.0f, 1.0f));
     _thetaMax = MathUtility.Acos(MathUtility.Clamp(_zMax / radius, -1.0f, 1.0f));
     _phiMax   = MathUtility.ToRadians(MathUtility.Clamp(phiMax, 0.0f, 360.0f));
 }
Beispiel #2
0
        public static Quaternion Slerp(float t, Quaternion q1, Quaternion q2)
        {
            float cosTheta = Dot(q1, q2);

            if (cosTheta > .9995f)
            {
                return(Normalize((1.0f - t) * q1 + t * q2));
            }
            float      theta  = MathUtility.Acos(MathUtility.Clamp(cosTheta, -1.0f, 1.0f));
            float      thetap = theta * t;
            Quaternion qperp  = Normalize(q2 - q1 * cosTheta);

            return(q1 * MathUtility.Cos(thetap) + qperp * MathUtility.Sin(thetap));
        }
Beispiel #3
0
        public override bool TryIntersect(Ray r, out float tHit, out float rayEpsilon, out DifferentialGeometry dg)
        {
            tHit       = float.NegativeInfinity;
            rayEpsilon = 0.0f;
            dg         = null;

            float phi;
            Point phit;
            float thit;

            if (!DoIntersection(r, out phi, out phit, out thit))
            {
                return(false);
            }

            // Find parametric representation of sphere hit
            float u     = phi / _phiMax;
            float theta = MathUtility.Acos(MathUtility.Clamp(phit.Z / _radius, -1.0f, 1.0f));
            float v     = (theta - _thetaMin) / (_thetaMax - _thetaMin);

            // Compute sphere $\dpdu$ and $\dpdv$
            float zradius    = MathUtility.Sqrt(phit.X * phit.X + phit.Y * phit.Y);
            float invzradius = 1.0f / zradius;
            float cosphi     = phit.X * invzradius;
            float sinphi     = phit.Y * invzradius;
            var   dpdu       = new Vector(-_phiMax * phit.Y, _phiMax * phit.X, 0);
            var   dpdv       = (_thetaMax - _thetaMin) *
                               new Vector(phit.Z * cosphi, phit.Z * sinphi, -_radius * MathUtility.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.0f);
            Vector d2Pdvv = -(_thetaMax - _thetaMin) * (_thetaMax - _thetaMin) * new Vector(phit.X, phit.Y, phit.Z);

            // Compute coefficients for fundamental forms
            float  E = Vector.Dot(dpdu, dpdu);
            float  F = Vector.Dot(dpdu, dpdv);
            float  G = Vector.Dot(dpdv, dpdv);
            Vector N = Vector.Normalize(Vector.Cross(dpdu, dpdv));
            float  e = Vector.Dot(N, d2Pduu);
            float  f = Vector.Dot(N, d2Pduv);
            float  g = Vector.Dot(N, d2Pdvv);

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

            // Initialize _DifferentialGeometry_ from parametric information
            var o2w = ObjectToWorld;

            dg = new DifferentialGeometry(
                o2w.TransformPoint(ref phit),
                o2w.TransformVector(ref dpdu),
                o2w.TransformVector(ref dpdv),
                o2w.TransformNormal(ref dndu),
                o2w.TransformNormal(ref dndv),
                u, v, this);

            // Update _tHit_ for quadric intersection
            tHit = thit;

            // Compute _rayEpsilon_ for quadric intersection
            rayEpsilon = 5e-4f * tHit;
            return(true);
        }
Beispiel #4
0
 public static float SphericalTheta(Vector v)
 {
     return(MathUtility.Acos(MathUtility.Clamp(v.Z, -1.0f, 1.0f)));
 }