public static bool IsVisible(ShapeVisibilityTracker tracker, bool ignoreLocalCamera)
 {
     return(tracker.gameObject.activeInHierarchy &&
            IsVisibleUsingCameraFrustum(tracker, ignoreLocalCamera) &&
            QSBPlayerManager.GetPlayersWithCameras(!ignoreLocalCamera)
            .Any(x => VisibilityOccluder.CanYouSee(tracker, x.Camera.mainCamera.transform.position)));
 }
Example #2
0
    /*
     * Recursively traverse all lights under `parent`.
     */
    private float TraverseLights(Transform parent)
    {
        float       lightsum    = 0.0f;
        LightSprite lightSprite = parent.gameObject.GetComponent <LightSprite>();

        // if parent is not active, ignore
        if (!parent.gameObject.activeSelf)
        {
            return(lightsum);
        }

        // if parent is not a light, traverse its children and return immediately
        if (lightSprite == null)
        {
            foreach (Transform child in parent)
            {
                lightsum += TraverseLights(child);
            }
            return(lightsum);
        }

        // parent is a light.
        // calculate illumination from light
        Vector4 color     = lightSprite.Color;
        float   luminance = 0.3f * color.x + 0.59f * color.y + 0.11f * color.z; // red, green, blue components

        luminance *= color.w;                                                   // alpha component
        float dx            = parent.position.x - transform.position.x;
        float dy            = parent.position.y - transform.position.y;
        float distance      = Mathf.Sqrt(dx * dx + dy * dy);
        float falloff_denom = Mathf.Pow(distance, visibility_illumination_falloff);

        // raycast to see if player is occluded
        CircleCollider2D player_collider = GetComponent <CircleCollider2D>();
        Vector2          dir             = transform.position - parent.position;
        float            player_radius   = player_collider.radius;
        float            radius_offset   = player_radius + 0.01f; // offset player radius

        //RaycastHit2D hit = Physics2D.Raycast(parent.position, dir, distance - (radius_offset));
        RaycastHit2D[] hits = Physics2D.RaycastAll(parent.position, dir, distance - (radius_offset));
        if (hits.Length == 0)
        {
            lightsum += luminance / falloff_denom; // inverse square fall-off
        }
        else
        {
            bool hit_visibility_occluder = false;

            foreach (RaycastHit2D hit in hits)
            {
                VisibilityOccluder visibility_occluder = hit.collider.gameObject.GetComponent <VisibilityOccluder>();
                hit_visibility_occluder = visibility_occluder != null;
                if (hit_visibility_occluder)
                {
                    float occlusion_multiplier = 1.0f - visibility_occluder.obstacle_multiplicative_alpha;
                    lightsum += (luminance / falloff_denom) * occlusion_multiplier;
                    break;
                }
            }

            if (!hit_visibility_occluder)
            {
                lightsum += luminance / falloff_denom;
            }
        }

        // TODO illumination from guard flashlights. Take flashlight cone shape into account.

        return(lightsum);
    }