< Summary

Class:DCL.ECSComponents.GltfContainerHandler
Assembly:DCL.ECSComponents.GltfContainer
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/ECS7/ECSComponents/GltfContainer/GltfContainerHandler.cs
Covered lines:89
Uncovered lines:7
Coverable lines:96
Total lines:214
Line coverage:92.7% (89 of 96)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
GltfContainerHandler(...)0%110100%
OnComponentCreated(...)0%110100%
OnComponentRemoved(...)0%110100%
OnComponentModelUpdated(...)0%3.013088.89%
OnLoadSuccess(...)0%440100%
OnLoadFail(...)0%6200%
CleanUp(...)0%11110100%
SetUpPhysicColliders(...)0%440100%
SetUpPointerCollidersAndRenderers(...)0%55096%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/DCLPlugins/ECS7/ECSComponents/GltfContainer/GltfContainerHandler.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using DCL.Components;
 4using DCL.Configuration;
 5using DCL.Controllers;
 6using DCL.ECS7.InternalComponents;
 7using DCL.ECSRuntime;
 8using DCL.Helpers;
 9using DCL.Models;
 10using UnityEngine;
 11using Object = UnityEngine.Object;
 12
 13namespace DCL.ECSComponents
 14{
 15    public class GltfContainerHandler : IECSComponentHandler<PBGltfContainer>
 16    {
 17        const string POINTER_COLLIDER_NAME = "OnPointerEventCollider";
 18
 19        internal RendereableAssetLoadHelper gltfLoader;
 20        internal GameObject gameObject;
 21        private IList<Collider> physicColliders;
 22        private IList<Collider> pointerColliders;
 23        private IList<Renderer> renderers;
 24        private string prevLoadedGltf = null;
 25
 26        private readonly IInternalECSComponent<InternalColliders> pointerColliderComponent;
 27        private readonly IInternalECSComponent<InternalColliders> physicColliderComponent;
 28        private readonly IInternalECSComponent<InternalRenderers> renderersComponent;
 29        private readonly DataStore_ECS7 dataStoreEcs7;
 30
 631        public GltfContainerHandler(IInternalECSComponent<InternalColliders> pointerColliderComponent,
 32            IInternalECSComponent<InternalColliders> physicColliderComponent,
 33            IInternalECSComponent<InternalRenderers> renderersComponent,
 34            DataStore_ECS7 dataStoreEcs7)
 35        {
 636            this.pointerColliderComponent = pointerColliderComponent;
 637            this.physicColliderComponent = physicColliderComponent;
 638            this.renderersComponent = renderersComponent;
 639            this.dataStoreEcs7 = dataStoreEcs7;
 640        }
 41
 42        public void OnComponentCreated(IParcelScene scene, IDCLEntity entity)
 43        {
 644            gameObject = new GameObject("GLTF mesh");
 45
 646            Transform transform = gameObject.transform;
 647            transform.SetParent(entity.gameObject.transform);
 648            transform.ResetLocalTRS();
 49
 650            gltfLoader = new RendereableAssetLoadHelper(scene.contentProvider, scene.sceneData.baseUrlBundles);
 651            gltfLoader.settings.forceGPUOnlyMesh = true;
 652            gltfLoader.settings.parent = transform;
 653            gltfLoader.settings.visibleFlags = AssetPromiseSettings_Rendering.VisibleFlags.VISIBLE_WITH_TRANSITION;
 654        }
 55
 56        public void OnComponentRemoved(IParcelScene scene, IDCLEntity entity)
 57        {
 858            CleanUp(scene, entity);
 859            Object.Destroy(gameObject);
 860        }
 61
 62        public void OnComponentModelUpdated(IParcelScene scene, IDCLEntity entity, PBGltfContainer model)
 63        {
 1264            if (string.IsNullOrEmpty(model.Src) || prevLoadedGltf == model.Src)
 065                return;
 66
 1267            prevLoadedGltf = model.Src;
 68
 1269            CleanUp(scene, entity);
 70
 2371            gltfLoader.OnSuccessEvent += rendereable => OnLoadSuccess(scene, entity, rendereable);
 1272            gltfLoader.OnFailEvent += exception => OnLoadFail(scene, exception);
 73
 1274            dataStoreEcs7.AddPendingResource(scene.sceneData.id, prevLoadedGltf);
 1275            gltfLoader.Load(model.Src);
 1276        }
 77
 78        private void OnLoadSuccess(IParcelScene scene, IDCLEntity entity, Rendereable rendereable)
 79        {
 80            // create physic colliders
 1181            MeshFilter[] meshFilters = gameObject.GetComponentsInChildren<MeshFilter>();
 1182            physicColliders = SetUpPhysicColliders(meshFilters);
 83
 84            // create pointer colliders and renderers
 1185            (pointerColliders, renderers) = SetUpPointerCollidersAndRenderers(rendereable.renderers);
 86
 87            // set colliders and renderers
 7488            for (int i = 0; i < pointerColliders.Count; i++)
 89            {
 2690                pointerColliderComponent.AddCollider(scene, entity, pointerColliders[i]);
 91            }
 3492            for (int i = 0; i < physicColliders.Count; i++)
 93            {
 694                physicColliderComponent.AddCollider(scene, entity, physicColliders[i]);
 95            }
 7496            for (int i = 0; i < renderers.Count; i++)
 97            {
 2698                renderersComponent.AddRenderer(scene, entity, renderers[i]);
 99            }
 100            // TODO: modify Animator component to remove `AddShapeReady` usage
 11101            dataStoreEcs7.AddShapeReady(entity.entityId, gameObject);
 11102            dataStoreEcs7.RemovePendingResource(scene.sceneData.id, prevLoadedGltf);
 11103        }
 104
 105        private void OnLoadFail(IParcelScene scene, Exception exception)
 106        {
 0107            MaterialTransitionController[] transitionController =
 108                gameObject.GetComponentsInChildren<MaterialTransitionController>(true);
 109
 0110            for (int i = 0; i < transitionController.Length; i++)
 111            {
 0112                MaterialTransitionController material = transitionController[i];
 0113                Object.Destroy(material);
 114            }
 0115            dataStoreEcs7.RemovePendingResource(scene.sceneData.id, prevLoadedGltf);
 0116        }
 117
 118        private void CleanUp(IParcelScene scene, IDCLEntity entity)
 119        {
 20120            int count = pointerColliders?.Count ?? 0;
 92121            for (int i = 0; i < count; i++)
 122            {
 26123                pointerColliderComponent.RemoveCollider(scene, entity, pointerColliders[i]);
 124            }
 20125            count = physicColliders?.Count ?? 0;
 52126            for (int i = 0; i < count; i++)
 127            {
 6128                physicColliderComponent.RemoveCollider(scene, entity, physicColliders[i]);
 129            }
 20130            count = renderers?.Count ?? 0;
 92131            for (int i = 0; i < count; i++)
 132            {
 26133                renderersComponent.RemoveRenderer(scene, entity, renderers[i]);
 134            }
 135
 20136            physicColliders = null;
 20137            pointerColliders = null;
 20138            renderers = null;
 139
 20140            if (!string.IsNullOrEmpty(prevLoadedGltf))
 141            {
 20142                dataStoreEcs7.RemovePendingResource(scene.sceneData.id, prevLoadedGltf);
 143            }
 144            // TODO: modify Animator component to remove `RemoveShapeReady` usage
 20145            dataStoreEcs7.RemoveShapeReady(entity.entityId);
 146
 20147            gltfLoader.ClearEvents();
 20148            gltfLoader.Unload();
 20149        }
 150
 151        private static List<Collider> SetUpPhysicColliders(MeshFilter[] meshFilters)
 152        {
 11153            List<Collider> physicColliders = new List<Collider>(meshFilters.Length);
 154
 86155            for (int i = 0; i < meshFilters.Length; i++)
 156            {
 32157                if (meshFilters[i].gameObject.layer == PhysicsLayers.characterOnlyLayer)
 158                {
 1159                    physicColliders.Add(meshFilters[i].gameObject.GetComponent<Collider>());
 1160                    continue;
 161                }
 162
 31163                if (!meshFilters[i].transform.parent.name.ToLower().Contains("_collider"))
 164                    continue;
 165
 5166                MeshCollider collider = meshFilters[i].gameObject.AddComponent<MeshCollider>();
 5167                collider.sharedMesh = meshFilters[i].sharedMesh;
 5168                meshFilters[i].gameObject.layer = PhysicsLayers.characterOnlyLayer;
 5169                physicColliders.Add(collider);
 170
 5171                Object.Destroy(meshFilters[i].GetComponent<Renderer>());
 172            }
 173
 11174            return physicColliders;
 175        }
 176
 177        private static (List<Collider>, List<Renderer>) SetUpPointerCollidersAndRenderers(HashSet<Renderer> renderers)
 178        {
 11179            List<Collider> pointerColliders = new List<Collider>(renderers.Count);
 11180            List<Renderer> rendererList = new List<Renderer>(renderers.Count);
 181
 182            // (sadly we are stuck with a hashset here)
 74183            foreach (var renderer in renderers)
 184            {
 26185                rendererList.Add(renderer);
 26186                Transform rendererT = renderer.transform;
 26187                bool alreadyHasCollider = false;
 52188                for (int i = 0; i < rendererT.childCount; i++)
 189                {
 5190                    Transform child = rendererT.GetChild(i);
 5191                    if (child.gameObject.layer != PhysicsLayers.onPointerEventLayer)
 192                        continue;
 193
 5194                    alreadyHasCollider = true;
 5195                    pointerColliders.Add(child.GetComponent<Collider>());
 5196                    break;
 197                }
 198
 26199                if (alreadyHasCollider)
 200                    continue;
 201
 21202                GameObject colliderGo = new GameObject(POINTER_COLLIDER_NAME);
 21203                colliderGo.layer = PhysicsLayers.onPointerEventLayer;
 21204                MeshCollider collider = colliderGo.AddComponent<MeshCollider>();
 21205                collider.sharedMesh = renderer.GetComponent<MeshFilter>().sharedMesh;
 21206                colliderGo.transform.SetParent(renderer.transform);
 21207                colliderGo.transform.ResetLocalTRS();
 21208                pointerColliders.Add(collider);
 209            }
 210
 11211            return (pointerColliders, rendererList);
 212        }
 213    }
 214}