< Summary

Class:DCL.AvatarsLODController
Assembly:AvatarShape
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Avatar/AvatarLOD/AvatarsLODController.cs
Covered lines:77
Uncovered lines:3
Coverable lines:80
Total lines:176
Line coverage:96.2% (77 of 80)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
AvatarsLODController()0%110100%
Initialize()0%4.474069.23%
RegisterAvatar(...)0%220100%
CreateLodController(...)0%110100%
UnregisterAvatar(...)0%220100%
Update()0%110100%
UpdateAllLODs(...)0%880100%
IsInInvisibleDistance(...)0%220100%
ComposeLODControllersSortedByDistance(...)0%220100%
DistanceToOwnPlayer(...)0%330100%
IsInFrontOfCamera(...)0%110100%
Dispose()0%220100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Avatar/AvatarLOD/AvatarsLODController.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using DCL.CameraTool;
 5using UnityEngine;
 6
 7namespace DCL
 8{
 9    public class AvatarsLODController : IAvatarsLODController
 10    {
 11        internal const float RENDERED_DOT_PRODUCT_ANGLE = 0.25f;
 12        internal const float AVATARS_INVISIBILITY_DISTANCE = 1.75f;
 13        private const float MIN_DISTANCE_BETWEEN_NAMES_PIXELS = 70f;
 14
 340515        private BaseDictionary<string, Player> otherPlayers => DataStore.i.player.otherPlayers;
 702016        private BaseVariable<float> simpleAvatarDistance => DataStore.i.avatarsLOD.simpleAvatarDistance;
 017        private BaseVariable<float> LODDistance => DataStore.i.avatarsLOD.LODDistance;
 701918        private BaseVariable<int> maxAvatars => DataStore.i.avatarsLOD.maxAvatars;
 701919        private BaseVariable<int> maxImpostors => DataStore.i.avatarsLOD.maxImpostors;
 20        private Vector3 cameraPosition;
 21        private Vector3 cameraForward;
 22        private GPUSkinningThrottlingCurveSO gpuSkinningThrottlingCurve;
 68123        private SimpleOverlappingTracker overlappingTracker = new SimpleOverlappingTracker(MIN_DISTANCE_BETWEEN_NAMES_PI
 24
 68125        internal readonly Dictionary<string, IAvatarLODController> lodControllers = new Dictionary<string, IAvatarLODCon
 26        private UnityEngine.Camera mainCamera;
 27
 68128        public AvatarsLODController ()
 29        {
 68130            gpuSkinningThrottlingCurve = Resources.Load<GPUSkinningThrottlingCurveSO>("GPUSkinningThrottlingCurve");
 68131        }
 32
 33        public void Initialize()
 34        {
 68135            Environment.i.platform.updateEventHandler.AddListener(IUpdateEventHandler.EventType.Update, Update);
 36
 136237            foreach (IAvatarLODController lodController in lodControllers.Values)
 38            {
 039                lodController.Dispose();
 40            }
 41
 68142            lodControllers.Clear();
 43
 136244            foreach (var keyValuePair in otherPlayers.Get())
 45            {
 046                RegisterAvatar(keyValuePair.Key, keyValuePair.Value);
 47            }
 48
 68149            otherPlayers.OnAdded += RegisterAvatar;
 68150            otherPlayers.OnRemoved += UnregisterAvatar;
 68151        }
 52
 53        public void RegisterAvatar(string id, Player player)
 54        {
 2555            if (lodControllers.ContainsKey(id))
 156                return;
 57
 2458            lodControllers.Add(id, CreateLodController(player));
 2459        }
 60
 2061        protected internal virtual IAvatarLODController CreateLodController(Player player) => new AvatarLODController(pl
 62
 63        public void UnregisterAvatar(string id, Player player)
 64        {
 865            if (!lodControllers.ContainsKey(id))
 166                return;
 67
 768            lodControllers[id].Dispose();
 769            lodControllers.Remove(id);
 770        }
 71
 72        public void Update()
 73        {
 701974            cameraPosition = CommonScriptableObjects.cameraPosition.Get();
 701975            cameraForward = CommonScriptableObjects.cameraForward.Get();
 76
 701977            UpdateAllLODs(maxAvatars.Get(), maxImpostors.Get());
 701978        }
 79
 80        internal void UpdateAllLODs(int maxAvatars = DataStore_AvatarsLOD.DEFAULT_MAX_AVATAR, int maxImpostors = DataSto
 81        {
 702082            if (mainCamera == null)
 226683                mainCamera = UnityEngine.Camera.main;
 702084            int avatarsCount = 0; //Full Avatar + Simple Avatar
 702085            int impostorCount = 0; //Impostor
 86
 702087            float simpleAvatarDistance = this.simpleAvatarDistance.Get();
 702088            Vector3 ownPlayerPosition = CommonScriptableObjects.playerUnityPosition.Get();
 89
 702090            overlappingTracker.Reset();
 91
 702092            (IAvatarLODController lodController, float distance)[] lodControllersByDistance = ComposeLODControllersSorte
 93
 1414094            for (int index = 0; index < lodControllersByDistance.Length; index++)
 95            {
 5096                (IAvatarLODController lodController, float distance) = lodControllersByDistance[index];
 97
 5098                if (IsInInvisibleDistance(distance))
 99                {
 5100                    lodController.SetNameVisible(false);
 5101                    lodController.SetInvisible();
 5102                    continue;
 103                }
 104
 45105                if (avatarsCount < maxAvatars)
 106                {
 38107                    lodController.SetAnimationThrottling((int)gpuSkinningThrottlingCurve.curve.Evaluate(distance));
 38108                    if (distance < simpleAvatarDistance)
 34109                        lodController.SetLOD0();
 110                    else
 4111                        lodController.SetLOD1();
 38112                    avatarsCount++;
 113
 38114                    if (mainCamera == null)
 14115                        lodController.SetNameVisible(true);
 116                    else
 24117                        lodController.SetNameVisible(overlappingTracker.RegisterPosition(lodController.player.playerName
 118
 24119                    continue;
 120                }
 121
 7122                lodController.SetNameVisible(false);
 7123                if (impostorCount < maxImpostors)
 124                {
 6125                    lodController.SetLOD2();
 6126                    lodController.UpdateImpostorTint(distance);
 6127                    impostorCount++;
 6128                    continue;
 129                }
 130
 1131                lodController.SetInvisible();
 132            }
 7020133        }
 134
 135        private bool IsInInvisibleDistance(float distance)
 136        {
 50137            bool firstPersonCamera = CommonScriptableObjects.cameraMode.Get() == CameraMode.ModeId.FirstPerson;
 138
 50139            return firstPersonCamera ? distance < AVATARS_INVISIBILITY_DISTANCE : distance < 0f; // < 0 is behind camera
 140        }
 141
 142        private (IAvatarLODController lodController, float distance)[] ComposeLODControllersSortedByDistance(IEnumerable
 143        {
 7070144            (IAvatarLODController lodController, float distance)[] lodControllersWithDistance = lodControllers.Select(x 
 7059145            Array.Sort(lodControllersWithDistance, (x, y) => x.distance.CompareTo(y.distance));
 7020146            return lodControllersWithDistance;
 147        }
 148
 149        /// <summary>
 150        /// Returns -1 if player is not in front of camera or not found
 151        /// </summary>
 152        /// <param name="player"></param>
 153        /// <returns></returns>
 154        private float DistanceToOwnPlayer(Player player, Vector3 ownPlayerPosition)
 155        {
 50156            if (player == null || !IsInFrontOfCamera(player.worldPosition))
 4157                return -1;
 158
 46159            return Vector3.Distance(ownPlayerPosition, player.worldPosition);
 160        }
 161
 50162        private bool IsInFrontOfCamera(Vector3 position) { return Vector3.Dot(cameraForward, (position - cameraPosition)
 163
 164        public void Dispose()
 165        {
 1418166            foreach (IAvatarLODController lodController in lodControllers.Values)
 167            {
 28168                lodController.Dispose();
 169            }
 170
 681171            otherPlayers.OnAdded -= RegisterAvatar;
 681172            otherPlayers.OnRemoved -= UnregisterAvatar;
 681173            DCL.Environment.i.platform.updateEventHandler.RemoveListener(IUpdateEventHandler.EventType.Update, Update);
 681174        }
 175    }
 176}