< 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:78
Uncovered lines:6
Coverable lines:84
Total lines:178
Line coverage:92.8% (78 of 84)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
AvatarsLODController()0%110100%
Initialize(...)0%440100%
RegisterAvatar(...)0%330100%
CreateLodController(...)0%2100%
UnregisterAvatar(...)0%220100%
Update()0%220100%
UpdateLODsBillboard()0%330100%
UpdateAllLODs(...)0%880100%
ComposeLODControllersSortedByDistance(...)0%220100%
SqrDistanceToOwnPlayer(...)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 UnityEngine;
 5
 6namespace DCL
 7{
 8    public class AvatarsLODController : IAvatarsLODController
 9    {
 10        internal const float RENDERED_DOT_PRODUCT_ANGLE = 0.25f;
 11
 012        private BaseDictionary<string, Player> otherPlayers => DataStore.i.player.otherPlayers;
 013        private BaseVariable<float> simpleAvatarDistance => DataStore.i.avatarsLOD.simpleAvatarDistance;
 014        private BaseVariable<float> LODDistance => DataStore.i.avatarsLOD.LODDistance;
 015        private BaseVariable<int> maxAvatars => DataStore.i.avatarsLOD.maxAvatars;
 016        private BaseVariable<int> maxImpostors => DataStore.i.avatarsLOD.maxImpostors;
 17        private Vector3 cameraPosition;
 18        private Vector3 cameraForward;
 19
 68020        internal readonly Dictionary<string, IAvatarLODController> lodControllers = new Dictionary<string, IAvatarLODCon
 21        internal bool enabled;
 22
 68023        public AvatarsLODController()
 24        {
 68025            KernelConfig.i.EnsureConfigInitialized()
 26                        .Then(Initialize);
 68027        }
 28
 29        internal void Initialize(KernelConfigModel config)
 30        {
 68431            enabled = config.features.enableAvatarLODs;
 68432            if (!enabled)
 68033                return;
 34
 1235            foreach (var keyValuePair in otherPlayers.Get())
 36            {
 237                RegisterAvatar(keyValuePair.Key, keyValuePair.Value);
 38            }
 439            otherPlayers.OnAdded += RegisterAvatar;
 440            otherPlayers.OnRemoved += UnregisterAvatar;
 441        }
 42
 43        public void RegisterAvatar(string id, Player player)
 44        {
 545            if (!enabled || lodControllers.ContainsKey(id))
 146                return;
 47
 448            lodControllers.Add(id, CreateLodController(player));
 449        }
 50
 051        protected internal virtual IAvatarLODController CreateLodController(Player player) => new AvatarLODController(pl
 52
 53        public void UnregisterAvatar(string id, Player player)
 54        {
 355            if (!lodControllers.ContainsKey(id))
 156                return;
 57
 258            lodControllers[id].Dispose();
 259            lodControllers.Remove(id);
 260        }
 61
 62        public void Update()
 63        {
 1694164            if (!enabled)
 1693565                return;
 66
 667            cameraPosition = CommonScriptableObjects.cameraPosition.Get();
 668            cameraForward = CommonScriptableObjects.cameraForward.Get();
 69
 670            UpdateAllLODs(maxAvatars.Get(), maxImpostors.Get());
 671            UpdateLODsBillboard();
 672        }
 73
 74        internal void UpdateLODsBillboard()
 75        {
 5276            foreach (var kvp in lodControllers)
 77            {
 2078                Player player = kvp.Value.player;
 79
 2080                if (!IsInFrontOfCamera(player.worldPosition))
 81                    continue;
 82
 1983                Vector3 previousForward = player.forwardDirection;
 1984                Vector3 lookAtDir = (cameraPosition - player.worldPosition).normalized;
 85
 1986                lookAtDir.y = previousForward.y;
 1987                player.renderer.SetImpostorForward(lookAtDir);
 88            }
 689        }
 90
 91        internal void UpdateAllLODs(int maxAvatars = DataStore.DataStore_AvatarsLOD.DEFAULT_MAX_AVATAR, int maxImpostors
 92        {
 893            int avatarsCount = 0; //Full Avatar + Simple Avatar
 894            int impostorCount = 0; //Impostor
 95
 96            //Cache .Get to boost performance. Also use squared values to boost distance comparison
 897            float lodDistance = LODDistance.Get() * LODDistance.Get();
 898            float squaredSimpleAvatarDistance = simpleAvatarDistance.Get() * simpleAvatarDistance.Get();
 899            Vector3 ownPlayerPosition = CommonScriptableObjects.playerUnityPosition.Get();
 100
 8101            (IAvatarLODController lodController, float sqrDistance)[] lodControllersByDistance = ComposeLODControllersSo
 64102            for (int index = 0; index < lodControllersByDistance.Length; index++)
 103            {
 24104                (IAvatarLODController lodController, float sqrtDistance) = lodControllersByDistance[index];
 24105                if (sqrtDistance < 0) //Behind camera
 106                {
 5107                    lodController.SetInvisible();
 5108                    continue;
 109                }
 110
 111                //Nearby player
 19112                if (sqrtDistance < lodDistance)
 113                {
 14114                    if (avatarsCount < maxAvatars)
 115                    {
 11116                        if (sqrtDistance < squaredSimpleAvatarDistance)
 8117                            lodController.SetFullAvatar();
 118                        else
 3119                            lodController.SetSimpleAvatar();
 11120                        avatarsCount++;
 11121                        continue;
 122                    }
 123
 3124                    lodController.SetInvisible();
 3125                    continue;
 126                }
 127
 5128                if (avatarsCount < maxAvatars)
 129                {
 2130                    lodController.SetSimpleAvatar();
 2131                    avatarsCount++;
 2132                    continue;
 133                }
 3134                if (impostorCount < maxImpostors)
 135                {
 2136                    lodController.SetImpostor();
 2137                    impostorCount++;
 2138                    continue;
 139                }
 140
 1141                lodController.SetInvisible();
 142            }
 8143        }
 144
 145        private (IAvatarLODController lodController, float sqrDistance)[] ComposeLODControllersSortedByDistance(IEnumera
 146        {
 32147            (IAvatarLODController lodController, float sqrDistance)[] lodControllersWithDistance = lodControllers.Select
 30148            Array.Sort(lodControllersWithDistance, (x, y) => x.sqrDistance.CompareTo(y.sqrDistance));
 8149            return lodControllersWithDistance;
 150        }
 151
 152        /// <summary>
 153        /// Returns -1 if player is not in front of camera or not found
 154        /// </summary>
 155        /// <param name="player"></param>
 156        /// <returns></returns>
 157        private float SqrDistanceToOwnPlayer(Player player, Vector3 ownPlayerPosition)
 158        {
 24159            if (player == null || !IsInFrontOfCamera(player.worldPosition))
 5160                return -1;
 161
 19162            return Vector3.SqrMagnitude(ownPlayerPosition - player.worldPosition);
 163        }
 164
 44165        private bool IsInFrontOfCamera(Vector3 position) { return Vector3.Dot(cameraForward, (position - cameraPosition)
 166
 167        public void Dispose()
 168        {
 1456169            foreach (IAvatarLODController lodController in lodControllers.Values)
 170            {
 28171                lodController.Dispose();
 172            }
 173
 700174            otherPlayers.OnAdded -= RegisterAvatar;
 700175            otherPlayers.OnRemoved -= UnregisterAvatar;
 700176        }
 177    }
 178}