Page MenuHomePhabricator

Texture3DPreviewDrawer.cs
No OneTemporary

Texture3DPreviewDrawer.cs

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// ///
/// MIT License ///
/// ///
/// Copyright (c) 2016 Raphaël Ernaelsten (@RaphErnaelsten) ///
/// ///
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), ///
/// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, ///
/// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: ///
/// ///
/// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. ///
/// ///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ///
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ///
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ///
/// IN THE SOFTWARE. ///
/// ///
/// PLEASE CONSIDER CREDITING AURA IN YOUR PROJECTS. IF RELEVANT, USE THE UNMODIFIED LOGO PROVIDED IN THE "LICENSE" FOLDER. ///
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
using UnityEditor;
using UnityEngine;
namespace AuraAPI
{
/// <summary>
/// Custom drawer for Texture3DPreview attribute
/// </summary>
[CustomPropertyDrawer(typeof(Texture3DPreviewAttribute))]
internal sealed class Texture3DPreviewDrawer : PropertyDrawer
{
#region Private Members
/// <summary>
/// Maximum preview size in the Inspector
/// </summary>
private const int _maxSize = 512;
/// <summary>
/// The material which the preview will be rendered with
/// </summary>
private static Material _material;
/// <summary>
/// String to show if the field is not a Texture3D
/// </summary>
private const string _notObjectOrTexture3DString = "Texture3DPreview attribute can only be used with Texture3D fields.";
/// <summary>
/// The angle of the camera preview
/// </summary>
private Vector2 _cameraAngle = new Vector2(127.5f, -22.5f);
/// <summary>
/// The raymarch interations
/// </summary>
private int _samplingIterations = 64;
/// <summary>
/// The factor of the Texture3D
/// </summary>
private float _density = 1;
#endregion
#region Functions
/// <summary>
/// Gets if the Texture3D should be displayed
/// </summary>
private bool ShowField
{
get
{
return ((Texture3DPreviewAttribute)attribute).showField;
}
}
/// <summary>
/// Checks if the drawn property is a UnityEngine.Object derived type
/// </summary>
/// <param name="property">The drawn object</param>
/// <returns>True if the drawn object is a UnityEngine.Object derived type, false otherwise</returns>
private bool CheckIfObjectType(SerializedProperty property)
{
return property.propertyType == SerializedPropertyType.ObjectReference;
}
/// <summary>
/// Checks if the drawn property is a Texture3D
/// </summary>
/// <param name="property">The drawn object</param>
/// <returns>True if the drawn object is a Texture3D, false otherwise</returns>
private bool CheckIfTexture3D(SerializedProperty property)
{
return property.objectReferenceValue is Texture3D;
}
/// <summary>
/// Checks if the drawn property is null
/// </summary>
/// <param name="property">The drawn object</param>
/// <returns>True if the drawn object is null, false otherwise</returns>
private bool CheckIfNull(SerializedProperty property)
{
return property.objectReferenceValue == null;
}
/// <summary>
/// Computes the size of the preview accordingly to the Inspector width
/// </summary>
/// <param name="rightMargin">The margin reserved on the right of the preview</param>
/// <returns>The size of the preview</returns>
private int ComputePreviewSize(int rightMargin)
{
int size = Mathf.FloorToInt(EditorGUIUtility.currentViewWidth) - rightMargin;
size = Mathf.Min(size, Texture3DPreviewDrawer._maxSize);
return size;
}
/// <summary>
/// Sets back the camera angle
/// </summary>
public void ResetPreviewCameraAngle()
{
_cameraAngle = new Vector2(127.5f, -22.5f);
}
#endregion
#region Overriden base class functions (https://docs.unity3d.com/ScriptReference/PropertyDrawer.html)
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
float size = 0;
if(CheckIfObjectType(property))
{
if(ShowField)
{
size += EditorGUIUtility.singleLineHeight;
}
if(!CheckIfNull(property))
{
if(CheckIfTexture3D(property))
{
size += EditorGUIUtility.singleLineHeight;
size += ComputePreviewSize((int)EditorGUIUtility.singleLineHeight);
size += EditorGUIUtility.singleLineHeight;
}
else
{
size += EditorGUIUtility.singleLineHeight;
}
}
else
{
size += EditorGUIUtility.singleLineHeight * 3;
}
}
else
{
size += EditorGUIUtility.singleLineHeight;
}
return size;
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if(CheckIfObjectType(property))
{
if(ShowField)
{
Rect rect = position;
rect.height = EditorGUIUtility.singleLineHeight;
EditorGUI.ObjectField(rect, property, typeof(Texture3D));
position.y += EditorGUIUtility.singleLineHeight;
}
if(!CheckIfNull(property))
{
if(CheckIfTexture3D(property))
{
if(Event.current.type == EventType.Layout)
{
return;
}
position.y += EditorGUIUtility.singleLineHeight;
int size = ComputePreviewSize((int)position.x * 2);
Rect drawArea = position;
drawArea.width = size;
drawArea.height = drawArea.width;
drawArea.x += position.width * 0.5f - drawArea.width * 0.5f;
_cameraAngle = PreviewRenderUtilityHelpers.DragToAngles(_cameraAngle, drawArea);
if(Event.current.type == EventType.Repaint)
{
GUI.Box(drawArea, ((Texture3D)property.objectReferenceValue).RenderTexture3DPreview(drawArea, _cameraAngle, 6.5f /*TODO : Find distance with fov and boundingsphere, when non uniform size will be supported*/, _samplingIterations, _density));
}
Rect rect = drawArea;
rect.y += drawArea.height;
rect.height = EditorGUIUtility.singleLineHeight;
rect.width = 100; // TODO : not use magic numbers
if(GUI.Button(rect, "Reset Camera", EditorStyles.miniButton))
{
ResetPreviewCameraAngle();
}
rect.x += rect.width;
rect.width = 60; // TODO : not use magic numbers
EditorGUI.LabelField(rect, "Quality :");
rect.x += rect.width;
_samplingIterations = EditorGUI.IntPopup(rect, _samplingIterations, new[]
{
"16",
"32",
"64",
"128",
"256",
"512"
}, new[]
{
16,
32,
64,
128,
256,
512
});
rect.x += rect.width;
rect.width = 60; // TODO : not use magic numbers
EditorGUI.LabelField(rect, "Density :");
rect.x += rect.width;
rect.width = drawArea.width - 280; // TODO : not use magic numbers
_density = EditorGUI.Slider(rect, _density, 0, 5);
}
else
{
EditorGUI.LabelField(position, Texture3DPreviewDrawer._notObjectOrTexture3DString, EditorStyles.boldLabel);
}
}
else
{
EditorGUI.LabelField(position, "Texture3D field is empty.", EditorStyles.centeredGreyMiniLabel);
}
}
else
{
EditorGUI.LabelField(position, Texture3DPreviewDrawer._notObjectOrTexture3DString, EditorStyles.boldLabel);
}
}
#endregion
}
}

File Metadata

Mime Type
text/x-c++
Expires
Fri, Nov 22, 2:22 PM (1 d, 4 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
311747
Default Alt Text
Texture3DPreviewDrawer.cs (12 KB)

Event Timeline