< Summary

Class:WearableController
Assembly:AvatarShape
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Avatar/WearableController.cs
Covered lines:78
Uncovered lines:22
Coverable lines:100
Total lines:214
Line coverage:78% (78 of 100)
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%
SetupAssetBundlesConfig()0%220100%
Load(...)0%6.116085.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 System;
 2using System.Collections.Generic;
 3using System.Collections.ObjectModel;
 4using System.Linq;
 5using DCL;
 6using DCL.Components;
 7using DCL.Helpers;
 8using UnityEngine;
 9
 10public class WearableController
 11{
 12    private const string MATERIAL_FILTER_HAIR = "hair";
 13    private const string MATERIAL_FILTER_SKIN = "skin";
 14    private const string AB_FEATURE_FLAG_NAME = "wearable_asset_bundles";
 15
 16    public readonly WearableItem wearable;
 17    protected RendereableAssetLoadHelper loader;
 18
 019    public string id => wearable.id;
 020    public string category => wearable.data.category;
 21
 3222    public GameObject assetContainer => loader?.loadedAsset.container;
 3123    public bool isReady => loader != null && loader.isFinished && assetContainer != null;
 24
 25    public bool boneRetargetingDirty = false;
 26    internal string lastMainFileLoaded = null;
 1327    internal bool useAssetBundles = true;
 28
 29    protected SkinnedMeshRenderer[] assetRenderers;
 1330    Dictionary<Renderer, Material[]> originalMaterials = new Dictionary<Renderer, Material[]>();
 31
 632    public IReadOnlyList<SkinnedMeshRenderer> GetRenderers() { return new ReadOnlyCollection<SkinnedMeshRenderer>(assetR
 33
 1334    public WearableController(WearableItem wearableItem)
 35    {
 1336        wearable = wearableItem;
 1337        SetupAssetBundlesConfig();
 1338    }
 39
 040    protected WearableController(WearableController original)
 41    {
 042        wearable = original.wearable;
 043        loader = original.loader;
 044        assetRenderers = original.assetRenderers;
 45
 046        SetupAssetBundlesConfig();
 047    }
 48
 49    private void SetupAssetBundlesConfig()
 50    {
 51        // In preview mode featureFlags.flags.Get() can be null.
 1352        var featureFlags = DataStore.i.featureFlags.flags.Get();
 1353        useAssetBundles = featureFlags != null && featureFlags.IsFeatureEnabled(AB_FEATURE_FLAG_NAME);
 1354    }
 55
 56    public virtual void Load(string bodyShapeId, Transform parent, Action<WearableController> onSuccess, Action<Wearable
 57    {
 1358        if (isReady)
 059            return;
 60
 1361        boneRetargetingDirty = true;
 62
 1363        var representation = wearable.GetRepresentation(bodyShapeId);
 64
 1365        if (representation == null)
 66        {
 067            onFail?.Invoke(this, new Exception($"Wearable load fail. There is no representation for bodyShape {bodyShape
 068            return;
 69        }
 70
 1371        var provider = wearable.GetContentProvider(bodyShapeId);
 72
 1373        loader = new RendereableAssetLoadHelper(provider, wearable.baseUrlBundles);
 74
 1375        loader.settings.forceNewInstance = false;
 1376        loader.settings.initialLocalPosition = Vector3.up * 0.75f;
 1377        loader.settings.cachingFlags = MaterialCachingHelper.Mode.CACHE_SHADERS;
 1378        loader.settings.visibleFlags = AssetPromiseSettings_Rendering.VisibleFlags.INVISIBLE;
 1379        loader.settings.parent = parent;
 1380        loader.settings.layer = parent.gameObject.layer;
 81
 1382        assetRenderers = null;
 83
 84        void OnSuccessWrapper(Rendereable rendereable)
 85        {
 1286            if (loader != null)
 87            {
 1288                loader.OnSuccessEvent -= OnSuccessWrapper;
 89            }
 90
 1291            assetRenderers = rendereable.container.GetComponentsInChildren<SkinnedMeshRenderer>();
 1292            StoreOriginalMaterials();
 1293            PrepareWearable(rendereable.container);
 1294            onSuccess?.Invoke(this);
 995        }
 96
 1397        loader.OnSuccessEvent += OnSuccessWrapper;
 98
 99        void OnFailEventWrapper(Exception error)
 100        {
 1101            if (loader != null)
 102            {
 1103                loader.OnFailEvent -= OnFailEventWrapper;
 1104                loader.ClearEvents();
 1105                lastMainFileLoaded = null;
 1106                loader = null;
 107            }
 108
 1109            onFail?.Invoke(this, error);
 1110        }
 111
 13112        loader.OnFailEvent += OnFailEventWrapper;
 113
 13114        lastMainFileLoaded = representation.mainFile;
 115
 13116        loader.Load(representation.mainFile, useAssetBundles ? RendereableAssetLoadHelper.LoadingType.ASSET_BUNDLE_WITH_
 13117    }
 118
 119    public void SetupHairAndSkinColors(Color skinColor, Color hairColor)
 120    {
 8121        if (assetContainer == null)
 0122            return;
 123
 8124        AvatarUtils.SetColorInHierarchy(assetContainer.transform, MATERIAL_FILTER_SKIN, skinColor, ShaderUtils.BaseColor
 8125        AvatarUtils.SetColorInHierarchy(assetContainer.transform, MATERIAL_FILTER_HAIR, hairColor, ShaderUtils.BaseColor
 8126    }
 127
 128    public void SetAnimatorBones(Transform[] bones, Transform rootBone)
 129    {
 1130        if (!boneRetargetingDirty || assetContainer == null)
 0131            return;
 132
 1133        SkinnedMeshRenderer[] skinnedRenderers = assetContainer.GetComponentsInChildren<SkinnedMeshRenderer>();
 134
 4135        for (int i = 0; i < skinnedRenderers.Length; i++)
 136        {
 1137            skinnedRenderers[i].rootBone = rootBone;
 1138            skinnedRenderers[i].bones = bones;
 139        }
 140
 1141        boneRetargetingDirty = false;
 1142    }
 143
 144    public virtual void CleanUp()
 145    {
 13146        RestoreOriginalMaterials();
 13147        assetRenderers = null;
 148
 13149        if (loader != null)
 150        {
 12151            loader.ClearEvents();
 12152            loader.Unload();
 12153            loader = null;
 12154            lastMainFileLoaded = null;
 155        }
 13156    }
 157
 158    public void SetAssetRenderersEnabled(bool active)
 159    {
 56160        for (var i = 0; i < assetRenderers.Length; i++)
 161        {
 18162            if (assetRenderers[i] != null)
 18163                assetRenderers[i].enabled = active;
 164        }
 10165    }
 166
 12167    protected virtual void PrepareWearable(GameObject assetContainer) { }
 168
 4169    public virtual void UpdateVisibility(HashSet<string> hiddenList) { SetAssetRenderersEnabled(!hiddenList.Contains(wea
 170
 171    public bool IsLoadedForBodyShape(string bodyShapeId)
 172    {
 0173        if (loader == null || !isReady || lastMainFileLoaded == null)
 0174            return false;
 175
 0176        return wearable.data.representations.FirstOrDefault(x => x.bodyShapes.Contains(bodyShapeId))?.mainFile == lastMa
 177    }
 178
 179    private void StoreOriginalMaterials()
 180    {
 64181        for (int i = 0; i < assetRenderers.Length; i++)
 182        {
 20183            if (originalMaterials.ContainsKey(assetRenderers[i]))
 184                continue;
 185
 20186            originalMaterials.Add(assetRenderers[i], assetRenderers[i].sharedMaterials.ToArray());
 187        }
 12188    }
 189
 190    private void RestoreOriginalMaterials()
 191    {
 66192        foreach (var kvp in originalMaterials)
 193        {
 20194            if (kvp.Key != null)
 20195                kvp.Key.materials = kvp.Value;
 196        }
 197
 13198        originalMaterials.Clear();
 13199    }
 200
 201    public void SetFadeDither(float ditherFade)
 202    {
 0203        if (assetRenderers == null)
 0204            return;
 205
 0206        for (int i = 0; i < assetRenderers.Length; i++)
 207        {
 0208            for (int j = 0; j < assetRenderers[i].materials.Length; j++)
 209            {
 0210                assetRenderers[i].materials[j].SetFloat(ShaderUtils.DitherFade, ditherFade);
 211            }
 212        }
 0213    }
 214}