private static void CalculateTextureCoordinates(ChiselBrush pr, ChiselSurface surface, Plane clip, int textureWidth, int textureHeight, VmfAxis UAxis, VmfAxis VAxis) { var localToPlaneSpace = (Matrix4x4)MathExtensions.GenerateLocalToPlaneSpaceMatrix(new float4(clip.normal, clip.distance)); var planeSpaceToLocal = (Matrix4x4)math.inverse(localToPlaneSpace); UAxis.Translation %= textureWidth; VAxis.Translation %= textureHeight; if (UAxis.Translation < -textureWidth / 2f) { UAxis.Translation += textureWidth; } if (VAxis.Translation < -textureHeight / 2f) { VAxis.Translation += textureHeight; } var scaleX = textureWidth * UAxis.Scale * _conversionScale; var scaleY = textureHeight * VAxis.Scale * _conversionScale; var uoffset = Vector3.Dot(Vector3.zero, new Vector3(UAxis.Vector.X, UAxis.Vector.Z, UAxis.Vector.Y)) + (UAxis.Translation / textureWidth); var voffset = Vector3.Dot(Vector3.zero, new Vector3(VAxis.Vector.X, VAxis.Vector.Z, VAxis.Vector.Y)) + (VAxis.Translation / textureHeight); var uVector = new Vector4(UAxis.Vector.X / scaleX, UAxis.Vector.Z / scaleX, UAxis.Vector.Y / scaleX, uoffset); var vVector = new Vector4(VAxis.Vector.X / scaleY, VAxis.Vector.Z / scaleY, VAxis.Vector.Y / scaleY, voffset); var uvMatrix = new UVMatrix(uVector, -vVector); var matrix = uvMatrix.ToMatrix(); matrix = matrix * planeSpaceToLocal; surface.surfaceDescription.UV0 = new UVMatrix(matrix); }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { SerializedProperty UProp = property.FindPropertyRelative(nameof(UVMatrix.U)); SerializedProperty VProp = property.FindPropertyRelative(nameof(UVMatrix.V)); int translationID = GUIUtility.GetControlID(FocusType.Keyboard); int scaleID = GUIUtility.GetControlID(FocusType.Keyboard); int rotationID = GUIUtility.GetControlID(FocusType.Keyboard); var uvMatrix = new UVMatrix(UProp.vector4Value, VProp.vector4Value); var state = (UVMatrixState)EditorGUIUtility.GetStateObject(typeof(UVMatrixState), translationID); if (!state.initialized || state.uvMatrix.U != uvMatrix.U || state.uvMatrix.V != uvMatrix.V) { uvMatrix.Decompose(out state.translation, out state.rotation, out state.scale); state.uvMatrix = uvMatrix; state.initialized = true; } var hasLabel = ChiselGUIUtility.LabelHasContent(label); var prevIndenLevel = EditorGUI.indentLevel; EditorGUI.BeginProperty(position, label, property); { EditorGUI.BeginChangeCheck(); var prevMixedValues = EditorGUI.showMixedValue; EditorGUI.showMixedValue = property.hasMultipleDifferentValues; var translationContent = (label == null) ? GUIContent.none : kTranslationContent; var scaleContent = (label == null) ? GUIContent.none : kScaleContent; var rotationContent = (label == null) ? GUIContent.none : kRotationContent; position.height = EditorGUI.GetPropertyHeight(SerializedPropertyType.Vector2, GUIContent.none); var fieldRect = EditorGUI.PrefixLabel(position, translationID, !hasLabel ? GUIContent.none : translationContent); EditorGUI.indentLevel = 0; state.translation = EditorGUI.Vector2Field(fieldRect, GUIContent.none, state.translation); EditorGUI.indentLevel = prevIndenLevel; position.y += position.height + kSpacing; position.height = EditorGUI.GetPropertyHeight(SerializedPropertyType.Vector2, GUIContent.none); fieldRect = EditorGUI.PrefixLabel(position, scaleID, !hasLabel ? GUIContent.none : scaleContent); EditorGUI.indentLevel = 0; state.scale = EditorGUI.Vector2Field(fieldRect, GUIContent.none, state.scale); EditorGUI.indentLevel = prevIndenLevel; position.y += position.height + kSpacing; position.height = EditorGUI.GetPropertyHeight(SerializedPropertyType.Float, GUIContent.none); fieldRect = EditorGUI.PrefixLabel(position, rotationID, !hasLabel ? GUIContent.none : rotationContent); EditorGUI.indentLevel = 0; state.rotation = EditorGUI.FloatField(fieldRect, GUIContent.none, state.rotation); EditorGUI.indentLevel = prevIndenLevel; position.y += position.height + kSpacing; EditorGUI.showMixedValue = prevMixedValues; if (EditorGUI.EndChangeCheck()) { state.scale.x = (float)Math.Max(Math.Abs(state.scale.x), UVMatrix.kMinScale) * Math.Sign(state.scale.x); state.scale.y = (float)Math.Max(Math.Abs(state.scale.y), UVMatrix.kMinScale) * Math.Sign(state.scale.y); uvMatrix = UVMatrix.TRS(state.translation, state.rotation, state.scale); UProp.vector4Value = uvMatrix.U; VProp.vector4Value = uvMatrix.V; state.uvMatrix = uvMatrix; property.serializedObject.ApplyModifiedProperties(); } } EditorGUI.EndProperty(); /* * * SerializedProperty UxProp = property.FindPropertyRelative($"{nameof(UVMatrix.U)}.{nameof(UVMatrix.U.x)}"); * SerializedProperty VxProp = property.FindPropertyRelative($"{nameof(UVMatrix.V)}.{nameof(UVMatrix.V.x)}"); * * EditorGUI.BeginProperty(position, label, property); * { * position.height = EditorGUI.GetPropertyHeight(SerializedPropertyType.Vector4, GUIContent.none); * position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Keyboard), label); * * EditorGUI.MultiPropertyField(position, xyzw, UxProp); * position.y += position.height + kSpace; * * EditorGUI.MultiPropertyField(position, xyzw, VxProp); * } * EditorGUI.EndProperty(); */ }