< Summary

Class:WearableController
Assembly:AvatarShape
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Avatar/WearableController.cs
Covered lines:61
Uncovered lines:33
Coverable lines:94
Total lines:205
Line coverage:64.8% (61 of 94)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Load(...)0%4.054085.71%
WearableController(...)0%110100%
WearableController(...)0%2100%
SetupDefaultMaterial(...)0%12300%
StoreOriginalMaterials()0%12300%
RestoreOriginalMaterials()0%3.713057.14%
SetAnimatorBones(...)0%4.024090%
CleanUp()0%220100%
SetAssetRenderersEnabled(...)0%330100%
UnloadMaterials()0%6.283028.57%
PrepareWearable(...)0%110100%
UpdateVisibility(...)0%110100%
IsLoadedForBodyShape(...)0%42600%

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.Linq;
 7using UnityEngine;
 8using Object = UnityEngine.Object;
 9
 10public class WearableController
 11{
 12    private const string MATERIAL_FILTER_HAIR = "hair";
 13    private const string MATERIAL_FILTER_SKIN = "skin";
 14
 15    public readonly WearableItem wearable;
 16    protected RendereableAssetLoadHelper loader;
 17
 018    public string id => wearable.id;
 019    public string category => wearable.data.category;
 20
 021    public GameObject assetContainer => loader?.loadedAsset;
 2322    public bool isReady => loader != null && loader.isFinished && assetContainer != null;
 23
 24    protected Renderer[] assetRenderers;
 25
 26    List<Material> materials = null;
 27
 28    public bool boneRetargetingDirty = false;
 29
 30    internal string lastMainFileLoaded = null;
 31
 1532    public WearableController(WearableItem wearableItem) { this.wearable = wearableItem; }
 33
 034    protected WearableController(WearableController original)
 35    {
 036        wearable = original.wearable;
 037        loader = original.loader;
 038        assetRenderers = original.assetRenderers;
 039    }
 40
 41    public virtual void Load(string bodyShapeId, Transform parent, Action<WearableController> onSuccess, Action<Wearable
 42    {
 543        if (isReady)
 044            return;
 45
 546        boneRetargetingDirty = true;
 47
 548        var representation = wearable.GetRepresentation(bodyShapeId);
 49
 550        if (representation == null)
 51        {
 052            onFail?.Invoke(this);
 053            return;
 54        }
 55
 556        var provider = wearable.GetContentProvider(bodyShapeId);
 57
 558        loader = new RendereableAssetLoadHelper(provider, wearable.baseUrlBundles);
 59
 560        loader.settings.forceNewInstance = false;
 561        loader.settings.initialLocalPosition = Vector3.up * 0.75f;
 562        loader.settings.cachingFlags = MaterialCachingHelper.Mode.CACHE_SHADERS;
 563        loader.settings.visibleFlags = AssetPromiseSettings_Rendering.VisibleFlags.INVISIBLE;
 564        loader.settings.parent = parent;
 565        loader.settings.layer = parent.gameObject.layer;
 66
 567        assetRenderers = null;
 68
 69        void OnSuccessWrapper(GameObject gameObject)
 70        {
 471            if (loader != null)
 72            {
 473                loader.OnSuccessEvent -= OnSuccessWrapper;
 74            }
 75
 476            assetRenderers = gameObject.GetComponentsInChildren<Renderer>();
 477            PrepareWearable(gameObject);
 478            onSuccess?.Invoke(this);
 179        }
 80
 581        loader.OnSuccessEvent += OnSuccessWrapper;
 82
 83        void OnFailEventWrapper()
 84        {
 185            if (loader != null)
 86            {
 187                loader.OnFailEvent -= OnFailEventWrapper;
 188                loader.ClearEvents();
 189                lastMainFileLoaded = null;
 190                loader = null;
 91            }
 92
 193            onFail?.Invoke(this);
 194        }
 95
 596        loader.OnFailEvent += OnFailEventWrapper;
 97
 598        lastMainFileLoaded = representation.mainFile;
 599        loader.Load(representation.mainFile);
 5100    }
 101
 5102    Dictionary<Renderer, Material[]> originalMaterials = new Dictionary<Renderer, Material[]>();
 103
 104    public void SetupDefaultMaterial(Material defaultMaterial, Color skinColor, Color hairColor)
 105    {
 0106        if (assetContainer == null)
 0107            return;
 108
 0109        if (materials == null)
 110        {
 0111            StoreOriginalMaterials();
 0112            materials = AvatarUtils.ReplaceMaterialsWithCopiesOf(assetContainer.transform, defaultMaterial);
 113        }
 114
 0115        AvatarUtils.SetColorInHierarchy(assetContainer.transform, MATERIAL_FILTER_SKIN, skinColor);
 0116        AvatarUtils.SetColorInHierarchy(assetContainer.transform, MATERIAL_FILTER_HAIR, hairColor);
 0117    }
 118
 119    private void StoreOriginalMaterials()
 120    {
 0121        Renderer[] renderers = assetContainer.transform.GetComponentsInChildren<Renderer>();
 122
 0123        for (int i = 0; i < renderers.Length; i++)
 124        {
 0125            if (originalMaterials.ContainsKey(renderers[i]))
 126                continue;
 127
 0128            originalMaterials.Add(renderers[i], renderers[i].sharedMaterials.ToArray());
 129        }
 0130    }
 131
 132    private void RestoreOriginalMaterials()
 133    {
 10134        foreach (var kvp in originalMaterials)
 135        {
 0136            if (kvp.Key != null)
 0137                kvp.Key.materials = kvp.Value;
 138        }
 139
 5140        originalMaterials.Clear();
 5141    }
 142
 143    public void SetAnimatorBones(SkinnedMeshRenderer skinnedMeshRenderer)
 144    {
 1145        if (!boneRetargetingDirty || assetContainer == null)
 0146            return;
 147
 1148        SkinnedMeshRenderer[] skinnedRenderers = assetContainer.GetComponentsInChildren<SkinnedMeshRenderer>();
 149
 4150        for (int i = 0; i < skinnedRenderers.Length; i++)
 151        {
 1152            skinnedRenderers[i].rootBone = skinnedMeshRenderer.rootBone;
 1153            skinnedRenderers[i].bones = skinnedMeshRenderer.bones;
 154        }
 155
 1156        boneRetargetingDirty = false;
 1157    }
 158
 159    public void CleanUp()
 160    {
 5161        UnloadMaterials();
 5162        RestoreOriginalMaterials();
 5163        assetRenderers = null;
 164
 5165        if (loader != null)
 166        {
 4167            loader.ClearEvents();
 4168            loader.Unload();
 4169            loader = null;
 4170            lastMainFileLoaded = null;
 171        }
 5172    }
 173
 174    public virtual void SetAssetRenderersEnabled(bool active)
 175    {
 8176        for (var i = 0; i < assetRenderers.Length; i++)
 177        {
 2178            if (assetRenderers[i] != null)
 2179                assetRenderers[i].enabled = active;
 180        }
 2181    }
 182
 183    protected virtual void UnloadMaterials()
 184    {
 5185        if (materials == null)
 5186            return;
 187
 0188        for (var i = 0; i < materials.Count; i++)
 189        {
 0190            Object.Destroy(materials[i]);
 191        }
 0192    }
 193
 4194    protected virtual void PrepareWearable(GameObject assetContainer) { }
 195
 4196    public virtual void UpdateVisibility(HashSet<string> hiddenList) { SetAssetRenderersEnabled(!hiddenList.Contains(wea
 197
 198    public bool IsLoadedForBodyShape(string bodyShapeId)
 199    {
 0200        if (loader == null || !isReady || lastMainFileLoaded == null)
 0201            return false;
 202
 0203        return wearable.data.representations.FirstOrDefault(x => x.bodyShapes.Contains(bodyShapeId))?.mainFile == lastMa
 204    }
 205}