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.
 
 
 
 

374 lines
13 KiB

using System;
using System.Reflection;
using UnityEditor.ShaderGraph.Drawing;
using UnityEngine;
using UnityEngine.UIElements;
namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers
{
[SGPropertyDrawer(typeof(Matrix4x4))]
class MatrixPropertyDrawer : IPropertyDrawer
{
public enum MatrixDimensions
{
Two,
Three,
Four
}
public MatrixDimensions dimension { get; set; }
public delegate Vector4 GetMatrixRowDelegate(int rowNumber);
internal Action PreValueChangeCallback;
internal delegate void ValueChangedCallback(Matrix4x4 newValue);
internal Action PostValueChangeCallback;
// Matrix4x4, Matrix3x3, Matrix2x2 are all value types,
// hence the local value doesn't stay up to date after modified
// Need a callback to fetch the row data directly from the source
internal GetMatrixRowDelegate MatrixRowFetchCallback;
void HandleMatrix2Property(
ValueChangedCallback valueChangedCallback,
PropertySheet propertySheet,
Matrix4x4 matrix2Property,
string labelName = "Default")
{
var vector2PropertyDrawer = new Vector2PropertyDrawer();
vector2PropertyDrawer.preValueChangeCallback = PreValueChangeCallback;
vector2PropertyDrawer.postValueChangeCallback = PostValueChangeCallback;
propertySheet.Add(vector2PropertyDrawer.CreateGUI(
newValue =>
{
Vector2 row1 = MatrixRowFetchCallback(1);
valueChangedCallback(new Matrix4x4()
{
m00 = newValue.x,
m01 = newValue.y,
m02 = 0,
m03 = 0,
m10 = row1.x,
m11 = row1.y,
m12 = 0,
m13 = 0,
m20 = 0,
m21 = 0,
m22 = 0,
m23 = 0,
m30 = 0,
m31 = 0,
m32 = 0,
m33 = 0,
});
},
matrix2Property.GetRow(0),
labelName,
out var row0Field
));
propertySheet.Add(vector2PropertyDrawer.CreateGUI(
newValue =>
{
Vector2 row0 = MatrixRowFetchCallback(0);
valueChangedCallback(new Matrix4x4()
{
m00 = row0.x,
m01 = row0.y,
m02 = 0,
m03 = 0,
m10 = newValue.x,
m11 = newValue.y,
m12 = 0,
m13 = 0,
m20 = 0,
m21 = 0,
m22 = 0,
m23 = 0,
m30 = 0,
m31 = 0,
m32 = 0,
m33 = 0,
});
},
matrix2Property.GetRow(1),
"",
out var row1Field
));
}
void HandleMatrix3Property(
ValueChangedCallback valueChangedCallback,
PropertySheet propertySheet,
Matrix4x4 matrix3Property,
string labelName = "Default")
{
var vector3PropertyDrawer = new Vector3PropertyDrawer();
vector3PropertyDrawer.preValueChangeCallback = PreValueChangeCallback;
vector3PropertyDrawer.postValueChangeCallback = PostValueChangeCallback;
propertySheet.Add(vector3PropertyDrawer.CreateGUI(
newValue =>
{
Vector3 row1 = MatrixRowFetchCallback(1);
Vector3 row2 = MatrixRowFetchCallback(2);
valueChangedCallback(new Matrix4x4()
{
m00 = newValue.x,
m01 = newValue.y,
m02 = newValue.z,
m03 = 0,
m10 = row1.x,
m11 = row1.y,
m12 = row1.z,
m13 = 0,
m20 = row2.x,
m21 = row2.y,
m22 = row2.z,
m23 = 0,
m30 = 0,
m31 = 0,
m32 = 0,
m33 = 0,
});
},
matrix3Property.GetRow(0),
labelName,
out var row0Field
));
propertySheet.Add(vector3PropertyDrawer.CreateGUI(
newValue =>
{
Vector3 row0 = MatrixRowFetchCallback(0);
Vector3 row2 = MatrixRowFetchCallback(2);
valueChangedCallback(new Matrix4x4()
{
m00 = row0.x,
m01 = row0.y,
m02 = row0.z,
m03 = 0,
m10 = newValue.x,
m11 = newValue.y,
m12 = newValue.z,
m13 = 0,
m20 = row2.x,
m21 = row2.y,
m22 = row2.z,
m23 = 0,
m30 = 0,
m31 = 0,
m32 = 0,
m33 = 0,
});
},
matrix3Property.GetRow(1),
"",
out var row1Field
));
propertySheet.Add(vector3PropertyDrawer.CreateGUI(
newValue =>
{
Vector3 row0 = MatrixRowFetchCallback(0);
Vector3 row1 = MatrixRowFetchCallback(1);
valueChangedCallback(new Matrix4x4()
{
m00 = row0.x,
m01 = row0.y,
m02 = row0.z,
m03 = 0,
m10 = row1.x,
m11 = row1.y,
m12 = row1.z,
m13 = 0,
m20 = newValue.x,
m21 = newValue.y,
m22 = newValue.z,
m23 = 0,
m30 = 0,
m31 = 0,
m32 = 0,
m33 = 0,
});
},
matrix3Property.GetRow(2),
"",
out var row2Field
));
}
void HandleMatrix4Property(
ValueChangedCallback valueChangedCallback,
PropertySheet propertySheet,
Matrix4x4 matrix4Property,
string labelName = "Default")
{
var vector4PropertyDrawer = new Vector4PropertyDrawer();
vector4PropertyDrawer.preValueChangeCallback = PreValueChangeCallback;
vector4PropertyDrawer.postValueChangeCallback = PostValueChangeCallback;
propertySheet.Add(vector4PropertyDrawer.CreateGUI(
newValue =>
{
Vector4 row1 = MatrixRowFetchCallback(1);
Vector4 row2 = MatrixRowFetchCallback(2);
Vector4 row3 = MatrixRowFetchCallback(3);
valueChangedCallback(new Matrix4x4()
{
m00 = newValue.x,
m01 = newValue.y,
m02 = newValue.z,
m03 = newValue.w,
m10 = row1.x,
m11 = row1.y,
m12 = row1.z,
m13 = row1.w,
m20 = row2.x,
m21 = row2.y,
m22 = row2.z,
m23 = row2.w,
m30 = row3.x,
m31 = row3.y,
m32 = row3.z,
m33 = row3.w,
});
},
matrix4Property.GetRow(0),
labelName,
out var row0Field
));
propertySheet.Add(vector4PropertyDrawer.CreateGUI(
newValue =>
{
Vector4 row0 = MatrixRowFetchCallback(0);
Vector4 row2 = MatrixRowFetchCallback(2);
Vector4 row3 = MatrixRowFetchCallback(3);
valueChangedCallback(new Matrix4x4()
{
m00 = row0.x,
m01 = row0.y,
m02 = row0.z,
m03 = row0.w,
m10 = newValue.x,
m11 = newValue.y,
m12 = newValue.z,
m13 = newValue.w,
m20 = row2.x,
m21 = row2.y,
m22 = row2.z,
m23 = row2.w,
m30 = row3.x,
m31 = row3.y,
m32 = row3.z,
m33 = row3.w,
});
},
matrix4Property.GetRow(1),
"",
out var row1Field
));
propertySheet.Add(vector4PropertyDrawer.CreateGUI(
newValue =>
{
Vector4 row0 = MatrixRowFetchCallback(0);
Vector4 row1 = MatrixRowFetchCallback(1);
Vector4 row3 = MatrixRowFetchCallback(3);
valueChangedCallback(new Matrix4x4()
{
m00 = row0.x,
m01 = row0.y,
m02 = row0.z,
m03 = row0.w,
m10 = row1.x,
m11 = row1.y,
m12 = row1.z,
m13 = row1.w,
m20 = newValue.x,
m21 = newValue.y,
m22 = newValue.z,
m23 = newValue.w,
m30 = row3.x,
m31 = row3.y,
m32 = row3.z,
m33 = row3.w,
});
},
matrix4Property.GetRow(2),
"",
out var row2Field));
propertySheet.Add(vector4PropertyDrawer.CreateGUI(
newValue =>
{
Vector4 row0 = MatrixRowFetchCallback(0);
Vector4 row1 = MatrixRowFetchCallback(1);
Vector4 row2 = MatrixRowFetchCallback(2);
valueChangedCallback(new Matrix4x4()
{
m00 = row0.x,
m01 = row0.y,
m02 = row0.z,
m03 = row0.w,
m10 = row1.x,
m11 = row1.y,
m12 = row1.z,
m13 = row1.w,
m20 = row2.x,
m21 = row2.y,
m22 = row2.z,
m23 = row2.w,
m30 = newValue.x,
m31 = newValue.y,
m32 = newValue.z,
m33 = newValue.w,
});
},
matrix4Property.GetRow(3),
"",
out var row3Field
));
}
internal VisualElement CreateGUI(
ValueChangedCallback valueChangedCallback,
Matrix4x4 fieldToDraw,
string labelName,
out VisualElement propertyMatrixField,
int indentLevel = 0)
{
var propertySheet = new PropertySheet();
switch (dimension)
{
case MatrixDimensions.Two:
HandleMatrix2Property(valueChangedCallback, propertySheet, fieldToDraw, labelName);
break;
case MatrixDimensions.Three:
HandleMatrix3Property(valueChangedCallback, propertySheet, fieldToDraw, labelName);
break;
case MatrixDimensions.Four:
HandleMatrix4Property(valueChangedCallback, propertySheet, fieldToDraw, labelName);
break;
}
propertyMatrixField = propertySheet;
return propertyMatrixField;
}
public Action inspectorUpdateDelegate { get; set; }
public VisualElement DrawProperty(PropertyInfo propertyInfo, object actualObject, InspectableAttribute attribute)
{
return this.CreateGUI(
// Use the setter from the provided property as the callback
newValue => propertyInfo.GetSetMethod(true).Invoke(actualObject, new object[] { newValue }),
(Matrix4x4)propertyInfo.GetValue(actualObject),
attribute.labelName,
out var propertyVisualElement);
}
void IPropertyDrawer.DisposePropertyDrawer() { }
}
}