< Summary

Class:DCL.Components.BasicMaterial
Assembly:DCL.Components.Materials
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Materials/BasicMaterial.cs
Covered lines:87
Uncovered lines:15
Coverable lines:102
Total lines:230
Line coverage:85.2% (87 of 102)
Covered branches:0
Total branches:0
Covered methods:13
Total methods:15
Method coverage:86.6% (13 of 15)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Model()0%110100%
GetDataFromJSON(...)0%110100%
GetDataFromPb(...)0%30500%
BasicMaterial()0%110100%
BasicMaterial()0%110100%
GetModel()0%110100%
GetClassId()0%2100%
AttachTo(...)0%2.032080%
DetachFrom(...)0%110100%
ApplyChanges()0%10.2910085.71%
OnMaterialAttached(...)0%330100%
InitMaterial(...)0%6.016093.75%
OnShapeUpdated(...)0%220100%
OnMaterialDetached(...)0%440100%
Dispose()0%440100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Materials/BasicMaterial.cs

#LineLine coverage
 1using Cysharp.Threading.Tasks;
 2using DCL.Controllers;
 3using DCL.Helpers;
 4using DCL.Models;
 5using System.Collections;
 6using System.Linq;
 7using System.Threading;
 8using UnityEngine;
 9using UnityEngine.Rendering;
 10using Decentraland.Sdk.Ecs6;
 11using System;
 12using Object = UnityEngine.Object;
 13
 14namespace DCL.Components
 15{
 16    public class BasicMaterial : BaseDisposable
 17    {
 18        [System.Serializable]
 19        public class Model : BaseModel
 20        {
 21            public string texture;
 22
 23            // value that defines if a pixel is visible or invisible (no transparency gradients)
 24            [Range(0f, 1f)]
 17325            public float alphaTest = 0.5f;
 26
 17327            public bool castShadows = true;
 28
 29            public override BaseModel GetDataFromJSON(string json) =>
 6430                Utils.SafeFromJson<Model>(json);
 31
 32            public override BaseModel GetDataFromPb(ComponentBodyPayload pbModel)
 33            {
 034                if (pbModel.PayloadCase != ComponentBodyPayload.PayloadOneofCase.BasicMaterial)
 035                    return Utils.SafeUnimplemented<BasicMaterial, Model>(expected: ComponentBodyPayload.PayloadOneofCase
 36
 037                var pb = new Model();
 038                if (pbModel.BasicMaterial.HasTexture) pb.texture = pbModel.BasicMaterial.Texture;
 039                if (pbModel.BasicMaterial.HasAlphaTest) pb.alphaTest = pbModel.BasicMaterial.AlphaTest;
 040                if (pbModel.BasicMaterial.HasCastShadows) pb.castShadows = pbModel.BasicMaterial.CastShadows;
 41
 042                return pb;
 43            }
 44        }
 45
 46        public Material material;
 47
 48        private DCLTexture dclTexture = null;
 49
 150        private static readonly int _BaseMap = Shader.PropertyToID("_BaseMap");
 151        private static readonly int _AlphaClip = Shader.PropertyToID("_AlphaClip");
 152        private static readonly int _Cutoff = Shader.PropertyToID("_Cutoff");
 153        private static readonly int _ZWrite = Shader.PropertyToID("_ZWrite");
 54
 4555        private readonly DCLTexture.Fetcher dclTextureFetcher = new DCLTexture.Fetcher();
 56        private bool isDisposed;
 57
 4558        public BasicMaterial()
 59        {
 4560            material = new Material(Utils.EnsureResourcesMaterial("Materials/BasicShapeMaterial"));
 61
 4562            OnAttach += OnMaterialAttached;
 4563            OnDetach += OnMaterialDetached;
 4564            model = new Model();
 4565        }
 66
 467        new public Model GetModel() { return (Model) model; }
 68
 069        public override int GetClassId() { return (int) CLASS_ID.BASIC_MATERIAL; }
 70
 71        public override void AttachTo(IDCLEntity entity, System.Type overridenAttachedType = null)
 72        {
 4473            if (attachedEntities.Contains(entity))
 074                return;
 75
 4476            scene.componentsManagerLegacy.RemoveSharedComponent(entity, (typeof(PBRMaterial)));
 4477            base.AttachTo(entity, overridenAttachedType);
 4478        }
 79
 80        public override void DetachFrom(IDCLEntity entity, System.Type overridenAttachedType = null)
 81        {
 4482            base.DetachFrom(entity, overridenAttachedType);
 4483        }
 84
 85        public override IEnumerator ApplyChanges(BaseModel newModel)
 86        {
 6487            if (material == null)
 88            {
 089                yield break; // We escape ApplyChanges called in the parent's constructor
 90            }
 91
 92#if UNITY_EDITOR
 6493            material.name = "BasicMaterial_" + id;
 94#endif
 95
 6496            Model model = (Model) newModel;
 97
 6498            if (!string.IsNullOrEmpty(model.texture))
 99            {
 50100                if (dclTexture == null || dclTexture.id != model.texture)
 101                {
 50102                    yield return dclTextureFetcher.Fetch(
 103                        scene,
 104                        model.texture,
 105                        texture =>
 106                        {
 48107                            if (isDisposed)
 0108                                return false;
 109
 48110                            if (dclTexture != null)
 111                            {
 15112                                dclTexture.DetachFrom(this);
 113                            }
 114
 48115                            material.SetTexture(_BaseMap, texture.texture);
 48116                            dclTexture = texture;
 48117                            dclTexture.AttachTo(this);
 48118                            return true;
 119                        }).ToCoroutine(e =>
 120                    {
 2121                        if (e is not OperationCanceledException)
 0122                            throw e;
 2123                    });
 124                    // using `ToCoroutine()` since using Task directly arise some component lifecycle issues
 125                }
 126            }
 127            else
 128            {
 14129                material.mainTexture = null;
 130
 14131                if ( dclTexture != null )
 132                {
 0133                    dclTexture.DetachFrom(this);
 0134                    dclTexture = null;
 135                }
 136            }
 137
 64138            material.EnableKeyword("_ALPHATEST_ON");
 62139            material.SetInt(_ZWrite, 1);
 62140            material.SetFloat(_AlphaClip, 1);
 62141            material.SetFloat(_Cutoff, model.alphaTest);
 62142            material.renderQueue = (int) UnityEngine.Rendering.RenderQueue.AlphaTest;
 143
 216144            foreach (IDCLEntity entity in attachedEntities)
 145            {
 46146                InitMaterial(entity);
 147            }
 62148        }
 149
 150        void OnMaterialAttached(IDCLEntity entity)
 151        {
 44152            entity.OnShapeUpdated -= OnShapeUpdated;
 44153            entity.OnShapeUpdated += OnShapeUpdated;
 154
 44155            if (entity.meshRootGameObject != null)
 156            {
 20157                var meshRenderer = entity.meshRootGameObject.GetComponent<MeshRenderer>();
 158
 20159                if (meshRenderer != null)
 20160                    InitMaterial(entity);
 161            }
 44162        }
 163
 164        void InitMaterial(IDCLEntity entity)
 165        {
 107166            var meshGameObject = entity.meshRootGameObject;
 167
 107168            if (meshGameObject == null)
 20169                return;
 170
 87171            var meshRenderer = meshGameObject.GetComponent<MeshRenderer>();
 172
 87173            if (meshRenderer == null)
 0174                return;
 175
 87176            Model model = (Model) this.model;
 177
 87178            meshRenderer.shadowCastingMode = model.castShadows ? ShadowCastingMode.On : ShadowCastingMode.Off;
 179
 87180            if (meshRenderer.sharedMaterial == material)
 52181                return;
 182
 35183            SRPBatchingHelper.OptimizeMaterial(material);
 184
 35185            Material oldMaterial = meshRenderer.sharedMaterial;
 35186            meshRenderer.sharedMaterial = material;
 187
 35188            DataStore.i.sceneWorldObjects.RemoveMaterial(scene.sceneData.sceneNumber, entity.entityId, oldMaterial);
 35189            DataStore.i.sceneWorldObjects.AddMaterial(scene.sceneData.sceneNumber, entity.entityId, material);
 35190        }
 191
 192        private void OnShapeUpdated(IDCLEntity entity)
 193        {
 41194            if (entity != null)
 41195                InitMaterial(entity);
 41196        }
 197
 198        void OnMaterialDetached(IDCLEntity entity)
 199        {
 44200            if (entity.meshRootGameObject == null)
 11201                return;
 202
 33203            entity.OnShapeUpdated -= OnShapeUpdated;
 204
 33205            var meshRenderer = entity.meshRootGameObject.GetComponent<MeshRenderer>();
 206
 33207            if (meshRenderer && meshRenderer.sharedMaterial == material)
 31208                meshRenderer.sharedMaterial = null;
 209
 33210            DataStore.i.sceneWorldObjects.RemoveMaterial(scene.sceneData.sceneNumber, entity.entityId, material);
 33211        }
 212
 213        public override void Dispose()
 214        {
 41215            isDisposed = true;
 216
 41217            dclTexture?.DetachFrom(this);
 218
 62219            while (attachedEntities != null && attachedEntities.Count > 0 )
 220            {
 21221                DetachFrom(attachedEntities.First());
 222            }
 223
 41224            Object.Destroy(material);
 225
 41226            dclTextureFetcher.Dispose();
 41227            base.Dispose();
 41228        }
 229    }
 230}