< Summary

Class:WearableController
Assembly:AvatarShape
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Avatar/WearableController.cs
Covered lines:71
Uncovered lines:22
Coverable lines:93
Total lines:209
Line coverage:76.3% (71 of 93)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
WearableController(...)0%110100%
WearableController(...)0%2100%
GetRenderers()0%110100%
Load(...)0%4.054085.71%
SetupHairAndSkinColors(...)0%2.032080%
SetAnimatorBones(...)0%4.024090%
CleanUp()0%220100%
SetAssetRenderersEnabled(...)0%330100%
PrepareWearable(...)0%110100%
UpdateVisibility(...)0%110100%
IsLoadedForBodyShape(...)0%42600%
StoreOriginalMaterials()0%330100%
RestoreOriginalMaterials()0%330100%
SetFadeDither(...)0%20400%

File(s)

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

#LineLine coverage
 1using DCL;
 2using DCL.Components;
 3using DCL.Helpers;
 4using System;
 5using System.Collections.Generic;
 6using System.Collections.ObjectModel;
 7using System.Linq;
 8using UnityEngine;
 9using UnityGLTF.Cache;
 10using Object = UnityEngine.Object;
 11
 12public class WearableController
 13{
 14    private const string MATERIAL_FILTER_HAIR = "hair";
 15    private const string MATERIAL_FILTER_SKIN = "skin";
 16
 17    public readonly WearableItem wearable;
 18    protected RendereableAssetLoadHelper loader;
 19
 020    public string id => wearable.id;
 021    public string category => wearable.data.category;
 22
 023    public GameObject assetContainer => loader?.loadedAsset;
 2824    public bool isReady => loader != null && loader.isFinished && assetContainer != null;
 25
 26    public bool boneRetargetingDirty = false;
 27    internal string lastMainFileLoaded = null;
 28
 29    protected SkinnedMeshRenderer[] assetRenderers;
 1030    Dictionary<Renderer, Material[]> originalMaterials = new Dictionary<Renderer, Material[]>();
 31
 32    public IReadOnlyList<SkinnedMeshRenderer> GetRenderers()
 33    {
 534        return new ReadOnlyCollection<SkinnedMeshRenderer>(assetRenderers);
 35    }
 36
 3037    public WearableController(WearableItem wearableItem) { this.wearable = wearableItem; }
 38
 039    protected WearableController(WearableController original)
 40    {
 041        wearable = original.wearable;
 042        loader = original.loader;
 043        assetRenderers = original.assetRenderers;
 044    }
 45
 46    public virtual void Load(string bodyShapeId, Transform parent, Action<WearableController> onSuccess, Action<Wearable
 47    {
 1048        if (isReady)
 049            return;
 50
 1051        boneRetargetingDirty = true;
 52
 1053        var representation = wearable.GetRepresentation(bodyShapeId);
 54
 1055        if (representation == null)
 56        {
 057            onFail?.Invoke(this);
 058            return;
 59        }
 60
 1061        var provider = wearable.GetContentProvider(bodyShapeId);
 62
 1063        loader = new RendereableAssetLoadHelper(provider, wearable.baseUrlBundles);
 64
 1065        loader.settings.forceNewInstance = false;
 1066        loader.settings.initialLocalPosition = Vector3.up * 0.75f;
 1067        loader.settings.cachingFlags = MaterialCachingHelper.Mode.CACHE_EVERYTHING;
 1068        loader.settings.visibleFlags = AssetPromiseSettings_Rendering.VisibleFlags.INVISIBLE;
 1069        loader.settings.parent = parent;
 1070        loader.settings.layer = parent.gameObject.layer;
 71
 1072        assetRenderers = null;
 73
 74        void OnSuccessWrapper(GameObject gameObject)
 75        {
 976            if (loader != null)
 77            {
 978                loader.OnSuccessEvent -= OnSuccessWrapper;
 79            }
 80
 981            assetRenderers = gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
 982            StoreOriginalMaterials();
 983            PrepareWearable(gameObject);
 984            onSuccess?.Invoke(this);
 685        }
 86
 1087        loader.OnSuccessEvent += OnSuccessWrapper;
 88
 89        void OnFailEventWrapper()
 90        {
 191            if (loader != null)
 92            {
 193                loader.OnFailEvent -= OnFailEventWrapper;
 194                loader.ClearEvents();
 195                lastMainFileLoaded = null;
 196                loader = null;
 97            }
 98
 199            onFail?.Invoke(this);
 1100        }
 101
 10102        loader.OnFailEvent += OnFailEventWrapper;
 103
 10104        lastMainFileLoaded = representation.mainFile;
 10105        loader.Load(representation.mainFile);
 10106    }
 107
 108    public void SetupHairAndSkinColors(Color skinColor, Color hairColor)
 109    {
 5110        if (assetContainer == null)
 0111            return;
 112
 5113        AvatarUtils.SetColorInHierarchy(assetContainer.transform, MATERIAL_FILTER_SKIN, skinColor, ShaderUtils.BaseColor
 5114        AvatarUtils.SetColorInHierarchy(assetContainer.transform, MATERIAL_FILTER_HAIR, hairColor, ShaderUtils.BaseColor
 5115    }
 116
 117    public void SetAnimatorBones(Transform[] bones, Transform rootBone)
 118    {
 1119        if (!boneRetargetingDirty || assetContainer == null)
 0120            return;
 121
 1122        SkinnedMeshRenderer[] skinnedRenderers = assetContainer.GetComponentsInChildren<SkinnedMeshRenderer>();
 123
 4124        for (int i = 0; i < skinnedRenderers.Length; i++)
 125        {
 1126            skinnedRenderers[i].rootBone = rootBone;
 1127            skinnedRenderers[i].bones = bones;
 128        }
 129
 1130        boneRetargetingDirty = false;
 1131    }
 132
 133    public virtual void CleanUp()
 134    {
 10135        RestoreOriginalMaterials();
 10136        assetRenderers = null;
 137
 10138        if (loader != null)
 139        {
 9140            loader.ClearEvents();
 9141            loader.Unload();
 9142            loader = null;
 9143            lastMainFileLoaded = null;
 144        }
 10145    }
 146
 147    public void SetAssetRenderersEnabled(bool active)
 148    {
 38149        for (var i = 0; i < assetRenderers.Length; i++)
 150        {
 12151            if (assetRenderers[i] != null)
 12152                assetRenderers[i].enabled = active;
 153        }
 7154    }
 155
 156    protected virtual void PrepareWearable(GameObject assetContainer)
 157    {
 9158    }
 159
 160    public virtual void UpdateVisibility(HashSet<string> hiddenList)
 161    {
 2162        SetAssetRenderersEnabled(!hiddenList.Contains(wearable.data.category));
 2163    }
 164
 165    public bool IsLoadedForBodyShape(string bodyShapeId)
 166    {
 0167        if (loader == null || !isReady || lastMainFileLoaded == null)
 0168            return false;
 169
 0170        return wearable.data.representations.FirstOrDefault(x => x.bodyShapes.Contains(bodyShapeId))?.mainFile == lastMa
 171    }
 172
 173
 174    private void StoreOriginalMaterials()
 175    {
 46176        for (int i = 0; i < assetRenderers.Length; i++)
 177        {
 14178            if (originalMaterials.ContainsKey(assetRenderers[i]))
 179                continue;
 180
 14181            originalMaterials.Add(assetRenderers[i], assetRenderers[i].sharedMaterials.ToArray());
 182        }
 9183    }
 184
 185    private void RestoreOriginalMaterials()
 186    {
 48187        foreach (var kvp in originalMaterials)
 188        {
 14189            if (kvp.Key != null)
 14190                kvp.Key.materials = kvp.Value;
 191        }
 192
 10193        originalMaterials.Clear();
 10194    }
 195
 196    public void SetFadeDither(float ditherFade)
 197    {
 0198        if (assetRenderers == null)
 0199            return;
 200
 0201        for (int i = 0; i < assetRenderers.Length; i++)
 202        {
 0203            for (int j = 0; j < assetRenderers[i].materials.Length; j++)
 204            {
 0205                assetRenderers[i].materials[j].SetFloat(ShaderUtils.DitherFade, ditherFade);
 206            }
 207        }
 0208    }
 209}