< 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 DCL;
 2using DCL.Components;
 3using DCL.Helpers;
 4using System;
 5using System.Collections.Generic;
 6using System.Collections.ObjectModel;
 7using System.Linq;
 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
 3522    public GameObject assetContainer => loader?.loadedAsset.container;
 3523    public bool isReady => loader != null && loader.isFinished && assetContainer != null;
 24
 25    public bool boneRetargetingDirty = false;
 26    internal string lastMainFileLoaded = null;
 1427    internal bool useAssetBundles = true;
 28
 29    protected SkinnedMeshRenderer[] assetRenderers;
 1430    Dictionary<Renderer, Material[]> originalMaterials = new Dictionary<Renderer, Material[]>();
 31
 732    public IReadOnlyList<SkinnedMeshRenderer> GetRenderers() { return new ReadOnlyCollection<SkinnedMeshRenderer>(assetR
 33
 1434    public WearableController(WearableItem wearableItem)
 35    {
 1436        this.wearable = wearableItem;
 1437        SetupAssetBundlesConfig();
 1438    }
 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.
 1452        var featureFlags = DataStore.i.featureFlags.flags.Get();
 1453        useAssetBundles = featureFlags != null && featureFlags.IsFeatureEnabled(AB_FEATURE_FLAG_NAME);
 1454    }
 55
 56    public virtual void Load(string bodyShapeId, Transform parent, Action<WearableController> onSuccess, Action<Wearable
 57    {
 1458        if (isReady)
 059            return;
 60
 1461        boneRetargetingDirty = true;
 62
 1463        var representation = wearable.GetRepresentation(bodyShapeId);
 64
 1465        if (representation == null)
 66        {
 067            onFail?.Invoke(this);
 068            return;
 69        }
 70
 1471        var provider = wearable.GetContentProvider(bodyShapeId);
 72
 1473        loader = new RendereableAssetLoadHelper(provider, wearable.baseUrlBundles);
 74
 1475        loader.settings.forceNewInstance = false;
 1476        loader.settings.initialLocalPosition = Vector3.up * 0.75f;
 1477        loader.settings.cachingFlags = MaterialCachingHelper.Mode.CACHE_SHADERS;
 1478        loader.settings.visibleFlags = AssetPromiseSettings_Rendering.VisibleFlags.INVISIBLE;
 1479        loader.settings.parent = parent;
 1480        loader.settings.layer = parent.gameObject.layer;
 81
 1482        assetRenderers = null;
 83
 84        void OnSuccessWrapper(Rendereable rendereable)
 85        {
 1386            if (loader != null)
 87            {
 1388                loader.OnSuccessEvent -= OnSuccessWrapper;
 89            }
 90
 1391            assetRenderers = rendereable.container.GetComponentsInChildren<SkinnedMeshRenderer>();
 1392            StoreOriginalMaterials();
 1393            PrepareWearable(rendereable.container);
 1394            onSuccess?.Invoke(this);
 1095        }
 96
 1497        loader.OnSuccessEvent += OnSuccessWrapper;
 98
 99        void OnFailEventWrapper()
 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);
 1110        }
 111
 14112        loader.OnFailEvent += OnFailEventWrapper;
 113
 14114        lastMainFileLoaded = representation.mainFile;
 115
 14116        loader.Load(representation.mainFile, useAssetBundles ? RendereableAssetLoadHelper.LoadingType.ASSET_BUNDLE_WITH_
 14117    }
 118
 119    public void SetupHairAndSkinColors(Color skinColor, Color hairColor)
 120    {
 9121        if (assetContainer == null)
 0122            return;
 123
 9124        AvatarUtils.SetColorInHierarchy(assetContainer.transform, MATERIAL_FILTER_SKIN, skinColor, ShaderUtils.BaseColor
 9125        AvatarUtils.SetColorInHierarchy(assetContainer.transform, MATERIAL_FILTER_HAIR, hairColor, ShaderUtils.BaseColor
 9126    }
 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    {
 14146        RestoreOriginalMaterials();
 14147        assetRenderers = null;
 148
 14149        if (loader != null)
 150        {
 13151            loader.ClearEvents();
 13152            loader.Unload();
 13153            loader = null;
 13154            lastMainFileLoaded = null;
 155        }
 14156    }
 157
 158    public void SetAssetRenderersEnabled(bool active)
 159    {
 62160        for (var i = 0; i < assetRenderers.Length; i++)
 161        {
 20162            if (assetRenderers[i] != null)
 20163                assetRenderers[i].enabled = active;
 164        }
 11165    }
 166
 13167    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    {
 70181        for (int i = 0; i < assetRenderers.Length; i++)
 182        {
 22183            if (originalMaterials.ContainsKey(assetRenderers[i]))
 184                continue;
 185
 22186            originalMaterials.Add(assetRenderers[i], assetRenderers[i].sharedMaterials.ToArray());
 187        }
 13188    }
 189
 190    private void RestoreOriginalMaterials()
 191    {
 72192        foreach (var kvp in originalMaterials)
 193        {
 22194            if (kvp.Key != null)
 22195                kvp.Key.materials = kvp.Value;
 196        }
 197
 14198        originalMaterials.Clear();
 14199    }
 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}