示例#1
0
 public uint4x2(sfloat v)
 {
     this.c0 = new uint4(v);
     this.c1 = new uint4(v);
 }
示例#2
0
 public int3x3(sfloat v)
 {
     this.c0 = (int3)v;
     this.c1 = (int3)v;
     this.c2 = (int3)v;
 }
示例#3
0
 public FloatRange(sfloat min, sfloat max)
 {
     Min = min;
     Max = max;
 }
示例#4
0
        public void AddForce(sfloat Force, svector3 Direction)
        {
            sfloat Acceleration = Force / (sfloat)Mass;

            CalculationVelocity += (Vector3) new svector3(Direction.x * Acceleration, Direction.y * Acceleration, Direction.z * Acceleration);
        }
示例#5
0
        public void Solve(ref MotionVelocity velocityA, ref MotionVelocity velocityB, sfloat timestep, sfloat invTimestep)
        {
            // Predict the relative orientation at the end of the step
            quaternion futureBFromA = JacobianUtilities.IntegrateOrientationBFromA(BFromA, velocityA.AngularVelocity, velocityB.AngularVelocity, timestep);

            // Find the future axis and angle of rotation between the free axes
            float3 jacA0, jacA1, jacA2, jacB0, jacB1, jacB2;
            float3 effectiveMass; // first column of 3x3 effective mass matrix, don't need the others because only jac0 can have nonzero error
            sfloat futureAngle;
            {
                // Calculate the relative rotation between joint spaces
                quaternion jointOrientation = math.mul(math.inverse(RefBFromA), futureBFromA);

                // Find the axis and angle of rotation
                jacA0 = jointOrientation.value.xyz;
                sfloat sinHalfAngleSq  = math.lengthsq(jacA0);
                sfloat invSinHalfAngle = Math.RSqrtSafe(sinHalfAngleSq);
                sfloat sinHalfAngle    = sinHalfAngleSq * invSinHalfAngle;
                futureAngle = math.asin(sinHalfAngle) * (sfloat)2.0f;

                jacA0 = math.select(jacA0 * invSinHalfAngle, new float3(sfloat.One, sfloat.Zero, sfloat.Zero), invSinHalfAngle.IsZero());
                jacA0 = math.select(jacA0, -jacA0, jointOrientation.value.w < sfloat.Zero);
                Math.CalculatePerpendicularNormalized(jacA0, out jacA1, out jacA2);

                jacB0 = math.mul(futureBFromA, -jacA0);
                jacB1 = math.mul(futureBFromA, -jacA1);
                jacB2 = math.mul(futureBFromA, -jacA2);

                // Calculate the effective mass
                float3 invEffectiveMassDiag = new float3(
                    math.csum(jacA0 * jacA0 * velocityA.InverseInertia + jacB0 * jacB0 * velocityB.InverseInertia),
                    math.csum(jacA1 * jacA1 * velocityA.InverseInertia + jacB1 * jacB1 * velocityB.InverseInertia),
                    math.csum(jacA2 * jacA2 * velocityA.InverseInertia + jacB2 * jacB2 * velocityB.InverseInertia));
                float3 invEffectiveMassOffDiag = new float3(
                    math.csum(jacA0 * jacA1 * velocityA.InverseInertia + jacB0 * jacB1 * velocityB.InverseInertia),
                    math.csum(jacA0 * jacA2 * velocityA.InverseInertia + jacB0 * jacB2 * velocityB.InverseInertia),
                    math.csum(jacA1 * jacA2 * velocityA.InverseInertia + jacB1 * jacB2 * velocityB.InverseInertia));
                JacobianUtilities.InvertSymmetricMatrix(invEffectiveMassDiag, invEffectiveMassOffDiag, out float3 effectiveMassDiag, out float3 effectiveMassOffDiag);
                effectiveMass = JacobianUtilities.BuildSymmetricMatrix(effectiveMassDiag, effectiveMassOffDiag).c0;
            }

            // Calculate the error, adjust by tau and damping, and apply an impulse to correct it
            sfloat futureError   = JacobianUtilities.CalculateError(futureAngle, MinAngle, MaxAngle);
            sfloat solveError    = JacobianUtilities.CalculateCorrection(futureError, InitialError, Tau, Damping);
            sfloat solveVelocity = -solveError * invTimestep;
            float3 impulseA      = solveVelocity * (jacA0 * effectiveMass.x + jacA1 * effectiveMass.y + jacA2 * effectiveMass.z);
            float3 impulseB      = solveVelocity * (jacB0 * effectiveMass.x + jacB1 * effectiveMass.y + jacB2 * effectiveMass.z);

            velocityA.ApplyAngularImpulse(impulseA);
            velocityB.ApplyAngularImpulse(impulseB);
        }
示例#6
0
 /// <summary>
 /// Returns the remainder when dividing x by y
 /// </summary>
 public static sfloat remainderf(sfloat x, sfloat y)
 {
     remquof(x, y, out sfloat remainder, out _);
     return(remainder);
 }
示例#7
0
        /// <summary>
        /// Returns the square root of x
        /// </summary>
        public static sfloat sqrtf(sfloat x)
        {
            int  sign = unchecked ((int)0x80000000);
            int  ix;
            int  s;
            int  q;
            int  m;
            int  t;
            int  i;
            uint r;

            ix = (int)x.RawValue;

            /* take care of Inf and NaN */
            if (((uint)ix & 0x7f800000) == 0x7f800000)
            {
                //return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */
                if (x.IsNaN() || x.IsNegativeInfinity())
                {
                    return(sfloat.NaN);
                }
                else // if (x.IsPositiveInfinity())
                {
                    return(sfloat.PositiveInfinity);
                }
            }

            /* take care of zero */
            if (ix <= 0)
            {
                if ((ix & ~sign) == 0)
                {
                    return(x); /* sqrt(+-0) = +-0 */
                }

                if (ix < 0)
                {
                    //return (x - x) / (x - x); /* sqrt(-ve) = sNaN */
                    return(sfloat.NaN);
                }
            }

            /* normalize x */
            m = ix >> 23;
            if (m == 0)
            {
                /* subnormal x */
                i = 0;
                while ((ix & 0x00800000) == 0)
                {
                    ix <<= 1;
                    i   += 1;
                }

                m -= i - 1;
            }

            m -= 127; /* unbias exponent */
            ix = (ix & 0x007fffff) | 0x00800000;
            if ((m & 1) == 1)
            {
                /* odd m, double x to make it even */
                ix += ix;
            }

            m >>= 1; /* m = [m/2] */

            /* generate sqrt(x) bit by bit */
            ix += ix;
            q   = 0;
            s   = 0;
            r   = 0x01000000; /* r = moving bit from right to left */

            while (r != 0)
            {
                t = s + (int)r;
                if (t <= ix)
                {
                    s   = t + (int)r;
                    ix -= t;
                    q  += (int)r;
                }

                ix += ix;
                r >>= 1;
            }

            /* use floating add to find out rounding direction */
            if (ix != 0)
            {
                q += q & 1;
            }

            ix  = (q >> 1) + 0x3f000000;
            ix += m << 23;
            return(sfloat.FromRaw((uint)ix));
        }
示例#8
0
 public uint4x3(sfloat v)
 {
     this.c0 = (uint4)v;
     this.c1 = (uint4)v;
     this.c2 = (uint4)v;
 }
示例#9
0
        // Solve the Jacobian
        public void Solve(ref MotionVelocity velocityA, ref MotionVelocity velocityB, sfloat timestep, sfloat invTimestep)
        {
            // Predict the relative orientation at the end of the step
            quaternion futureBFromA = JacobianUtilities.IntegrateOrientationBFromA(BFromA, velocityA.AngularVelocity, velocityB.AngularVelocity, timestep);

            // Calculate the jacobian axis and angle
            float3 axisAinB     = math.mul(futureBFromA, AxisAinA);
            float3 jacB0        = math.cross(axisAinB, AxisBinB);
            float3 jacA0        = math.mul(math.inverse(futureBFromA), -jacB0);
            sfloat jacLengthSq  = math.lengthsq(jacB0);
            sfloat invJacLength = Math.RSqrtSafe(jacLengthSq);
            sfloat futureAngle;
            {
                sfloat sinAngle = jacLengthSq * invJacLength;
                sfloat cosAngle = math.dot(axisAinB, AxisBinB);
                futureAngle = math.atan2(sinAngle, cosAngle);
            }

            // Choose a second jacobian axis perpendicular to A
            float3 jacB1 = math.cross(jacB0, axisAinB);
            float3 jacA1 = math.mul(math.inverse(futureBFromA), -jacB1);

            // Calculate effective mass
            float2 effectiveMass; // First column of the 2x2 matrix, we don't need the second column because the second component of error is zero

            {
                // Calculate the inverse effective mass matrix, then invert it
                sfloat invEffMassDiag0   = math.csum(jacA0 * jacA0 * velocityA.InverseInertia + jacB0 * jacB0 * velocityB.InverseInertia);
                sfloat invEffMassDiag1   = math.csum(jacA1 * jacA1 * velocityA.InverseInertia + jacB1 * jacB1 * velocityB.InverseInertia);
                sfloat invEffMassOffDiag = math.csum(jacA0 * jacA1 * velocityA.InverseInertia + jacB0 * jacB1 * velocityB.InverseInertia);
                sfloat det    = invEffMassDiag0 * invEffMassDiag1 - invEffMassOffDiag * invEffMassOffDiag;
                sfloat invDet = math.select(jacLengthSq / det, sfloat.Zero, det.IsZero()); // scale by jacLengthSq because the jacs were not normalized
                effectiveMass = invDet * new float2(invEffMassDiag1, -invEffMassOffDiag);
            }

            // Normalize the jacobians
            jacA0 *= invJacLength;
            jacB0 *= invJacLength;
            jacA1 *= invJacLength;
            jacB1 *= invJacLength;

            // Calculate the error, adjust by tau and damping, and apply an impulse to correct it
            sfloat futureError = JacobianUtilities.CalculateError(futureAngle, MinAngle, MaxAngle);
            sfloat solveError  = JacobianUtilities.CalculateCorrection(futureError, InitialError, Tau, Damping);
            float2 impulse     = -effectiveMass * solveError * invTimestep;

            velocityA.ApplyAngularImpulse(impulse.x * jacA0 + impulse.y * jacA1);
            velocityB.ApplyAngularImpulse(impulse.x * jacB0 + impulse.y * jacB1);
        }
示例#10
0
        /// <summary>
        /// Returns e raised to the power x (e ~= 2.71828182845904523536)
        /// </summary>
        public static sfloat expf(sfloat x)
        {
            const uint LN2_HI_U32  = 0x3f317200;         // 6.9314575195e-01
            const uint LN2_LO_U32  = 0x35bfbe8e;         // 1.4286067653e-06
            const uint INV_LN2_U32 = 0x3fb8aa3b;         // 1.4426950216e+00

            const uint P1_U32 = 0x3e2aaa8f;              // 1.6666625440e-1 /*  0xaaaa8f.0p-26 */
            const uint P2_U32 = 0xbb355215;              // -2.7667332906e-3 /* -0xb55215.0p-32 */

            sfloat x1p127  = sfloat.FromRaw(0x7f000000); // 0x1p127f === 2 ^ 127
            sfloat x1p_126 = sfloat.FromRaw(0x800000);   // 0x1p-126f === 2 ^ -126  /*original 0x1p-149f    ??????????? */
            uint   hx      = x.RawValue;
            int    sign    = (int)(hx >> 31);            /* sign bit of x */
            bool   signb   = sign != 0;

            hx &= 0x7fffffff; /* high word of |x| */

            /* special cases */
            if (hx >= 0x42aeac50)
            {
                /* if |x| >= -87.33655f or NaN */
                if (hx > 0x7f800000)
                {
                    /* NaN */
                    return(x);
                }

                if (hx >= 0x42b17218 && !signb)
                {
                    /* x >= 88.722839f */
                    /* overflow */
                    x *= x1p127;
                    return(x);
                }

                if (signb)
                {
                    /* underflow */
                    //force_eval!(-x1p_126 / x);

                    if (hx >= 0x42cff1b5)
                    {
                        /* x <= -103.972084f */
                        return(sfloat.Zero);
                    }
                }
            }

            /* argument reduction */
            int    k;
            sfloat hi;
            sfloat lo;

            if (hx > 0x3eb17218)
            {
                /* if |x| > 0.5 ln2 */
                if (hx > 0x3f851592)
                {
                    /* if |x| > 1.5 ln2 */
                    k = (int)(sfloat.FromRaw(INV_LN2_U32) * x + (signb ? (sfloat)0.5f : (sfloat)(-0.5f)));
                }
                else
                {
                    k = 1 - sign - sign;
                }

                sfloat kf = (sfloat)k;
                hi = x - kf * sfloat.FromRaw(LN2_HI_U32); /* k*ln2hi is exact here */
                lo = kf * sfloat.FromRaw(LN2_LO_U32);
                x  = hi - lo;
            }
            else if (hx > 0x39000000)
            {
                /* |x| > 2**-14 */
                k  = 0;
                hi = x;
                lo = sfloat.Zero;
            }
            else
            {
                /* raise inexact */
                //force_eval!(x1p127 + x);
                return(sfloat.One + x);
            }

            /* x is now in primary range */
            sfloat xx = x * x;
            sfloat c  = x - xx * (sfloat.FromRaw(P1_U32) + xx * sfloat.FromRaw(P2_U32));
            sfloat y  = sfloat.One + (x * c / ((sfloat)2.0f - c) - lo + hi);

            return(k == 0 ? y : scalbnf(y, k));
        }
示例#11
0
 public static uint4x3 uint4x3(sfloat v)
 {
     return(new uint4x3(v));
 }
示例#12
0
        /// <summary>
        /// Returns x raised to the power y
        /// </summary>
        public static sfloat powf(sfloat x, sfloat y)
        {
            const uint BP_0_U32    = 0x3f800000; /* 1.0 */
            const uint BP_1_U32    = 0x3fc00000; /* 1.5 */
            const uint DP_H_0_U32  = 0x00000000; /* 0.0 */
            const uint DP_H_1_U32  = 0x3f15c000; /* 5.84960938e-01 */
            const uint DP_L_0_U32  = 0x00000000; /* 0.0 */
            const uint DP_L_1_U32  = 0x35d1cfdc; /* 1.56322085e-06 */
            const uint TWO24_U32   = 0x4b800000; /* 16777216.0 */
            const uint HUGE_U32    = 0x7149f2ca; /* 1.0e30 */
            const uint TINY_U32    = 0x0da24260; /* 1.0e-30 */
            const uint L1_U32      = 0x3f19999a; /* 6.0000002384e-01 */
            const uint L2_U32      = 0x3edb6db7; /* 4.2857143283e-01 */
            const uint L3_U32      = 0x3eaaaaab; /* 3.3333334327e-01 */
            const uint L4_U32      = 0x3e8ba305; /* 2.7272811532e-01 */
            const uint L5_U32      = 0x3e6c3255; /* 2.3066075146e-01 */
            const uint L6_U32      = 0x3e53f142; /* 2.0697501302e-01 */
            const uint P1_U32      = 0x3e2aaaab; /* 1.6666667163e-01 */
            const uint P2_U32      = 0xbb360b61; /* -2.7777778450e-03 */
            const uint P3_U32      = 0x388ab355; /* 6.6137559770e-05 */
            const uint P4_U32      = 0xb5ddea0e; /* -1.6533901999e-06 */
            const uint P5_U32      = 0x3331bb4c; /* 4.1381369442e-08 */
            const uint LG2_U32     = 0x3f317218; /* 6.9314718246e-01 */
            const uint LG2_H_U32   = 0x3f317200; /* 6.93145752e-01 */
            const uint LG2_L_U32   = 0x35bfbe8c; /* 1.42860654e-06 */
            const uint OVT_U32     = 0x3338aa3c; /* 4.2995665694e-08 =-(128-log2(ovfl+.5ulp)) */
            const uint CP_U32      = 0x3f76384f; /* 9.6179670095e-01 =2/(3ln2) */
            const uint CP_H_U32    = 0x3f764000; /* 9.6191406250e-01 =12b cp */
            const uint CP_L_U32    = 0xb8f623c6; /* -1.1736857402e-04 =tail of cp_h */
            const uint IVLN2_U32   = 0x3fb8aa3b; /* 1.4426950216e+00 */
            const uint IVLN2_H_U32 = 0x3fb8aa00; /* 1.4426879883e+00 */
            const uint IVLN2_L_U32 = 0x36eca570; /* 7.0526075433e-06 */

            sfloat z;
            sfloat ax;
            sfloat z_h;
            sfloat z_l;
            sfloat p_h;
            sfloat p_l;
            sfloat y1;
            sfloat t1;
            sfloat t2;
            sfloat r;
            sfloat s;
            sfloat sn;
            sfloat t;
            sfloat u;
            sfloat v;
            sfloat w;
            int    i;
            int    j;
            int    k;
            int    yisint;
            int    n;
            int    hx;
            int    hy;
            int    ix;
            int    iy;
            int    iS;

            hx = (int)x.RawValue;
            hy = (int)y.RawValue;

            ix = hx & 0x7fffffff;
            iy = hy & 0x7fffffff;

            /* x**0 = 1, even if x is NaN */
            if (iy == 0)
            {
                return(sfloat.One);
            }

            /* 1**y = 1, even if y is NaN */
            if (hx == 0x3f800000)
            {
                return(sfloat.One);
            }

            /* NaN if either arg is NaN */
            if (ix > 0x7f800000 || iy > 0x7f800000)
            {
                return(sfloat.NaN);
            }

            /* determine if y is an odd int when x < 0
             * yisint = 0       ... y is not an integer
             * yisint = 1       ... y is an odd int
             * yisint = 2       ... y is an even int
             */
            yisint = 0;
            if (hx < 0)
            {
                if (iy >= 0x4b800000)
                {
                    yisint = 2; /* even integer y */
                }
                else if (iy >= 0x3f800000)
                {
                    k = (iy >> 23) - 0x7f; /* exponent */
                    j = iy >> (23 - k);
                    if ((j << (23 - k)) == iy)
                    {
                        yisint = 2 - (j & 1);
                    }
                }
            }

            /* special value of y */
            if (iy == 0x7f800000)
            {
                /* y is +-inf */
                if (ix == 0x3f800000)
                {
                    /* (-1)**+-inf is 1 */
                    return(sfloat.One);
                }
                else if (ix > 0x3f800000)
                {
                    /* (|x|>1)**+-inf = inf,0 */
                    return(hy >= 0 ? y : sfloat.Zero);
                }
                else
                {
                    /* (|x|<1)**+-inf = 0,inf */
                    return(hy >= 0 ? sfloat.Zero : -y);
                }
            }

            if (iy == 0x3f800000)
            {
                /* y is +-1 */
                return(hy >= 0 ? x : sfloat.One / x);
            }

            if (hy == 0x40000000)
            {
                /* y is 2 */
                return(x * x);
            }

            if (hy == 0x3f000000
                /* y is  0.5 */
                && hx >= 0)
            {
                /* x >= +0 */
                return(sqrtf(x));
            }

            ax = sfloat.Abs(x);
            /* special value of x */
            if (ix == 0x7f800000 || ix == 0 || ix == 0x3f800000)
            {
                /* x is +-0,+-inf,+-1 */
                z = ax;
                if (hy < 0)
                {
                    /* z = (1/|x|) */
                    z = sfloat.One / z;
                }

                if (hx < 0)
                {
                    if (((ix - 0x3f800000) | yisint) == 0)
                    {
                        z = (z - z) / (z - z); /* (-1)**non-int is NaN */
                    }
                    else if (yisint == 1)
                    {
                        z = -z; /* (x<0)**odd = -(|x|**odd) */
                    }
                }

                return(z);
            }

            sn = sfloat.One; /* sign of result */
            if (hx < 0)
            {
                if (yisint == 0)
                {
                    /* (x<0)**(non-int) is NaN */
                    //return (x - x) / (x - x);
                    return(sfloat.NaN);
                }

                if (yisint == 1)
                {
                    /* (x<0)**(odd int) */
                    sn = -sfloat.One;
                }
            }

            /* |y| is HUGE */
            if (iy > 0x4d000000)
            {
                /* if |y| > 2**27 */
                /* over/underflow if x is not close to one */
                if (ix < 0x3f7ffff8)
                {
                    return(hy < 0
                        ? sn * sfloat.FromRaw(HUGE_U32) * sfloat.FromRaw(HUGE_U32)
                        : sn *sfloat.FromRaw(TINY_U32) * sfloat.FromRaw(TINY_U32));
                }

                if (ix > 0x3f800007)
                {
                    return(hy > 0
                        ? sn * sfloat.FromRaw(HUGE_U32) * sfloat.FromRaw(HUGE_U32)
                        : sn *sfloat.FromRaw(TINY_U32) * sfloat.FromRaw(TINY_U32));
                }

                /* now |1-x| is TINY <= 2**-20, suffice to compute
                 * log(x) by x-x^2/2+x^3/3-x^4/4 */
                t  = ax - sfloat.One;                 /* t has 20 trailing zeros */
                w  = (t * t) * (sfloat.FromRaw(0x3f000000) - t * (sfloat.FromRaw(0x3eaaaaab) - t * sfloat.FromRaw(0x3e800000)));
                u  = sfloat.FromRaw(IVLN2_H_U32) * t; /* IVLN2_H has 16 sig. bits */
                v  = t * sfloat.FromRaw(IVLN2_L_U32) - w * sfloat.FromRaw(IVLN2_U32);
                t1 = u + v;
                iS = (int)t1.RawValue;
                t1 = sfloat.FromRaw((uint)iS & 0xfffff000);
                t2 = v - (t1 - u);
            }
            else
            {
                sfloat s2;
                sfloat s_h;
                sfloat s_l;
                sfloat t_h;
                sfloat t_l;

                n = 0;
                /* take care subnormal number */
                if (ix < 0x00800000)
                {
                    ax *= sfloat.FromRaw(TWO24_U32);
                    n  -= 24;
                    ix  = (int)ax.RawValue;
                }

                n += ((ix) >> 23) - 0x7f;
                j  = ix & 0x007fffff;
                /* determine interval */
                ix = j | 0x3f800000; /* normalize ix */
                if (j <= 0x1cc471)
                {
                    /* |x|<sqrt(3/2) */
                    k = 0;
                }
                else if (j < 0x5db3d7)
                {
                    /* |x|<sqrt(3)   */
                    k = 1;
                }
                else
                {
                    k   = 0;
                    n  += 1;
                    ix -= 0x00800000;
                }

                ax = sfloat.FromRaw((uint)ix);

                /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
                u   = ax - sfloat.FromRaw(k == 0 ? BP_0_U32 : BP_1_U32); /* bp[0]=1.0, bp[1]=1.5 */
                v   = sfloat.One / (ax + sfloat.FromRaw(k == 0 ? BP_0_U32 : BP_1_U32));
                s   = u * v;
                s_h = s;
                iS  = (int)s_h.RawValue;
                s_h = sfloat.FromRaw((uint)iS & 0xfffff000);

                /* t_h=ax+bp[k] High */
                iS  = (int)((((uint)ix >> 1) & 0xfffff000) | 0x20000000);
                t_h = sfloat.FromRaw((uint)iS + 0x00400000 + (((uint)k) << 21));
                t_l = ax - (t_h - sfloat.FromRaw(k == 0 ? BP_0_U32 : BP_1_U32));
                s_l = v * ((u - s_h * t_h) - s_h * t_l);

                /* compute log(ax) */
                s2  = s * s;
                r   = s2 * s2 * (sfloat.FromRaw(L1_U32) + s2 * (sfloat.FromRaw(L2_U32) + s2 * (sfloat.FromRaw(L3_U32) + s2 * (sfloat.FromRaw(L4_U32) + s2 * (sfloat.FromRaw(L5_U32) + s2 * sfloat.FromRaw(L6_U32))))));
                r  += s_l * (s_h + s);
                s2  = s_h * s_h;
                t_h = sfloat.FromRaw(0x40400000) + s2 + r;
                iS  = (int)t_h.RawValue;
                t_h = sfloat.FromRaw((uint)iS & 0xfffff000);
                t_l = r - ((t_h - sfloat.FromRaw(0x40400000)) - s2);

                /* u+v = s*(1+...) */
                u = s_h * t_h;
                v = s_l * t_h + t_l * s;

                /* 2/(3log2)*(s+...) */
                p_h = u + v;
                iS  = (int)p_h.RawValue;
                p_h = sfloat.FromRaw((uint)iS & 0xfffff000);
                p_l = v - (p_h - u);
                z_h = sfloat.FromRaw(CP_H_U32) * p_h; /* cp_h+cp_l = 2/(3*log2) */
                z_l = sfloat.FromRaw(CP_L_U32) * p_h + p_l * sfloat.FromRaw(CP_U32) + sfloat.FromRaw(k == 0 ? DP_L_0_U32 : DP_L_1_U32);

                /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
                t  = (sfloat)n;
                t1 = ((z_h + z_l) + sfloat.FromRaw(k == 0 ? DP_H_0_U32 : DP_H_1_U32)) + t;
                iS = (int)t1.RawValue;
                t1 = sfloat.FromRaw((uint)iS & 0xfffff000);
                t2 = z_l - (((t1 - t) - sfloat.FromRaw(k == 0 ? DP_H_0_U32 : DP_H_1_U32)) - z_h);
            };

            /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
            iS  = (int)y.RawValue;
            y1  = sfloat.FromRaw((uint)iS & 0xfffff000);
            p_l = (y - y1) * t1 + y * t2;
            p_h = y1 * t1;
            z   = p_l + p_h;
            j   = (int)z.RawValue;
            if (j > 0x43000000)
            {
                /* if z > 128 */
                return(sn * sfloat.FromRaw(HUGE_U32) * sfloat.FromRaw(HUGE_U32)); /* overflow */
            }
            else if (j == 0x43000000)
            {
                /* if z == 128 */
                if (p_l + sfloat.FromRaw(OVT_U32) > z - p_h)
                {
                    return(sn * sfloat.FromRaw(HUGE_U32) * sfloat.FromRaw(HUGE_U32)); /* overflow */
                }
            }
            else if ((j & 0x7fffffff) > 0x43160000)
            {
                /* z < -150 */
                // FIXME: check should be  (uint32_t)j > 0xc3160000
                return(sn * sfloat.FromRaw(TINY_U32) * sfloat.FromRaw(TINY_U32)); /* underflow */
            }
            else if ((uint)j == 0xc3160000
                     /* z == -150 */
                     && p_l <= z - p_h)
            {
                return(sn * sfloat.FromRaw(TINY_U32) * sfloat.FromRaw(TINY_U32)); /* underflow */
            }

            /*
             * compute 2**(p_h+p_l)
             */
            i = j & 0x7fffffff;
            k = (i >> 23) - 0x7f;
            n = 0;
            if (i > 0x3f000000)
            {
                /* if |z| > 0.5, set n = [z+0.5] */
                n = j + (0x00800000 >> (k + 1));
                k = ((n & 0x7fffffff) >> 23) - 0x7f; /* new k for n */
                t = sfloat.FromRaw((uint)n & ~(0x007fffffu >> k));
                n = ((n & 0x007fffff) | 0x00800000) >> (23 - k);
                if (j < 0)
                {
                    n = -n;
                }
                p_h -= t;
            }

            t  = p_l + p_h;
            iS = (int)t.RawValue;
            t  = sfloat.FromRaw((uint)iS & 0xffff8000);
            u  = t * sfloat.FromRaw(LG2_H_U32);
            v  = (p_l - (t - p_h)) * sfloat.FromRaw(LG2_U32) + t * sfloat.FromRaw(LG2_L_U32);
            z  = u + v;
            w  = v - (z - u);
            t  = z * z;
            t1 = z - t * (sfloat.FromRaw(P1_U32) + t * (sfloat.FromRaw(P2_U32) + t * (sfloat.FromRaw(P3_U32) + t * (sfloat.FromRaw(P4_U32) + t * sfloat.FromRaw(P5_U32)))));
            r  = (z * t1) / (t1 - sfloat.FromRaw(0x40000000)) - (w + z * w);
            z  = sfloat.One - (r - z);
            j  = (int)z.RawValue;
            j += n << 23;
            if ((j >> 23) <= 0)
            {
                /* subnormal output */
                z = scalbnf(z, n);
            }
            else
            {
                z = sfloat.FromRaw((uint)j);
            }

            return(sn * z);
        }
示例#13
0
        /// <summary>
        /// Returns the base 2 logarithm of x
        /// </summary>
        public static sfloat log2f(sfloat x)
        {
            const uint IVLN2HI_U32 = 0x3fb8b000; // 1.4428710938e+00
            const uint IVLN2LO_U32 = 0xb9389ad4; // -1.7605285393e-04

            /* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
            const uint LG1_U32 = 0x3f2aaaaa;            // 0.66666662693 /*  0xaaaaaa.0p-24*/
            const uint LG2_U32 = 0x3eccce13;            // 0.40000972152 /*  0xccce13.0p-25 */
            const uint LG3_U32 = 0x3e91e9ee;            // 0.28498786688 /*  0x91e9ee.0p-25 */
            const uint LG4_U32 = 0x3e789e26;            // 0.24279078841 /*  0xf89e26.0p-26 */

            sfloat x1p25f = sfloat.FromRaw(0x4c000000); // 0x1p25f === 2 ^ 25

            uint   ui = x.RawValue;
            sfloat hfsq;
            sfloat f;
            sfloat s;
            sfloat z;
            sfloat r;
            sfloat w;
            sfloat t1;
            sfloat t2;
            sfloat hi;
            sfloat lo;
            uint   ix;
            int    k;

            ix = ui;
            k  = 0;
            if (ix < 0x00800000 || (ix >> 31) > 0)
            {
                /* x < 2**-126  */
                if (ix << 1 == 0)
                {
                    //return -1. / (x * x); /* log(+-0)=-inf */
                    return(sfloat.NegativeInfinity);
                }

                if ((ix >> 31) > 0)
                {
                    //return (x - x) / 0.0; /* log(-#) = NaN */
                    return(sfloat.NaN);
                }

                /* subnormal number, scale up x */
                k -= 25;
                x *= x1p25f;
                ui = x.RawValue;
                ix = ui;
            }
            else if (ix >= 0x7f800000)
            {
                return(x);
            }
            else if (ix == 0x3f800000)
            {
                return(sfloat.Zero);
            }

            /* reduce x into [sqrt(2)/2, sqrt(2)] */
            ix += 0x3f800000 - 0x3f3504f3;
            k  += (int)(ix >> 23) - 0x7f;
            ix  = (ix & 0x007fffff) + 0x3f3504f3;
            ui  = ix;
            x   = sfloat.FromRaw(ui);

            f    = x - sfloat.One;
            s    = f / ((sfloat)2.0f + f);
            z    = s * s;
            w    = z * z;
            t1   = w * (sfloat.FromRaw(LG2_U32) + w * sfloat.FromRaw(LG4_U32));
            t2   = z * (sfloat.FromRaw(LG1_U32) + w * sfloat.FromRaw(LG3_U32));
            r    = t2 + t1;
            hfsq = (sfloat)0.5f * f * f;

            hi  = f - hfsq;
            ui  = hi.RawValue;
            ui &= 0xfffff000;
            hi  = sfloat.FromRaw(ui);
            lo  = f - hi - hfsq + s * (hfsq + r);
            return((lo + hi) * sfloat.FromRaw(IVLN2LO_U32) + lo * sfloat.FromRaw(IVLN2HI_U32) + hi * sfloat.FromRaw(IVLN2HI_U32) + (sfloat)k);
        }
示例#14
0
        /// <summary>
        /// Returns the natural logarithm (base e) of x
        /// </summary>
        public static sfloat logf(sfloat x)
        {
            const uint LN2_HI_U32 = 0x3f317180; // 6.9313812256e-01
            const uint LN2_LO_U32 = 0x3717f7d1; // 9.0580006145e-06

            /* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
            const uint LG1_U32 = 0x3f2aaaaa; // 0.66666662693 /*  0xaaaaaa.0p-24*/
            const uint LG2_U32 = 0x3eccce13; // 0.40000972152 /*  0xccce13.0p-25 */
            const uint LG3_U32 = 0x3e91e9ee; // 0.28498786688 /*  0x91e9ee.0p-25 */
            const uint LG4_U32 = 0x3e789e26; // 0.24279078841 /*  0xf89e26.0p-26 */

            uint ix = x.RawValue;
            int  k  = 0;

            if ((ix < 0x00800000) || ((ix >> 31) != 0))
            {
                /* x < 2**-126  */
                if (ix << 1 == 0)
                {
                    //return -1. / (x * x); /* log(+-0)=-inf */
                    return(sfloat.NegativeInfinity);
                }

                if ((ix >> 31) != 0)
                {
                    //return (x - x) / 0.; /* log(-#) = NaN */
                    return(sfloat.NaN);
                }

                /* subnormal number, scale up x */
                sfloat x1p25 = sfloat.FromRaw(0x4c000000); // 0x1p25f === 2 ^ 25
                k -= 25;
                x *= x1p25;
                ix = x.RawValue;
            }
            else if (ix >= 0x7f800000)
            {
                return(x);
            }
            else if (ix == 0x3f800000)
            {
                return(sfloat.Zero);
            }

            /* reduce x into [sqrt(2)/2, sqrt(2)] */
            ix += 0x3f800000 - 0x3f3504f3;
            k  += ((int)(ix >> 23)) - 0x7f;
            ix  = (ix & 0x007fffff) + 0x3f3504f3;
            x   = sfloat.FromRaw(ix);

            sfloat f    = x - sfloat.One;
            sfloat s    = f / ((sfloat)2.0f + f);
            sfloat z    = s * s;
            sfloat w    = z * z;
            sfloat t1   = w * (sfloat.FromRaw(LG2_U32) + w * sfloat.FromRaw(LG4_U32));
            sfloat t2   = z * (sfloat.FromRaw(LG1_U32) + w * sfloat.FromRaw(LG3_U32));
            sfloat r    = t2 + t1;
            sfloat hfsq = (sfloat)0.5f * f * f;
            sfloat dk   = (sfloat)k;

            return(s * (hfsq + r) + dk * sfloat.FromRaw(LN2_LO_U32) - hfsq + f + dk * sfloat.FromRaw(LN2_HI_U32));
        }
示例#15
0
 public static int3x2 int3x2(sfloat v)
 {
     return(new int3x2(v));
 }
示例#16
0
 public float2x2(sfloat m00, sfloat m01,
                 sfloat m10, sfloat m11)
 {
     this.c0 = new float2(m00, m10);
     this.c1 = new float2(m01, m11);
 }
示例#17
0
 public int3x2(sfloat v)
 {
     this.c0 = (int3)(float3)v;
     this.c1 = (int3)(float3)v;
 }
示例#18
0
 public static float2x2 float2x2(sfloat m00, sfloat m01,
                                 sfloat m10, sfloat m11)
 {
     return(new float2x2(m00, m01,
                         m10, m11));
 }
示例#19
0
        /// <summary>
        /// Returns x modulo y
        /// </summary>
        public static sfloat fmodf(sfloat x, sfloat y)
        {
            uint uxi = x.RawValue;
            uint uyi = y.RawValue;
            int  ex  = (int)(uxi >> 23 & 0xff);
            int  ey  = (int)(uyi >> 23 & 0xff);
            uint sx  = uxi & 0x80000000;
            uint i;

            if (uyi << 1 == 0 || y.IsNaN() || ex == 0xff)
            {
                return((x * y) / (x * y));
            }

            if (uxi << 1 <= uyi << 1)
            {
                if (uxi << 1 == uyi << 1)
                {
                    //return 0.0 * x;
                    return(sfloat.Zero);
                }

                return(x);
            }

            /* normalize x and y */
            if (ex == 0)
            {
                i = uxi << 9;
                while (i >> 31 == 0)
                {
                    ex -= 1;
                    i <<= 1;
                }

                uxi <<= -ex + 1;
            }
            else
            {
                uxi &= uint.MaxValue >> 9;
                uxi |= 1 << 23;
            }

            if (ey == 0)
            {
                i = uyi << 9;
                while (i >> 31 == 0)
                {
                    ey -= 1;
                    i <<= 1;
                }

                uyi <<= -ey + 1;
            }
            else
            {
                uyi &= uint.MaxValue >> 9;
                uyi |= 1 << 23;
            }

            /* x mod y */
            while (ex > ey)
            {
                i = uxi - uyi;
                if (i >> 31 == 0)
                {
                    if (i == 0)
                    {
                        //return 0.0 * x;
                        return(sfloat.Zero);
                    }

                    uxi = i;
                }

                uxi <<= 1;

                ex -= 1;
            }

            i = uxi - uyi;
            if (i >> 31 == 0)
            {
                if (i == 0)
                {
                    //return 0.0 * x;
                    return(sfloat.Zero);
                }

                uxi = i;
            }

            while (uxi >> 23 == 0)
            {
                uxi <<= 1;
                ex   -= 1;
            }

            /* scale result up */
            if (ex > 0)
            {
                uxi -= 1 << 23;
                uxi |= ((uint)ex) << 23;
            }
            else
            {
                uxi >>= -ex + 1;
            }

            uxi |= sx;
            return(sfloat.FromRaw(uxi));
        }
示例#20
0
 public float2x2(sfloat v)
 {
     this.c0 = v;
     this.c1 = v;
 }
示例#21
0
        /// <summary>
        /// Returns the remainder and the quotient when dividing x by y, so that x == y * quotient + remainder
        /// </summary>
        public static void remquof(sfloat x, sfloat y, out sfloat remainder, out int quotient)
        {
            uint ux = x.RawValue;
            uint uy = y.RawValue;
            int  ex = (int)((ux >> 23) & 0xff);
            int  ey = (int)((uy >> 23) & 0xff);
            bool sx = (ux >> 31) != 0;
            bool sy = (uy >> 31) != 0;
            uint q;
            uint i;
            var  uxi = ux;

            if ((uy << 1) == 0 || y.IsNaN() || ex == 0xff)
            {
                sfloat m = (x * y);
                remainder = m / m;
                quotient  = 0;
                return;
            }

            if ((ux << 1) == 0)
            {
                remainder = x;
                quotient  = 0;
                return;
            }

            /* normalize x and y */
            if (ex == 0)
            {
                i = uxi << 9;
                while ((i >> 31) == 0)
                {
                    ex -= 1;
                    i <<= 1;
                }

                uxi <<= -ex + 1;
            }
            else
            {
                uxi &= (~0u) >> 9;
                uxi |= 1 << 23;
            }

            if (ey == 0)
            {
                i = uy << 9;
                while ((i >> 31) == 0)
                {
                    ey -= 1;
                    i <<= 1;
                }

                uy <<= -ey + 1;
            }
            else
            {
                uy &= (~0u) >> 9;
                uy |= 1 << 23;
            }

            q = 0;
            if (ex + 1 != ey)
            {
                if (ex < ey)
                {
                    remainder = x;
                    quotient  = 0;
                    return;
                }

                /* x mod y */
                while (ex > ey)
                {
                    i = uxi - uy;
                    if ((i >> 31) == 0)
                    {
                        uxi = i;
                        q  += 1;
                    }

                    uxi <<= 1;
                    q   <<= 1;
                    ex   -= 1;
                }

                i = uxi - uy;
                if ((i >> 31) == 0)
                {
                    uxi = i;
                    q  += 1;
                }

                if (uxi == 0)
                {
                    ex = -30;
                }
                else
                {
                    while ((uxi >> 23) == 0)
                    {
                        uxi <<= 1;
                        ex   -= 1;
                    }
                }
            }

            /* scale result and decide between |x| and |x|-|y| */
            if (ex > 0)
            {
                uxi -= 1 << 23;
                uxi |= ((uint)ex) << 23;
            }
            else
            {
                uxi >>= -ex + 1;
            }

            x = sfloat.FromRaw(uxi);
            if (sy)
            {
                y = -y;
            }

            if ((ex == ey || (ex + 1 == ey && ((sfloat)2.0f * x > y || ((sfloat)2.0f * x == y && (q % 2) != 0)))) && x > y)
            {
                x -= y;
                q += 1;
            }

            q &= 0x7fffffff;
            int quo = sx ^ sy ? -(int)q : (int)q;

            remainder = sx ? -x : x;
            quotient  = quo;
        }
示例#22
0
 public static float2x2 float2x2(sfloat v)
 {
     return(new float2x2(v));
 }
示例#23
0
 void Update()
 {
     GravityTimer = GravityTimer + (sfloat)Time.deltaTime;
 }
示例#24
0
 public int4x2(sfloat v)
 {
     this.c0 = (int4)(int)v;
     this.c1 = (int4)(int)v;
 }
示例#25
0
 public static int3x3 int3x3(sfloat v)
 {
     return(new int3x3(v));
 }
示例#26
0
 public static int2x4 int2x4(sfloat v)
 {
     return(new int2x4(v));
 }
示例#27
0
 public static uint3x4 uint3x4(sfloat v)
 {
     return(new uint3x4(v));
 }
示例#28
0
 public float3x3(sfloat v)
 {
     this.c0 = v;
     this.c1 = v;
     this.c2 = v;
 }
示例#29
0
 public static float4x3 float4x3(sfloat v)
 {
     return(new float4x3(v));
 }
示例#30
0
 public static uint4x2 uint4x2(sfloat v)
 {
     return(new uint4x2(v));
 }