예제 #1
0
        /// <summary>
        /// <para>Retrieves a <see cref="Texture2D"/> from the cache for a <see cref="GameObject"/> using a <see cref="CameraSetup"/>.</para>
        /// </summary>
        /// <param name="cameraSetup">A camera setup to use when rendering the graphic.</param>
        /// <param name="target">A Prefab to render a graphic for.</param>
        /// <returns>
        /// <para>A <see cref="Texture2D"/> of the renedred <see cref="GameObject"/> with the <see cref="CameraSetup"/>.</para>
        /// </returns>
        public static Texture2D GetTexture(CameraSetup cameraSetup, GameObject target)
        {
            string path = AssetDatabase.GetAssetPath(target);

            Dictionary <string, Texture2D> styleCache;

            bool result = Renders.TryGetValue(cameraSetup, out styleCache);

            if (!result)
            {
                styleCache = new Dictionary <string, Texture2D>();
                Renders.Add(cameraSetup, styleCache);
            }

            Texture2D texture;

            result = styleCache.TryGetValue(path, out texture);

            if (!result || texture == null || texture.Equals(null))
            {
                int size = AssetIconsPreferences.PrefabResolution.Value;

                texture = AssetIconRenderer.RenderModel(target, cameraSetup, size, size);

                styleCache[path] = texture;
            }

            return(texture);
        }
예제 #2
0
        private static float RecalculateMaxDistance(float maxDistance, Vector3 point, Vector3 boundsCenter, float aspect, CameraSetup style)
        {
            var intersectionPoint = ClosestPointOnPlane(projectionPlaneHorizontal, point);

            float horizontalDistance = projectionPlaneHorizontal.GetDistanceToPoint(point);
            float verticalDistance   = projectionPlaneVertical.GetDistanceToPoint(point);

            float halfFrustumHeight = Mathf.Max(verticalDistance, horizontalDistance / aspect);
            float distance          = halfFrustumHeight / Mathf.Tan(RenderCamera.fieldOfView * 0.5f * Mathf.Deg2Rad);

            float distanceToCenter = (intersectionPoint - style.PreviewDirection.normalized * distance - boundsCenter).sqrMagnitude;

            if (distanceToCenter > maxDistance)
            {
                maxDistance = distanceToCenter;
            }
            return(maxDistance);
        }
예제 #3
0
        /// <summary>
        /// <para>Attempts to draw an icon for an object.</para>
        /// </summary>
        /// <param name="rect">The <see cref="Rect"/> in which the item is drawn.</param>
        /// <param name="objectIcon">The target object to draw a graphic for.</param>
        /// <param name="style">A style used to modify the appearance of a graphic.</param>
        /// <param name="selected">Whether the graphic should be rendered with a selection tint.</param>
        public static void DrawObject(Rect rect, object objectIcon,
                                      CompiledStyleDefinition style = null, bool selected = false)
        {
            if (Event.current.type != EventType.Repaint)
            {
                return;
            }

            if (objectIcon == null)
            {
                return;
            }

            if (objectIcon.GetType() == typeof(AssetReference))
            {
                var assetReference = (AssetReference)objectIcon;
                DrawObject(rect, assetReference.ObjectReference, style, selected);
                return;
            }

            var iconType = objectIcon.GetType();

            if (typeof(Sprite).IsAssignableFrom(iconType))
            {
                var spriteIcon = (Sprite)objectIcon;

                if (spriteIcon != null)
                {
                    DrawSprite(rect, spriteIcon, style, selected);
                }
            }
            else if (typeof(Texture).IsAssignableFrom(iconType))
            {
                var textureIcon = (Texture)objectIcon;

                if (textureIcon != null)
                {
                    DrawTexture(rect, textureIcon, style, selected);
                }
            }
            else if (typeof(Color).IsAssignableFrom(iconType))
            {
                var color = (Color)objectIcon;

                DrawColor(rect, color, style, selected);
            }
            else if (typeof(Color32).IsAssignableFrom(iconType))
            {
                var color = (Color32)objectIcon;

                DrawColor(rect, color, style, selected);
            }
            else if (typeof(string).IsAssignableFrom(iconType))
            {
                string iconText = (string)objectIcon;

                if (!string.IsNullOrEmpty(iconText))
                {
                    DrawText(rect, iconText, style, selected);
                }
            }
            else if (typeof(int).IsAssignableFrom(iconType))
            {
                int iconText = (int)objectIcon;

                DrawText(rect, iconText.ToString(), style, selected);
            }
            else if (typeof(GameObject).IsAssignableFrom(iconType))
            {
                var prefab = (GameObject)objectIcon;

                if (prefab != null)
                {
                    var col = BackgroundColor;
                    col = new Color(col.r, col.g, col.b, 0);

                    var setup = new CameraSetup()
                    {
                        BackgroundColor       = col,
                        TransparentBackground = true,
                        Orthographic          = style.Projection == IconProjection.Orthographic,

                        PreviewDirection = new Vector3(-1.0f, -1.0f, -1.0f)
                    };

                    var thumbnail = RenderCache.GetTexture(setup, prefab);

                    DrawTexture(rect, thumbnail, style, selected);
                }
            }
            else
            {
                throw new InvalidOperationException("Could not draw icon of type " + iconType);
            }
        }
예제 #4
0
        /// <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="style">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, CameraSetup style, int width = 64, int height = 64)
        {
            if (model == null || model.Equals(null))
            {
                return(null);
            }

#if USE_PREVIEW_SCENE
            var previewObject = (GameObject)PrefabUtility.InstantiatePrefab(model, RenderCamera.scene);
#else
            var previewObject = (GameObject)PrefabUtility.InstantiatePrefab(model);
#endif

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

            Texture2D result = null;

            style.ApplyToCamera(RenderCamera);

            try
            {
                var previewDir = previewObject.transform.rotation * style.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 (style.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 + style.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, style);
                    point.x    -= boundsSize.x;
                    maxDistance = RecalculateMaxDistance(maxDistance, point, boundsCenter, aspect, style);
                    point.y    -= boundsSize.y;
                    maxDistance = RecalculateMaxDistance(maxDistance, point, boundsCenter, aspect, style);
                    point.x    += boundsSize.x;
                    maxDistance = RecalculateMaxDistance(maxDistance, point, boundsCenter, aspect, style);
                    point.z    -= boundsSize.z;
                    maxDistance = RecalculateMaxDistance(maxDistance, point, boundsCenter, aspect, style);
                    point.x    -= boundsSize.x;
                    maxDistance = RecalculateMaxDistance(maxDistance, point, boundsCenter, aspect, style);
                    point.y    += boundsSize.y;
                    maxDistance = RecalculateMaxDistance(maxDistance, point, boundsCenter, aspect, style);
                    point.x    += boundsSize.x;
                    maxDistance = RecalculateMaxDistance(maxDistance, point, boundsCenter, aspect, style);

                    distance = (1f + style.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 (style.TransparentBackground)
                {
                    GL.Clear(false, true, style.BackgroundColor);
                }

                RenderCamera.targetTexture = renderTex;

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

                var textureFormat = style.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 e)
            {
                Debug.LogException(e);
            }
            finally
            {
                UnityEngine.Object.DestroyImmediate(previewObject);
            }

            return(result);
        }