Exemplo n.º 1
0
        public override bool CalculateShadow()
        {
            if (RingComponent == null)
            {
                RingCachedComponent.TryInit(this);
            }

            if (base.CalculateShadow() == true)
            {
                if (RingComponent == null)
                {
                    return(false);
                }

                if (GetTexture() != null)
                {
                    if (Helper.Enabled(RingComponent) == true)
                    {
                        InnerRadius = RingComponent.InnerRadius;
                        OuterRadius = RingComponent.OuterRadius;
                    }

                    var direction = default(Vector3);
                    var position  = default(Vector3);
                    var color     = default(Color);

                    Helper.CalculateLight(Light, transform.position, null, null, ref position, ref direction, ref color);

                    var rotation = Quaternion.FromToRotation(direction, Vector3.back);
                    var squash   = Vector3.Dot(direction, transform.up); // Find how squashed the ellipse is based on light direction
                    var width    = transform.lossyScale.x * OuterRadius;
                    var length   = transform.lossyScale.z * OuterRadius;
                    var axis     = rotation * transform.up;                                                // Find the transformed up axis
                    var spin     = Quaternion.LookRotation(Vector3.forward, new Vector2(-axis.x, axis.y)); // Orient the shadow ellipse
                    var scale    = Helper.Reciprocal3(new Vector3(width, length * Mathf.Abs(squash), 1.0f));
                    var skew     = Mathf.Tan(Helper.Acos(-squash));

                    var shadowT = MatrixHelper.Translation(-transform.position);
                    var shadowR = MatrixHelper.Rotation(spin * rotation);          // Spin the shadow so lines up with its tilt
                    var shadowS = MatrixHelper.Scaling(scale);                     // Scale the ring into an oval
                    var shadowK = MatrixHelper.ShearingZ(new Vector2(0.0f, skew)); // Skew the shadow so it aligns with the ring plane

                    Matrix = shadowS * shadowK * shadowR * shadowT;
                    Ratio  = Helper.Divide(OuterRadius, OuterRadius - InnerRadius);

                    return(true);
                }
            }

            return(false);
        }