< Summary

Class:AvatarSystem.AvatarSystemUtils
Assembly:AvatarSystem
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/AvatarSystem/AvatarSystemUtils.cs
Covered lines:63
Uncovered lines:45
Coverable lines:108
Total lines:226
Line coverage:58.3% (63 of 108)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
IsCategoryRequired(...)0%110100%
UseAssetBundles()0%220100%
GetFacialFeatureTexturesUrls(...)0%7562700%
CopyBones(...)0%4.034087.5%
PrepareMaterialColors(...)0%550100%
SplitWearables(...)0%72800%
ExtractBodyshapeParts(...)0%10100100%
FilterHiddenWearables(...)0%20400%
GetActiveBodyParts(...)0%880100%
GetActiveBodyPartsRenderers(...)0%5.685070%
SpawnAvatarLoadedParticles(...)0%6200%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/AvatarSystem/AvatarSystemUtils.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using DCL;
 5using DCL.Helpers;
 6using UnityEngine;
 7using Object = UnityEngine.Object;
 8
 9namespace AvatarSystem
 10{
 11    public static class AvatarSystemUtils
 12    {
 13        public const float AVATAR_Y_OFFSET = 0.75f;
 14        private const string AB_FEATURE_FLAG_NAME = "wearable_asset_bundles";
 15
 1216        public static bool IsCategoryRequired(string category) { return WearableLiterals.Categories.REQUIRED_CATEGORIES.
 17
 18        public static bool UseAssetBundles()
 19        {
 8420            var featureFlags = DataStore.i.featureFlags.flags.Get();
 8421            return featureFlags != null && featureFlags.IsFeatureEnabled(AB_FEATURE_FLAG_NAME);
 22        }
 23
 24        public static (string mainTextureUrl, string maskTextureUrl) GetFacialFeatureTexturesUrls(string bodyshapeId, We
 25        {
 026            if (facialFeature.data.category != WearableLiterals.Categories.EYES && facialFeature.data.category == Wearab
 027                return (null, null);
 28
 029            var representation = facialFeature.GetRepresentation(bodyshapeId);
 030            string mainTextureHash = representation?.contents?.FirstOrDefault(x => x.key == representation?.mainFile)?.h
 031            if (string.IsNullOrEmpty(mainTextureHash))
 032                mainTextureHash = representation?.contents?.FirstOrDefault(x => !x.key.ToLower().Contains("_mask.png"))?
 033            if (string.IsNullOrEmpty(mainTextureHash))
 034                return (null, null);
 35
 036            string maskTextureHash = representation?.contents?.FirstOrDefault(x => x.key.ToLower().Contains("_mask.png")
 37
 038            string mainTextureUrl = facialFeature.baseUrl + mainTextureHash;
 039            string maskTextureUrl = maskTextureHash == null ? null : facialFeature.baseUrl + maskTextureHash;
 40
 041            return (mainTextureUrl, maskTextureUrl);
 42        }
 43
 44        public static void CopyBones(SkinnedMeshRenderer source, IEnumerable<SkinnedMeshRenderer> targets)
 45        {
 246            if (source == null)
 047                return;
 48
 2449            foreach (SkinnedMeshRenderer skinnedMeshRenderer in targets)
 50            {
 1051                skinnedMeshRenderer.rootBone = source.rootBone;
 1052                skinnedMeshRenderer.bones = source.bones;
 53            }
 254        }
 55
 56        public static void PrepareMaterialColors(Rendereable rendereable, Color skinColor, Color hairColor)
 57        {
 8858            foreach (Renderer renderer in rendereable.renderers)
 59            {
 12860                foreach (Material material in renderer.materials)
 61                {
 3262                    if (material.name.ToLower().Contains("skin"))
 763                        material.SetColor(ShaderUtils.BaseColor, skinColor);
 2564                    else if (material.name.ToLower().Contains("hair"))
 565                        material.SetColor(ShaderUtils.BaseColor, hairColor);
 66                }
 67            }
 1268        }
 69
 70        public static (WearableItem bodyshape, WearableItem eyes, WearableItem eyebrows, WearableItem mouth, List<Wearab
 71        {
 072            WearableItem bodyshape = null;
 073            WearableItem eyes = null;
 074            WearableItem eyebrows = null;
 075            WearableItem mouth = null;
 076            List<WearableItem> resultWearables = new List<WearableItem>();
 077            foreach (WearableItem wearable in wearables)
 78            {
 079                switch (wearable.data.category)
 80                {
 81                    case WearableLiterals.Categories.BODY_SHAPE:
 082                        bodyshape = wearable;
 083                        break;
 84                    case WearableLiterals.Categories.EYES:
 085                        eyes = wearable;
 086                        break;
 87                    case WearableLiterals.Categories.EYEBROWS:
 088                        eyebrows = wearable;
 089                        break;
 90                    case WearableLiterals.Categories.MOUTH:
 091                        mouth = wearable;
 092                        break;
 93                    default:
 094                        resultWearables.Add(wearable);
 95                        break;
 96                }
 97            }
 98
 099            return (bodyshape, eyes, eyebrows, mouth, resultWearables);
 100        }
 101
 102        /// <summary>
 103        /// Extract bodyparts of a Rendereable.
 104        ///
 105        /// Using this on a Rendereable that doesn't comes from a bodyshape might result in unexpected result
 106        /// </summary>
 107        /// <param name="rendereable"></param>
 108        /// <returns></returns>
 109        public static (
 110            SkinnedMeshRenderer head,
 111            SkinnedMeshRenderer upperBody,
 112            SkinnedMeshRenderer lowerBody,
 113            SkinnedMeshRenderer feet,
 114            SkinnedMeshRenderer eyes,
 115            SkinnedMeshRenderer eyebrows,
 116            SkinnedMeshRenderer mouth
 117            ) ExtractBodyshapeParts(Rendereable rendereable)
 118        {
 1119            SkinnedMeshRenderer head = null;
 1120            SkinnedMeshRenderer upperBody = null;
 1121            SkinnedMeshRenderer lowerBody = null;
 1122            SkinnedMeshRenderer feet = null;
 1123            SkinnedMeshRenderer eyes = null;
 1124            SkinnedMeshRenderer eyebrows = null;
 1125            SkinnedMeshRenderer mouth = null;
 126
 16127            foreach (Renderer r in rendereable.renderers)
 128            {
 7129                if (!(r is SkinnedMeshRenderer renderer))
 130                    continue;
 131
 7132                string parentName = renderer.transform.parent.name.ToLower();
 133
 7134                if (parentName.Contains("head"))
 1135                    head = renderer;
 6136                else if (parentName.Contains("ubody"))
 1137                    upperBody = renderer;
 5138                else if (parentName.Contains("lbody"))
 1139                    lowerBody = renderer;
 4140                else if (parentName.Contains("feet"))
 1141                    feet = renderer;
 3142                else if (parentName.Contains("eyes"))
 1143                    eyes = renderer;
 2144                else if (parentName.Contains("eyebrows"))
 1145                    eyebrows = renderer;
 1146                else if (parentName.Contains("mouth"))
 1147                    mouth = renderer;
 148            }
 149
 1150            return (head, upperBody, lowerBody, feet, eyes, eyebrows, mouth);
 151        }
 152
 153        /// <summary>
 154        /// Filters hidden wearables.
 155        /// Conflicts will be resolved by order in the array
 156        /// </summary>
 157        /// <param name="bodyshapeId"></param>
 158        /// <param name="wearables"></param>
 159        /// <returns></returns>
 160        public static List<WearableItem> FilterHiddenWearables(string bodyshapeId, IEnumerable<WearableItem> wearables)
 161        {
 0162            HashSet<string> hiddenCategories = new HashSet<string>();
 0163            List<WearableItem> filteredWearables = new List<WearableItem>();
 0164            foreach (WearableItem wearable in wearables)
 165            {
 0166                if (hiddenCategories.Contains(wearable.data.category))
 167                {
 168                    continue;
 169                }
 170
 0171                filteredWearables.Add(wearable);
 0172                hiddenCategories.UnionWith(wearable.GetHidesList(bodyshapeId));
 173            }
 174
 0175            return filteredWearables;
 176        }
 177
 178        public static (bool headVisible, bool upperBodyVisible, bool lowerBodyVisible, bool feetVisible) GetActiveBodyPa
 179        {
 2180            bool headVisible = true;
 2181            bool upperBodyVisible = true;
 2182            bool lowerBodyVisible = true;
 2183            bool feetVisible = true;
 184
 2185            HashSet<string> hiddenList = new HashSet<string>();
 2186            HashSet<string> usedCategories = new HashSet<string>();
 187
 24188            foreach (WearableItem wearable in wearables)
 189            {
 10190                usedCategories.Add(wearable.data.category);
 10191                string[] hiddenByThisWearable = wearable.GetHidesList(bodyshapeId);
 10192                if (hiddenByThisWearable != null)
 10193                    hiddenList.UnionWith(hiddenByThisWearable);
 194            }
 195
 2196            headVisible = !hiddenList.Contains(WearableLiterals.Misc.HEAD) && !usedCategories.Contains(WearableLiterals.
 2197            upperBodyVisible = !hiddenList.Contains(WearableLiterals.Categories.UPPER_BODY) && !usedCategories.Contains(
 2198            lowerBodyVisible = !hiddenList.Contains(WearableLiterals.Categories.LOWER_BODY) && !usedCategories.Contains(
 2199            feetVisible = !hiddenList.Contains(WearableLiterals.Categories.FEET) && !usedCategories.Contains(WearableLit
 2200            return (headVisible, upperBodyVisible, lowerBodyVisible, feetVisible);
 201        }
 202
 203        public static List<SkinnedMeshRenderer> GetActiveBodyPartsRenderers(IBodyshapeLoader bodyshapeLoader, bool headV
 204        {
 2205            List<SkinnedMeshRenderer> result = new List<SkinnedMeshRenderer>();
 2206            if (headVisible)
 2207                result.Add(bodyshapeLoader.headRenderer);
 2208            if (upperBodyVisible)
 0209                result.Add(bodyshapeLoader.upperBodyRenderer);
 2210            if (lowerBodyVisible)
 0211                result.Add(bodyshapeLoader.lowerBodyRenderer);
 2212            if (feetVisible)
 0213                result.Add(bodyshapeLoader.feetRenderer);
 2214            return result;
 215        }
 216
 217        public static void SpawnAvatarLoadedParticles(Transform avatarContainer, GameObject particlePrefab)
 218        {
 0219            if (!particlePrefab.TryGetComponent(out DestroyParticlesOnFinish selfDestroyScript))
 0220                throw new Exception("A self destructive particles prefab is expected");
 221
 0222            GameObject particles = Object.Instantiate(particlePrefab);
 0223            particles.transform.position = avatarContainer.position + particlePrefab.transform.position;
 0224        }
 225    }
 226}