< 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:50
Uncovered lines:9
Coverable lines:59
Total lines:186
Line coverage:84.7% (50 of 59)
Covered branches:0
Total branches:0
Covered methods:10
Total methods:11
Method coverage:90.9% (10 of 11)

Metrics

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

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        {
 35611            Bounds bounds = new Bounds();
 35612            bool initializedBounds = false;
 13
 35614            if (renderers != null)
 15            {
 174216                for (int i = 0; i < renderers.Length; i++)
 17                {
 51518                    if (renderers[i] == null) continue;
 19
 51520                    if (!initializedBounds)
 21                    {
 35022                        initializedBounds = true;
 35023                        bounds = GetSafeBounds(renderers[i].bounds, renderers[i].transform.position);
 24                    }
 16525                    else { bounds.Encapsulate(GetSafeBounds(renderers[i].bounds, renderers[i].transform.position)); }
 26                }
 27            }
 28
 35629            if (colliders != null)
 30            {
 146431                foreach (Collider collider in colliders)
 32                {
 37633                    if (collider == null) continue;
 34
 37635                    if (!initializedBounds)
 36                    {
 337                        initializedBounds = true;
 338                        bounds = GetSafeBounds(collider.bounds, collider.transform.position);
 39                    }
 37340                    else { bounds.Encapsulate(GetSafeBounds(collider.bounds, collider.transform.position)); }
 41                }
 42            }
 43
 35644            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
 93162            if (objectPosition.sqrMagnitude > POSITION_OVERFLOW_LIMIT_SQR)
 063                return new Bounds(Vector3.one * POSITION_OVERFLOW_LIMIT, Vector3.one * 0.1f);
 64
 93165            return bounds;
 66        }
 67
 68        public static int ComputeTotalTriangles(IEnumerable<Renderer> renderers,
 69            Dictionary<Mesh, int> meshToTriangleCount)
 70        {
 1971            int result = 0;
 72
 11873            foreach (var renderer in renderers)
 74            {
 75                switch (renderer)
 76                {
 77                    case MeshRenderer r:
 4078                        MeshFilter mf = r.GetComponent<MeshFilter>();
 79
 4080                        if (mf == null)
 81                            continue;
 82
 4083                        int triangles = meshToTriangleCount[mf.sharedMesh];
 4084                        result += triangles;
 4085                        break;
 86                    case SkinnedMeshRenderer skr:
 087                        result += meshToTriangleCount[skr.sharedMesh];
 88                        break;
 89                }
 90            }
 91
 1992            return result;
 93        }
 94
 95        public static Dictionary<Mesh, int> ExtractMeshToTriangleMap(IEnumerable<Mesh> meshes)
 96        {
 797            Dictionary<Mesh, int> result = new Dictionary<Mesh, int>();
 98
 9899            foreach (var mesh in meshes) { result[mesh] = mesh.triangles.Length; }
 100
 7101            return result;
 102        }
 103
 1104        private static List<int> texIdsCache = new List<int>();
 1105        private static List<string> texNameCache = new List<string>();
 106
 107        public static HashSet<Animation> ExtractUniqueAnimations(GameObject container)
 108        {
 12109            return new HashSet<Animation>(container.GetComponentsInChildren<Animation>(true));
 110        }
 111
 112        public static HashSet<AnimationClip> ExtractUniqueAnimationClips(HashSet<Animation> animations)
 113        {
 0114            HashSet<AnimationClip> result = new HashSet<AnimationClip>();
 115
 0116            foreach (var anim in animations)
 117            {
 0118                foreach (AnimationState state in anim) { result.Add(state.clip); }
 119            }
 120
 0121            return result;
 122        }
 123
 124        public static HashSet<Renderer> ExtractUniqueRenderers(GameObject container)
 125        {
 347126            return new HashSet<Renderer>(container.GetComponentsInChildren<Renderer>(true));
 127        }
 128
 129        public static HashSet<Material> ExtractUniqueMaterials(IEnumerable<Renderer> renderers)
 130        {
 31131            return new HashSet<Material>(renderers.SelectMany((x) =>
 118132                x.sharedMaterials.Where((mat) => mat != null && mat.shader.name != "DCL/FX/Hologram")
 133            ));
 134        }
 135
 136        public static HashSet<Texture> ExtractUniqueTextures(IEnumerable<Material> materials)
 137        {
 19138            return new HashSet<Texture>(
 139                materials.SelectMany(
 140                    (mat) =>
 141                    {
 54142                        mat.GetTexturePropertyNameIDs(texIdsCache);
 54143                        mat.GetTexturePropertyNames(texNameCache);
 54144                        List<Texture> result = new List<Texture>();
 145
 1828146                        for (int i = 0; i < texIdsCache.Count; i++)
 147                        {
 860148                            var tex = mat.GetTexture(texIdsCache[i]);
 149
 907150                            if (tex != null) { result.Add(tex); }
 151                        }
 152
 54153                        return result;
 154                    }));
 155        }
 156
 157        public static HashSet<Mesh> ExtractUniqueMeshes(IEnumerable<Renderer> renderers)
 158        {
 19159            List<Mesh> result = new List<Mesh>();
 160
 118161            foreach (Renderer renderer in renderers)
 162            {
 163                switch (renderer)
 164                {
 165                    case SkinnedMeshRenderer skr:
 0166                        if (skr.sharedMesh == null)
 167                            continue;
 168
 0169                        result.Add(skr.sharedMesh);
 0170                        break;
 171                    case MeshRenderer mr:
 40172                        MeshFilter mf = mr.GetComponent<MeshFilter>();
 173
 40174                        if (mf.mesh == null)
 175                            continue;
 176
 40177                        result.Add(mf.mesh);
 178                        break;
 179                }
 180            }
 181
 182            // Ensure meshes are unique
 19183            return new HashSet<Mesh>(result);
 184        }
 185    }
 186}