Ejemplo n.º 1
0
    private static bool Quadratic(TScalar a, TScalar b, TScalar c, out TScalar root1, out TScalar root2)
    {
        var q = (b * b) - (NumberValues.Four <TScalar>() * a * c);

        if (q >= TScalar.Zero)
        {
            var sq = TScalar.Sqrt(q);
            var d  = TScalar.One / (NumberValues.Two <TScalar>() * a);
            root1 = (-b + sq) * d;
            root2 = (-b - sq) * d;
            return(true);
        }
        else
        {
            root1 = TScalar.NaN;
            root2 = TScalar.NaN;
            return(false);
        }
    }
Ejemplo n.º 2
0
    public Frustum(
        TScalar aspectRatio,
        Vector3 <TScalar> axis,
        TScalar fieldOfViewAngle,
        TScalar nearPlaneDistance,
        Vector3 <TScalar> position,
        Quaternion <TScalar> rotation)
    {
        AspectRatio       = aspectRatio;
        Axis              = axis;
        FieldOfViewAngle  = fieldOfViewAngle;
        NearPlaneDistance = nearPlaneDistance;
        Position          = position;
        Rotation          = rotation;

        var farPlaneDistSq = Vector3 <TScalar> .LengthSquared(Axis);

        FarPlaneDistance = TScalar.Sqrt(farPlaneDistSq);

        var two    = NumberValues.Two <TScalar>();
        var tan    = TScalar.Tan(fieldOfViewAngle);
        var tanSq4 = tan.Square() * NumberValues.Four <TScalar>();
        var tanAR  = tan * aspectRatio;

        Volume = tanSq4
                 * aspectRatio
                 * ((farPlaneDistSq * FarPlaneDistance) - nearPlaneDistance.Cube())
                 / NumberValues.Three <TScalar>();

        SmallestDimension = aspectRatio <= TScalar.One
            ? two * tanAR * nearPlaneDistance
            : two * tan * nearPlaneDistance;

        ContainingRadius = TScalar.Sqrt(
            (FarPlaneDistance - nearPlaneDistance).Square()
            + (tanSq4 * farPlaneDistSq * (TScalar.One + aspectRatio.Square())))
                           / two;

        axis = position - (axis / two);
        var basis1 = Vector3 <TScalar> .Transform(Vector3 <TScalar> .Normalize(axis), rotation);

        Vector3 <TScalar> basis2, basis3;

        if (basis1.Z.IsNearlyEqualTo(TScalar.NegativeOne))
        {
            basis2 = new Vector3 <TScalar>(TScalar.Zero, TScalar.NegativeOne, TScalar.Zero);
            basis3 = new Vector3 <TScalar>(TScalar.NegativeOne, TScalar.Zero, TScalar.Zero);
        }
        else
        {
            var a = TScalar.One / (TScalar.One + basis1.Z);
            var b = -basis1.X * basis1.Y * a;
            basis2 = new Vector3 <TScalar>(TScalar.One - (basis1.X.Square() * a), b, -basis1.X);
            basis3 = new Vector3 <TScalar>(b, TScalar.One - (basis1.Y.Square() * a), -basis1.Y);
        }
        var farY  = basis2 * farPlaneDistSq * tanAR;
        var farZ  = basis3 * tan * FarPlaneDistance;
        var nearX = basis1 * nearPlaneDistance;
        var nearY = basis2 * nearPlaneDistance.Square() * tanAR;
        var nearZ = basis3 * tan * nearPlaneDistance;

        Corners = new Vector3 <TScalar>[8]
        {
            Position + axis - farY + farZ,
            Position + axis + farY + farZ,
            Position + axis - farY - farZ,
            Position + axis + farY - farZ,
            Position + nearX + nearY - nearZ,
            Position + nearX - nearY - nearZ,
            Position + nearX - nearY + nearZ,
            Position + nearX + nearY + nearZ
        };

        HighestPoint = Corners[0];
        LowestPoint  = Corners[0];
        for (var i = 1; i < 8; i++)
        {
            if (Corners[i].Y > HighestPoint.Y)
            {
                HighestPoint = Corners[i];
            }
            if (Corners[i].Y < LowestPoint.Y)
            {
                LowestPoint = Corners[i];
            }
        }

        Planes = new Plane <TScalar>[6]
        {
            Plane <TScalar> .CreateFromVertices(Corners[0], Corners[1], Corners[2]),
            Plane <TScalar> .CreateFromVertices(Corners[0], Corners[1], Corners[4]),
            Plane <TScalar> .CreateFromVertices(Corners[0], Corners[1], Corners[5]),
            Plane <TScalar> .CreateFromVertices(Corners[0], Corners[1], Corners[6]),
            Plane <TScalar> .CreateFromVertices(Corners[0], Corners[1], Corners[7]),
            Plane <TScalar> .CreateFromVertices(Corners[4], Corners[5], Corners[6]),
        };
    }