private float GetSlotHmdAngleQuality(PlacementSlotModel placementSlot, Vector3 hmdPosition, Vector3 hmdDirection)
        {
            var slotDirection = placementSlot.Position - hmdPosition;
            var angle         = Vector3.Angle(slotDirection, hmdDirection);

            var angleQuality = angle / 180.0f;

            return(angleQuality);
        }
    private float UpdateQuality(PlacementSlotModel slot)
    {
        var posInFoV           = new Vector2(slot.Position.x, slot.Position.y);
        var center             = new Vector2(0, 0);
        var offset             = (center - posInFoV);
        var centerDistance     = offset.magnitude;
        var horizontalDistance = Mathf.Abs(offset.x);
        //var quality = Mathf.Max(0, QualityFunction.Evaluate(horizontalDistance) - Mathf.Abs(offset.y));
        var quality = QualityFunction.Evaluate(centerDistance);

        slot.ChangeQuality(quality);
        return(quality);
    }
        private bool ContainsGeometry(PlacementSlotModel slot, out Transform occluder)
        {
            var allElements = Room.GetComponentsInChildren <Collider>();

            foreach (var collider in allElements)
            {
                if (collider.bounds.Intersects(slot.Bounds))
                {
                    occluder = collider.transform;
                    return(true);
                }
            }

            occluder = null;
            return(false);
        }
        private bool IsOccluded(PlacementSlotModel placementSlot, Vector3 hmdPosition, out float distance)
        {
            var slotPlayerDistance = (hmdPosition - placementSlot.Position).magnitude;

            var containsGeometry = ContainsGeometry(placementSlot, out placementSlot.Occluder);

            if (containsGeometry)
            {
                distance = float.NegativeInfinity;
                return(true);
            }

            var slotDistance = Mathf.Max(0, slotPlayerDistance - OcclusionOffset);

            var isHit = Physics.Raycast(hmdPosition, placementSlot.Position - hmdPosition, out var hit, slotDistance);

            if (isHit)
            {
                placementSlot.Occluder = hit.transform;
            }

            if (isHit || slotPlayerDistance < MinPlayerSlotDistance)
            {
                distance = float.NegativeInfinity;
                return(true);
            }

            placementSlot.ChangeVisibility(ShowDebugVisuals);

            //var normalizedDistance = 1.0f - Mathf.Pow(slotPlayerDistance / maxDistance, 1f / 2f);
            var normalizedDistance = slotPlayerDistance / _maxDistance;

            distance = Mathf.Clamp(normalizedDistance, 0.0f, 1.0f);

            return(false);
        }