142 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			142 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using System; | ||
|  | using System.Collections.Generic; | ||
|  | using System.Collections.ObjectModel; | ||
|  | using UnityEditor; | ||
|  | using UnityEngine; | ||
|  | 
 | ||
|  | namespace Unity.Mathematics.Editor | ||
|  | { | ||
|  |     [CustomPropertyDrawer(typeof(bool2x2)), CustomPropertyDrawer(typeof(bool2x3)), CustomPropertyDrawer(typeof(bool2x4))] | ||
|  |     [CustomPropertyDrawer(typeof(bool3x2)), CustomPropertyDrawer(typeof(bool3x3)), CustomPropertyDrawer(typeof(bool3x4))] | ||
|  |     [CustomPropertyDrawer(typeof(bool4x2)), CustomPropertyDrawer(typeof(bool4x3)), CustomPropertyDrawer(typeof(bool4x4))] | ||
|  |     [CustomPropertyDrawer(typeof(double2x2)), CustomPropertyDrawer(typeof(double2x3)), CustomPropertyDrawer(typeof(double2x4))] | ||
|  |     [CustomPropertyDrawer(typeof(double3x2)), CustomPropertyDrawer(typeof(double3x3)), CustomPropertyDrawer(typeof(double3x4))] | ||
|  |     [CustomPropertyDrawer(typeof(double4x2)), CustomPropertyDrawer(typeof(double4x3)), CustomPropertyDrawer(typeof(double4x4))] | ||
|  |     [CustomPropertyDrawer(typeof(float2x2)), CustomPropertyDrawer(typeof(float2x3)), CustomPropertyDrawer(typeof(float2x4))] | ||
|  |     [CustomPropertyDrawer(typeof(float3x2)), CustomPropertyDrawer(typeof(float3x3)), CustomPropertyDrawer(typeof(float3x4))] | ||
|  |     [CustomPropertyDrawer(typeof(float4x2)), CustomPropertyDrawer(typeof(float4x3)), CustomPropertyDrawer(typeof(float4x4))] | ||
|  |     [CustomPropertyDrawer(typeof(int2x2)), CustomPropertyDrawer(typeof(int2x3)), CustomPropertyDrawer(typeof(int2x4))] | ||
|  |     [CustomPropertyDrawer(typeof(int3x2)), CustomPropertyDrawer(typeof(int3x3)), CustomPropertyDrawer(typeof(int3x4))] | ||
|  |     [CustomPropertyDrawer(typeof(int4x2)), CustomPropertyDrawer(typeof(int4x3)), CustomPropertyDrawer(typeof(int4x4))] | ||
|  |     [CustomPropertyDrawer(typeof(uint2x2)), CustomPropertyDrawer(typeof(uint2x3)), CustomPropertyDrawer(typeof(uint2x4))] | ||
|  |     [CustomPropertyDrawer(typeof(uint3x2)), CustomPropertyDrawer(typeof(uint3x3)), CustomPropertyDrawer(typeof(uint3x4))] | ||
|  |     [CustomPropertyDrawer(typeof(uint4x2)), CustomPropertyDrawer(typeof(uint4x3)), CustomPropertyDrawer(typeof(uint4x4))] | ||
|  |     class MatrixDrawer : PropertyDrawer | ||
|  |     { | ||
|  | #if !UNITY_2023_2_OR_NEWER | ||
|  |         public override bool CanCacheInspectorGUI(SerializedProperty property) | ||
|  |         { | ||
|  |             return false; | ||
|  |         } | ||
|  | #endif | ||
|  | 
 | ||
|  |         public override float GetPropertyHeight(SerializedProperty property, GUIContent label) | ||
|  |         { | ||
|  |             if (!property.isExpanded) | ||
|  |                 return EditorGUIUtility.singleLineHeight; | ||
|  |             var rows = 1 + property.type[property.type.Length - 3] - '0'; | ||
|  |             return rows * EditorGUIUtility.singleLineHeight + (rows - 1) * EditorGUIUtility.standardVerticalSpacing; | ||
|  |         } | ||
|  | 
 | ||
|  |         static ReadOnlyCollection<string> k_ColPropertyPaths = | ||
|  |             new ReadOnlyCollection<string>(new[] { "c0", "c1", "c2", "c3" }); | ||
|  |         static ReadOnlyCollection<string> k_RowPropertyPaths = | ||
|  |             new ReadOnlyCollection<string>(new[] { "x", "y", "z", "w" }); | ||
|  | 
 | ||
|  |         public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | ||
|  |         { | ||
|  |             position.height = EditorGUIUtility.singleLineHeight; | ||
|  |             EditorGUI.PropertyField(position, property, label, false); | ||
|  | 
 | ||
|  |             if (Event.current.type == EventType.ContextClick && position.Contains(Event.current.mousePosition)) | ||
|  |             { | ||
|  |                 DoUtilityMenu(property); | ||
|  |                 Event.current.Use(); | ||
|  |             } | ||
|  | 
 | ||
|  |             if (!property.isExpanded) | ||
|  |                 return; | ||
|  | 
 | ||
|  |             var rows = property.type[property.type.Length - 3] - '0'; | ||
|  |             var cols = property.type[property.type.Length - 1] - '0'; | ||
|  | 
 | ||
|  |             ++EditorGUI.indentLevel; | ||
|  |             position = EditorGUI.IndentedRect(position); | ||
|  |             --EditorGUI.indentLevel; | ||
|  | 
 | ||
|  |             var elementType = property.FindPropertyRelative("c0.x").propertyType; | ||
|  |             for (var row = 0; row < rows; ++row) | ||
|  |             { | ||
|  |                 position.y += position.height + EditorGUIUtility.standardVerticalSpacing; | ||
|  |                 var elementRect = new Rect(position) | ||
|  |                 { | ||
|  |                     width = elementType == SerializedPropertyType.Boolean | ||
|  |                         ? EditorGUIUtility.singleLineHeight | ||
|  |                         : (position.width - (cols - 1) * EditorGUIUtility.standardVerticalSpacing) / cols | ||
|  |                 }; | ||
|  |                 for (var col = 0; col < cols; ++col) | ||
|  |                 { | ||
|  |                     EditorGUI.PropertyField( | ||
|  |                         elementRect, | ||
|  |                         property.FindPropertyRelative($"{k_ColPropertyPaths[col]}.{k_RowPropertyPaths[row]}"), | ||
|  |                         GUIContent.none | ||
|  |                     ); | ||
|  |                     elementRect.x += elementRect.width + EditorGUIUtility.standardVerticalSpacing; | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         Dictionary<SerializedPropertyType, Action<SerializedProperty, bool>> k_UtilityValueSetters = | ||
|  |             new Dictionary<SerializedPropertyType, Action<SerializedProperty, bool>> | ||
|  |             { | ||
|  |                 { SerializedPropertyType.Boolean, (property, b) => property.boolValue = b }, | ||
|  |                 { SerializedPropertyType.Float, (property, b) => property.floatValue = b ? 1f : 0f }, | ||
|  |                 { SerializedPropertyType.Integer, (property, b) => property.intValue = b ? 1 : 0 } | ||
|  |             }; | ||
|  | 
 | ||
|  |         void DoUtilityMenu(SerializedProperty property) | ||
|  |         { | ||
|  |             var rows = property.type[property.type.Length - 3] - '0'; | ||
|  |             var cols = property.type[property.type.Length - 1] - '0'; | ||
|  |             var elementType = property.FindPropertyRelative("c0.x").propertyType; | ||
|  |             var setValue = k_UtilityValueSetters[elementType]; | ||
|  |             var menu = new GenericMenu(); | ||
|  |             property = property.Copy(); | ||
|  |             menu.AddItem( | ||
|  |                 EditorGUIUtility.TrTextContent("Set to Zero"), | ||
|  |                 false, | ||
|  |                 () => | ||
|  |                 { | ||
|  |                     property.serializedObject.Update();; | ||
|  |                     for (var row = 0; row < rows; ++row) | ||
|  |                     for (var col = 0; col < cols; ++col) | ||
|  |                         setValue( | ||
|  |                             property.FindPropertyRelative($"{k_ColPropertyPaths[col]}.{k_RowPropertyPaths[row]}"), | ||
|  |                             false | ||
|  |                         ); | ||
|  |                     property.serializedObject.ApplyModifiedProperties(); | ||
|  |                 } | ||
|  |             ); | ||
|  |             if (rows == cols) | ||
|  |             { | ||
|  |                 menu.AddItem( | ||
|  |                     EditorGUIUtility.TrTextContent("Reset to Identity"), | ||
|  |                     false, | ||
|  |                     () => | ||
|  |                     { | ||
|  |                         property.serializedObject.Update(); | ||
|  |                         for (var row = 0; row < rows; ++row) | ||
|  |                         for (var col = 0; col < cols; ++col) | ||
|  |                             setValue( | ||
|  |                                 property.FindPropertyRelative($"{k_ColPropertyPaths[col]}.{k_RowPropertyPaths[row]}"), | ||
|  |                                 row == col | ||
|  |                             ); | ||
|  |                         property.serializedObject.ApplyModifiedProperties(); | ||
|  |                     } | ||
|  |                 ); | ||
|  |             } | ||
|  |             menu.ShowAsContext(); | ||
|  |         } | ||
|  |     } | ||
|  | } |