< 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
 341515        private BaseDictionary<string, Player> otherPlayers => DataStore.i.player.otherPlayers;
 705116        private BaseVariable<float> simpleAvatarDistance => DataStore.i.avatarsLOD.simpleAvatarDistance;
 017        private BaseVariable<float> LODDistance => DataStore.i.avatarsLOD.LODDistance;
 705018        private BaseVariable<int> maxAvatars => DataStore.i.avatarsLOD.maxAvatars;
 705019        private BaseVariable<int> maxImpostors => DataStore.i.avatarsLOD.maxImpostors;
 20        private Vector3 cameraPosition;
 21        private Vector3 cameraForward;
 22        private GPUSkinningThrottlingCurveSO gpuSkinningThrottlingCurve;
 68323        private SimpleOverlappingTracker overlappingTracker = new SimpleOverlappingTracker(MIN_DISTANCE_BETWEEN_NAMES_PI
 24
 68325        internal readonly Dictionary<string, IAvatarLODController> lodControllers = new Dictionary<string, IAvatarLODCon
 26        private UnityEngine.Camera mainCamera;
 27
 68328        public AvatarsLODController ()
 29        {
 68330            gpuSkinningThrottlingCurve = Resources.Load<GPUSkinningThrottlingCurveSO>("GPUSkinningThrottlingCurve");
 68331        }
 32
 33        public void Initialize()
 34        {
 68335            Environment.i.platform.updateEventHandler.AddListener(IUpdateEventHandler.EventType.Update, Update);
 36
 136637            foreach (IAvatarLODController lodController in lodControllers.Values)
 38            {
 039                lodController.Dispose();
 40            }
 41
 68342            lodControllers.Clear();
 43
 136644            foreach (var keyValuePair in otherPlayers.Get())
 45            {
 046                RegisterAvatar(keyValuePair.Key, keyValuePair.Value);
 47            }
 48
 68349            otherPlayers.OnAdded += RegisterAvatar;
 68350            otherPlayers.OnRemoved += UnregisterAvatar;
 68351        }
 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        {
 705074            cameraPosition = CommonScriptableObjects.cameraPosition.Get();
 705075            cameraForward = CommonScriptableObjects.cameraForward.Get();
 76
 705077            UpdateAllLODs(maxAvatars.Get(), maxImpostors.Get());
 705078        }
 79
 80        internal void UpdateAllLODs(int maxAvatars = DataStore_AvatarsLOD.DEFAULT_MAX_AVATAR, int maxImpostors = DataSto
 81        {
 705182            if (mainCamera == null)
 226683                mainCamera = UnityEngine.Camera.main;
 705184            int avatarsCount = 0; //Full Avatar + Simple Avatar
 705185            int impostorCount = 0; //Impostor
 86
 705187            float simpleAvatarDistance = this.simpleAvatarDistance.Get();
 705188            Vector3 ownPlayerPosition = CommonScriptableObjects.playerUnityPosition.Get();
 89
 705190            overlappingTracker.Reset();
 91
 705192            (IAvatarLODController lodController, float distance)[] lodControllersByDistance = ComposeLODControllersSorte
 93
 1420294            for (int index = 0; index < lodControllersByDistance.Length; index++)
 95            {
 5096                (IAvatarLODController lodController, float distance) = lodControllersByDistance[index];
 97
 5098                if (IsInInvisibleDistance(distance))
 99                {
 9100                    lodController.SetNameVisible(false);
 9101                    lodController.SetInvisible();
 9102                    continue;
 103                }
 104
 41105                if (avatarsCount < maxAvatars)
 106                {
 34107                    lodController.SetAnimationThrottling((int)gpuSkinningThrottlingCurve.curve.Evaluate(distance));
 34108                    if (distance < simpleAvatarDistance)
 30109                        lodController.SetLOD0();
 110                    else
 4111                        lodController.SetLOD1();
 34112                    avatarsCount++;
 113
 34114                    if (mainCamera == null)
 14115                        lodController.SetNameVisible(true);
 116                    else
 20117                        lodController.SetNameVisible(overlappingTracker.RegisterPosition(lodController.player.playerName
 118
 20119                    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            }
 7051133        }
 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        {
 7101144            (IAvatarLODController lodController, float distance)[] lodControllersWithDistance = lodControllers.Select(x 
 7090145            Array.Sort(lodControllersWithDistance, (x, y) => x.distance.CompareTo(y.distance));
 7051146            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))
 8157                return -1;
 158
 42159            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        {
 1422166            foreach (IAvatarLODController lodController in lodControllers.Values)
 167            {
 28168                lodController.Dispose();
 169            }
 170
 683171            otherPlayers.OnAdded -= RegisterAvatar;
 683172            otherPlayers.OnRemoved -= UnregisterAvatar;
 683173            DCL.Environment.i.platform.updateEventHandler.RemoveListener(IUpdateEventHandler.EventType.Update, Update);
 683174        }
 175    }
 176}