< Summary

Class:DCL.Models.MeshesInfoUtils
Assembly:MeshesInfo
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/MeshesInfo/MeshesInfoUtils.cs
Covered lines:61
Uncovered lines:1
Coverable lines:62
Total lines:194
Line coverage:98.3% (61 of 62)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
BuildMergedBounds(...)0%770100%
GetSafeBounds(...)0%2.152066.67%
ComputeTotalTriangles(...)0%660100%
ExtractMeshToTriangleMap(...)0%330100%
MeshesInfoUtils()0%110100%
ExtractUniqueAnimations(...)0%110100%
ExtractUniqueAnimationClips(...)0%440100%
ExtractUniqueRenderers(...)0%110100%
ExtractUniqueMaterials(...)0%220100%
ExtractUniqueTextures(...)0%220100%
ExtractUniqueMeshes(...)0%770100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/WorldRuntime/MeshesInfo/MeshesInfoUtils.cs

#LineLine coverage
 1using System.Collections.Generic;
 2using System.Linq;
 3using UnityEngine;
 4
 5namespace DCL.Models
 6{
 7    public static class MeshesInfoUtils
 8    {
 9        public static Bounds BuildMergedBounds(Renderer[] renderers, HashSet<Collider> colliders)
 10        {
 53811            Bounds bounds = new Bounds();
 53812            bool initializedBounds = false;
 13
 272614            for (int i = 0; i < renderers.Length; i++)
 15            {
 82516                if (renderers[i] == null) continue;
 17
 82518                if (!initializedBounds)
 19                {
 53520                    initializedBounds = true;
 53521                    bounds = GetSafeBounds(renderers[i].bounds, renderers[i].transform.position);
 53522                }
 23                else
 24                {
 29025                    bounds.Encapsulate(GetSafeBounds(renderers[i].bounds, renderers[i].transform.position));
 26                }
 27            }
 28
 183429            foreach (Collider collider in colliders)
 30            {
 37931                if (collider == null) continue;
 32
 37933                if (!initializedBounds)
 34                {
 335                    initializedBounds = true;
 336                    bounds = GetSafeBounds(collider.bounds, collider.transform.position);
 337                }
 38                else
 39                {
 37640                    bounds.Encapsulate(GetSafeBounds(collider.bounds, collider.transform.position));
 41                }
 42            }
 43
 53844            return bounds;
 45        }
 46
 47        /// <summary>
 48        /// This get the object bounds with a check to ensure the renderer is at a safe position.
 49        /// If the object is too far away from 0,0,0, wasm target ensures a crash.
 50        /// NOTE: If returning a mocked bounds object becomes problematic (e.g. for getting real bounds size),
 51        /// we should find a solution using meshFilter.mesh.bounds instead as those bounds are local.
 52        /// </summary>
 53        /// <param name="bounds"></param>
 54        /// <param name="objectPosition"></param>
 55        /// <returns>The bounds value if the value is correct, or a mocked bounds object with clamped values if its too 
 56        public static Bounds GetSafeBounds(Bounds bounds, Vector3 objectPosition)
 57        {
 58            // World extents are of 4800 world mts, so this limit far exceeds the world size.
 59            const float POSITION_OVERFLOW_LIMIT = 10000;
 60            const float POSITION_OVERFLOW_LIMIT_SQR = POSITION_OVERFLOW_LIMIT * POSITION_OVERFLOW_LIMIT;
 61
 126262            if (objectPosition.sqrMagnitude > POSITION_OVERFLOW_LIMIT_SQR)
 063                return new Bounds(Vector3.one * POSITION_OVERFLOW_LIMIT, Vector3.one * 0.1f);
 64
 126265            return bounds;
 66        }
 67
 68        public static int ComputeTotalTriangles(IEnumerable<Renderer> renderers,
 69            Dictionary<Mesh, int> meshToTriangleCount)
 70        {
 16971            int result = 0;
 72
 119673            foreach (var renderer in renderers)
 74            {
 75                switch (renderer)
 76                {
 77                    case MeshRenderer r:
 21878                        MeshFilter mf = r.GetComponent<MeshFilter>();
 79
 21880                        if (mf == null)
 81                            continue;
 82
 21883                        int triangles = meshToTriangleCount[mf.sharedMesh];
 21884                        result += triangles;
 21885                        break;
 86                    case SkinnedMeshRenderer skr:
 21187                        result += meshToTriangleCount[skr.sharedMesh];
 88                        break;
 89                }
 90            }
 91
 16992            return result;
 93        }
 94
 95        public static Dictionary<Mesh, int> ExtractMeshToTriangleMap(IEnumerable<Mesh> meshes)
 96        {
 4097            Dictionary<Mesh, int> result = new Dictionary<Mesh, int>();
 98
 20899            foreach (var mesh in meshes)
 100            {
 64101                result[mesh] = mesh.triangles.Length;
 102            }
 103
 40104            return result;
 105        }
 106
 1107        private static List<int> texIdsCache = new List<int>();
 1108        private static List<string> texNameCache = new List<string>();
 109
 110        public static HashSet<Animation> ExtractUniqueAnimations(GameObject container)
 111        {
 129112            return new HashSet<Animation>(container.GetComponentsInChildren<Animation>(true));
 113        }
 114
 115        public static HashSet<AnimationClip> ExtractUniqueAnimationClips(HashSet<Animation> animations)
 116        {
 117117            HashSet<AnimationClip> result = new HashSet<AnimationClip>();
 118
 262119            foreach (var anim in animations)
 120            {
 70121                foreach (AnimationState state in anim)
 122                {
 21123                    result.Add(state.clip);
 124                }
 125            }
 126
 117127            return result;
 128        }
 129
 130        public static HashSet<Renderer> ExtractUniqueRenderers(GameObject container)
 131        {
 568132            return new HashSet<Renderer>(container.GetComponentsInChildren<Renderer>(true));
 133        }
 134
 135        public static HashSet<Material> ExtractUniqueMaterials(IEnumerable<Renderer> renderers)
 136        {
 169137            return new HashSet<Material>(renderers.SelectMany((x) =>
 874138                x.sharedMaterials.Where((mat) => mat != null && mat.shader.name != "DCL/FX/Hologram")
 139            ));
 140        }
 141
 142        public static HashSet<Texture> ExtractUniqueTextures(IEnumerable<Material> materials)
 143        {
 169144            return new HashSet<Texture>(
 145                materials.SelectMany(
 146                    (mat) =>
 147                    {
 294148                        mat.GetTexturePropertyNameIDs(texIdsCache);
 294149                        mat.GetTexturePropertyNames(texNameCache);
 294150                        List<Texture> result = new List<Texture>();
 10396151                        for (int i = 0; i < texIdsCache.Count; i++)
 152                        {
 4904153                            var tex = mat.GetTexture(texIdsCache[i]);
 154
 4904155                            if (tex != null)
 156                            {
 293157                                result.Add(tex);
 158                            }
 159                        }
 160
 294161                        return result;
 162                    }));
 163        }
 164
 165        public static HashSet<Mesh> ExtractUniqueMeshes(IEnumerable<Renderer> renderers)
 166        {
 52167            List<Mesh> result = new List<Mesh>();
 168
 328169            foreach (Renderer renderer in renderers)
 170            {
 171                switch (renderer)
 172                {
 173                    case SkinnedMeshRenderer skr:
 68174                        if (skr.sharedMesh == null)
 175                            continue;
 176
 68177                        result.Add(skr.sharedMesh);
 68178                        break;
 179                    case MeshRenderer mr:
 44180                        MeshFilter mf = mr.GetComponent<MeshFilter>();
 181
 44182                        if (mf.mesh == null)
 183                            continue;
 184
 44185                        result.Add(mf.mesh);
 186                        break;
 187                }
 188            }
 189
 190            // Ensure meshes are unique
 52191            return new HashSet<Mesh>(result);
 192        }
 193    }
 194}