< 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:59
Uncovered lines:1
Coverable lines:60
Total lines:194
Line coverage:98.3% (59 of 60)
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        {
 47111            Bounds bounds = new Bounds();
 47112            bool initializedBounds = false;
 13
 240414            for (int i = 0; i < renderers.Length; i++)
 15            {
 73116                if (renderers[i] == null) continue;
 17
 73118                if (!initializedBounds)
 19                {
 46820                    initializedBounds = true;
 46821                    bounds = GetSafeBounds(renderers[i].bounds, renderers[i].transform.position);
 22                }
 23                else
 24                {
 26325                    bounds.Encapsulate(GetSafeBounds(renderers[i].bounds, renderers[i].transform.position));
 26                }
 27            }
 28
 167229            foreach (Collider collider in colliders)
 30            {
 36531                if (collider == null) continue;
 32
 36533                if (!initializedBounds)
 34                {
 335                    initializedBounds = true;
 336                    bounds = GetSafeBounds(collider.bounds, collider.transform.position);
 37                }
 38                else
 39                {
 36240                    bounds.Encapsulate(GetSafeBounds(collider.bounds, collider.transform.position));
 41                }
 42            }
 43
 47144            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
 113462            if (objectPosition.sqrMagnitude > POSITION_OVERFLOW_LIMIT_SQR)
 063                return new Bounds(Vector3.one * POSITION_OVERFLOW_LIMIT, Vector3.one * 0.1f);
 64
 113465            return bounds;
 66        }
 67
 68        public static int ComputeTotalTriangles(IEnumerable<Renderer> renderers,
 69            Dictionary<Mesh, int> meshToTriangleCount)
 70        {
 15471            int result = 0;
 72
 112673            foreach (var renderer in renderers)
 74            {
 75                switch (renderer)
 76                {
 77                    case MeshRenderer r:
 19878                        MeshFilter mf = r.GetComponent<MeshFilter>();
 79
 19880                        if (mf == null)
 81                            continue;
 82
 19883                        int triangles = meshToTriangleCount[mf.sharedMesh];
 19884                        result += triangles;
 19885                        break;
 86                    case SkinnedMeshRenderer skr:
 21187                        result += meshToTriangleCount[skr.sharedMesh];
 88                        break;
 89                }
 90            }
 91
 15492            return result;
 93        }
 94
 95        public static Dictionary<Mesh, int> ExtractMeshToTriangleMap(IEnumerable<Mesh> meshes)
 96        {
 3997            Dictionary<Mesh, int> result = new Dictionary<Mesh, int>();
 98
 19899            foreach (var mesh in meshes)
 100            {
 60101                result[mesh] = mesh.triangles.Length;
 102            }
 103
 39104            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        {
 115112            return new HashSet<Animation>(container.GetComponentsInChildren<Animation>(true));
 113        }
 114
 115        public static HashSet<AnimationClip> ExtractUniqueAnimationClips(HashSet<Animation> animations)
 116        {
 103117            HashSet<AnimationClip> result = new HashSet<AnimationClip>();
 118
 234119            foreach (var anim in animations)
 120            {
 70121                foreach (AnimationState state in anim)
 122                {
 21123                    result.Add(state.clip);
 124                }
 125            }
 126
 103127            return result;
 128        }
 129
 130        public static HashSet<Renderer> ExtractUniqueRenderers(GameObject container)
 131        {
 552132            return new HashSet<Renderer>(container.GetComponentsInChildren<Renderer>(true));
 133        }
 134
 135        public static HashSet<Material> ExtractUniqueMaterials(IEnumerable<Renderer> renderers)
 136        {
 154137            return new HashSet<Material>(renderers.SelectMany((x) =>
 832138                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        {
 154144            return new HashSet<Texture>(
 145                materials.SelectMany(
 146                    (mat) =>
 147                    {
 274148                        mat.GetTexturePropertyNameIDs(texIdsCache);
 274149                        mat.GetTexturePropertyNames(texNameCache);
 274150                        List<Texture> result = new List<Texture>();
 9956151                        for (int i = 0; i < texIdsCache.Count; i++)
 152                        {
 4704153                            var tex = mat.GetTexture(texIdsCache[i]);
 154
 4704155                            if (tex != null)
 156                            {
 271157                                result.Add(tex);
 158                            }
 159                        }
 160
 274161                        return result;
 162                    }));
 163        }
 164
 165        public static HashSet<Mesh> ExtractUniqueMeshes(IEnumerable<Renderer> renderers)
 166        {
 51167            List<Mesh> result = new List<Mesh>();
 168
 318169            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:
 40180                        MeshFilter mf = mr.GetComponent<MeshFilter>();
 181
 40182                        if (mf.mesh == null)
 183                            continue;
 184
 40185                        result.Add(mf.mesh);
 186                        break;
 187                }
 188            }
 189
 190            // Ensure meshes are unique
 51191            return new HashSet<Mesh>(result);
 192        }
 193    }
 194}