< 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:157
Uncovered lines:14
Coverable lines:171
Total lines:470
Line coverage:91.8% (157 of 171)
Covered branches:0
Total branches:0
Covered methods:15
Total methods:17
Method coverage:88.2% (15 of 17)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
ActiveCollidersData()0%110100%
GltfContainerHandler(...)0%110100%
OnComponentCreated(...)0%110100%
OnComponentRemoved(...)0%330100%
OnComponentModelUpdated(...)0%14140100%
OnGltfSrcChanged(...)0%550100%
OnLoadSuccess(...)0%770100%
UnloadGltf(...)0%33093.75%
InitColliders(...)0%110100%
SetUpColliders(...)0%330100%
RemoveColliders(...)0%440100%
SetColliders(...)0%18180100%
SetUpRenderers(...)0%5.035088.89%
SetGltfLoaded(...)0%4.134080%
OnLoadFail(...)0%110100%
AddCurrentRendereableToSceneMetrics()0%20400%
RemoveCurrentRendereableFromSceneMetrics()0%12300%

File(s)

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

#LineLine coverage
 1using DCL.Components;
 2using DCL.Controllers;
 3using DCL.ECS7.InternalComponents;
 4using DCL.ECSComponents.Utils;
 5using DCL.ECSRuntime;
 6using DCL.Helpers;
 7using DCL.Models;
 8using System;
 9using System.Collections.Generic;
 10using UnityEngine;
 11using Object = UnityEngine.Object;
 12
 13namespace DCL.ECSComponents
 14{
 15    public class GltfContainerHandler : IECSComponentHandler<PBGltfContainer>
 16    {
 17        private class ActiveCollidersData
 18        {
 6619            public readonly List<Collider> PhysicColliders = new List<Collider>(10);
 6620            public readonly List<Collider> PointerColliders = new List<Collider>(10);
 6621            public readonly List<Collider> CustomLayerColliders = new List<Collider>(10);
 22        }
 23
 24        private const uint LAYER_PHYSICS = (uint)ColliderLayer.ClPhysics;
 25        private const uint LAYER_POINTER = (uint)ColliderLayer.ClPointer;
 26        private const string SMR_UPDATE_OFFSCREEN_FEATURE_FLAG = "smr_update_offscreen";
 27
 28        private readonly IInternalECSComponent<InternalColliders> pointerColliderComponent;
 29        private readonly IInternalECSComponent<InternalColliders> physicColliderComponent;
 30        private readonly IInternalECSComponent<InternalColliders> customLayerColliderComponent;
 31        private readonly IInternalECSComponent<InternalRenderers> renderersComponent;
 32        private readonly IInternalECSComponent<InternalGltfContainerLoadingState> gltfContainerLoadingStateComponent;
 33        private readonly IInternalECSComponent<InternalAnimation> animationComponent;
 34
 35        private readonly DataStore_ECS7 dataStoreEcs7;
 36        private readonly DataStore_FeatureFlag featureFlags;
 37        private readonly DataStore_WorldObjects dataStoreWorldObjects;
 38
 3339        private readonly ActiveCollidersData visibleActiveColliders = new ActiveCollidersData();
 3340        private readonly ActiveCollidersData invisibleActiveColliders = new ActiveCollidersData();
 41        private readonly bool isDebugMode = false;
 42
 43        public RendereableAssetLoadHelper gltfLoader;
 44        internal GameObject gameObject;
 45
 46        private IReadOnlyCollection<Renderer> renderers;
 47        private Rendereable currentRendereable;
 48
 49        internal GltfContainerCollidersHandler collidersHandler;
 50        private PBGltfContainer previousModel = null;
 51        private IParcelScene scene;
 52        private IDCLEntity entity;
 53
 3354        public GltfContainerHandler(IInternalECSComponent<InternalColliders> pointerColliderComponent,
 55            IInternalECSComponent<InternalColliders> physicColliderComponent,
 56            IInternalECSComponent<InternalColliders> customLayerColliderComponent,
 57            IInternalECSComponent<InternalRenderers> renderersComponent,
 58            IInternalECSComponent<InternalGltfContainerLoadingState> gltfContainerLoadingStateComponent,
 59            IInternalECSComponent<InternalAnimation> animationComponent,
 60            DataStore_ECS7 dataStoreEcs7,
 61            DataStore_FeatureFlag featureFlags,
 62            DataStore_WorldObjects dataStoreWorldObjects,
 63            DebugConfig debugConfig)
 64        {
 3365            this.featureFlags = featureFlags;
 3366            this.pointerColliderComponent = pointerColliderComponent;
 3367            this.physicColliderComponent = physicColliderComponent;
 3368            this.customLayerColliderComponent = customLayerColliderComponent;
 3369            this.renderersComponent = renderersComponent;
 3370            this.gltfContainerLoadingStateComponent = gltfContainerLoadingStateComponent;
 3371            this.animationComponent = animationComponent;
 3372            this.dataStoreEcs7 = dataStoreEcs7;
 3373            this.dataStoreWorldObjects = dataStoreWorldObjects;
 3374            this.isDebugMode = debugConfig.isDebugMode.Get();
 3375        }
 76
 77        public void OnComponentCreated(IParcelScene scene, IDCLEntity entity)
 78        {
 3379            this.scene = scene;
 3380            this.entity = entity;
 3381            gameObject = new GameObject("GLTF mesh");
 82
 3383            Transform transform = gameObject.transform;
 3384            transform.SetParent(entity.gameObject.transform);
 3385            transform.ResetLocalTRS();
 86
 3387            gltfLoader = new RendereableAssetLoadHelper(scene.contentProvider, scene.sceneData.baseUrlBundles);
 3388            gltfLoader.settings.forceGPUOnlyMesh = true;
 3389            gltfLoader.settings.parent = transform;
 3390            gltfLoader.settings.visibleFlags = AssetPromiseSettings_Rendering.VisibleFlags.VISIBLE_WITH_TRANSITION;
 3391            gltfLoader.settings.smrUpdateWhenOffScreen = featureFlags.flags.Get().IsFeatureEnabled(SMR_UPDATE_OFFSCREEN_
 92
 3393            collidersHandler = new GltfContainerCollidersHandler();
 3394        }
 95
 96        public void OnComponentRemoved(IParcelScene scene, IDCLEntity entity)
 97        {
 1298            UnloadGltf(entity, previousModel?.Src);
 99
 12100            gltfContainerLoadingStateComponent.RemoveFor(scene, entity,
 101                new InternalGltfContainerLoadingState() { GltfContainerRemoved = true });
 102
 12103            Object.Destroy(gameObject);
 12104        }
 105
 106        public void OnComponentModelUpdated(IParcelScene scene, IDCLEntity entity, PBGltfContainer model)
 107        {
 49108            bool srcChanged = previousModel?.Src != model.Src;
 49109            bool visibleMeshColliderMaskChanged = previousModel?.GetVisibleMeshesCollisionMask() != model.GetVisibleMesh
 49110            bool invisibleMeshColliderMaskChanged = previousModel?.GetInvisibleMeshesCollisionMask() != model.GetInvisib
 111
 49112            if (srcChanged)
 113            {
 38114                OnGltfSrcChanged(previousModel, model);
 115            }
 116            else
 117            {
 11118                if (visibleMeshColliderMaskChanged)
 119                {
 6120                    SetUpColliders(
 121                        previousModel?.GetVisibleMeshesCollisionMask() ?? 0,
 122                        model.GetVisibleMeshesCollisionMask(),
 123                        collidersHandler.GetVisibleMeshesColliders(),
 124                        visibleActiveColliders.PointerColliders,
 125                        visibleActiveColliders.PhysicColliders,
 126                        visibleActiveColliders.CustomLayerColliders);
 127                }
 128
 11129                if (invisibleMeshColliderMaskChanged)
 130                {
 7131                    SetUpColliders(
 132                        previousModel?.GetInvisibleMeshesCollisionMask() ?? 0,
 133                        model.GetInvisibleMeshesCollisionMask(),
 134                        collidersHandler.GetInvisibleMeshesColliders(),
 135                        invisibleActiveColliders.PointerColliders,
 136                        invisibleActiveColliders.PhysicColliders,
 137                        invisibleActiveColliders.CustomLayerColliders);
 138                }
 139            }
 140
 49141            previousModel = model;
 49142        }
 143
 144        private void OnGltfSrcChanged(PBGltfContainer prevModel, PBGltfContainer model)
 145        {
 38146            if (!string.IsNullOrEmpty(prevModel?.Src))
 147            {
 7148                UnloadGltf(entity, prevModel.Src);
 149            }
 150
 38151            string newGltfSrc = model.Src;
 152
 38153            if (!string.IsNullOrEmpty(newGltfSrc))
 154            {
 38155                gltfContainerLoadingStateComponent.PutFor(scene, entity,
 156                    new InternalGltfContainerLoadingState() { LoadingState = LoadingState.Loading });
 157
 69158                gltfLoader.OnSuccessEvent += rendereable => OnLoadSuccess(rendereable, model);
 159
 39160                gltfLoader.OnFailEvent += exception => OnLoadFail(scene, entity, newGltfSrc, exception,
 161                    dataStoreEcs7, gltfContainerLoadingStateComponent);
 162
 38163                dataStoreEcs7.AddPendingResource(scene.sceneData.sceneNumber, newGltfSrc);
 38164                gltfLoader.Load(newGltfSrc);
 165            }
 38166        }
 167
 168        private void OnLoadSuccess(
 169            Rendereable rendereable,
 170            PBGltfContainer model)
 171        {
 31172            renderers = rendereable.renderers;
 173
 31174            InitColliders(
 175                rendereable.renderers,
 176                gameObject,
 177                collidersHandler,
 178                model.GetVisibleMeshesCollisionMask() != 0);
 179
 31180            SetUpRenderers(scene, entity, rendereable.renderers, renderersComponent);
 181
 182            // setup colliders for visible meshes
 31183            SetUpColliders(
 184                previousModel?.GetVisibleMeshesCollisionMask() ?? 0,
 185                model.GetVisibleMeshesCollisionMask(),
 186                model.GetVisibleMeshesCollisionMask() != 0 ? collidersHandler.GetVisibleMeshesColliders() : null,
 187                visibleActiveColliders.PointerColliders,
 188                visibleActiveColliders.PhysicColliders,
 189                visibleActiveColliders.CustomLayerColliders);
 190
 191            // setup colliders for invisible meshes
 31192            SetUpColliders(
 193                previousModel?.GetInvisibleMeshesCollisionMask() ?? 0,
 194                model.GetInvisibleMeshesCollisionMask(),
 195                collidersHandler.GetInvisibleMeshesColliders(),
 196                invisibleActiveColliders.PointerColliders,
 197                invisibleActiveColliders.PhysicColliders,
 198                invisibleActiveColliders.CustomLayerColliders);
 199
 31200            SetGltfLoaded(gameObject, model.Src, rendereable);
 31201        }
 202
 203        private void UnloadGltf(IDCLEntity entity, string gltfSrc)
 204        {
 205            void RemoveActiveColliders(IList<Collider> colliders, IInternalECSComponent<InternalColliders> colliderCompo
 206            {
 272207                for (int i = 0; i < colliders.Count; i++)
 208                {
 22209                    colliderComponent.RemoveCollider(scene, entity, colliders[i]);
 210                }
 211
 114212                colliders.Clear();
 114213            }
 214
 19215            RemoveActiveColliders(invisibleActiveColliders.PointerColliders, pointerColliderComponent);
 19216            RemoveActiveColliders(visibleActiveColliders.PointerColliders, pointerColliderComponent);
 19217            RemoveActiveColliders(invisibleActiveColliders.PhysicColliders, physicColliderComponent);
 19218            RemoveActiveColliders(visibleActiveColliders.PhysicColliders, physicColliderComponent);
 19219            RemoveActiveColliders(invisibleActiveColliders.CustomLayerColliders, customLayerColliderComponent);
 19220            RemoveActiveColliders(visibleActiveColliders.CustomLayerColliders, customLayerColliderComponent);
 221
 19222            renderersComponent.RemoveRenderers(scene, entity, renderers);
 223
 19224            if (!string.IsNullOrEmpty(gltfSrc))
 225            {
 18226                dataStoreEcs7.RemovePendingResource(scene.sceneData.sceneNumber, gltfSrc);
 227            }
 228
 19229            animationComponent.RemoveFor(scene, entity);
 230
 19231            collidersHandler.CleanUp();
 232
 19233            gltfLoader.ClearEvents();
 19234            gltfLoader.Unload();
 235
 19236            if (isDebugMode)
 0237                RemoveCurrentRendereableFromSceneMetrics();
 19238        }
 239
 240        private static void InitColliders(
 241            HashSet<Renderer> rendererHashSet,
 242            GameObject rootGameObject,
 243            GltfContainerCollidersHandler collidersHandler,
 244            bool createVisibleMeshColliders)
 245        {
 31246            MeshFilter[] meshFilters = rootGameObject.GetComponentsInChildren<MeshFilter>();
 31247            collidersHandler.InitInvisibleMeshesColliders(meshFilters);
 31248            collidersHandler.InitVisibleMeshesColliders(rendererHashSet, createVisibleMeshColliders);
 31249        }
 250
 251        private void SetUpColliders(
 252            uint prevColliderLayer,
 253            uint colliderLayer,
 254            IReadOnlyList<Collider> gltfColliders,
 255            IList<Collider> currentPointerColliders,
 256            IList<Collider> currentPhysicColliders,
 257            IList<Collider> currentCustomLayerColliders)
 258        {
 75259            if (prevColliderLayer != 0)
 260            {
 47261                RemoveColliders(prevColliderLayer, currentPointerColliders,
 262                    currentPhysicColliders, currentCustomLayerColliders);
 263            }
 264
 75265            if (colliderLayer != 0)
 266            {
 46267                SetColliders(colliderLayer, gltfColliders, currentPointerColliders,
 268                    currentPhysicColliders, currentCustomLayerColliders);
 269            }
 75270        }
 271
 272        private void RemoveColliders(
 273            uint colliderLayer,
 274            IList<Collider> currentPointerColliders,
 275            IList<Collider> currentPhysicColliders,
 276            IList<Collider> currentCustomLayerColliders)
 277        {
 278            void LocalRemoveColliders(
 279                IInternalECSComponent<InternalColliders> collidersComponent,
 280                IList<Collider> currentColliders)
 281            {
 99282                var collidersModel = collidersComponent.GetFor(scene, entity)?.model;
 283
 99284                if (collidersModel != null)
 285                {
 112286                    for (int i = 0; i < currentColliders.Count; i++)
 287                    {
 19288                        currentColliders[i].enabled = false;
 19289                        collidersModel.Value.colliders.Remove(currentColliders[i]);
 290                    }
 291
 37292                    collidersComponent.PutFor(scene, entity, collidersModel.Value);
 293                }
 294
 99295                currentColliders.Clear();
 99296            }
 297
 47298            if ((colliderLayer & LAYER_PHYSICS) != 0)
 299            {
 39300                LocalRemoveColliders(physicColliderComponent, currentPhysicColliders);
 301            }
 302
 47303            if ((colliderLayer & LAYER_POINTER) != 0)
 304            {
 39305                LocalRemoveColliders(pointerColliderComponent, currentPointerColliders);
 306            }
 307
 47308            if (LayerMaskUtils.LayerMaskHasAnySDKCustomLayer(colliderLayer))
 309            {
 21310                LocalRemoveColliders(customLayerColliderComponent, currentCustomLayerColliders);
 311            }
 47312        }
 313
 314        private void SetColliders(
 315            uint colliderLayer,
 316            IReadOnlyList<Collider> gltfColliders,
 317            IList<Collider> currentPointerColliders,
 318            IList<Collider> currentPhysicColliders,
 319            IList<Collider> currentCustomLayerColliders)
 320        {
 46321            int? unityGameObjectLayer = LayerMaskUtils.SdkLayerMaskToUnityLayer(colliderLayer);
 46322            bool hasCustomLayer = LayerMaskUtils.LayerMaskHasAnySDKCustomLayer(colliderLayer);
 323
 46324            var pointerColliders = pointerColliderComponent.GetFor(scene, entity)?.model;
 46325            var physicColliders = physicColliderComponent.GetFor(scene, entity)?.model;
 46326            var customColliders = customLayerColliderComponent.GetFor(scene, entity)?.model;
 327
 46328            bool hasPointerColliders = false;
 46329            bool hasPhysicColliders = false;
 46330            bool hasCustomColliders = false;
 331
 168332            for (int i = 0; i < gltfColliders.Count; i++)
 333            {
 38334                Collider collider = gltfColliders[i];
 335
 38336                if (unityGameObjectLayer.HasValue)
 337                {
 38338                    collider.gameObject.layer = unityGameObjectLayer.Value;
 339                }
 340
 38341                collider.enabled = true;
 342
 38343                if ((colliderLayer & LAYER_PHYSICS) != 0)
 344                {
 30345                    physicColliders ??= new InternalColliders(new KeyValueSet<Collider, uint>());
 30346                    physicColliders.Value.colliders.Add(collider, colliderLayer);
 30347                    currentPhysicColliders.Add(collider);
 30348                    hasPhysicColliders = true;
 349                }
 350
 38351                if ((colliderLayer & LAYER_POINTER) != 0)
 352                {
 30353                    pointerColliders ??= new InternalColliders(new KeyValueSet<Collider, uint>());
 30354                    pointerColliders.Value.colliders.Add(collider, colliderLayer);
 30355                    currentPointerColliders.Add(collider);
 30356                    hasPointerColliders = true;
 357                }
 358
 38359                if (hasCustomLayer)
 360                {
 20361                    customColliders ??= new InternalColliders(new KeyValueSet<Collider, uint>());
 20362                    customColliders.Value.colliders.Add(collider, colliderLayer);
 20363                    currentCustomLayerColliders.Add(collider);
 20364                    hasCustomColliders = true;
 365                }
 366            }
 367
 46368            if (hasPhysicColliders)
 369            {
 28370                physicColliderComponent.PutFor(scene, entity, physicColliders.Value);
 371            }
 372
 46373            if (hasPointerColliders)
 374            {
 28375                pointerColliderComponent.PutFor(scene, entity, pointerColliders.Value);
 376            }
 377
 46378            if (hasCustomColliders)
 379            {
 18380                customLayerColliderComponent.PutFor(scene, entity, customColliders.Value);
 381            }
 46382        }
 383
 384        private static void SetUpRenderers(
 385            IParcelScene scene,
 386            IDCLEntity entity,
 387            HashSet<Renderer> rendererHashSet,
 388            IInternalECSComponent<InternalRenderers> renderersComponent)
 389        {
 31390            if (rendererHashSet == null || rendererHashSet.Count == 0)
 0391                return;
 392
 31393            var model = renderersComponent.GetFor(scene, entity)?.model ?? new InternalRenderers(new List<Renderer>());
 394
 128395            foreach (Renderer renderer in rendererHashSet)
 396            {
 33397                model.renderers.Add(renderer);
 398            }
 399
 31400            renderersComponent.PutFor(scene, entity, model);
 31401        }
 402
 403        private void SetGltfLoaded(
 404            GameObject rootGameObject,
 405            string prevLoadedGltf,
 406            Rendereable rendereable)
 407        {
 31408            gltfContainerLoadingStateComponent.PutFor(scene, entity,
 409                new InternalGltfContainerLoadingState() { LoadingState = LoadingState.Finished });
 410
 31411            Animation animation = rootGameObject.GetComponentInChildren<Animation>(true);
 412
 31413            if (animation)
 414            {
 9415                animationComponent.PutFor(scene, entity, new InternalAnimation(animation));
 416            }
 417
 31418            if (!string.IsNullOrEmpty(prevLoadedGltf))
 419            {
 31420                dataStoreEcs7.RemovePendingResource(scene.sceneData.sceneNumber, prevLoadedGltf);
 421            }
 422
 31423            if (isDebugMode)
 424            {
 0425                currentRendereable = rendereable;
 0426                AddCurrentRendereableToSceneMetrics();
 427            }
 31428        }
 429
 430        private static void OnLoadFail(
 431            IParcelScene scene,
 432            IDCLEntity entity,
 433            string gltfSrc,
 434            Exception exception,
 435            DataStore_ECS7 dataStoreEcs7,
 436            IInternalECSComponent<InternalGltfContainerLoadingState> gltfContainerLoadingStateComponent)
 437        {
 1438            gltfContainerLoadingStateComponent.PutFor(scene, entity,
 439                new InternalGltfContainerLoadingState() { LoadingState = LoadingState.FinishedWithError });
 440
 1441            dataStoreEcs7.RemovePendingResource(scene.sceneData.sceneNumber, gltfSrc);
 1442        }
 443
 444        private void AddCurrentRendereableToSceneMetrics()
 445        {
 0446            dataStoreWorldObjects.AddRendereable(entity.scene.sceneData.sceneNumber, currentRendereable);
 447
 0448            foreach (Renderer renderer in renderers)
 449            {
 0450                foreach (Material material in renderer.sharedMaterials)
 451                {
 0452                    dataStoreWorldObjects.AddMaterial(entity.scene.sceneData.sceneNumber, entity.entityId, material);
 453                }
 454            }
 0455        }
 456
 457        private void RemoveCurrentRendereableFromSceneMetrics()
 458        {
 0459            foreach (Renderer renderer in currentRendereable.renderers)
 460            {
 0461                foreach (Material material in renderer.sharedMaterials)
 462                {
 0463                    dataStoreWorldObjects.RemoveMaterial(entity.scene.sceneData.sceneNumber, entity.entityId, material);
 464                }
 465            }
 466
 0467            dataStoreWorldObjects.RemoveRendereable(scene.sceneData.sceneNumber, currentRendereable);
 0468        }
 469    }
 470}

Methods/Properties

ActiveCollidersData()
GltfContainerHandler(.IInternalECSComponent[InternalColliders], .IInternalECSComponent[InternalColliders], .IInternalECSComponent[InternalColliders], .IInternalECSComponent[InternalRenderers], .IInternalECSComponent[InternalGltfContainerLoadingState], .IInternalECSComponent[InternalAnimation], DCL.DataStore_ECS7, DCL.DataStore_FeatureFlag, DCL.DataStore_WorldObjects, DCL.DebugConfig)
OnComponentCreated(DCL.Controllers.IParcelScene, DCL.Models.IDCLEntity)
OnComponentRemoved(DCL.Controllers.IParcelScene, DCL.Models.IDCLEntity)
OnComponentModelUpdated(DCL.Controllers.IParcelScene, DCL.Models.IDCLEntity, DCL.ECSComponents.PBGltfContainer)
OnGltfSrcChanged(DCL.ECSComponents.PBGltfContainer, DCL.ECSComponents.PBGltfContainer)
OnLoadSuccess(DCL.Rendereable, DCL.ECSComponents.PBGltfContainer)
UnloadGltf(DCL.Models.IDCLEntity, System.String)
InitColliders(System.Collections.Generic.HashSet[Renderer], UnityEngine.GameObject, DCL.ECSComponents.GltfContainerCollidersHandler, System.Boolean)
SetUpColliders(System.UInt32, System.UInt32, System.Collections.Generic.IReadOnlyList[Collider], System.Collections.Generic.IList[Collider], System.Collections.Generic.IList[Collider], System.Collections.Generic.IList[Collider])
RemoveColliders(System.UInt32, System.Collections.Generic.IList[Collider], System.Collections.Generic.IList[Collider], System.Collections.Generic.IList[Collider])
SetColliders(System.UInt32, System.Collections.Generic.IReadOnlyList[Collider], System.Collections.Generic.IList[Collider], System.Collections.Generic.IList[Collider], System.Collections.Generic.IList[Collider])
SetUpRenderers(DCL.Controllers.IParcelScene, DCL.Models.IDCLEntity, System.Collections.Generic.HashSet[Renderer], .IInternalECSComponent[InternalRenderers])
SetGltfLoaded(UnityEngine.GameObject, System.String, DCL.Rendereable)
OnLoadFail(DCL.Controllers.IParcelScene, DCL.Models.IDCLEntity, System.String, System.Exception, DCL.DataStore_ECS7, .IInternalECSComponent[InternalGltfContainerLoadingState])
AddCurrentRendereableToSceneMetrics()
RemoveCurrentRendereableFromSceneMetrics()