< 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:86
Uncovered lines:7
Coverable lines:93
Total lines:217
Line coverage:92.4% (86 of 93)
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%
IsCollider(...)0%220100%
SetUpPointerCollidersAndRenderers(...)0%66096.3%

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        private const string POINTER_COLLIDER_NAME = "OnPointerEventCollider";
 18        private const string FEATURE_GLTFAST = "gltfast";
 19        private const StringComparison IGNORE_CASE = StringComparison.CurrentCultureIgnoreCase;
 20
 21        internal RendereableAssetLoadHelper gltfLoader;
 22        internal GameObject gameObject;
 23        private IList<Collider> physicColliders;
 24        private IList<Collider> pointerColliders;
 25        private IList<Renderer> renderers;
 26        private string prevLoadedGltf = null;
 27
 28        private readonly IInternalECSComponent<InternalColliders> pointerColliderComponent;
 29        private readonly IInternalECSComponent<InternalColliders> physicColliderComponent;
 30        private readonly IInternalECSComponent<InternalRenderers> renderersComponent;
 31        private readonly DataStore_ECS7 dataStoreEcs7;
 32        private DataStore_FeatureFlag featureFlags;
 33
 634        public GltfContainerHandler(IInternalECSComponent<InternalColliders> pointerColliderComponent,
 35            IInternalECSComponent<InternalColliders> physicColliderComponent,
 36            IInternalECSComponent<InternalRenderers> renderersComponent,
 37            DataStore_ECS7 dataStoreEcs7, DataStore_FeatureFlag featureFlags)
 38        {
 639            this.featureFlags = featureFlags;
 640            this.pointerColliderComponent = pointerColliderComponent;
 641            this.physicColliderComponent = physicColliderComponent;
 642            this.renderersComponent = renderersComponent;
 643            this.dataStoreEcs7 = dataStoreEcs7;
 644        }
 45
 46        public void OnComponentCreated(IParcelScene scene, IDCLEntity entity)
 47        {
 648            gameObject = new GameObject("GLTF mesh");
 49
 650            Transform transform = gameObject.transform;
 651            transform.SetParent(entity.gameObject.transform);
 652            transform.ResetLocalTRS();
 53
 1854            gltfLoader = new RendereableAssetLoadHelper(scene.contentProvider, scene.sceneData.baseUrlBundles, () => fea
 655            gltfLoader.settings.forceGPUOnlyMesh = true;
 656            gltfLoader.settings.parent = transform;
 657            gltfLoader.settings.visibleFlags = AssetPromiseSettings_Rendering.VisibleFlags.VISIBLE_WITH_TRANSITION;
 658        }
 59
 60        public void OnComponentRemoved(IParcelScene scene, IDCLEntity entity)
 61        {
 862            CleanUp(scene, entity);
 863            Object.Destroy(gameObject);
 864        }
 65
 66        public void OnComponentModelUpdated(IParcelScene scene, IDCLEntity entity, PBGltfContainer model)
 67        {
 1268            if (string.IsNullOrEmpty(model.Src) || prevLoadedGltf == model.Src)
 069                return;
 70
 1271            prevLoadedGltf = model.Src;
 72
 1273            CleanUp(scene, entity);
 74
 2375            gltfLoader.OnSuccessEvent += rendereable => OnLoadSuccess(scene, entity, rendereable);
 1276            gltfLoader.OnFailEvent += exception => OnLoadFail(scene, exception);
 77
 1278            dataStoreEcs7.AddPendingResource(scene.sceneData.sceneNumber, prevLoadedGltf);
 1279            gltfLoader.Load(model.Src);
 1280        }
 81
 82        private void OnLoadSuccess(IParcelScene scene, IDCLEntity entity, Rendereable rendereable)
 83        {
 84            // create physic colliders
 1185            MeshFilter[] meshFilters = gameObject.GetComponentsInChildren<MeshFilter>();
 1186            physicColliders = SetUpPhysicColliders(meshFilters);
 87
 88            // create pointer colliders and renderers
 1189            (pointerColliders, renderers) = SetUpPointerCollidersAndRenderers(rendereable.renderers);
 90
 91            // set colliders and renderers
 10092            for (int i = 0; i < pointerColliders.Count; i++) { pointerColliderComponent.AddCollider(scene, entity, point
 93
 4094            for (int i = 0; i < physicColliders.Count; i++) { physicColliderComponent.AddCollider(scene, entity, physicC
 95
 10096            for (int i = 0; i < renderers.Count; i++) { renderersComponent.AddRenderer(scene, entity, renderers[i]); }
 97
 98            // TODO: modify Animator component to remove `AddShapeReady` usage
 1199            dataStoreEcs7.AddShapeReady(entity.entityId, gameObject);
 11100            dataStoreEcs7.RemovePendingResource(scene.sceneData.sceneNumber, prevLoadedGltf);
 11101        }
 102
 103        private void OnLoadFail(IParcelScene scene, Exception exception)
 104        {
 0105            MaterialTransitionController[] transitionController =
 106                gameObject.GetComponentsInChildren<MaterialTransitionController>(true);
 107
 0108            for (int i = 0; i < transitionController.Length; i++)
 109            {
 0110                MaterialTransitionController material = transitionController[i];
 0111                Object.Destroy(material);
 112            }
 113
 0114            dataStoreEcs7.RemovePendingResource(scene.sceneData.sceneNumber, prevLoadedGltf);
 0115        }
 116
 117        private void CleanUp(IParcelScene scene, IDCLEntity entity)
 118        {
 20119            int count = pointerColliders?.Count ?? 0;
 120
 118121            for (int i = 0; i < count; i++) { pointerColliderComponent.RemoveCollider(scene, entity, pointerColliders[i]
 122
 20123            count = physicColliders?.Count ?? 0;
 124
 58125            for (int i = 0; i < count; i++) { physicColliderComponent.RemoveCollider(scene, entity, physicColliders[i]);
 126
 20127            count = renderers?.Count ?? 0;
 128
 118129            for (int i = 0; i < count; i++) { renderersComponent.RemoveRenderer(scene, entity, renderers[i]); }
 130
 20131            physicColliders = null;
 20132            pointerColliders = null;
 20133            renderers = null;
 134
 40135            if (!string.IsNullOrEmpty(prevLoadedGltf)) { dataStoreEcs7.RemovePendingResource(scene.sceneData.sceneNumber
 136
 137            // TODO: modify Animator component to remove `RemoveShapeReady` usage
 20138            dataStoreEcs7.RemoveShapeReady(entity.entityId);
 139
 20140            gltfLoader.ClearEvents();
 20141            gltfLoader.Unload();
 20142        }
 143
 144        private static List<Collider> SetUpPhysicColliders(MeshFilter[] meshFilters)
 145        {
 11146            List<Collider> physicColliders = new List<Collider>(meshFilters.Length);
 147
 86148            for (int i = 0; i < meshFilters.Length; i++)
 149            {
 32150                if (meshFilters[i].gameObject.layer == PhysicsLayers.characterOnlyLayer)
 151                {
 1152                    physicColliders.Add(meshFilters[i].gameObject.GetComponent<Collider>());
 1153                    continue;
 154                }
 155
 31156                if (!IsCollider(meshFilters[i]))
 157                    continue;
 158
 5159                MeshCollider collider = meshFilters[i].gameObject.AddComponent<MeshCollider>();
 5160                collider.sharedMesh = meshFilters[i].sharedMesh;
 5161                meshFilters[i].gameObject.layer = PhysicsLayers.characterOnlyLayer;
 5162                physicColliders.Add(collider);
 163
 5164                Object.Destroy(meshFilters[i].GetComponent<Renderer>());
 165            }
 166
 11167            return physicColliders;
 168        }
 169
 170        // Compatibility layer for old GLTF importer and GLTFast
 171        private static bool IsCollider(MeshFilter meshFilter) =>
 31172            meshFilter.name.Contains("_collider", IGNORE_CASE)
 173            || meshFilter.transform.parent.name.Contains("_collider", IGNORE_CASE);
 174
 175        private static (List<Collider>, List<Renderer>) SetUpPointerCollidersAndRenderers(HashSet<Renderer> renderers)
 176        {
 11177            List<Collider> pointerColliders = new List<Collider>(renderers.Count);
 11178            List<Renderer> rendererList = new List<Renderer>(renderers.Count);
 179
 180            // (sadly we are stuck with a hashset here)
 74181            foreach (var renderer in renderers)
 182            {
 26183                rendererList.Add(renderer);
 26184                Transform rendererT = renderer.transform;
 26185                bool alreadyHasCollider = false;
 186
 52187                for (int i = 0; i < rendererT.childCount; i++)
 188                {
 5189                    Transform child = rendererT.GetChild(i);
 190
 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                MeshFilter meshFilter = renderer.GetComponent<MeshFilter>();
 21206                if (meshFilter == null) continue;
 207
 21208                collider.sharedMesh = meshFilter.sharedMesh;
 21209                colliderGo.transform.SetParent(renderer.transform);
 21210                colliderGo.transform.ResetLocalTRS();
 21211                pointerColliders.Add(collider);
 212            }
 213
 11214            return (pointerColliders, rendererList);
 215        }
 216    }
 217}