public void CollectGraphicsFromMember(MemberInfo memberInfo, List <GraphicSource> sources)
        {
            if (memberInfo is FieldInfo)
            {
                var field = memberInfo as FieldInfo;

                object[] attributeObjects = field.GetCustomAttributes(typeof(AssetIconAttribute), true);

                foreach (object attributeObject in attributeObjects)
                {
                    var attribute = (AssetIconAttribute)attributeObject;

                    sources.Add(new FieldGraphicSource(new AssetIconsCompiledStyle(attribute.Style), field));
                }
            }
            else if (memberInfo is PropertyInfo)
            {
                var property = memberInfo as PropertyInfo;

                object[] attributeObjects = property.GetCustomAttributes(typeof(AssetIconAttribute), true);

                if (attributeObjects != null && attributeObjects.Length != 0)
                {
                    var  getMethod           = property.GetGetMethod(true);
                    bool isSupportedProperty = getMethod != null;

                    foreach (object attributeObject in attributeObjects)
                    {
                        var attribute = (AssetIconAttribute)attributeObject;

                        if (!isSupportedProperty)
                        {
                            AssetIconsLogger.UnsupportedSetOnlyProperties(attribute, property);
                            continue;
                        }

                        sources.Add(new MethodGraphicProvider(new AssetIconsCompiledStyle(attribute.Style), getMethod));
                    }
                }
            }
            else if (memberInfo is MethodInfo)
            {
                var method = memberInfo as MethodInfo;

                object[] attributeObjects = method.GetCustomAttributes(typeof(AssetIconAttribute), true);

                if (attributeObjects != null && attributeObjects.Length != 0)
                {
                    bool isSupportedParameters = IsSupportedParameters(method.GetParameters());

                    foreach (object attributeObject in attributeObjects)
                    {
                        var attribute = (AssetIconAttribute)attributeObject;

                        if (!isSupportedParameters)
                        {
                            AssetIconsLogger.UnsupportedParametersError(attribute, method);
                            continue;
                        }

                        sources.Add(new MethodGraphicProvider(new AssetIconsCompiledStyle(attribute.Style), method));
                    }
                }
            }
        }
        /// <summary>
        /// <para>Creates a preview <see cref="Texture2D"/> of a model.</para>
        /// </summary>
        /// <param name="model">The object to render a preview of.</param>
        /// <param name="camera">The style to render the model with.</param>
        /// <param name="width">The width (in pixels) of the rendered <see cref="Texture2D"/>.</param>
        /// <param name="height">The height (in pixels) of the rendered <see cref="Texture2D"/>.</param>
        /// <returns>
        /// <para>A rendered preview <see cref="Texture2D"/>.</para>
        /// </returns>
        public static Texture2D RenderModel(GameObject model, AssetIconsCameraSetup camera, int width = 64, int height = 64)
        {
            if (model == null || model.Equals(null))
            {
                return(null);
            }

            GameObject previewObject;

#if USE_PREVIEW_SCENE
            if (!RenderCamera.scene.IsValid())
            {
                previewObject = (GameObject)PrefabUtility.InstantiatePrefab(model);
            }
            else
            {
                previewObject = (GameObject)PrefabUtility.InstantiatePrefab(model, RenderCamera.scene);
            }
#else
            previewObject = (GameObject)PrefabUtility.InstantiatePrefab(model);
#endif

            previewObject.gameObject.hideFlags = HideFlags.HideAndDontSave;
            SetLayerRecursively(previewObject.transform);
            previewObject.SetActive(true);

            Texture2D result = null;

            camera.ApplyToCamera(RenderCamera);

            try
            {
                var previewDir = previewObject.transform.rotation * camera.PreviewDirection.normalized;

                prefabRenderers.Clear();
                previewObject.GetComponentsInChildren(prefabRenderers);

                var  previewBounds = new Bounds();
                bool anyRenderers  = false;
                for (int i = 0; i < prefabRenderers.Count; i++)
                {
                    var renderer = prefabRenderers[i];
                    if (!renderer.enabled)
                    {
                        continue;
                    }

                    if (!anyRenderers)
                    {
                        previewBounds = renderer.bounds;
                        anyRenderers  = true;
                    }
                    else
                    {
                        previewBounds.Encapsulate(renderer.bounds);
                    }
                }

                if (!anyRenderers)
                {
                    return(null);
                }

                var boundsCenter  = previewBounds.center;
                var boundsExtents = previewBounds.extents;
                var boundsSize    = 2f * boundsExtents;

                float aspect = (float)width / height;
                RenderCamera.aspect             = aspect;
                RenderCamera.transform.rotation = Quaternion.LookRotation(previewDir, previewObject.transform.up);

                float distance;
                if (camera.Orthographic)
                {
                    RenderCamera.transform.position = boundsCenter;

                    minX = minY = Mathf.Infinity;
                    maxX = maxY = Mathf.NegativeInfinity;

                    var point = boundsCenter + boundsExtents;
                    ProjectBoundingBoxMinMax(point);
                    point.x -= boundsSize.x;
                    ProjectBoundingBoxMinMax(point);
                    point.y -= boundsSize.y;
                    ProjectBoundingBoxMinMax(point);
                    point.x += boundsSize.x;
                    ProjectBoundingBoxMinMax(point);
                    point.z -= boundsSize.z;
                    ProjectBoundingBoxMinMax(point);
                    point.x -= boundsSize.x;
                    ProjectBoundingBoxMinMax(point);
                    point.y += boundsSize.y;
                    ProjectBoundingBoxMinMax(point);
                    point.x += boundsSize.x;
                    ProjectBoundingBoxMinMax(point);

                    distance = boundsExtents.magnitude + 1f;
                    RenderCamera.orthographicSize = (1f + camera.Padding * 2f) * Mathf.Max(maxY - minY, (maxX - minX) / aspect) * 0.5f;
                }
                else
                {
                    projectionPlaneHorizontal = new Plane(RenderCamera.transform.up, boundsCenter);
                    projectionPlaneVertical   = new Plane(RenderCamera.transform.right, boundsCenter);

                    float maxDistance = Mathf.NegativeInfinity;

                    var point = boundsCenter + boundsExtents;
                    maxDistance = RecalculateMaxDistance(maxDistance, point, boundsCenter, aspect, camera);
                    point.x    -= boundsSize.x;
                    maxDistance = RecalculateMaxDistance(maxDistance, point, boundsCenter, aspect, camera);
                    point.y    -= boundsSize.y;
                    maxDistance = RecalculateMaxDistance(maxDistance, point, boundsCenter, aspect, camera);
                    point.x    += boundsSize.x;
                    maxDistance = RecalculateMaxDistance(maxDistance, point, boundsCenter, aspect, camera);
                    point.z    -= boundsSize.z;
                    maxDistance = RecalculateMaxDistance(maxDistance, point, boundsCenter, aspect, camera);
                    point.x    -= boundsSize.x;
                    maxDistance = RecalculateMaxDistance(maxDistance, point, boundsCenter, aspect, camera);
                    point.y    += boundsSize.y;
                    maxDistance = RecalculateMaxDistance(maxDistance, point, boundsCenter, aspect, camera);
                    point.x    += boundsSize.x;
                    maxDistance = RecalculateMaxDistance(maxDistance, point, boundsCenter, aspect, camera);

                    distance = (1f + camera.Padding * 2f) * Mathf.Sqrt(maxDistance);
                }

                RenderCamera.transform.position = boundsCenter - previewDir * distance;
                RenderCamera.farClipPlane       = distance * 4f;

                var temp      = RenderTexture.active;
                var renderTex = RenderTexture.GetTemporary(width, height, 16, RenderTextureFormat.ARGB32);
                RenderTexture.active = renderTex;

                if (camera.TransparentBackground)
                {
                    GL.Clear(false, true, camera.BackgroundColor);
                }

                RenderCamera.targetTexture = renderTex;

                RenderCamera.Render();
                RenderCamera.targetTexture = null;

                var textureFormat = camera.TransparentBackground ? TextureFormat.ARGB32 : TextureFormat.RGB24;

                result = new Texture2D(width, height, textureFormat, false)
                {
                    wrapMode   = TextureWrapMode.Clamp,
                    filterMode = FilterMode.Point
                };
                result.ReadPixels(new Rect(0, 0, width, height), 0, 0, false);
                result.Apply(false, true);

                RenderTexture.active = temp;
                RenderTexture.ReleaseTemporary(renderTex);
            }
            catch (Exception exception)
            {
                Debug.LogException(exception);
            }
            finally
            {
                try
                {
                    UnityEngine.Object.DestroyImmediate(previewObject);
                }
                catch (Exception destroyException)
                {
                    previewObject.SetActive(false);

                    AssetIconsLogger.LogException(destroyException);
                }
            }

            return(result);
        }