No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MatrixDrawer.cs 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using UnityEditor;
  5. using UnityEngine;
  6. namespace Unity.Mathematics.Editor
  7. {
  8. [CustomPropertyDrawer(typeof(bool2x2)), CustomPropertyDrawer(typeof(bool2x3)), CustomPropertyDrawer(typeof(bool2x4))]
  9. [CustomPropertyDrawer(typeof(bool3x2)), CustomPropertyDrawer(typeof(bool3x3)), CustomPropertyDrawer(typeof(bool3x4))]
  10. [CustomPropertyDrawer(typeof(bool4x2)), CustomPropertyDrawer(typeof(bool4x3)), CustomPropertyDrawer(typeof(bool4x4))]
  11. [CustomPropertyDrawer(typeof(double2x2)), CustomPropertyDrawer(typeof(double2x3)), CustomPropertyDrawer(typeof(double2x4))]
  12. [CustomPropertyDrawer(typeof(double3x2)), CustomPropertyDrawer(typeof(double3x3)), CustomPropertyDrawer(typeof(double3x4))]
  13. [CustomPropertyDrawer(typeof(double4x2)), CustomPropertyDrawer(typeof(double4x3)), CustomPropertyDrawer(typeof(double4x4))]
  14. [CustomPropertyDrawer(typeof(float2x2)), CustomPropertyDrawer(typeof(float2x3)), CustomPropertyDrawer(typeof(float2x4))]
  15. [CustomPropertyDrawer(typeof(float3x2)), CustomPropertyDrawer(typeof(float3x3)), CustomPropertyDrawer(typeof(float3x4))]
  16. [CustomPropertyDrawer(typeof(float4x2)), CustomPropertyDrawer(typeof(float4x3)), CustomPropertyDrawer(typeof(float4x4))]
  17. [CustomPropertyDrawer(typeof(int2x2)), CustomPropertyDrawer(typeof(int2x3)), CustomPropertyDrawer(typeof(int2x4))]
  18. [CustomPropertyDrawer(typeof(int3x2)), CustomPropertyDrawer(typeof(int3x3)), CustomPropertyDrawer(typeof(int3x4))]
  19. [CustomPropertyDrawer(typeof(int4x2)), CustomPropertyDrawer(typeof(int4x3)), CustomPropertyDrawer(typeof(int4x4))]
  20. [CustomPropertyDrawer(typeof(uint2x2)), CustomPropertyDrawer(typeof(uint2x3)), CustomPropertyDrawer(typeof(uint2x4))]
  21. [CustomPropertyDrawer(typeof(uint3x2)), CustomPropertyDrawer(typeof(uint3x3)), CustomPropertyDrawer(typeof(uint3x4))]
  22. [CustomPropertyDrawer(typeof(uint4x2)), CustomPropertyDrawer(typeof(uint4x3)), CustomPropertyDrawer(typeof(uint4x4))]
  23. class MatrixDrawer : PropertyDrawer
  24. {
  25. #if !UNITY_2023_2_OR_NEWER
  26. public override bool CanCacheInspectorGUI(SerializedProperty property)
  27. {
  28. return false;
  29. }
  30. #endif
  31. public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
  32. {
  33. if (!property.isExpanded)
  34. return EditorGUIUtility.singleLineHeight;
  35. var rows = 1 + property.type[property.type.Length - 3] - '0';
  36. return rows * EditorGUIUtility.singleLineHeight + (rows - 1) * EditorGUIUtility.standardVerticalSpacing;
  37. }
  38. static ReadOnlyCollection<string> k_ColPropertyPaths =
  39. new ReadOnlyCollection<string>(new[] { "c0", "c1", "c2", "c3" });
  40. static ReadOnlyCollection<string> k_RowPropertyPaths =
  41. new ReadOnlyCollection<string>(new[] { "x", "y", "z", "w" });
  42. public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
  43. {
  44. position.height = EditorGUIUtility.singleLineHeight;
  45. EditorGUI.PropertyField(position, property, label, false);
  46. if (Event.current.type == EventType.ContextClick && position.Contains(Event.current.mousePosition))
  47. {
  48. DoUtilityMenu(property);
  49. Event.current.Use();
  50. }
  51. if (!property.isExpanded)
  52. return;
  53. var rows = property.type[property.type.Length - 3] - '0';
  54. var cols = property.type[property.type.Length - 1] - '0';
  55. ++EditorGUI.indentLevel;
  56. position = EditorGUI.IndentedRect(position);
  57. --EditorGUI.indentLevel;
  58. var elementType = property.FindPropertyRelative("c0.x").propertyType;
  59. for (var row = 0; row < rows; ++row)
  60. {
  61. position.y += position.height + EditorGUIUtility.standardVerticalSpacing;
  62. var elementRect = new Rect(position)
  63. {
  64. width = elementType == SerializedPropertyType.Boolean
  65. ? EditorGUIUtility.singleLineHeight
  66. : (position.width - (cols - 1) * EditorGUIUtility.standardVerticalSpacing) / cols
  67. };
  68. for (var col = 0; col < cols; ++col)
  69. {
  70. EditorGUI.PropertyField(
  71. elementRect,
  72. property.FindPropertyRelative($"{k_ColPropertyPaths[col]}.{k_RowPropertyPaths[row]}"),
  73. GUIContent.none
  74. );
  75. elementRect.x += elementRect.width + EditorGUIUtility.standardVerticalSpacing;
  76. }
  77. }
  78. }
  79. Dictionary<SerializedPropertyType, Action<SerializedProperty, bool>> k_UtilityValueSetters =
  80. new Dictionary<SerializedPropertyType, Action<SerializedProperty, bool>>
  81. {
  82. { SerializedPropertyType.Boolean, (property, b) => property.boolValue = b },
  83. { SerializedPropertyType.Float, (property, b) => property.floatValue = b ? 1f : 0f },
  84. { SerializedPropertyType.Integer, (property, b) => property.intValue = b ? 1 : 0 }
  85. };
  86. void DoUtilityMenu(SerializedProperty property)
  87. {
  88. var rows = property.type[property.type.Length - 3] - '0';
  89. var cols = property.type[property.type.Length - 1] - '0';
  90. var elementType = property.FindPropertyRelative("c0.x").propertyType;
  91. var setValue = k_UtilityValueSetters[elementType];
  92. var menu = new GenericMenu();
  93. property = property.Copy();
  94. menu.AddItem(
  95. EditorGUIUtility.TrTextContent("Set to Zero"),
  96. false,
  97. () =>
  98. {
  99. property.serializedObject.Update();;
  100. for (var row = 0; row < rows; ++row)
  101. for (var col = 0; col < cols; ++col)
  102. setValue(
  103. property.FindPropertyRelative($"{k_ColPropertyPaths[col]}.{k_RowPropertyPaths[row]}"),
  104. false
  105. );
  106. property.serializedObject.ApplyModifiedProperties();
  107. }
  108. );
  109. if (rows == cols)
  110. {
  111. menu.AddItem(
  112. EditorGUIUtility.TrTextContent("Reset to Identity"),
  113. false,
  114. () =>
  115. {
  116. property.serializedObject.Update();
  117. for (var row = 0; row < rows; ++row)
  118. for (var col = 0; col < cols; ++col)
  119. setValue(
  120. property.FindPropertyRelative($"{k_ColPropertyPaths[col]}.{k_RowPropertyPaths[row]}"),
  121. row == col
  122. );
  123. property.serializedObject.ApplyModifiedProperties();
  124. }
  125. );
  126. }
  127. menu.ShowAsContext();
  128. }
  129. }
  130. }