From 8ad03d4e2c048a28f5ff439c5c818d6b9879814b Mon Sep 17 00:00:00 2001 From: RSlysz Date: Thu, 26 Nov 2020 10:44:42 +0100 Subject: [PATCH 01/20] Making a transform handle projected on a side --- .../Material/Decal/DecalProjectorEditor.cs | 385 ++++++++++++------ .../Material/Decal/DisplacableRectHandles.cs | 273 +++++++++++++ .../Decal/DisplacableRectHandles.cs.meta | 11 + .../Material/Decal/ProjectedTransform.cs | 254 ++++++++++++ .../Material/Decal/ProjectedTransform.cs.meta | 11 + 5 files changed, 817 insertions(+), 117 deletions(-) create mode 100644 com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs create mode 100644 com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs.meta create mode 100644 com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs create mode 100644 com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs.meta diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs index 48030f56d53..de4a0755be1 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs @@ -3,6 +3,11 @@ using UnityEngine.Rendering.HighDefinition; using UnityEditor.ShortcutManagement; using static UnityEditorInternal.EditMode; +using UnityEditor.IMGUI.Controls; +using System; +using System.Linq; +using System.Linq.Expressions; +using System.Collections.Generic; namespace UnityEditor.Rendering.HighDefinition { @@ -10,6 +15,9 @@ namespace UnityEditor.Rendering.HighDefinition [CanEditMultipleObjects] partial class DecalProjectorEditor : Editor { + const float k_Limit = 100000; + const float k_LimitInv = 1 / k_Limit; + MaterialEditor m_MaterialEditor = null; SerializedProperty m_MaterialProperty; SerializedProperty m_DrawDistanceProperty; @@ -21,6 +29,7 @@ partial class DecalProjectorEditor : Editor SerializedProperty m_AffectsTransparencyProperty; SerializedProperty m_Size; SerializedProperty[] m_SizeValues; + SerializedProperty m_Offset; SerializedProperty m_OffsetZ; SerializedProperty m_FadeFactor; SerializedProperty m_DecalLayerMask; @@ -65,34 +74,39 @@ bool showAffectTransparencyHaveMultipleDifferentValue } } - static HierarchicalBox s_Handle; - static HierarchicalBox handle + static HierarchicalBox s_BoxHandle; + static HierarchicalBox boxHandle { get { - if (s_Handle == null || s_Handle.Equals(null)) + if (s_BoxHandle == null || s_BoxHandle.Equals(null)) { - s_Handle = new HierarchicalBox(k_GizmoColorBase, k_BaseHandlesColor); - s_Handle.monoHandle = false; + s_BoxHandle = new HierarchicalBox(k_GizmoColorBase, k_BaseHandlesColor); + s_BoxHandle.monoHandle = false; } - return s_Handle; + return s_BoxHandle; } } + static DisplacableRectHandles m_UVHandles = new DisplacableRectHandles(Color.white); + + static readonly BoxBoundsHandle s_AreaLightHandle = + new BoxBoundsHandle { axes = PrimitiveBoundsHandle.Axes.X | PrimitiveBoundsHandle.Axes.Y }; + const SceneViewEditMode k_EditShapeWithoutPreservingUV = (SceneViewEditMode)90; const SceneViewEditMode k_EditShapePreservingUV = (SceneViewEditMode)91; - const SceneViewEditMode k_EditUV = (SceneViewEditMode)92; + const SceneViewEditMode k_EditUVAndPivot = (SceneViewEditMode)92; static readonly SceneViewEditMode[] k_EditVolumeModes = new SceneViewEditMode[] { k_EditShapeWithoutPreservingUV, k_EditShapePreservingUV }; - static readonly SceneViewEditMode[] k_EditPivotModes = new SceneViewEditMode[] + static readonly SceneViewEditMode[] k_EditUVAndPivotModes = new SceneViewEditMode[] { - k_EditUV + k_EditUVAndPivot }; - static SceneViewEditMode s_CurrentEditMode; - static bool s_ModeSwitched; + + static Func s_DrawPivotHandle; static GUIContent[] k_EditVolumeLabels = null; static GUIContent[] editVolumeLabels => k_EditVolumeLabels ?? (k_EditVolumeLabels = new GUIContent[] @@ -106,11 +120,52 @@ static HierarchicalBox handle EditorGUIUtility.TrIconContent("d_MoveTool", k_EditUVTooltip) }); - static Editor s_Owner; + static List s_Instances = new List(); + + static DecalProjectorEditor FindEditorFromSelection() + { + GameObject[] selection = Selection.gameObjects; + DecalProjector[] selectionTargets = Selection.GetFiltered(SelectionMode.Unfiltered); + + foreach (DecalProjectorEditor editor in s_Instances) + { + Debug.Log("Check Start"); + if (selectionTargets.Length != editor.targets.Length) + { + Debug.Log("Length missmatch"); + continue; + } + bool allOk = true; + foreach (DecalProjector selectionTarget in selectionTargets) + if (!Array.Find(editor.targets, t => t == selectionTarget)) + { + Debug.Log("Missing " + selectionTarget); + allOk = false; + break; + } + if (!allOk) + continue; + Debug.Log("All good"); + return editor; + } + return null; + } + + static DecalProjectorEditor() + { + Type TransformHandleIdsType = Type.GetType("UnityEditor.Handles.TransformHandleIds, UnityEditor"); + var transformTranslationXHash = Expression.Variable(typeof(int), "TransformTranslationXHash"); + var transformTranslationYHash = Expression.Variable(typeof(int), "TransformTranslationYHash"); + var transformTranslationXYHash = Expression.Variable(typeof(int), "TransformTranslationXYHash"); + Type transformHandleParamType = Type.GetType("UnityEditor.Handles.TransformHandleParam, UnityEditor"); + //var transformHandleParam = Expression.Variable(transformHandleParamType, "TransformHandleParam"); + + } + private void OnEnable() { - s_Owner = this; + s_Instances.Add(this); // Create an instance of the MaterialEditor UpdateMaterialEditor(); @@ -135,7 +190,8 @@ private void OnEnable() m_Size.FindPropertyRelative("y"), m_Size.FindPropertyRelative("z"), }; - m_OffsetZ = serializedObject.FindProperty("m_Offset").FindPropertyRelative("z"); + m_Offset = serializedObject.FindProperty("m_Offset"); + m_OffsetZ = m_Offset.FindPropertyRelative("z"); m_FadeFactor = serializedObject.FindProperty("m_FadeFactor"); m_DecalLayerMask = serializedObject.FindProperty("m_DecalLayerMask"); } @@ -147,7 +203,8 @@ private void OnDisable() if (decalProjector != null) decalProjector.OnMaterialChange -= RequireUpdateMaterialEditor; } - s_Owner = null; + + s_Instances.Remove(this); } private void OnDestroy() => @@ -162,7 +219,7 @@ public Bounds OnGetFrameBounds() { DecalProjector decalProjector = target as DecalProjector; - return new Bounds(decalProjector.transform.position, handle.size); + return new Bounds(decalProjector.transform.position, boxHandle.size); } private bool m_RequireUpdateMaterialEditor = false; @@ -199,7 +256,6 @@ void OnSceneGUI() void DrawHandles() { - //Note: each target need to be handled individually to allow multi edition DecalProjector decalProjector = target as DecalProjector; if (editMode == k_EditShapePreservingUV || editMode == k_EditShapeWithoutPreservingUV) @@ -208,26 +264,30 @@ void DrawHandles() { bool needToRefreshDecalProjector = false; - handle.center = decalProjector.offset; - handle.size = decalProjector.size; + Vector3 centerStart = new Vector3( + -decalProjector.offset.x, + -decalProjector.offset.y, + decalProjector.size.z * .5f - decalProjector.offset.z); + boxHandle.center = centerStart; + boxHandle.size = decalProjector.size; - Vector3 boundsSizePreviousOS = handle.size; - Vector3 boundsMinPreviousOS = handle.size * -0.5f + handle.center; + Vector3 boundsSizePreviousOS = boxHandle.size; + Vector3 boundsMinPreviousOS = boxHandle.size * -0.5f + boxHandle.center; EditorGUI.BeginChangeCheck(); - handle.DrawHandle(); + boxHandle.DrawHandle(); if (EditorGUI.EndChangeCheck()) { needToRefreshDecalProjector = true; // Adjust decal transform if handle changed. - Undo.RecordObject(decalProjector, "Decal Projector Change"); + Undo.RecordObjects(new UnityEngine.Object[] { decalProjector, decalProjector.transform }, "Decal Projector Change"); - decalProjector.size = handle.size; - decalProjector.offset = handle.center; + decalProjector.size = boxHandle.size; + decalProjector.transform.position += decalProjector.transform.rotation * (boxHandle.center - centerStart); - Vector3 boundsSizeCurrentOS = handle.size; - Vector3 boundsMinCurrentOS = handle.size * -0.5f + handle.center; + Vector3 boundsSizeCurrentOS = boxHandle.size; + Vector3 boundsMinCurrentOS = boxHandle.size * -0.5f + boxHandle.center; if (editMode == k_EditShapePreservingUV) { @@ -252,25 +312,25 @@ void DrawHandles() // Automatically recenter our transform component if necessary. // In order to correctly handle world-space snapping, we only perform this recentering when the user is no longer interacting with the gizmo. - if ((GUIUtility.hotControl == 0) && (decalProjector.offset != Vector3.zero)) - { - needToRefreshDecalProjector = true; - - // Both the DecalProjectorComponent, and the transform will be modified. - // The undo system will automatically group all RecordObject() calls here into a single action. - Undo.RecordObject(decalProjector.transform, "Decal Projector Change"); - - // Re-center the transform to the center of the decal projector bounds, - // while maintaining the world-space coordinates of the decal projector boundings vertices. - // Center of the decal projector is not the same of the HierarchicalBox as we want it to be on the z face as lights - decalProjector.transform.Translate(decalProjector.offset + new Vector3(0f, 0f, handle.size.z * -0.5f), Space.Self); - - decalProjector.offset = new Vector3(0f, 0f, handle.size.z * 0.5f); - if (PrefabUtility.IsPartOfNonAssetPrefabInstance(decalProjector)) - { - PrefabUtility.RecordPrefabInstancePropertyModifications(decalProjector); - } - } + //if (GUIUtility.hotControl == 0 && decalProjector.offset != Vector3.zero) + //{ + // needToRefreshDecalProjector = true; + + // // Both the DecalProjectorComponent, and the transform will be modified. + // // The undo system will automatically group all RecordObject() calls here into a single action. + // Undo.RecordObject(decalProjector.transform, "Decal Projector Change"); + + // // Re-center the transform to the center of the decal projector bounds, + // // while maintaining the world-space coordinates of the decal projector boundings vertices. + // // Center of the decal projector is not the same of the HierarchicalBox as we want it to be on the z face as lights + // decalProjector.transform.Translate(decalProjector.offset + new Vector3(0f, 0f, handle.size.z * -0.5f), Space.Self); + + // decalProjector.offset = new Vector3(0f, 0f, handle.size.z * 0.5f); + // if (PrefabUtility.IsPartOfNonAssetPrefabInstance(decalProjector)) + // { + // PrefabUtility.RecordPrefabInstancePropertyModifications(decalProjector); + // } + //} if (needToRefreshDecalProjector) { @@ -280,78 +340,138 @@ void DrawHandles() } } - //[TODO: add editable pivot. Uncomment this when ready] - //else if (editMode == k_EditUV) - //{ - // //here should be handles code to manipulate the pivot without changing the UV - //} + else if (editMode == k_EditUVAndPivot) + { + // Pivot + using (new Handles.DrawingScope(Color.white, Matrix4x4.TRS(Vector3.zero, decalProjector.transform.rotation, Vector3.one))) + { + EditorGUI.BeginChangeCheck(); + Vector3 newPosition = ProjectedTransform.DrawHandles(decalProjector.transform.position, decalProjector.offset.z, decalProjector.transform.rotation); + if (EditorGUI.EndChangeCheck()) + { + decalProjector.offset -= Quaternion.Inverse(decalProjector.transform.rotation) * (decalProjector.transform.position - newPosition); + decalProjector.transform.position = newPosition; + } + } + + // UV + //using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position - decalProjector.transform.rotation * (new Vector3(decalProjector.size.x * 0.5f, decalProjector.size.y * 0.5f, 0) + decalProjector.offset), decalProjector.transform.rotation, Vector3.one))) + //Vector3 drawingSpaceOrigin = decalProjector.transform.position - decalProjector.transform.rotation * (new Vector3(decalProjector.size.x * 0.5f, decalProjector.size.y * 0.5f, 0) + decalProjector.offset); + //float drawingSpaceZRotated = (Quaternion.Inverse(decalProjector.transform.rotation) * decalProjector.transform.position).z + decalProjector.offset.z; + Vector3 drawingSpaceOriginRotated = Quaternion.Inverse(decalProjector.transform.rotation) * decalProjector.transform.position - new Vector3(decalProjector.size.x * 0.5f, decalProjector.size.y * 0.5f, 0) + decalProjector.offset; + using (new Handles.DrawingScope(Matrix4x4.TRS(Vector3.zero, decalProjector.transform.rotation, Vector3.one))) + { + Vector2 UVSize = new Vector2( + decalProjector.uvScale.x > k_Limit || decalProjector.uvScale.x < -k_Limit ? 0f : decalProjector.size.x / decalProjector.uvScale.x, + decalProjector.uvScale.y > k_Limit || decalProjector.uvScale.y < -k_Limit ? 0f : decalProjector.size.y / decalProjector.uvScale.y + ); + Vector2 UVStart = -new Vector2(decalProjector.uvBias.x * UVSize.x, decalProjector.uvBias.y * UVSize.y); + Vector2 UVCenter = UVStart + UVSize * 0.5f + (Vector2)drawingSpaceOriginRotated; + + m_UVHandles.center = UVCenter; + m_UVHandles.size = UVSize; + + string debugBefore = m_UVHandles.debug; + + EditorGUI.BeginChangeCheck(); + m_UVHandles.DrawHandle(); + if (EditorGUI.EndChangeCheck()) + { + Debug.Log($"Rect changed {debugBefore} -> {m_UVHandles.debug}"); + + Vector2 limit = new Vector2(Mathf.Abs(decalProjector.size.x * k_LimitInv), Mathf.Abs(decalProjector.size.y * k_LimitInv)); + Debug.Log($"Limit:({limit.x},{limit.y})"); + Vector2 uvScale = m_UVHandles.size; + Debug.Log($"local uvScale before:({uvScale.x},{uvScale.y})"); + for (int channel = 0; channel < 2; channel++) + { + if (Mathf.Abs(uvScale[channel]) > limit[channel]) + uvScale[channel] = decalProjector.size[channel] / uvScale[channel]; + else + uvScale[channel] = Mathf.Sign(decalProjector.size[channel]) * Mathf.Sign(uvScale[channel]) * k_Limit; + } + Debug.Log($"local uvScale after:({uvScale.x},{uvScale.y})"); + + Vector2 debugUvScale = decalProjector.uvScale; + Vector2 debugUvBias = decalProjector.uvBias; + + decalProjector.uvScale = uvScale; + Debug.Log($"uvScale ({debugUvScale.x},{debugUvScale.y})->({decalProjector.uvScale.x},{decalProjector.uvScale.y})"); + + var newUVStart = m_UVHandles.center - .5f * m_UVHandles.size - (Vector2)drawingSpaceOriginRotated; + decalProjector.uvBias = -new Vector2( + m_UVHandles.size.x < k_LimitInv && m_UVHandles.size.x > -k_LimitInv ? k_Limit * newUVStart.x / decalProjector.size.x : newUVStart.x / m_UVHandles.size.x, + m_UVHandles.size.y < k_LimitInv && m_UVHandles.size.y > -k_LimitInv ? k_Limit * newUVStart.y / decalProjector.size.y : newUVStart.y / m_UVHandles.size.y + ); + Debug.Log($"uvBias {D(debugUvBias)}->{D(decalProjector.uvBias)} UVCenter:{D(UVCenter)} UVSize:{D(UVSize)} UVStart:{D(UVStart)} newUVStart:{D(newUVStart)}"); + } + } + } } + static string D(Vector2 a) => $"({a.x},{a.y})"; + + [DrawGizmo(GizmoType.Selected | GizmoType.Active)] static void DrawGizmosSelected(DecalProjector decalProjector, GizmoType gizmoType) { + const float k_DotLength = 5f; + //draw them scale independent using (new Handles.DrawingScope(Color.white, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, Vector3.one))) { - handle.center = decalProjector.offset; - handle.size = decalProjector.size; - bool inEditMode = editMode == k_EditShapePreservingUV || editMode == k_EditShapeWithoutPreservingUV; - handle.DrawHull(inEditMode); - - Quaternion arrowRotation = Quaternion.LookRotation(Vector3.down, Vector3.right); - float arrowSize = decalProjector.size.z * 0.25f; - Vector3 pivot = decalProjector.offset; - Vector3 projectedPivot = pivot + decalProjector.size.z * 0.5f * Vector3.back; - Handles.ArrowHandleCap(0, projectedPivot, Quaternion.identity, arrowSize, EventType.Repaint); - - //[TODO: add editable pivot. Uncomment this when ready] - //draw pivot - //Handles.SphereHandleCap(controlID, pivot, Quaternion.identity, 0.02f, EventType.Repaint); - //Color c = Color.white; - //c.a = 0.2f; - //Handles.color = c; - //Handles.DrawLine(projectedPivot, projectedPivot + decalProjector.m_Size.x * 0.5f * Vector3.right); - //Handles.DrawLine(projectedPivot, projectedPivot + decalProjector.m_Size.y * 0.5f * Vector3.up); - //Handles.DrawLine(projectedPivot, projectedPivot + decalProjector.m_Size.z * 0.5f * Vector3.forward); + boxHandle.center = new Vector3( + -decalProjector.offset.x, + -decalProjector.offset.y, + decalProjector.size.z * .5f - decalProjector.offset.z); + boxHandle.size = decalProjector.size; + bool isVolumeEditMode = editMode == k_EditShapePreservingUV || editMode == k_EditShapeWithoutPreservingUV; + bool isPivotEditMode = editMode == k_EditUVAndPivot; + boxHandle.DrawHull(isVolumeEditMode); + + Vector3 pivot = Vector3.zero; + Vector3 projectedPivot = new Vector3(0, 0, -decalProjector.offset.z); + + if (isPivotEditMode) + { + Handles.DrawDottedLines(new[] { projectedPivot, pivot }, k_DotLength); + } + else + { + Quaternion arrowRotation = Quaternion.LookRotation(Vector3.down, Vector3.right); + float arrowSize = decalProjector.size.z * 0.25f; + Handles.ArrowHandleCap(0, projectedPivot, Quaternion.identity, arrowSize, EventType.Repaint); + } //draw UV and bolder edges - using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position - decalProjector.transform.rotation * (decalProjector.size * 0.5f + decalProjector.offset.z * Vector3.back), decalProjector.transform.rotation, Vector3.one))) + using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position - decalProjector.transform.rotation * decalProjector.offset, decalProjector.transform.rotation, Vector3.one))) { - if (inEditMode) - { - Vector2 size = new Vector2( - (decalProjector.uvScale.x > 100000 || decalProjector.uvScale.x < -100000 ? 0f : 1f / decalProjector.uvScale.x) * decalProjector.size.x, - (decalProjector.uvScale.y > 100000 || decalProjector.uvScale.y < -100000 ? 0f : 1f / decalProjector.uvScale.y) * decalProjector.size.y + Vector2 UVSize = new Vector2( + decalProjector.uvScale.x > k_Limit || decalProjector.uvScale.x < -k_Limit ? 0f : decalProjector.size.x / decalProjector.uvScale.x, + decalProjector.uvScale.y > k_Limit || decalProjector.uvScale.y < -k_Limit ? 0f : decalProjector.size.y / decalProjector.uvScale.y ); - Vector2 start = (Vector2)projectedPivot - new Vector2(decalProjector.uvBias.x * size.x, decalProjector.uvBias.y * size.y); - Handles.DrawDottedLines( - new Vector3[] - { - start, start + new Vector2(size.x, 0), - start + new Vector2(size.x, 0), start + size, - start + size, start + new Vector2(0, size.y), - start + new Vector2(0, size.y), start - }, - 5f); - } - - Vector2 halfSize = decalProjector.size * .5f; - Vector2 halfSize2 = new Vector2(halfSize.x, -halfSize.y); - Vector2 center = (Vector2)projectedPivot + halfSize; - Handles.DrawLine(center - halfSize, center - halfSize2, 3f); - Handles.DrawLine(center - halfSize2, center + halfSize, 3f); - Handles.DrawLine(center + halfSize, center + halfSize2, 3f); - Handles.DrawLine(center + halfSize2, center - halfSize, 3f); + Vector2 UVCenter = UVSize * .5f - new Vector2(decalProjector.uvBias.x * UVSize.x, decalProjector.uvBias.y * UVSize.y) - (Vector2)decalProjector.size * .5f; + + m_UVHandles.center = UVCenter; + m_UVHandles.size = UVSize; + m_UVHandles.DrawRect(dottedLine: true, screenSpaceSize: k_DotLength); + + m_UVHandles.center = default; + m_UVHandles.size = decalProjector.size; + m_UVHandles.DrawRect(dottedLine: false, sickness: 3f); } } } - - Bounds GetBoundsGetter() + + static Func GetBoundsGetter(DecalProjector decalProjector) { - var bounds = new Bounds(); - var decalTransform = ((Component)target).transform; - bounds.Encapsulate(decalTransform.position); - return bounds; + return () => + { + var bounds = new Bounds(); + var decalTransform = decalProjector.transform; + bounds.Encapsulate(decalTransform.position); + return bounds; + }; } public override void OnInspectorGUI() @@ -368,10 +488,8 @@ public override void OnInspectorGUI() { EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); - DoInspectorToolbar(k_EditVolumeModes, editVolumeLabels, GetBoundsGetter, this); - - //[TODO: add editable pivot. Uncomment this when ready] - //DoInspectorToolbar(k_EditPivotModes, editPivotLabels, GetBoundsGetter, this); + DoInspectorToolbar(k_EditVolumeModes, editVolumeLabels, GetBoundsGetter(target as DecalProjector), this); + DoInspectorToolbar(k_EditUVAndPivotModes, editPivotLabels, GetBoundsGetter(target as DecalProjector), this); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); @@ -449,6 +567,16 @@ public override void OnInspectorGUI() } else if (showAffectTransparency) EditorGUILayout.PropertyField(m_AffectsTransparencyProperty, k_AffectTransparentContent); + + EditorGUI.BeginChangeCheck(); + Vector3 previousOffset = m_Offset.vector3Value; + EditorGUILayout.PropertyField(m_Offset); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObjects(targets.SelectMany(t => new[] { t, (t as DecalProjector).transform }).ToArray(), "Decal Projector Offset Change"); + foreach (DecalProjector projector in targets) + projector.transform.position += projector.transform.rotation * (m_Offset.vector3Value - previousOffset); + } } if (EditorGUI.EndChangeCheck()) serializedObject.ApplyModifiedProperties(); @@ -498,35 +626,48 @@ public override void OnInspectorGUI() } } } - + [Shortcut("HDRP/Decal: Handle changing size stretching UV", typeof(SceneView), KeyCode.Keypad1, ShortcutModifiers.Action)] static void EnterEditModeWithoutPreservingUV(ShortcutArguments args) { //If editor is not there, then the selected GameObject does not contains a DecalProjector - if (s_Owner == null || s_Owner.Equals(null)) + DecalProjector activeDecalProjector = Selection.activeGameObject?.GetComponent(); + if (activeDecalProjector == null || activeDecalProjector.Equals(null)) return; - ChangeEditMode(k_EditShapeWithoutPreservingUV, (s_Owner as DecalProjectorEditor).GetBoundsGetter(), s_Owner); + ChangeEditMode(k_EditShapeWithoutPreservingUV, GetBoundsGetter(activeDecalProjector)(), FindEditorFromSelection()); } [Shortcut("HDRP/Decal: Handle changing size cropping UV", typeof(SceneView), KeyCode.Keypad2, ShortcutModifiers.Action)] static void EnterEditModePreservingUV(ShortcutArguments args) { //If editor is not there, then the selected GameObject does not contains a DecalProjector - if (s_Owner == null || s_Owner.Equals(null)) + DecalProjector activeDecalProjector = Selection.activeGameObject?.GetComponent(); + if (activeDecalProjector == null || activeDecalProjector.Equals(null)) return; - ChangeEditMode(k_EditShapePreservingUV, (s_Owner as DecalProjectorEditor).GetBoundsGetter(), s_Owner); + ChangeEditMode(k_EditShapePreservingUV, GetBoundsGetter(activeDecalProjector)(), FindEditorFromSelection()); } + + [Shortcut("HDRP/Decal: Handle changing pivot position and UVs", typeof(SceneView), KeyCode.Keypad3, ShortcutModifiers.Action)] + static void EnterEditModePivotPreservingUV(ShortcutArguments args) + { + //If editor is not there, then the selected GameObject does not contains a DecalProjector + DecalProjector activeDecalProjector = Selection.activeGameObject?.GetComponent(); + if (activeDecalProjector == null || activeDecalProjector.Equals(null)) + return; - //[TODO: add editable pivot. Uncomment this when ready] - //[Shortcut("HDRP/Decal: Handle changing pivot position while preserving UV position", typeof(SceneView), KeyCode.Keypad3, ShortcutModifiers.Action)] - //static void EnterEditModePivotPreservingUV(ShortcutArguments args) => - // ChangeEditMode(k_EditUV, (s_Owner as DecalProjectorComponentEditor).GetBoundsGetter(), s_Owner); + ChangeEditMode(k_EditUVAndPivot, GetBoundsGetter(activeDecalProjector)(), FindEditorFromSelection()); + } [Shortcut("HDRP/Decal: Handle swap between cropping and stretching UV", typeof(SceneView), KeyCode.W, ShortcutModifiers.Action)] static void SwappingEditUVMode(ShortcutArguments args) { + //If editor is not there, then the selected GameObject does not contains a DecalProjector + DecalProjector activeDecalProjector = Selection.activeGameObject?.GetComponent(); + if (activeDecalProjector == null || activeDecalProjector.Equals(null)) + return; + SceneViewEditMode targetMode = SceneViewEditMode.None; switch (editMode) { @@ -538,10 +679,20 @@ static void SwappingEditUVMode(ShortcutArguments args) break; } if (targetMode != SceneViewEditMode.None) - ChangeEditMode(targetMode, (s_Owner as DecalProjectorEditor).GetBoundsGetter(), s_Owner); + ChangeEditMode(targetMode, GetBoundsGetter(activeDecalProjector)(), FindEditorFromSelection()); } [Shortcut("HDRP/Decal: Stop Editing", typeof(SceneView), KeyCode.Keypad0, ShortcutModifiers.Action)] - static void ExitEditMode(ShortcutArguments args) => QuitEditMode(); + static void ExitEditMode(ShortcutArguments args) + { + //If editor is not there, then the selected GameObject does not contains a DecalProjector + DecalProjector activeDecalProjector = Selection.activeGameObject?.GetComponent(); + if (activeDecalProjector == null || activeDecalProjector.Equals(null)) + return; + + QuitEditMode(); + } } } + + diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs new file mode 100644 index 00000000000..60b7a1a4fb4 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs @@ -0,0 +1,273 @@ +using System; +using System.Linq; +using System.Reflection; +using UnityEngine; + +namespace UnityEditor.Rendering.HighDefinition +{ + class DisplacableRectHandles + { + const float k_HandleSizeCoef = 0.05f; + + enum NamedEdge { Right, Top, Left, Bottom, None } + + int[] m_ControlIDs = new int[4] { 0, 0, 0, 0 }; + Color m_MonochromeHandleColor; + Color m_WireframeColor; + Color m_WireframeColorBehind; + + /// The position of the center of the box in Handle.matrix space. On plane z=0. + public Vector2 center { get; set; } + + /// The size of the box in Handle.matrix space. On plane z=0. + public Vector2 size { get; set; } + + //Note: Handles.Slider not allow to use a specific ControlID. + //Thus Slider1D is used (with reflection) + static Type k_Slider1D = Type.GetType("UnityEditorInternal.Slider1D, UnityEditor"); + static MethodInfo k_Slider1D_Do = k_Slider1D + .GetMethod( + "Do", + BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, + null, + CallingConventions.Any, + new[] { typeof(int), typeof(Vector3), typeof(Vector3), typeof(float), typeof(Handles.CapFunction), typeof(float) }, + null); + static void Slider1D(int controlID, ref Vector3 handlePosition, Vector3 handleOrientation, float snapScale) + { + handlePosition = (Vector3)k_Slider1D_Do.Invoke(null, new object[] + { + controlID, + handlePosition, + handleOrientation, + HandleUtility.GetHandleSize(handlePosition) * k_HandleSizeCoef, + new Handles.CapFunction(Handles.DotHandleCap), + snapScale + }); + } + + public DisplacableRectHandles(Color baseTint) + { + baseTint.a = 1f; + m_MonochromeHandleColor = baseTint; + baseTint.a = 0.7f; + m_WireframeColor = baseTint; + baseTint.a = 0.2f; + m_WireframeColorBehind = baseTint; + } + + /// Draw the rect. + public void DrawRect(bool dottedLine = false, float sickness = .0f, float screenSpaceSize = 5f) + { + Vector2 start = center - size * .5f; + Vector3[] positions = new Vector3[] + { + start, + start + size * Vector2.right, + start + size, + start + size * Vector2.up + }; + Vector3[] edges = new Vector3[] + { + positions[0], positions[1], + positions[1], positions[2], + positions[2], positions[3], + positions[3], positions[0], + }; + + void Draw() + { + if (dottedLine) + Handles.DrawDottedLines(edges, screenSpaceSize); + else + { + Handles.DrawLine(positions[0], positions[1], sickness); + Handles.DrawLine(positions[1], positions[2], sickness); + Handles.DrawLine(positions[2], positions[3], sickness); + Handles.DrawLine(positions[3], positions[0], sickness); + } + } + + Color previousColor = Handles.color; + Handles.color = m_WireframeColor; + Handles.zTest = UnityEngine.Rendering.CompareFunction.LessEqual; + Draw(); + Handles.color = m_WireframeColorBehind; + Handles.zTest = UnityEngine.Rendering.CompareFunction.Greater; + Draw(); + Handles.zTest = UnityEngine.Rendering.CompareFunction.Always; + Handles.color = previousColor; + } + + /// Draw the manipulable handles + public void DrawHandle() + { + Event evt = Event.current; + bool useHomothety = evt.shift; + bool useSymetry = evt.alt || evt.command; + // Note: snapping is handled natively on ctrl for each Slider1D + + for (int i = 0, count = m_ControlIDs.Length; i < count; ++i) + m_ControlIDs[i] = GUIUtility.GetControlID("DisplacableRectHandles".GetHashCode() + i, FocusType.Passive); + + Vector3 leftPosition = center + size.x * .5f * Vector2.left; + Vector3 rightPosition = center + size.x * .5f * Vector2.right; + Vector3 topPosition = center + size.y * .5f * Vector2.up; + Vector3 bottomPosition = center + size.y * .5f * Vector2.down; + + var theChangedEdge = NamedEdge.None; + + EditorGUI.BeginChangeCheck(); + using (new Handles.DrawingScope(m_MonochromeHandleColor)) + { + EditorGUI.BeginChangeCheck(); + Slider1D(m_ControlIDs[(int)NamedEdge.Left], ref leftPosition, Vector3.left, EditorSnapSettings.scale); + if (EditorGUI.EndChangeCheck()) + theChangedEdge = NamedEdge.Left; + + EditorGUI.BeginChangeCheck(); + Slider1D(m_ControlIDs[(int)NamedEdge.Right], ref rightPosition, Vector3.right, EditorSnapSettings.scale); + if (EditorGUI.EndChangeCheck()) + theChangedEdge = NamedEdge.Right; + + EditorGUI.BeginChangeCheck(); + Slider1D(m_ControlIDs[(int)NamedEdge.Top], ref topPosition, Vector3.up, EditorSnapSettings.scale); + if (EditorGUI.EndChangeCheck()) + theChangedEdge = NamedEdge.Top; + + EditorGUI.BeginChangeCheck(); + Slider1D(m_ControlIDs[(int)NamedEdge.Bottom], ref bottomPosition, Vector3.down, EditorSnapSettings.scale); + if (EditorGUI.EndChangeCheck()) + theChangedEdge = NamedEdge.Bottom; + } + if (EditorGUI.EndChangeCheck()) + { + float delta = 0f; + switch (theChangedEdge) + { + case NamedEdge.Left: delta = ((Vector2)leftPosition - center - size.x * .5f * Vector2.left).x; break; + case NamedEdge.Right: delta = -((Vector2)rightPosition - center - size.x * .5f * Vector2.right).x; break; + case NamedEdge.Top: delta = -((Vector2)topPosition - center - size.y * .5f * Vector2.up).y; break; + case NamedEdge.Bottom: delta = ((Vector2)bottomPosition - center - size.y * .5f * Vector2.down).y; break; + } + + if (useHomothety && useSymetry) + { + var tempSize = size - Vector2.one * delta; + + //ensure that the rect edges are still facing outside + for (int axis = 0; axis < 3; ++axis) + { + if (tempSize[axis] < 0) + { + delta += tempSize[axis]; + tempSize = size - Vector2.one * delta; + } + } + + size = tempSize; + } + else + { + if (useSymetry) + { + switch (theChangedEdge) + { + case NamedEdge.Left: rightPosition.x -= delta; break; + case NamedEdge.Right: leftPosition.x += delta; break; + case NamedEdge.Top: bottomPosition.y += delta; break; + case NamedEdge.Bottom: topPosition.y -= delta; break; + } + + //ensure that the rect edges are still facing outside + switch (theChangedEdge) + { + case NamedEdge.Left: + case NamedEdge.Right: + if (rightPosition.x < leftPosition.x) + rightPosition.x = leftPosition.x = center.x; + break; + case NamedEdge.Top: + case NamedEdge.Bottom: + if (topPosition.y < bottomPosition.y) + topPosition.y = bottomPosition.y = center.y; + break; + } + } + + if (useHomothety) + { + float halfDelta = delta * 0.5f; + switch (theChangedEdge) + { + case NamedEdge.Left: + case NamedEdge.Right: + bottomPosition.y += halfDelta; + topPosition.y -= halfDelta; + break; + case NamedEdge.Top: + case NamedEdge.Bottom: + rightPosition.x -= halfDelta; + leftPosition.x += halfDelta; + break; + } + + //ensure that the rect edges are still facing outside + switch (theChangedEdge) + { + case NamedEdge.Left: + if (rightPosition.x < leftPosition.x) + leftPosition.x = rightPosition.x; + if (topPosition.y < bottomPosition.y) + topPosition.y = bottomPosition.y = center.y; + break; + case NamedEdge.Right: + if (rightPosition.x < leftPosition.x) + rightPosition.x = leftPosition.x; + if (topPosition.y < bottomPosition.y) + topPosition.y = bottomPosition.y = center.y; + break; + case NamedEdge.Top: + if (topPosition.y < bottomPosition.y) + topPosition.y = bottomPosition.y; + if (rightPosition.x < leftPosition.x) + rightPosition.x = leftPosition.x = center.x; + break; + case NamedEdge.Bottom: + if (topPosition.y < bottomPosition.y) + bottomPosition.y = topPosition.y; + if (rightPosition.x < leftPosition.x) + rightPosition.x = leftPosition.x = center.x; + break; + } + } + + var max = new Vector2(rightPosition.x, topPosition.y); + var min = new Vector2(leftPosition.x, bottomPosition.y); + + if (!useSymetry && !useHomothety) + { + //ensure that the rect edges are still facing outside + for (int axis = 0; axis < 2; ++axis) + { + if (min[axis] > max[axis]) + { + // Control IDs in m_ControlIDs[0-3[ are for positive axes + if (GUIUtility.hotControl == m_ControlIDs[axis]) + max[axis] = min[axis]; + else + min[axis] = max[axis]; + } + } + } + + center = (max + min) * .5f; + size = max - min; + } + } + } + + + internal string debug => $"center:({center.x},{center.y}) size:({size.x},{size.y})"; + } +} diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs.meta b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs.meta new file mode 100644 index 00000000000..335e9f208c5 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ec7aa4f206331154bacd45514acb99b1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs new file mode 100644 index 00000000000..9fce48315e7 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs @@ -0,0 +1,254 @@ +using System; +using System.Linq.Expressions; +using System.Reflection; +using UnityEditor; + +namespace UnityEngine.Rendering.HighDefinition +{ + class ProjectedTransform + { + struct PositionHandleIds + { + static int s_xAxisMoveHandleHash = "xAxisDecalPivot".GetHashCode(); + static int s_yAxisMoveHandleHash = "yAxisDecalPivot".GetHashCode(); + static int s_zAxisMoveHandleHash = "zAxisDecalPivot".GetHashCode(); + static int s_xyAxisMoveHandleHash = "xyAxisDecalPivot".GetHashCode(); + + public static PositionHandleIds @default + { + get + { + return new PositionHandleIds( + GUIUtility.GetControlID(s_xAxisMoveHandleHash, FocusType.Passive), + GUIUtility.GetControlID(s_yAxisMoveHandleHash, FocusType.Passive), + GUIUtility.GetControlID(s_zAxisMoveHandleHash, FocusType.Passive), + GUIUtility.GetControlID(s_xyAxisMoveHandleHash, FocusType.Passive) + ); + } + } + + public readonly int x, y, z, xy; + + public int this[int index] + { + get + { + switch (index) + { + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return xy; + } + return -1; + } + } + + public bool Has(int id) + { + return x == id + || y == id + || z == id + || xy == id; + } + + public PositionHandleIds(int x, int y, int z, int xy) + { + this.x = x; + this.y = y; + this.z = z; + this.xy = xy; + } + + public override int GetHashCode() + { + return x ^ y ^ z ^ xy; + } + + public override bool Equals(object obj) + { + if (!(obj is PositionHandleIds)) + return false; + + var o = (PositionHandleIds)obj; + return o.x == x && o.y == y && o.z == z && o.xy == xy; + } + } + + struct PositionHandleParam + { + public static PositionHandleParam defaultHandleXY = new PositionHandleParam( + Handle.X | Handle.Y | Handle.XY, + Vector3.zero, Vector3.one, Vector3.zero, Vector3.one * .25f, + Orientation.Signed, Orientation.Camera); + + public static PositionHandleParam defaultHandleZ = new PositionHandleParam( + Handle.Z, + Vector3.zero, Vector3.one, Vector3.zero, Vector3.one * .25f, + Orientation.Signed, Orientation.Camera); + + [Flags] + public enum Handle + { + None = 0, + X = 1 << 0, + Y = 1 << 1, + Z = 1 << 2, + XY = 1 << 3, + All = ~None + } + + public enum Orientation + { + Signed, + Camera + } + + public readonly Vector3 axisOffset; + public readonly Vector3 axisSize; + public readonly Vector3 planeOffset; + public readonly Vector3 planeSize; + public readonly Handle handles; + public readonly Orientation axesOrientation; + public readonly Orientation planeOrientation; + + public bool ShouldShow(int axis) + { + return (handles & (Handle)(1 << axis)) != 0; + } + + public bool ShouldShow(Handle handle) + { + return (handles & handle) != 0; + } + + public PositionHandleParam( + Handle handles, + Vector3 axisOffset, + Vector3 axisSize, + Vector3 planeOffset, + Vector3 planeSize, + Orientation axesOrientation, + Orientation planeOrientation) + { + this.axisOffset = axisOffset; + this.axisSize = axisSize; + this.planeOffset = planeOffset; + this.planeSize = planeSize; + this.handles = handles; + this.axesOrientation = axesOrientation; + this.planeOrientation = planeOrientation; + } + } + + static PositionHandleParam paramXY = PositionHandleParam.defaultHandleXY; + static PositionHandleParam paramZ = PositionHandleParam.defaultHandleZ; + static PositionHandleIds ids = PositionHandleIds.@default; + + static int[] s_DoPositionHandle_Internal_NextIndex = { 1, 2, 0 }; + static int[] s_DoPositionHandle_Internal_PrevIndex = { 2, 0, 1 }; + static Vector3[] verts = { Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero }; + + static Func s_IsGridSnappingActive; + + + static ProjectedTransform() + { + Type gridSnappingType = typeof(Handles).Assembly.GetType("UnityEditor.GridSnapping"); + PropertyInfo activePropertyInfo = gridSnappingType.GetProperty("active", BindingFlags.Public | BindingFlags.Static); + MethodCallExpression activePropertyGetCall = Expression.Call(null, activePropertyInfo.GetGetMethod()); + var activeGetLambda = Expression.Lambda>(activePropertyGetCall); + s_IsGridSnappingActive = activeGetLambda.Compile(); + } + + static bool IsHovering(int controlID, Event evt) + { + return controlID == HandleUtility.nearestControl && GUIUtility.hotControl == 0 && !Tools.viewToolActive; + } + + //position = decalProjector.transform.position + //zProjectionDistance = decalProjector.offset.z + //rotation = decalProjector.transform.rotation + public static Vector3 DrawHandles(Vector3 position, float zProjectionDistance, Quaternion rotation) + { + //using (new Handles.DrawingScope(Color.white, Matrix4x4.TRS(Vector3.zero, rotation, Vector3.one))) + //{ + var isHot = ids.Has(GUIUtility.hotControl); + var planeSize = isHot ? paramXY.planeSize + paramXY.planeOffset : paramXY.planeSize; + var planarSize = Mathf.Max(planeSize[0], planeSize[s_DoPositionHandle_Internal_NextIndex[0]]); + Vector3 sliderRotatedWorldPos = Quaternion.Inverse(rotation) * position; + var size1D = HandleUtility.GetHandleSize(sliderRotatedWorldPos); + var size2D = HandleUtility.GetHandleSize(sliderRotatedWorldPos - new Vector3(0, 0, zProjectionDistance)) * planarSize * .5f; + Vector3 depthSlider = sliderRotatedWorldPos; + + EditorGUI.BeginChangeCheck(); + { + // dot offset = transform position seen as a sphere + EditorGUI.BeginChangeCheck(); + depthSlider = Handles.Slider(depthSlider, Vector3.forward, size1D * .1f, Handles.SphereHandleCap, -1); + if (EditorGUI.EndChangeCheck()) + sliderRotatedWorldPos.z = depthSlider.z; + + // 2D slider: square xy-axis + Vector3 sliderFaceProjected = sliderRotatedWorldPos - new Vector3(0, 0, zProjectionDistance); + sliderFaceProjected.x += size2D; + sliderFaceProjected.y += size2D; + using (new Handles.DrawingScope(Handles.zAxisColor)) + { + verts[0] = sliderFaceProjected + (Vector3.right + Vector3.up) * size2D; + verts[1] = sliderFaceProjected + (-Vector3.right + Vector3.up) * size2D; + verts[2] = sliderFaceProjected + (-Vector3.right - Vector3.up) * size2D; + verts[3] = sliderFaceProjected + (Vector3.right - Vector3.up) * size2D; + float faceOpacity = 0.8f; + if (GUIUtility.hotControl == ids.xy) + Handles.color = Handles.selectedColor; + else if (IsHovering(ids.xy, Event.current)) + faceOpacity = 0.4f; + else + faceOpacity = 0.1f; + Color faceColor = new Color(Handles.zAxisColor.r, Handles.zAxisColor.g, Handles.zAxisColor.b, Handles.zAxisColor.a * faceOpacity); + Handles.DrawSolidRectangleWithOutline(verts, faceColor, Color.clear); + EditorGUI.BeginChangeCheck(); + sliderFaceProjected = Handles.Slider2D(ids.xy, sliderFaceProjected, Vector3.forward, Vector3.right, Vector3.up, size2D, Handles.RectangleHandleCap, s_IsGridSnappingActive() ? Vector2.zero : new Vector2(EditorSnapSettings.move[0], EditorSnapSettings.move[1]), false); + if (EditorGUI.EndChangeCheck()) + { + sliderRotatedWorldPos.x = sliderFaceProjected.x; + sliderRotatedWorldPos.y = sliderFaceProjected.y; + } + } + sliderFaceProjected.x -= size2D; + sliderFaceProjected.y -= size2D; + + // 2D slider: x-axis + EditorGUI.BeginChangeCheck(); + using (new Handles.DrawingScope(Handles.xAxisColor)) + sliderFaceProjected = Handles.Slider(sliderFaceProjected, Vector3.right); + if (EditorGUI.EndChangeCheck()) + sliderRotatedWorldPos.x = sliderFaceProjected.x; + + // 2D slider: y-axis + EditorGUI.BeginChangeCheck(); + using (new Handles.DrawingScope(Handles.yAxisColor)) + sliderFaceProjected = Handles.Slider(sliderFaceProjected, Vector3.up); + if (EditorGUI.EndChangeCheck()) + sliderRotatedWorldPos.y = sliderFaceProjected.y; + + // depth: z-axis + EditorGUI.BeginChangeCheck(); + using (new Handles.DrawingScope(Handles.zAxisColor)) + depthSlider = Handles.Slider(depthSlider, Vector3.forward); + if (EditorGUI.EndChangeCheck()) + sliderRotatedWorldPos.z = depthSlider.z; + } + if (EditorGUI.EndChangeCheck()) + { + position = rotation * sliderRotatedWorldPos; + } + + return position; + //} + } + + + } +} diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs.meta b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs.meta new file mode 100644 index 00000000000..c25147271e6 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1955ced6df3d87641b9abc7588ca00da +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 3d189b3210a2c19bdcb6ea2560465faaae945b87 Mon Sep 17 00:00:00 2001 From: RSlysz Date: Wed, 6 Jan 2021 09:51:38 +0100 Subject: [PATCH 02/20] clean --- .../Material/Decal/DecalProjectorEditor.cs | 79 ++----------------- 1 file changed, 7 insertions(+), 72 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs index de4a0755be1..ef569f99187 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs @@ -129,40 +129,22 @@ static DecalProjectorEditor FindEditorFromSelection() foreach (DecalProjectorEditor editor in s_Instances) { - Debug.Log("Check Start"); if (selectionTargets.Length != editor.targets.Length) - { - Debug.Log("Length missmatch"); continue; - } bool allOk = true; foreach (DecalProjector selectionTarget in selectionTargets) if (!Array.Find(editor.targets, t => t == selectionTarget)) { - Debug.Log("Missing " + selectionTarget); allOk = false; break; } if (!allOk) continue; - Debug.Log("All good"); return editor; } return null; } - static DecalProjectorEditor() - { - Type TransformHandleIdsType = Type.GetType("UnityEditor.Handles.TransformHandleIds, UnityEditor"); - var transformTranslationXHash = Expression.Variable(typeof(int), "TransformTranslationXHash"); - var transformTranslationYHash = Expression.Variable(typeof(int), "TransformTranslationYHash"); - var transformTranslationXYHash = Expression.Variable(typeof(int), "TransformTranslationXYHash"); - Type transformHandleParamType = Type.GetType("UnityEditor.Handles.TransformHandleParam, UnityEditor"); - //var transformHandleParam = Expression.Variable(transformHandleParamType, "TransformHandleParam"); - - } - - private void OnEnable() { s_Instances.Add(this); @@ -262,8 +244,6 @@ void DrawHandles() { using (new Handles.DrawingScope(Color.white, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, Vector3.one))) { - bool needToRefreshDecalProjector = false; - Vector3 centerStart = new Vector3( -decalProjector.offset.x, -decalProjector.offset.y, @@ -278,8 +258,6 @@ void DrawHandles() boxHandle.DrawHandle(); if (EditorGUI.EndChangeCheck()) { - needToRefreshDecalProjector = true; - // Adjust decal transform if handle changed. Undo.RecordObjects(new UnityEngine.Object[] { decalProjector, decalProjector.transform }, "Decal Projector Change"); @@ -308,32 +286,7 @@ void DrawHandles() { PrefabUtility.RecordPrefabInstancePropertyModifications(decalProjector); } - } - - // Automatically recenter our transform component if necessary. - // In order to correctly handle world-space snapping, we only perform this recentering when the user is no longer interacting with the gizmo. - //if (GUIUtility.hotControl == 0 && decalProjector.offset != Vector3.zero) - //{ - // needToRefreshDecalProjector = true; - - // // Both the DecalProjectorComponent, and the transform will be modified. - // // The undo system will automatically group all RecordObject() calls here into a single action. - // Undo.RecordObject(decalProjector.transform, "Decal Projector Change"); - - // // Re-center the transform to the center of the decal projector bounds, - // // while maintaining the world-space coordinates of the decal projector boundings vertices. - // // Center of the decal projector is not the same of the HierarchicalBox as we want it to be on the z face as lights - // decalProjector.transform.Translate(decalProjector.offset + new Vector3(0f, 0f, handle.size.z * -0.5f), Space.Self); - - // decalProjector.offset = new Vector3(0f, 0f, handle.size.z * 0.5f); - // if (PrefabUtility.IsPartOfNonAssetPrefabInstance(decalProjector)) - // { - // PrefabUtility.RecordPrefabInstancePropertyModifications(decalProjector); - // } - //} - - if (needToRefreshDecalProjector) - { + // Smoothly update the decal image projected DecalSystem.instance.UpdateCachedData(decalProjector.Handle, decalProjector.GetCachedDecalData()); } @@ -355,9 +308,6 @@ void DrawHandles() } // UV - //using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position - decalProjector.transform.rotation * (new Vector3(decalProjector.size.x * 0.5f, decalProjector.size.y * 0.5f, 0) + decalProjector.offset), decalProjector.transform.rotation, Vector3.one))) - //Vector3 drawingSpaceOrigin = decalProjector.transform.position - decalProjector.transform.rotation * (new Vector3(decalProjector.size.x * 0.5f, decalProjector.size.y * 0.5f, 0) + decalProjector.offset); - //float drawingSpaceZRotated = (Quaternion.Inverse(decalProjector.transform.rotation) * decalProjector.transform.position).z + decalProjector.offset.z; Vector3 drawingSpaceOriginRotated = Quaternion.Inverse(decalProjector.transform.rotation) * decalProjector.transform.position - new Vector3(decalProjector.size.x * 0.5f, decalProjector.size.y * 0.5f, 0) + decalProjector.offset; using (new Handles.DrawingScope(Matrix4x4.TRS(Vector3.zero, decalProjector.transform.rotation, Vector3.one))) { @@ -370,19 +320,14 @@ void DrawHandles() m_UVHandles.center = UVCenter; m_UVHandles.size = UVSize; - - string debugBefore = m_UVHandles.debug; - + EditorGUI.BeginChangeCheck(); m_UVHandles.DrawHandle(); if (EditorGUI.EndChangeCheck()) { - Debug.Log($"Rect changed {debugBefore} -> {m_UVHandles.debug}"); Vector2 limit = new Vector2(Mathf.Abs(decalProjector.size.x * k_LimitInv), Mathf.Abs(decalProjector.size.y * k_LimitInv)); - Debug.Log($"Limit:({limit.x},{limit.y})"); Vector2 uvScale = m_UVHandles.size; - Debug.Log($"local uvScale before:({uvScale.x},{uvScale.y})"); for (int channel = 0; channel < 2; channel++) { if (Mathf.Abs(uvScale[channel]) > limit[channel]) @@ -390,28 +335,18 @@ void DrawHandles() else uvScale[channel] = Mathf.Sign(decalProjector.size[channel]) * Mathf.Sign(uvScale[channel]) * k_Limit; } - Debug.Log($"local uvScale after:({uvScale.x},{uvScale.y})"); - - Vector2 debugUvScale = decalProjector.uvScale; - Vector2 debugUvBias = decalProjector.uvBias; - decalProjector.uvScale = uvScale; - Debug.Log($"uvScale ({debugUvScale.x},{debugUvScale.y})->({decalProjector.uvScale.x},{decalProjector.uvScale.y})"); var newUVStart = m_UVHandles.center - .5f * m_UVHandles.size - (Vector2)drawingSpaceOriginRotated; decalProjector.uvBias = -new Vector2( m_UVHandles.size.x < k_LimitInv && m_UVHandles.size.x > -k_LimitInv ? k_Limit * newUVStart.x / decalProjector.size.x : newUVStart.x / m_UVHandles.size.x, m_UVHandles.size.y < k_LimitInv && m_UVHandles.size.y > -k_LimitInv ? k_Limit * newUVStart.y / decalProjector.size.y : newUVStart.y / m_UVHandles.size.y ); - Debug.Log($"uvBias {D(debugUvBias)}->{D(decalProjector.uvBias)} UVCenter:{D(UVCenter)} UVSize:{D(UVSize)} UVStart:{D(UVStart)} newUVStart:{D(newUVStart)}"); } } } } - static string D(Vector2 a) => $"({a.x},{a.y})"; - - [DrawGizmo(GizmoType.Selected | GizmoType.Active)] static void DrawGizmosSelected(DecalProjector decalProjector, GizmoType gizmoType) { @@ -428,7 +363,7 @@ static void DrawGizmosSelected(DecalProjector decalProjector, GizmoType gizmoTyp bool isVolumeEditMode = editMode == k_EditShapePreservingUV || editMode == k_EditShapeWithoutPreservingUV; bool isPivotEditMode = editMode == k_EditUVAndPivot; boxHandle.DrawHull(isVolumeEditMode); - + Vector3 pivot = Vector3.zero; Vector3 projectedPivot = new Vector3(0, 0, -decalProjector.offset.z); @@ -455,14 +390,14 @@ static void DrawGizmosSelected(DecalProjector decalProjector, GizmoType gizmoTyp m_UVHandles.center = UVCenter; m_UVHandles.size = UVSize; m_UVHandles.DrawRect(dottedLine: true, screenSpaceSize: k_DotLength); - + m_UVHandles.center = default; m_UVHandles.size = decalProjector.size; m_UVHandles.DrawRect(dottedLine: false, sickness: 3f); } } } - + static Func GetBoundsGetter(DecalProjector decalProjector) { return () => @@ -626,7 +561,7 @@ public override void OnInspectorGUI() } } } - + [Shortcut("HDRP/Decal: Handle changing size stretching UV", typeof(SceneView), KeyCode.Keypad1, ShortcutModifiers.Action)] static void EnterEditModeWithoutPreservingUV(ShortcutArguments args) { @@ -648,7 +583,7 @@ static void EnterEditModePreservingUV(ShortcutArguments args) ChangeEditMode(k_EditShapePreservingUV, GetBoundsGetter(activeDecalProjector)(), FindEditorFromSelection()); } - + [Shortcut("HDRP/Decal: Handle changing pivot position and UVs", typeof(SceneView), KeyCode.Keypad3, ShortcutModifiers.Action)] static void EnterEditModePivotPreservingUV(ShortcutArguments args) { From eadb3a1b92ccb469947b4f6ad7edcf36e14da11b Mon Sep 17 00:00:00 2001 From: RSlysz Date: Wed, 6 Jan 2021 09:53:42 +0100 Subject: [PATCH 03/20] update offset in inspector --- .../Material/Decal/DecalProjectorEditor.Skin.cs | 1 + .../Editor/Material/Decal/DecalProjectorEditor.cs | 12 ++---------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs index 98a337c4a73..8886fc17f99 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs @@ -24,6 +24,7 @@ partial class DecalProjectorEditor static readonly GUIContent k_UVBiasContent = EditorGUIUtility.TrTextContent("Offset", "Sets the offset for the decal Material. Moves the decal along its UV axes."); static readonly GUIContent k_FadeFactorContent = EditorGUIUtility.TrTextContent("Fade Factor", "Controls the transparency of the decal."); static readonly GUIContent k_AffectTransparentContent = EditorGUIUtility.TrTextContent("Affects Transparent", "When enabled, HDRP draws this projector's decal on top of transparent surfaces."); + static readonly GUIContent k_Offset = EditorGUIUtility.TrTextContent("Pivot", "Controls the position of the pivot point of the decal."); public static readonly Color k_GizmoColorBase = Color.white; public static readonly Color[] k_BaseHandlesColor = new Color[] diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs index ef569f99187..946865b17c7 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs @@ -452,6 +452,8 @@ public override void OnInspectorGUI() m_OffsetZ.floatValue = m_SizeValues[2].floatValue * 0.5f; } + EditorGUILayout.PropertyField(m_Offset, k_Offset); + EditorGUILayout.PropertyField(m_MaterialProperty, k_MaterialContent); bool decalLayerEnabled = false; @@ -502,16 +504,6 @@ public override void OnInspectorGUI() } else if (showAffectTransparency) EditorGUILayout.PropertyField(m_AffectsTransparencyProperty, k_AffectTransparentContent); - - EditorGUI.BeginChangeCheck(); - Vector3 previousOffset = m_Offset.vector3Value; - EditorGUILayout.PropertyField(m_Offset); - if (EditorGUI.EndChangeCheck()) - { - Undo.RecordObjects(targets.SelectMany(t => new[] { t, (t as DecalProjector).transform }).ToArray(), "Decal Projector Offset Change"); - foreach (DecalProjector projector in targets) - projector.transform.position += projector.transform.rotation * (m_Offset.vector3Value - previousOffset); - } } if (EditorGUI.EndChangeCheck()) serializedObject.ApplyModifiedProperties(); From 03fe6773f284ccb33b33e440f162cd02e3a5b990 Mon Sep 17 00:00:00 2001 From: RSlysz Date: Wed, 6 Jan 2021 09:54:57 +0100 Subject: [PATCH 04/20] Fix handle local coordinate systems --- .../Material/Decal/DecalProjectorEditor.cs | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs index 946865b17c7..11f6959f54d 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs @@ -244,10 +244,7 @@ void DrawHandles() { using (new Handles.DrawingScope(Color.white, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, Vector3.one))) { - Vector3 centerStart = new Vector3( - -decalProjector.offset.x, - -decalProjector.offset.y, - decalProjector.size.z * .5f - decalProjector.offset.z); + Vector3 centerStart = decalProjector.offset; boxHandle.center = centerStart; boxHandle.size = decalProjector.size; @@ -299,24 +296,22 @@ void DrawHandles() using (new Handles.DrawingScope(Color.white, Matrix4x4.TRS(Vector3.zero, decalProjector.transform.rotation, Vector3.one))) { EditorGUI.BeginChangeCheck(); - Vector3 newPosition = ProjectedTransform.DrawHandles(decalProjector.transform.position, decalProjector.offset.z, decalProjector.transform.rotation); + Vector3 newPosition = ProjectedTransform.DrawHandles(decalProjector.transform.position, .5f * decalProjector.size.z - decalProjector.offset.z, decalProjector.transform.rotation); if (EditorGUI.EndChangeCheck()) { - decalProjector.offset -= Quaternion.Inverse(decalProjector.transform.rotation) * (decalProjector.transform.position - newPosition); + decalProjector.offset += Quaternion.Inverse(decalProjector.transform.rotation) * (decalProjector.transform.position - newPosition); decalProjector.transform.position = newPosition; } } // UV - Vector3 drawingSpaceOriginRotated = Quaternion.Inverse(decalProjector.transform.rotation) * decalProjector.transform.position - new Vector3(decalProjector.size.x * 0.5f, decalProjector.size.y * 0.5f, 0) + decalProjector.offset; - using (new Handles.DrawingScope(Matrix4x4.TRS(Vector3.zero, decalProjector.transform.rotation, Vector3.one))) + using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position + decalProjector.transform.rotation * (decalProjector.offset - .5f * decalProjector.size), decalProjector.transform.rotation, Vector3.one))) { Vector2 UVSize = new Vector2( decalProjector.uvScale.x > k_Limit || decalProjector.uvScale.x < -k_Limit ? 0f : decalProjector.size.x / decalProjector.uvScale.x, decalProjector.uvScale.y > k_Limit || decalProjector.uvScale.y < -k_Limit ? 0f : decalProjector.size.y / decalProjector.uvScale.y ); - Vector2 UVStart = -new Vector2(decalProjector.uvBias.x * UVSize.x, decalProjector.uvBias.y * UVSize.y); - Vector2 UVCenter = UVStart + UVSize * 0.5f + (Vector2)drawingSpaceOriginRotated; + Vector2 UVCenter = UVSize * .5f - new Vector2(decalProjector.uvBias.x * UVSize.x, decalProjector.uvBias.y * UVSize.y); m_UVHandles.center = UVCenter; m_UVHandles.size = UVSize; @@ -336,8 +331,8 @@ void DrawHandles() uvScale[channel] = Mathf.Sign(decalProjector.size[channel]) * Mathf.Sign(uvScale[channel]) * k_Limit; } decalProjector.uvScale = uvScale; - - var newUVStart = m_UVHandles.center - .5f * m_UVHandles.size - (Vector2)drawingSpaceOriginRotated; + + var newUVStart = m_UVHandles.center - .5f * m_UVHandles.size; decalProjector.uvBias = -new Vector2( m_UVHandles.size.x < k_LimitInv && m_UVHandles.size.x > -k_LimitInv ? k_Limit * newUVStart.x / decalProjector.size.x : newUVStart.x / m_UVHandles.size.x, m_UVHandles.size.y < k_LimitInv && m_UVHandles.size.y > -k_LimitInv ? k_Limit * newUVStart.y / decalProjector.size.y : newUVStart.y / m_UVHandles.size.y @@ -355,17 +350,14 @@ static void DrawGizmosSelected(DecalProjector decalProjector, GizmoType gizmoTyp //draw them scale independent using (new Handles.DrawingScope(Color.white, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, Vector3.one))) { - boxHandle.center = new Vector3( - -decalProjector.offset.x, - -decalProjector.offset.y, - decalProjector.size.z * .5f - decalProjector.offset.z); + boxHandle.center = decalProjector.offset; boxHandle.size = decalProjector.size; bool isVolumeEditMode = editMode == k_EditShapePreservingUV || editMode == k_EditShapeWithoutPreservingUV; bool isPivotEditMode = editMode == k_EditUVAndPivot; boxHandle.DrawHull(isVolumeEditMode); Vector3 pivot = Vector3.zero; - Vector3 projectedPivot = new Vector3(0, 0, -decalProjector.offset.z); + Vector3 projectedPivot = new Vector3(0, 0, decalProjector.offset.z - .5f * decalProjector.size.z); if (isPivotEditMode) { @@ -379,7 +371,7 @@ static void DrawGizmosSelected(DecalProjector decalProjector, GizmoType gizmoTyp } //draw UV and bolder edges - using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position - decalProjector.transform.rotation * decalProjector.offset, decalProjector.transform.rotation, Vector3.one))) + using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position + decalProjector.transform.rotation * new Vector3(decalProjector.offset.x, decalProjector.offset.y, decalProjector.offset.z - .5f * decalProjector.size.z), decalProjector.transform.rotation, Vector3.one))) { Vector2 UVSize = new Vector2( decalProjector.uvScale.x > k_Limit || decalProjector.uvScale.x < -k_Limit ? 0f : decalProjector.size.x / decalProjector.uvScale.x, From 5b48a5f4e0c45d1ee86ac2f860e54b4bc48bd77d Mon Sep 17 00:00:00 2001 From: RSlysz Date: Wed, 6 Jan 2021 09:55:51 +0100 Subject: [PATCH 05/20] Add missing Undo --- .../Editor/Material/Decal/DecalProjectorEditor.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs index 11f6959f54d..1ffcc746d74 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs @@ -299,6 +299,8 @@ void DrawHandles() Vector3 newPosition = ProjectedTransform.DrawHandles(decalProjector.transform.position, .5f * decalProjector.size.z - decalProjector.offset.z, decalProjector.transform.rotation); if (EditorGUI.EndChangeCheck()) { + Undo.RecordObjects(new UnityEngine.Object[] { decalProjector, decalProjector.transform }, "Decal Projector Change"); + decalProjector.offset += Quaternion.Inverse(decalProjector.transform.rotation) * (decalProjector.transform.position - newPosition); decalProjector.transform.position = newPosition; } @@ -320,6 +322,7 @@ void DrawHandles() m_UVHandles.DrawHandle(); if (EditorGUI.EndChangeCheck()) { + Undo.RecordObject(decalProjector, "Decal Projector Change"); Vector2 limit = new Vector2(Mathf.Abs(decalProjector.size.x * k_LimitInv), Mathf.Abs(decalProjector.size.y * k_LimitInv)); Vector2 uvScale = m_UVHandles.size; From e42c5906494270e160ffc369da97f8dafc3f03ad Mon Sep 17 00:00:00 2001 From: RSlysz Date: Wed, 6 Jan 2021 14:48:51 +0100 Subject: [PATCH 06/20] Had color and opacity in preferences --- .../Editor/Gizmo/HierarchicalBox.cs | 26 +++-- .../Decal/DecalProjectorEditor.Skin.cs | 11 +-- .../Material/Decal/DecalProjectorEditor.cs | 96 ++++++++++++++----- .../Material/Decal/DisplacableRectHandles.cs | 24 +++-- 4 files changed, 109 insertions(+), 48 deletions(-) diff --git a/com.unity.render-pipelines.core/Editor/Gizmo/HierarchicalBox.cs b/com.unity.render-pipelines.core/Editor/Gizmo/HierarchicalBox.cs index e0dbb33c4e8..bb304646dd0 100644 --- a/com.unity.render-pipelines.core/Editor/Gizmo/HierarchicalBox.cs +++ b/com.unity.render-pipelines.core/Editor/Gizmo/HierarchicalBox.cs @@ -115,17 +115,27 @@ public Color baseColor set { value.a = 8f / 255; - m_MonochromeFillColor = value; - material.color = m_MonochromeFillColor; - value.a = 1f; - m_MonochromeHandleColor = value; - value.a = 0.7f; - m_WireframeColor = value; - value.a = 0.2f; - m_WireframeColorBehind = value; + SetBaseColorWithoutIntensityChange(value); } } + /// + /// Set the baseColor used to fill hull. All other colors are deduced from it except specific handle colors. + /// Instead of baseColor set, this will not force the opacity and keep what is provided for the filled faces. + /// + /// The color to use + public void SetBaseColorWithoutIntensityChange(Color color) + { + m_MonochromeFillColor = color; + material.color = m_MonochromeFillColor; + color.a = 1f; + m_MonochromeHandleColor = color; + color.a = 0.7f; + m_WireframeColor = color; + color.a = 0.2f; + m_WireframeColorBehind = color; + } + //Note: Handles.Slider not allow to use a specific ControlID. //Thus Slider1D is used (with reflection) static Type k_Slider1D = Type.GetType("UnityEditorInternal.Slider1D, UnityEditor"); diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs index 8886fc17f99..dfe11be103a 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs @@ -26,15 +26,6 @@ partial class DecalProjectorEditor static readonly GUIContent k_AffectTransparentContent = EditorGUIUtility.TrTextContent("Affects Transparent", "When enabled, HDRP draws this projector's decal on top of transparent surfaces."); static readonly GUIContent k_Offset = EditorGUIUtility.TrTextContent("Pivot", "Controls the position of the pivot point of the decal."); - public static readonly Color k_GizmoColorBase = Color.white; - public static readonly Color[] k_BaseHandlesColor = new Color[] - { - Color.white, - Color.white, - Color.white, - Color.white, - Color.white, - Color.white - }; + public static readonly Color k_GizmoColorBase = new Color(1, 1, 1, 8f/255); } } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs index 1ffcc746d74..3ed87c63712 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs @@ -1,13 +1,12 @@ using UnityEngine; -using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using UnityEditor.ShortcutManagement; using static UnityEditorInternal.EditMode; using UnityEditor.IMGUI.Controls; using System; -using System.Linq; -using System.Linq.Expressions; using System.Collections.Generic; +using System.Reflection; +using System.Linq.Expressions; namespace UnityEditor.Rendering.HighDefinition { @@ -17,7 +16,45 @@ partial class DecalProjectorEditor : Editor { const float k_Limit = 100000; const float k_LimitInv = 1 / k_Limit; + + static object s_ColorPref; + static Func GetColorPref; + static Color fullColor + { + get + { + Color c = s_LastColor; + c.a = 1; + return c; + } + } + static Color s_LastColor; + static void UpdateColorsInHandlesIfRequired() + { + Color c = GetColorPref(); + if (c != s_LastColor) + { + if (s_BoxHandle != null && !s_BoxHandle.Equals(null)) + s_BoxHandle = null; + + if (s_UVHandles != null && !s_UVHandles.Equals(null)) + s_UVHandles.baseColor = c; + + s_LastColor = c; + } + } + static DecalProjectorEditor() + { + Type prefColorType = typeof(Editor).Assembly.GetType("UnityEditor.PrefColor"); + s_ColorPref = Activator.CreateInstance(prefColorType, new object[] { "HDRP/Decal", k_GizmoColorBase.r, k_GizmoColorBase.g, k_GizmoColorBase.b, k_GizmoColorBase.a }); + ParameterExpression colorParameter = Expression.Parameter(prefColorType, "color"); + PropertyInfo colorInfo = prefColorType.GetProperty("Color"); + MemberExpression colorProperty = Expression.Property(Expression.Constant(s_ColorPref, prefColorType), colorInfo); + Expression> colorLambda = Expression.Lambda>(colorProperty); + GetColorPref = colorLambda.Compile(); + } + MaterialEditor m_MaterialEditor = null; SerializedProperty m_MaterialProperty; SerializedProperty m_DrawDistanceProperty; @@ -81,14 +118,25 @@ static HierarchicalBox boxHandle { if (s_BoxHandle == null || s_BoxHandle.Equals(null)) { - s_BoxHandle = new HierarchicalBox(k_GizmoColorBase, k_BaseHandlesColor); + Color c = fullColor; + s_BoxHandle = new HierarchicalBox(s_LastColor, new []{ c, c, c, c, c, c }); + s_BoxHandle.SetBaseColorWithoutIntensityChange(s_LastColor); s_BoxHandle.monoHandle = false; } return s_BoxHandle; } } - static DisplacableRectHandles m_UVHandles = new DisplacableRectHandles(Color.white); + static DisplacableRectHandles s_UVHandles; + static DisplacableRectHandles UVHandles + { + get + { + if (s_UVHandles == null || s_UVHandles.Equals(null)) + s_UVHandles = new DisplacableRectHandles(s_LastColor); + return s_UVHandles; + } + } static readonly BoxBoundsHandle s_AreaLightHandle = new BoxBoundsHandle { axes = PrimitiveBoundsHandle.Axes.X | PrimitiveBoundsHandle.Axes.Y }; @@ -242,7 +290,7 @@ void DrawHandles() if (editMode == k_EditShapePreservingUV || editMode == k_EditShapeWithoutPreservingUV) { - using (new Handles.DrawingScope(Color.white, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, Vector3.one))) + using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, Vector3.one))) { Vector3 centerStart = decalProjector.offset; boxHandle.center = centerStart; @@ -293,7 +341,7 @@ void DrawHandles() else if (editMode == k_EditUVAndPivot) { // Pivot - using (new Handles.DrawingScope(Color.white, Matrix4x4.TRS(Vector3.zero, decalProjector.transform.rotation, Vector3.one))) + using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(Vector3.zero, decalProjector.transform.rotation, Vector3.one))) { EditorGUI.BeginChangeCheck(); Vector3 newPosition = ProjectedTransform.DrawHandles(decalProjector.transform.position, .5f * decalProjector.size.z - decalProjector.offset.z, decalProjector.transform.rotation); @@ -315,17 +363,17 @@ void DrawHandles() ); Vector2 UVCenter = UVSize * .5f - new Vector2(decalProjector.uvBias.x * UVSize.x, decalProjector.uvBias.y * UVSize.y); - m_UVHandles.center = UVCenter; - m_UVHandles.size = UVSize; + UVHandles.center = UVCenter; + UVHandles.size = UVSize; EditorGUI.BeginChangeCheck(); - m_UVHandles.DrawHandle(); + UVHandles.DrawHandle(); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(decalProjector, "Decal Projector Change"); Vector2 limit = new Vector2(Mathf.Abs(decalProjector.size.x * k_LimitInv), Mathf.Abs(decalProjector.size.y * k_LimitInv)); - Vector2 uvScale = m_UVHandles.size; + Vector2 uvScale = UVHandles.size; for (int channel = 0; channel < 2; channel++) { if (Mathf.Abs(uvScale[channel]) > limit[channel]) @@ -334,11 +382,11 @@ void DrawHandles() uvScale[channel] = Mathf.Sign(decalProjector.size[channel]) * Mathf.Sign(uvScale[channel]) * k_Limit; } decalProjector.uvScale = uvScale; - - var newUVStart = m_UVHandles.center - .5f * m_UVHandles.size; + + var newUVStart = UVHandles.center - .5f * UVHandles.size; decalProjector.uvBias = -new Vector2( - m_UVHandles.size.x < k_LimitInv && m_UVHandles.size.x > -k_LimitInv ? k_Limit * newUVStart.x / decalProjector.size.x : newUVStart.x / m_UVHandles.size.x, - m_UVHandles.size.y < k_LimitInv && m_UVHandles.size.y > -k_LimitInv ? k_Limit * newUVStart.y / decalProjector.size.y : newUVStart.y / m_UVHandles.size.y + UVHandles.size.x < k_LimitInv && UVHandles.size.x > -k_LimitInv ? k_Limit * newUVStart.x / decalProjector.size.x : newUVStart.x / UVHandles.size.x, + UVHandles.size.y < k_LimitInv && UVHandles.size.y > -k_LimitInv ? k_Limit * newUVStart.y / decalProjector.size.y : newUVStart.y / UVHandles.size.y ); } } @@ -348,10 +396,12 @@ void DrawHandles() [DrawGizmo(GizmoType.Selected | GizmoType.Active)] static void DrawGizmosSelected(DecalProjector decalProjector, GizmoType gizmoType) { + UpdateColorsInHandlesIfRequired(); + const float k_DotLength = 5f; //draw them scale independent - using (new Handles.DrawingScope(Color.white, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, Vector3.one))) + using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, Vector3.one))) { boxHandle.center = decalProjector.offset; boxHandle.size = decalProjector.size; @@ -381,14 +431,14 @@ static void DrawGizmosSelected(DecalProjector decalProjector, GizmoType gizmoTyp decalProjector.uvScale.y > k_Limit || decalProjector.uvScale.y < -k_Limit ? 0f : decalProjector.size.y / decalProjector.uvScale.y ); Vector2 UVCenter = UVSize * .5f - new Vector2(decalProjector.uvBias.x * UVSize.x, decalProjector.uvBias.y * UVSize.y) - (Vector2)decalProjector.size * .5f; + + UVHandles.center = UVCenter; + UVHandles.size = UVSize; + UVHandles.DrawRect(dottedLine: true, screenSpaceSize: k_DotLength); - m_UVHandles.center = UVCenter; - m_UVHandles.size = UVSize; - m_UVHandles.DrawRect(dottedLine: true, screenSpaceSize: k_DotLength); - - m_UVHandles.center = default; - m_UVHandles.size = decalProjector.size; - m_UVHandles.DrawRect(dottedLine: false, sickness: 3f); + UVHandles.center = default; + UVHandles.size = decalProjector.size; + UVHandles.DrawRect(dottedLine: false, sickness: 3f); } } } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs index 60b7a1a4fb4..428fdcdf9f4 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs @@ -46,16 +46,26 @@ static void Slider1D(int controlID, ref Vector3 handlePosition, Vector3 handleOr }); } - public DisplacableRectHandles(Color baseTint) + /// The baseColor used to draw the rect. + public Color baseColor { - baseTint.a = 1f; - m_MonochromeHandleColor = baseTint; - baseTint.a = 0.7f; - m_WireframeColor = baseTint; - baseTint.a = 0.2f; - m_WireframeColorBehind = baseTint; + get { return m_MonochromeHandleColor; } + set + { + value.a = 1f; + m_MonochromeHandleColor = value; + value.a = 0.7f; + m_WireframeColor = value; + value.a = 0.2f; + m_WireframeColorBehind = value; + } } + public DisplacableRectHandles(Color baseTint) + { + baseColor = baseTint; + } + /// Draw the rect. public void DrawRect(bool dottedLine = false, float sickness = .0f, float screenSpaceSize = 5f) { From 1a5ee328f1b228c613ef6a64ad35ff3d60060bf2 Mon Sep 17 00:00:00 2001 From: RSlysz Date: Wed, 6 Jan 2021 17:45:06 +0100 Subject: [PATCH 07/20] Update CHANGELOG.md --- com.unity.render-pipelines.high-definition/CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 9a02fe28686..5c2fbfeb33a 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -6,7 +6,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [11.0.0] - 2020-10-21 +### Added + +- Added pivot point manipulation for Decals (inspector and edit mode). +- Added UV manipulation for Decals (edit mode). +- Added color and intensity customization for Decals. + ### Changed + - Removed the material pass probe volumes evaluation mode. ### Fixed From 0b047755fb56ada8adb37b9699dee9ade671b866 Mon Sep 17 00:00:00 2001 From: RSlysz Date: Thu, 7 Jan 2021 10:38:46 +0100 Subject: [PATCH 08/20] Adding feedbacks --- .../Editor/Gizmo/HierarchicalBox.cs | 4 ++-- .../Editor/Material/Decal/DecalProjectorEditor.cs | 4 +++- .../Editor/Material/Decal/DisplacableRectHandles.cs | 4 ++-- .../Editor/Material/Decal/ProjectedTransform.cs | 1 + 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/com.unity.render-pipelines.core/Editor/Gizmo/HierarchicalBox.cs b/com.unity.render-pipelines.core/Editor/Gizmo/HierarchicalBox.cs index bb304646dd0..682b1fc3ae4 100644 --- a/com.unity.render-pipelines.core/Editor/Gizmo/HierarchicalBox.cs +++ b/com.unity.render-pipelines.core/Editor/Gizmo/HierarchicalBox.cs @@ -115,7 +115,7 @@ public Color baseColor set { value.a = 8f / 255; - SetBaseColorWithoutIntensityChange(value); + SetBaseColor(value); } } @@ -124,7 +124,7 @@ public Color baseColor /// Instead of baseColor set, this will not force the opacity and keep what is provided for the filled faces. /// /// The color to use - public void SetBaseColorWithoutIntensityChange(Color color) + public void SetBaseColor(Color color) { m_MonochromeFillColor = color; material.color = m_MonochromeFillColor; diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs index 3ed87c63712..396c0b8d151 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs @@ -46,6 +46,8 @@ static void UpdateColorsInHandlesIfRequired() static DecalProjectorEditor() { + // PrefColor is the type to use to have a Color that is customizable inside the Preference/Colors panel. + // Sadly it is internal so we must create it and grab color from it by reflection. Type prefColorType = typeof(Editor).Assembly.GetType("UnityEditor.PrefColor"); s_ColorPref = Activator.CreateInstance(prefColorType, new object[] { "HDRP/Decal", k_GizmoColorBase.r, k_GizmoColorBase.g, k_GizmoColorBase.b, k_GizmoColorBase.a }); ParameterExpression colorParameter = Expression.Parameter(prefColorType, "color"); @@ -120,7 +122,7 @@ static HierarchicalBox boxHandle { Color c = fullColor; s_BoxHandle = new HierarchicalBox(s_LastColor, new []{ c, c, c, c, c, c }); - s_BoxHandle.SetBaseColorWithoutIntensityChange(s_LastColor); + s_BoxHandle.SetBaseColor(s_LastColor); s_BoxHandle.monoHandle = false; } return s_BoxHandle; diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs index 428fdcdf9f4..b26f366fca9 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs @@ -61,9 +61,9 @@ public Color baseColor } } - public DisplacableRectHandles(Color baseTint) + public DisplacableRectHandles(Color baseColor) { - baseColor = baseTint; + this.baseColor = baseColor; } /// Draw the rect. diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs index 9fce48315e7..32c14b71c27 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs @@ -154,6 +154,7 @@ public PositionHandleParam( static ProjectedTransform() { + //We need to know if grid snaping is active or not in Editor. Sadly this is internal so we must grab it by reflection. Type gridSnappingType = typeof(Handles).Assembly.GetType("UnityEditor.GridSnapping"); PropertyInfo activePropertyInfo = gridSnappingType.GetProperty("active", BindingFlags.Public | BindingFlags.Static); MethodCallExpression activePropertyGetCall = Expression.Call(null, activePropertyInfo.GetGetMethod()); From b5bffe03685a3a064c56e44f41c35dcccb7ec3aa Mon Sep 17 00:00:00 2001 From: RSlysz Date: Thu, 7 Jan 2021 18:15:34 +0100 Subject: [PATCH 09/20] Change Size and ProjectionDepth to scale around pivot point --- .../Material/Decal/DecalProjectorEditor.cs | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs index 396c0b8d151..18fc39717b6 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs @@ -69,7 +69,7 @@ static DecalProjectorEditor() SerializedProperty m_Size; SerializedProperty[] m_SizeValues; SerializedProperty m_Offset; - SerializedProperty m_OffsetZ; + SerializedProperty[] m_OffsetValues; SerializedProperty m_FadeFactor; SerializedProperty m_DecalLayerMask; @@ -223,7 +223,12 @@ private void OnEnable() m_Size.FindPropertyRelative("z"), }; m_Offset = serializedObject.FindProperty("m_Offset"); - m_OffsetZ = m_Offset.FindPropertyRelative("z"); + m_OffsetValues = new[] + { + m_Offset.FindPropertyRelative("x"), + m_Offset.FindPropertyRelative("y"), + m_Offset.FindPropertyRelative("z"), + }; m_FadeFactor = serializedObject.FindProperty("m_FadeFactor"); m_DecalLayerMask = serializedObject.FindProperty("m_DecalLayerMask"); } @@ -456,6 +461,13 @@ static Func GetBoundsGetter(DecalProjector decalProjector) }; } + void UpdateSize(int axe, float newSize, float oldSize) + { + m_SizeValues[axe].floatValue = newSize; + if (oldSize > Mathf.Epsilon) + m_OffsetValues[axe].floatValue *= newSize / oldSize; + } + public override void OnInspectorGUI() { serializedObject.Update(); @@ -485,18 +497,18 @@ public override void OnInspectorGUI() EditorGUI.MultiFloatField(rect, k_SizeContent, k_SizeSubContent, size); if (EditorGUI.EndChangeCheck()) { - m_SizeValues[0].floatValue = Mathf.Max(0, size[0]); - m_SizeValues[1].floatValue = Mathf.Max(0, size[1]); + for (int i=0; i <2; ++i) + UpdateSize(i, Mathf.Max(0, size[i]), m_SizeValues[i].floatValue); } EditorGUI.EndProperty(); EditorGUI.EndProperty(); EditorGUI.BeginChangeCheck(); + float oldSizeZ = m_SizeValues[2].floatValue; EditorGUILayout.PropertyField(m_SizeValues[2], k_ProjectionDepthContent); if (EditorGUI.EndChangeCheck()) { - m_SizeValues[2].floatValue = Mathf.Max(0, m_SizeValues[2].floatValue); - m_OffsetZ.floatValue = m_SizeValues[2].floatValue * 0.5f; + UpdateSize(2, Mathf.Max(0, m_SizeValues[2].floatValue), oldSizeZ); } EditorGUILayout.PropertyField(m_Offset, k_Offset); From 3bdc6b28e5f04b9086124b993be51ecfbcd37d1e Mon Sep 17 00:00:00 2001 From: RSlysz Date: Thu, 7 Jan 2021 18:32:20 +0100 Subject: [PATCH 10/20] Modify the bixe sizing edit modes to not touch transform any more For better placment with prefabs --- .../Editor/Material/Decal/DecalProjectorEditor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs index 18fc39717b6..a9a16d384d4 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs @@ -311,10 +311,10 @@ void DrawHandles() if (EditorGUI.EndChangeCheck()) { // Adjust decal transform if handle changed. - Undo.RecordObjects(new UnityEngine.Object[] { decalProjector, decalProjector.transform }, "Decal Projector Change"); + Undo.RecordObject(decalProjector, "Decal Projector Change"); decalProjector.size = boxHandle.size; - decalProjector.transform.position += decalProjector.transform.rotation * (boxHandle.center - centerStart); + decalProjector.offset += boxHandle.center - centerStart; Vector3 boundsSizeCurrentOS = boxHandle.size; Vector3 boundsMinCurrentOS = boxHandle.size * -0.5f + boxHandle.center; From ea4dde4977a85e7b0a2661ad549f40348938df5a Mon Sep 17 00:00:00 2001 From: RSlysz Date: Thu, 7 Jan 2021 18:37:27 +0100 Subject: [PATCH 11/20] Update tooltip --- .../Editor/Material/Decal/DecalProjectorEditor.Skin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs index dfe11be103a..ebfd593077e 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs @@ -6,7 +6,7 @@ partial class DecalProjectorEditor { const string k_EditShapePreservingUVTooltip = "Modifies the projector boundaries and crops/tiles the decal to fill them."; const string k_EditShapeWithoutPreservingUVTooltip = "Modifies the projector boundaries and stretches the decal to fill them."; - const string k_EditUVTooltip = "Modify the UV positions only"; + const string k_EditUVTooltip = "Modify the UV and the pivot position without moving the projection box. It can alter Transform."; static readonly GUIContent k_SizeContent = EditorGUIUtility.TrTextContent("Size", "Sets the size of the projector."); static readonly GUIContent[] k_SizeSubContent = new[] From 21d850a20b3195b565ebdf3048ab673e77f555f9 Mon Sep 17 00:00:00 2001 From: RSlysz Date: Mon, 11 Jan 2021 13:37:41 +0100 Subject: [PATCH 12/20] Update documentation --- .../Documentation~/Decal-Projector.md | 12 +++++++----- .../Documentation~/Images/DecalProjector3.png | 4 ++-- .../Documentation~/Images/DecalProjector4.png | 4 ++-- .../Documentation~/Images/DecalProjector5.png | 4 ++-- .../Documentation~/Images/DecalProjector6.png | 3 +++ 5 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector6.png diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Decal-Projector.md b/com.unity.render-pipelines.high-definition/Documentation~/Decal-Projector.md index 6b75cb3148e..7a4b97f2e20 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Decal-Projector.md +++ b/com.unity.render-pipelines.high-definition/Documentation~/Decal-Projector.md @@ -14,16 +14,17 @@ The Decal Projector includes a Scene view representation of its bounds and proje * A box that describes the 3D size of the projector; the projector draws its decal on every Material inside the box. -* An arrow that indicates the direction the projector faces. +* An arrow that indicates the direction the projector faces. This arrow is on the pivot point. ![](Images/DecalProjector2.png) -The decal Projector also includes two gizmos that add handles on every face for you to click and drag to alter the size of the projector's bounds. +The decal Projector also includes three gizmos. The first two add handles on every face for you to click and drag to alter the size of the projector's bounds. |**Button**|**Gizmo**|**Description**| |-----|-----|-----| -|![](Images/DecalProjector3.png)|**Scale**|Scales the decal with the projector box. This changes the UVs of the Material to match the size of the projector box. This stretches the decal.| -|![](Images/DecalProjector4.png)|**Crop**|Crops the decal with the projector box. This changes the size of the projector box but not the UVs of the Material. This crops the decal.| +|![](Images/DecalProjector3.png)|**Scale**|Scales the decal with the projector box. This changes the UVs of the Material to match the size of the projector box. This stretches the decal. The Pivot remains still.| +|![](Images/DecalProjector4.png)|**Crop**|Crops the decal with the projector box. This changes the size of the projector box but not the UVs of the Material. This crops the decal. The Pivot remains still.| +|![](Images/DecalProjector5.png)|**Pivot / UV**|Move the pivot without moving the projection box. This alter the transform position.
Also, set the UV used on the projected texture.| ## Using the Inspector @@ -31,12 +32,13 @@ Using the Inspector allows you to change all of the Decal Projector properties, ## Properties -![](Images/DecalProjector5.png) +![](Images/DecalProjector6.png) | **Property** | **Description** | | ----------------------- | ------------------------------------------------------------ | | **Size** | The size of the projector influence box, and thus the decal along the projected plane. The projector scales the decal to match the **Width** (along the local x-axis) and **Height** (along the local y-axis) components of the **Size**. | | **Projection Depth** | The depth of the projector influence box. The projector scales the decal to match **Projection Depth**. The Decal Projector component projects decals along the local z-axis. | +| **Pivot** | The offset position of the transform regarding the projection box. Adjusting X and Y allows to make rotation of the projected texture around a specific position, while Z allows to have a specific offset in depth. | | **Material** | The decal Material to project. The decal Material must use a HDRP/Decal Shader. | | **Decal Layer** | The layer that specifies the Materials to project the decal onto. Any Mesh Renderers or Terrain that uses a matching Decal Layer receives the decal. | | **Draw Distance** | The distance from the Camera to the Decal at which this projector stops projecting the decal and HDRP no longer renders the decal. | diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector3.png b/com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector3.png index 1fda03f14a3..f83fb4ea85f 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector3.png +++ b/com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ee48ea03dc20eb5f9795b6373da6f247e7d53659eb3884637d050c1a4fb7208 -size 335 +oid sha256:dc861506e84d5055dc66b6f3cf2f4f2ec2af4903996c2a57a7c01244983784d0 +size 731 diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector4.png b/com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector4.png index a51f5ee3151..849a223dd73 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector4.png +++ b/com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d1dc2574e29399b90a8b376882bd16b3b32f96cc281f172bb6bf4f71594e6037 -size 328 +oid sha256:ddef1d57d861335e487c5ecdaa4ff1530770d65aab69058f3f48675eb671abe6 +size 711 diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector5.png b/com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector5.png index 4ca38d845d8..321e309a2ba 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector5.png +++ b/com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f1521303080bc06ff09dc3e6e67c42afe113dcbca9fd5d708bebe59bf2751a54 -size 21831 +oid sha256:1f682e51dd43fca42cb9592725e476aecdb6677463124b5566c2180923acddbe +size 881 diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector6.png b/com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector6.png new file mode 100644 index 00000000000..564e3c78758 --- /dev/null +++ b/com.unity.render-pipelines.high-definition/Documentation~/Images/DecalProjector6.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa9f73b741574d9930dd763cae35847a4003d59b24d1997896d26b6f63f50e66 +size 16705 From 5a8957420e4a9cd492a9a2b356cea300cf888060 Mon Sep 17 00:00:00 2001 From: RSlysz Date: Mon, 11 Jan 2021 14:46:59 +0100 Subject: [PATCH 13/20] fix formating --- .../Decal/DecalProjectorEditor.Skin.cs | 2 +- .../Material/Decal/DecalProjectorEditor.cs | 35 +++-- .../Material/Decal/DisplacableRectHandles.cs | 5 +- .../Material/Decal/ProjectedTransform.cs | 128 +++++++++--------- 4 files changed, 82 insertions(+), 88 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs index ebfd593077e..0c8adc52a43 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.Skin.cs @@ -26,6 +26,6 @@ partial class DecalProjectorEditor static readonly GUIContent k_AffectTransparentContent = EditorGUIUtility.TrTextContent("Affects Transparent", "When enabled, HDRP draws this projector's decal on top of transparent surfaces."); static readonly GUIContent k_Offset = EditorGUIUtility.TrTextContent("Pivot", "Controls the position of the pivot point of the decal."); - public static readonly Color k_GizmoColorBase = new Color(1, 1, 1, 8f/255); + public static readonly Color k_GizmoColorBase = new Color(1, 1, 1, 8f / 255); } } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs index a9a16d384d4..41d1ded215d 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs @@ -16,7 +16,7 @@ partial class DecalProjectorEditor : Editor { const float k_Limit = 100000; const float k_LimitInv = 1 / k_Limit; - + static object s_ColorPref; static Func GetColorPref; static Color fullColor @@ -56,7 +56,7 @@ static DecalProjectorEditor() Expression> colorLambda = Expression.Lambda>(colorProperty); GetColorPref = colorLambda.Compile(); } - + MaterialEditor m_MaterialEditor = null; SerializedProperty m_MaterialProperty; SerializedProperty m_DrawDistanceProperty; @@ -121,7 +121,7 @@ static HierarchicalBox boxHandle if (s_BoxHandle == null || s_BoxHandle.Equals(null)) { Color c = fullColor; - s_BoxHandle = new HierarchicalBox(s_LastColor, new []{ c, c, c, c, c, c }); + s_BoxHandle = new HierarchicalBox(s_LastColor, new[] { c, c, c, c, c, c }); s_BoxHandle.SetBaseColor(s_LastColor); s_BoxHandle.monoHandle = false; } @@ -338,13 +338,12 @@ void DrawHandles() { PrefabUtility.RecordPrefabInstancePropertyModifications(decalProjector); } - + // Smoothly update the decal image projected DecalSystem.instance.UpdateCachedData(decalProjector.Handle, decalProjector.GetCachedDecalData()); } } } - else if (editMode == k_EditUVAndPivot) { // Pivot @@ -365,14 +364,14 @@ void DrawHandles() using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position + decalProjector.transform.rotation * (decalProjector.offset - .5f * decalProjector.size), decalProjector.transform.rotation, Vector3.one))) { Vector2 UVSize = new Vector2( - decalProjector.uvScale.x > k_Limit || decalProjector.uvScale.x < -k_Limit ? 0f : decalProjector.size.x / decalProjector.uvScale.x, - decalProjector.uvScale.y > k_Limit || decalProjector.uvScale.y < -k_Limit ? 0f : decalProjector.size.y / decalProjector.uvScale.y - ); + (decalProjector.uvScale.x > k_Limit || decalProjector.uvScale.x < -k_Limit) ? 0f : decalProjector.size.x / decalProjector.uvScale.x, + (decalProjector.uvScale.y > k_Limit || decalProjector.uvScale.y < -k_Limit) ? 0f : decalProjector.size.y / decalProjector.uvScale.y + ); Vector2 UVCenter = UVSize * .5f - new Vector2(decalProjector.uvBias.x * UVSize.x, decalProjector.uvBias.y * UVSize.y); UVHandles.center = UVCenter; UVHandles.size = UVSize; - + EditorGUI.BeginChangeCheck(); UVHandles.DrawHandle(); if (EditorGUI.EndChangeCheck()) @@ -389,11 +388,11 @@ void DrawHandles() uvScale[channel] = Mathf.Sign(decalProjector.size[channel]) * Mathf.Sign(uvScale[channel]) * k_Limit; } decalProjector.uvScale = uvScale; - + var newUVStart = UVHandles.center - .5f * UVHandles.size; decalProjector.uvBias = -new Vector2( - UVHandles.size.x < k_LimitInv && UVHandles.size.x > -k_LimitInv ? k_Limit * newUVStart.x / decalProjector.size.x : newUVStart.x / UVHandles.size.x, - UVHandles.size.y < k_LimitInv && UVHandles.size.y > -k_LimitInv ? k_Limit * newUVStart.y / decalProjector.size.y : newUVStart.y / UVHandles.size.y + (UVHandles.size.x < k_LimitInv) && (UVHandles.size.x > -k_LimitInv) ? k_Limit * newUVStart.x / decalProjector.size.x : newUVStart.x / UVHandles.size.x, //parenthesis to force format tool + (UVHandles.size.y < k_LimitInv) && (UVHandles.size.y > -k_LimitInv) ? k_Limit * newUVStart.y / decalProjector.size.y : newUVStart.y / UVHandles.size.y //parenthesis to force format tool ); } } @@ -434,11 +433,11 @@ static void DrawGizmosSelected(DecalProjector decalProjector, GizmoType gizmoTyp using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position + decalProjector.transform.rotation * new Vector3(decalProjector.offset.x, decalProjector.offset.y, decalProjector.offset.z - .5f * decalProjector.size.z), decalProjector.transform.rotation, Vector3.one))) { Vector2 UVSize = new Vector2( - decalProjector.uvScale.x > k_Limit || decalProjector.uvScale.x < -k_Limit ? 0f : decalProjector.size.x / decalProjector.uvScale.x, - decalProjector.uvScale.y > k_Limit || decalProjector.uvScale.y < -k_Limit ? 0f : decalProjector.size.y / decalProjector.uvScale.y - ); + (decalProjector.uvScale.x > k_Limit || decalProjector.uvScale.x < -k_Limit) ? 0f : decalProjector.size.x / decalProjector.uvScale.x, + (decalProjector.uvScale.y > k_Limit || decalProjector.uvScale.y < -k_Limit) ? 0f : decalProjector.size.y / decalProjector.uvScale.y + ); Vector2 UVCenter = UVSize * .5f - new Vector2(decalProjector.uvBias.x * UVSize.x, decalProjector.uvBias.y * UVSize.y) - (Vector2)decalProjector.size * .5f; - + UVHandles.center = UVCenter; UVHandles.size = UVSize; UVHandles.DrawRect(dottedLine: true, screenSpaceSize: k_DotLength); @@ -497,7 +496,7 @@ public override void OnInspectorGUI() EditorGUI.MultiFloatField(rect, k_SizeContent, k_SizeSubContent, size); if (EditorGUI.EndChangeCheck()) { - for (int i=0; i <2; ++i) + for (int i = 0; i < 2; ++i) UpdateSize(i, Mathf.Max(0, size[i]), m_SizeValues[i].floatValue); } EditorGUI.EndProperty(); @@ -680,5 +679,3 @@ static void ExitEditMode(ShortcutArguments args) } } } - - diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs index b26f366fca9..b3c5d1efff6 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs @@ -10,7 +10,7 @@ class DisplacableRectHandles const float k_HandleSizeCoef = 0.05f; enum NamedEdge { Right, Top, Left, Bottom, None } - + int[] m_ControlIDs = new int[4] { 0, 0, 0, 0 }; Color m_MonochromeHandleColor; Color m_WireframeColor; @@ -65,7 +65,7 @@ public DisplacableRectHandles(Color baseColor) { this.baseColor = baseColor; } - + /// Draw the rect. public void DrawRect(bool dottedLine = false, float sickness = .0f, float screenSpaceSize = 5f) { @@ -277,7 +277,6 @@ public void DrawHandle() } } - internal string debug => $"center:({center.x},{center.y}) size:({size.x},{size.y})"; } } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs index 32c14b71c27..ce4095c9093 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs @@ -144,7 +144,7 @@ public PositionHandleParam( static PositionHandleParam paramXY = PositionHandleParam.defaultHandleXY; static PositionHandleParam paramZ = PositionHandleParam.defaultHandleZ; static PositionHandleIds ids = PositionHandleIds.@default; - + static int[] s_DoPositionHandle_Internal_NextIndex = { 1, 2, 0 }; static int[] s_DoPositionHandle_Internal_PrevIndex = { 2, 0, 1 }; static Vector3[] verts = { Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero }; @@ -174,82 +174,80 @@ public static Vector3 DrawHandles(Vector3 position, float zProjectionDistance, Q { //using (new Handles.DrawingScope(Color.white, Matrix4x4.TRS(Vector3.zero, rotation, Vector3.one))) //{ - var isHot = ids.Has(GUIUtility.hotControl); - var planeSize = isHot ? paramXY.planeSize + paramXY.planeOffset : paramXY.planeSize; - var planarSize = Mathf.Max(planeSize[0], planeSize[s_DoPositionHandle_Internal_NextIndex[0]]); - Vector3 sliderRotatedWorldPos = Quaternion.Inverse(rotation) * position; - var size1D = HandleUtility.GetHandleSize(sliderRotatedWorldPos); - var size2D = HandleUtility.GetHandleSize(sliderRotatedWorldPos - new Vector3(0, 0, zProjectionDistance)) * planarSize * .5f; - Vector3 depthSlider = sliderRotatedWorldPos; - + var isHot = ids.Has(GUIUtility.hotControl); + var planeSize = isHot ? paramXY.planeSize + paramXY.planeOffset : paramXY.planeSize; + var planarSize = Mathf.Max(planeSize[0], planeSize[s_DoPositionHandle_Internal_NextIndex[0]]); + Vector3 sliderRotatedWorldPos = Quaternion.Inverse(rotation) * position; + var size1D = HandleUtility.GetHandleSize(sliderRotatedWorldPos); + var size2D = HandleUtility.GetHandleSize(sliderRotatedWorldPos - new Vector3(0, 0, zProjectionDistance)) * planarSize * .5f; + Vector3 depthSlider = sliderRotatedWorldPos; + + EditorGUI.BeginChangeCheck(); + { + // dot offset = transform position seen as a sphere EditorGUI.BeginChangeCheck(); + depthSlider = Handles.Slider(depthSlider, Vector3.forward, size1D * .1f, Handles.SphereHandleCap, -1); + if (EditorGUI.EndChangeCheck()) + sliderRotatedWorldPos.z = depthSlider.z; + + // 2D slider: square xy-axis + Vector3 sliderFaceProjected = sliderRotatedWorldPos - new Vector3(0, 0, zProjectionDistance); + sliderFaceProjected.x += size2D; + sliderFaceProjected.y += size2D; + using (new Handles.DrawingScope(Handles.zAxisColor)) { - // dot offset = transform position seen as a sphere + verts[0] = sliderFaceProjected + (Vector3.right + Vector3.up) * size2D; + verts[1] = sliderFaceProjected + (-Vector3.right + Vector3.up) * size2D; + verts[2] = sliderFaceProjected + (-Vector3.right - Vector3.up) * size2D; + verts[3] = sliderFaceProjected + (Vector3.right - Vector3.up) * size2D; + float faceOpacity = 0.8f; + if (GUIUtility.hotControl == ids.xy) + Handles.color = Handles.selectedColor; + else if (IsHovering(ids.xy, Event.current)) + faceOpacity = 0.4f; + else + faceOpacity = 0.1f; + Color faceColor = new Color(Handles.zAxisColor.r, Handles.zAxisColor.g, Handles.zAxisColor.b, Handles.zAxisColor.a * faceOpacity); + Handles.DrawSolidRectangleWithOutline(verts, faceColor, Color.clear); EditorGUI.BeginChangeCheck(); - depthSlider = Handles.Slider(depthSlider, Vector3.forward, size1D * .1f, Handles.SphereHandleCap, -1); + sliderFaceProjected = Handles.Slider2D(ids.xy, sliderFaceProjected, Vector3.forward, Vector3.right, Vector3.up, size2D, Handles.RectangleHandleCap, s_IsGridSnappingActive() ? Vector2.zero : new Vector2(EditorSnapSettings.move[0], EditorSnapSettings.move[1]), false); if (EditorGUI.EndChangeCheck()) - sliderRotatedWorldPos.z = depthSlider.z; - - // 2D slider: square xy-axis - Vector3 sliderFaceProjected = sliderRotatedWorldPos - new Vector3(0, 0, zProjectionDistance); - sliderFaceProjected.x += size2D; - sliderFaceProjected.y += size2D; - using (new Handles.DrawingScope(Handles.zAxisColor)) { - verts[0] = sliderFaceProjected + (Vector3.right + Vector3.up) * size2D; - verts[1] = sliderFaceProjected + (-Vector3.right + Vector3.up) * size2D; - verts[2] = sliderFaceProjected + (-Vector3.right - Vector3.up) * size2D; - verts[3] = sliderFaceProjected + (Vector3.right - Vector3.up) * size2D; - float faceOpacity = 0.8f; - if (GUIUtility.hotControl == ids.xy) - Handles.color = Handles.selectedColor; - else if (IsHovering(ids.xy, Event.current)) - faceOpacity = 0.4f; - else - faceOpacity = 0.1f; - Color faceColor = new Color(Handles.zAxisColor.r, Handles.zAxisColor.g, Handles.zAxisColor.b, Handles.zAxisColor.a * faceOpacity); - Handles.DrawSolidRectangleWithOutline(verts, faceColor, Color.clear); - EditorGUI.BeginChangeCheck(); - sliderFaceProjected = Handles.Slider2D(ids.xy, sliderFaceProjected, Vector3.forward, Vector3.right, Vector3.up, size2D, Handles.RectangleHandleCap, s_IsGridSnappingActive() ? Vector2.zero : new Vector2(EditorSnapSettings.move[0], EditorSnapSettings.move[1]), false); - if (EditorGUI.EndChangeCheck()) - { - sliderRotatedWorldPos.x = sliderFaceProjected.x; - sliderRotatedWorldPos.y = sliderFaceProjected.y; - } + sliderRotatedWorldPos.x = sliderFaceProjected.x; + sliderRotatedWorldPos.y = sliderFaceProjected.y; } - sliderFaceProjected.x -= size2D; - sliderFaceProjected.y -= size2D; + } + sliderFaceProjected.x -= size2D; + sliderFaceProjected.y -= size2D; - // 2D slider: x-axis - EditorGUI.BeginChangeCheck(); - using (new Handles.DrawingScope(Handles.xAxisColor)) - sliderFaceProjected = Handles.Slider(sliderFaceProjected, Vector3.right); - if (EditorGUI.EndChangeCheck()) - sliderRotatedWorldPos.x = sliderFaceProjected.x; + // 2D slider: x-axis + EditorGUI.BeginChangeCheck(); + using (new Handles.DrawingScope(Handles.xAxisColor)) + sliderFaceProjected = Handles.Slider(sliderFaceProjected, Vector3.right); + if (EditorGUI.EndChangeCheck()) + sliderRotatedWorldPos.x = sliderFaceProjected.x; - // 2D slider: y-axis - EditorGUI.BeginChangeCheck(); - using (new Handles.DrawingScope(Handles.yAxisColor)) - sliderFaceProjected = Handles.Slider(sliderFaceProjected, Vector3.up); - if (EditorGUI.EndChangeCheck()) - sliderRotatedWorldPos.y = sliderFaceProjected.y; + // 2D slider: y-axis + EditorGUI.BeginChangeCheck(); + using (new Handles.DrawingScope(Handles.yAxisColor)) + sliderFaceProjected = Handles.Slider(sliderFaceProjected, Vector3.up); + if (EditorGUI.EndChangeCheck()) + sliderRotatedWorldPos.y = sliderFaceProjected.y; - // depth: z-axis - EditorGUI.BeginChangeCheck(); - using (new Handles.DrawingScope(Handles.zAxisColor)) - depthSlider = Handles.Slider(depthSlider, Vector3.forward); - if (EditorGUI.EndChangeCheck()) - sliderRotatedWorldPos.z = depthSlider.z; - } + // depth: z-axis + EditorGUI.BeginChangeCheck(); + using (new Handles.DrawingScope(Handles.zAxisColor)) + depthSlider = Handles.Slider(depthSlider, Vector3.forward); if (EditorGUI.EndChangeCheck()) - { - position = rotation * sliderRotatedWorldPos; - } + sliderRotatedWorldPos.z = depthSlider.z; + } + if (EditorGUI.EndChangeCheck()) + { + position = rotation * sliderRotatedWorldPos; + } - return position; + return position; //} } - - } } From 0ccf247fc9de1642ef8672a643171efa84125b72 Mon Sep 17 00:00:00 2001 From: RSlysz Date: Mon, 11 Jan 2021 14:56:46 +0100 Subject: [PATCH 14/20] Update documentation (missing color location) --- .../Documentation~/Decal-Projector.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Decal-Projector.md b/com.unity.render-pipelines.high-definition/Documentation~/Decal-Projector.md index 7a4b97f2e20..3c4aa864cfb 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Decal-Projector.md +++ b/com.unity.render-pipelines.high-definition/Documentation~/Decal-Projector.md @@ -26,6 +26,8 @@ The decal Projector also includes three gizmos. The first two add handles on eve |![](Images/DecalProjector4.png)|**Crop**|Crops the decal with the projector box. This changes the size of the projector box but not the UVs of the Material. This crops the decal. The Pivot remains still.| |![](Images/DecalProjector5.png)|**Pivot / UV**|Move the pivot without moving the projection box. This alter the transform position.
Also, set the UV used on the projected texture.| +The color of the gizmos can be set up in the Preference window inside Color panel. + ## Using the Inspector Using the Inspector allows you to change all of the Decal Projector properties, and lets you use numerical values for **Size**, **Tiling**, and **Offset**, which allows for greater precision than the click-and-drag gizmo method. From f326fef7a3a24d5b62bcd6cf7e6008e02cf95b43 Mon Sep 17 00:00:00 2001 From: RSlysz Date: Mon, 11 Jan 2021 15:05:16 +0100 Subject: [PATCH 15/20] clean unneaded comments --- .../Editor/Material/Decal/ProjectedTransform.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs index ce4095c9093..6f0c060f728 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs @@ -167,13 +167,8 @@ static bool IsHovering(int controlID, Event evt) return controlID == HandleUtility.nearestControl && GUIUtility.hotControl == 0 && !Tools.viewToolActive; } - //position = decalProjector.transform.position - //zProjectionDistance = decalProjector.offset.z - //rotation = decalProjector.transform.rotation public static Vector3 DrawHandles(Vector3 position, float zProjectionDistance, Quaternion rotation) { - //using (new Handles.DrawingScope(Color.white, Matrix4x4.TRS(Vector3.zero, rotation, Vector3.one))) - //{ var isHot = ids.Has(GUIUtility.hotControl); var planeSize = isHot ? paramXY.planeSize + paramXY.planeOffset : paramXY.planeSize; var planarSize = Mathf.Max(planeSize[0], planeSize[s_DoPositionHandle_Internal_NextIndex[0]]); @@ -247,7 +242,6 @@ public static Vector3 DrawHandles(Vector3 position, float zProjectionDistance, Q } return position; - //} } } } From 5a64b7884a0ba07c23322feb3ef91316ce2fc6e4 Mon Sep 17 00:00:00 2001 From: RSlysz Date: Thu, 14 Jan 2021 17:37:53 +0100 Subject: [PATCH 16/20] Update documentation --- .../Documentation~/Decal-Projector.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Documentation~/Decal-Projector.md b/com.unity.render-pipelines.high-definition/Documentation~/Decal-Projector.md index 3c4aa864cfb..c322751ea28 100644 --- a/com.unity.render-pipelines.high-definition/Documentation~/Decal-Projector.md +++ b/com.unity.render-pipelines.high-definition/Documentation~/Decal-Projector.md @@ -14,7 +14,7 @@ The Decal Projector includes a Scene view representation of its bounds and proje * A box that describes the 3D size of the projector; the projector draws its decal on every Material inside the box. -* An arrow that indicates the direction the projector faces. This arrow is on the pivot point. +* An arrow that indicates the direction the projector faces. The base of this arrow is on the pivot point. ![](Images/DecalProjector2.png) @@ -24,7 +24,7 @@ The decal Projector also includes three gizmos. The first two add handles on eve |-----|-----|-----| |![](Images/DecalProjector3.png)|**Scale**|Scales the decal with the projector box. This changes the UVs of the Material to match the size of the projector box. This stretches the decal. The Pivot remains still.| |![](Images/DecalProjector4.png)|**Crop**|Crops the decal with the projector box. This changes the size of the projector box but not the UVs of the Material. This crops the decal. The Pivot remains still.| -|![](Images/DecalProjector5.png)|**Pivot / UV**|Move the pivot without moving the projection box. This alter the transform position.
Also, set the UV used on the projected texture.| +|![](Images/DecalProjector5.png)|**Pivot / UV**|Moves the decal's pivot point without moving the projection box. This changes the transform position.
Note this also sets the UV used on the projected texture.| The color of the gizmos can be set up in the Preference window inside Color panel. @@ -40,7 +40,7 @@ Using the Inspector allows you to change all of the Decal Projector properties, | ----------------------- | ------------------------------------------------------------ | | **Size** | The size of the projector influence box, and thus the decal along the projected plane. The projector scales the decal to match the **Width** (along the local x-axis) and **Height** (along the local y-axis) components of the **Size**. | | **Projection Depth** | The depth of the projector influence box. The projector scales the decal to match **Projection Depth**. The Decal Projector component projects decals along the local z-axis. | -| **Pivot** | The offset position of the transform regarding the projection box. Adjusting X and Y allows to make rotation of the projected texture around a specific position, while Z allows to have a specific offset in depth. | +| **Pivot** | The offset position of the transform regarding the projection box. To rotate the projected texture around a specific position, adjust the **X** and **Y** values. To set a depth offset for the projected texture, adjust the **Z** value. | | **Material** | The decal Material to project. The decal Material must use a HDRP/Decal Shader. | | **Decal Layer** | The layer that specifies the Materials to project the decal onto. Any Mesh Renderers or Terrain that uses a matching Decal Layer receives the decal. | | **Draw Distance** | The distance from the Camera to the Decal at which this projector stops projecting the decal and HDRP no longer renders the decal. | From 523adec1b17dfa6727f2ade7c2ad2ff9a1135d96 Mon Sep 17 00:00:00 2001 From: RSlysz Date: Wed, 20 Jan 2021 11:28:51 +0100 Subject: [PATCH 17/20] Clean and clarify with last feedbacks --- .../Editor/Gizmo/GizmoUtility.cs | 24 ++ .../Editor/Gizmo/GizmoUtility.cs.meta | 11 + .../Editor/Gizmo/HierarchicalBox.cs | 9 +- .../Runtime/RenderPipeline.meta | 8 + .../Material/Decal/DecalProjectorEditor.cs | 214 +++++++++--------- .../Material/Decal/DisplacableRectHandles.cs | 188 ++++++++------- .../Material/Decal/ProjectedTransform.cs | 5 +- 7 files changed, 260 insertions(+), 199 deletions(-) create mode 100644 com.unity.render-pipelines.core/Editor/Gizmo/GizmoUtility.cs create mode 100644 com.unity.render-pipelines.core/Editor/Gizmo/GizmoUtility.cs.meta create mode 100644 com.unity.render-pipelines.core/Runtime/RenderPipeline.meta diff --git a/com.unity.render-pipelines.core/Editor/Gizmo/GizmoUtility.cs b/com.unity.render-pipelines.core/Editor/Gizmo/GizmoUtility.cs new file mode 100644 index 00000000000..ff01839b6af --- /dev/null +++ b/com.unity.render-pipelines.core/Editor/Gizmo/GizmoUtility.cs @@ -0,0 +1,24 @@ +using System; +using UnityEngine; + +namespace UnityEditor.Rendering +{ + public static class GizmoUtility + { + public static Color GetHandleColor(Color baseColor) + { + baseColor.a = 1f; + return baseColor; + } + public static Color GetWireframeColor(Color baseColor) + { + baseColor.a = .7f; + return baseColor; + } + public static Color GetWireframeColorBehindObjects(Color baseColor) + { + baseColor.a = .2f; + return baseColor; + } + } +} diff --git a/com.unity.render-pipelines.core/Editor/Gizmo/GizmoUtility.cs.meta b/com.unity.render-pipelines.core/Editor/Gizmo/GizmoUtility.cs.meta new file mode 100644 index 00000000000..3fb6b736167 --- /dev/null +++ b/com.unity.render-pipelines.core/Editor/Gizmo/GizmoUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 13d32c9cdf2984447b4802095ce716ae +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.render-pipelines.core/Editor/Gizmo/HierarchicalBox.cs b/com.unity.render-pipelines.core/Editor/Gizmo/HierarchicalBox.cs index 682b1fc3ae4..d2d225dab6b 100644 --- a/com.unity.render-pipelines.core/Editor/Gizmo/HierarchicalBox.cs +++ b/com.unity.render-pipelines.core/Editor/Gizmo/HierarchicalBox.cs @@ -128,12 +128,9 @@ public void SetBaseColor(Color color) { m_MonochromeFillColor = color; material.color = m_MonochromeFillColor; - color.a = 1f; - m_MonochromeHandleColor = color; - color.a = 0.7f; - m_WireframeColor = color; - color.a = 0.2f; - m_WireframeColorBehind = color; + m_MonochromeHandleColor = GizmoUtility.GetHandleColor(color); + m_WireframeColor = GizmoUtility.GetWireframeColor(color); + m_WireframeColorBehind = GizmoUtility.GetWireframeColorBehindObjects(color); } //Note: Handles.Slider not allow to use a specific ControlID. diff --git a/com.unity.render-pipelines.core/Runtime/RenderPipeline.meta b/com.unity.render-pipelines.core/Runtime/RenderPipeline.meta new file mode 100644 index 00000000000..0275dea9475 --- /dev/null +++ b/com.unity.render-pipelines.core/Runtime/RenderPipeline.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 86f88b9c1e352fc4286a6c08619f2f19 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs index 41d1ded215d..272301cdafc 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs @@ -1,12 +1,12 @@ using UnityEngine; using UnityEngine.Rendering.HighDefinition; using UnityEditor.ShortcutManagement; -using static UnityEditorInternal.EditMode; using UnityEditor.IMGUI.Controls; using System; using System.Collections.Generic; using System.Reflection; using System.Linq.Expressions; +using static UnityEditorInternal.EditMode; namespace UnityEditor.Rendering.HighDefinition { @@ -37,8 +37,8 @@ static void UpdateColorsInHandlesIfRequired() if (s_BoxHandle != null && !s_BoxHandle.Equals(null)) s_BoxHandle = null; - if (s_UVHandles != null && !s_UVHandles.Equals(null)) - s_UVHandles.baseColor = c; + if (s_uvHandles != null && !s_uvHandles.Equals(null)) + s_uvHandles.baseColor = c; s_LastColor = c; } @@ -49,8 +49,7 @@ static DecalProjectorEditor() // PrefColor is the type to use to have a Color that is customizable inside the Preference/Colors panel. // Sadly it is internal so we must create it and grab color from it by reflection. Type prefColorType = typeof(Editor).Assembly.GetType("UnityEditor.PrefColor"); - s_ColorPref = Activator.CreateInstance(prefColorType, new object[] { "HDRP/Decal", k_GizmoColorBase.r, k_GizmoColorBase.g, k_GizmoColorBase.b, k_GizmoColorBase.a }); - ParameterExpression colorParameter = Expression.Parameter(prefColorType, "color"); + s_ColorPref = Activator.CreateInstance(prefColorType, new object[] { "Scene/Decal", k_GizmoColorBase.r, k_GizmoColorBase.g, k_GizmoColorBase.b, k_GizmoColorBase.a }); PropertyInfo colorInfo = prefColorType.GetProperty("Color"); MemberExpression colorProperty = Expression.Property(Expression.Constant(s_ColorPref, prefColorType), colorInfo); Expression> colorLambda = Expression.Lambda>(colorProperty); @@ -129,14 +128,14 @@ static HierarchicalBox boxHandle } } - static DisplacableRectHandles s_UVHandles; - static DisplacableRectHandles UVHandles + static DisplacableRectHandles s_uvHandles; + static DisplacableRectHandles uvHandles { get { - if (s_UVHandles == null || s_UVHandles.Equals(null)) - s_UVHandles = new DisplacableRectHandles(s_LastColor); - return s_UVHandles; + if (s_uvHandles == null || s_uvHandles.Equals(null)) + s_uvHandles = new DisplacableRectHandles(s_LastColor); + return s_uvHandles; } } @@ -291,114 +290,124 @@ void OnSceneGUI() DrawHandles(); } - void DrawHandles() + void DrawBoxTransformationHandles(DecalProjector decalProjector) { - DecalProjector decalProjector = target as DecalProjector; - - if (editMode == k_EditShapePreservingUV || editMode == k_EditShapeWithoutPreservingUV) + using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, Vector3.one))) { - using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, Vector3.one))) + Vector3 centerStart = decalProjector.offset; + boxHandle.center = centerStart; + boxHandle.size = decalProjector.size; + + Vector3 boundsSizePreviousOS = boxHandle.size; + Vector3 boundsMinPreviousOS = boxHandle.size * -0.5f + boxHandle.center; + + EditorGUI.BeginChangeCheck(); + boxHandle.DrawHandle(); + if (EditorGUI.EndChangeCheck()) { - Vector3 centerStart = decalProjector.offset; - boxHandle.center = centerStart; - boxHandle.size = decalProjector.size; + // Adjust decal transform if handle changed. + Undo.RecordObject(decalProjector, "Decal Projector Change"); - Vector3 boundsSizePreviousOS = boxHandle.size; - Vector3 boundsMinPreviousOS = boxHandle.size * -0.5f + boxHandle.center; + decalProjector.size = boxHandle.size; + decalProjector.offset += boxHandle.center - centerStart; - EditorGUI.BeginChangeCheck(); - boxHandle.DrawHandle(); - if (EditorGUI.EndChangeCheck()) + Vector3 boundsSizeCurrentOS = boxHandle.size; + Vector3 boundsMinCurrentOS = boxHandle.size * -0.5f + boxHandle.center; + + if (editMode == k_EditShapePreservingUV) { - // Adjust decal transform if handle changed. - Undo.RecordObject(decalProjector, "Decal Projector Change"); - - decalProjector.size = boxHandle.size; - decalProjector.offset += boxHandle.center - centerStart; - - Vector3 boundsSizeCurrentOS = boxHandle.size; - Vector3 boundsMinCurrentOS = boxHandle.size * -0.5f + boxHandle.center; - - if (editMode == k_EditShapePreservingUV) - { - // Treat decal projector bounds as a crop tool, rather than a scale tool. - // Compute a new uv scale and bias terms to pin decal projection pixels in world space, irrespective of projector bounds. - Vector2 uvScale = decalProjector.uvScale; - uvScale.x *= Mathf.Max(1e-5f, boundsSizeCurrentOS.x) / Mathf.Max(1e-5f, boundsSizePreviousOS.x); - uvScale.y *= Mathf.Max(1e-5f, boundsSizeCurrentOS.y) / Mathf.Max(1e-5f, boundsSizePreviousOS.y); - decalProjector.uvScale = uvScale; - - Vector2 uvBias = decalProjector.uvBias; - uvBias.x += (boundsMinCurrentOS.x - boundsMinPreviousOS.x) / Mathf.Max(1e-5f, boundsSizeCurrentOS.x) * decalProjector.uvScale.x; - uvBias.y += (boundsMinCurrentOS.y - boundsMinPreviousOS.y) / Mathf.Max(1e-5f, boundsSizeCurrentOS.y) * decalProjector.uvScale.y; - decalProjector.uvBias = uvBias; - } - - if (PrefabUtility.IsPartOfNonAssetPrefabInstance(decalProjector)) - { - PrefabUtility.RecordPrefabInstancePropertyModifications(decalProjector); - } - - // Smoothly update the decal image projected - DecalSystem.instance.UpdateCachedData(decalProjector.Handle, decalProjector.GetCachedDecalData()); + // Treat decal projector bounds as a crop tool, rather than a scale tool. + // Compute a new uv scale and bias terms to pin decal projection pixels in world space, irrespective of projector bounds. + Vector2 uvScale = decalProjector.uvScale; + uvScale.x *= Mathf.Max(1e-5f, boundsSizeCurrentOS.x) / Mathf.Max(1e-5f, boundsSizePreviousOS.x); + uvScale.y *= Mathf.Max(1e-5f, boundsSizeCurrentOS.y) / Mathf.Max(1e-5f, boundsSizePreviousOS.y); + decalProjector.uvScale = uvScale; + + Vector2 uvBias = decalProjector.uvBias; + uvBias.x += (boundsMinCurrentOS.x - boundsMinPreviousOS.x) / Mathf.Max(1e-5f, boundsSizeCurrentOS.x) * decalProjector.uvScale.x; + uvBias.y += (boundsMinCurrentOS.y - boundsMinPreviousOS.y) / Mathf.Max(1e-5f, boundsSizeCurrentOS.y) * decalProjector.uvScale.y; + decalProjector.uvBias = uvBias; } + + if (PrefabUtility.IsPartOfNonAssetPrefabInstance(decalProjector)) + { + PrefabUtility.RecordPrefabInstancePropertyModifications(decalProjector); + } + + // Smoothly update the decal image projected + DecalSystem.instance.UpdateCachedData(decalProjector.Handle, decalProjector.GetCachedDecalData()); } } - else if (editMode == k_EditUVAndPivot) + } + + void DrawPivotHandles(DecalProjector decalProjector) + { + using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(Vector3.zero, decalProjector.transform.rotation, Vector3.one))) { - // Pivot - using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(Vector3.zero, decalProjector.transform.rotation, Vector3.one))) + EditorGUI.BeginChangeCheck(); + Vector3 newPosition = ProjectedTransform.DrawHandles(decalProjector.transform.position, .5f * decalProjector.size.z - decalProjector.offset.z, decalProjector.transform.rotation); + if (EditorGUI.EndChangeCheck()) { - EditorGUI.BeginChangeCheck(); - Vector3 newPosition = ProjectedTransform.DrawHandles(decalProjector.transform.position, .5f * decalProjector.size.z - decalProjector.offset.z, decalProjector.transform.rotation); - if (EditorGUI.EndChangeCheck()) - { - Undo.RecordObjects(new UnityEngine.Object[] { decalProjector, decalProjector.transform }, "Decal Projector Change"); + Undo.RecordObjects(new UnityEngine.Object[] { decalProjector, decalProjector.transform }, "Decal Projector Change"); - decalProjector.offset += Quaternion.Inverse(decalProjector.transform.rotation) * (decalProjector.transform.position - newPosition); - decalProjector.transform.position = newPosition; - } + decalProjector.offset += Quaternion.Inverse(decalProjector.transform.rotation) * (decalProjector.transform.position - newPosition); + decalProjector.transform.position = newPosition; } + } + } + + void DrawUVHandles(DecalProjector decalProjector) + { + using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position + decalProjector.transform.rotation * (decalProjector.offset - .5f * decalProjector.size), decalProjector.transform.rotation, Vector3.one))) + { + Vector2 uvSize = new Vector2( + (decalProjector.uvScale.x > k_Limit || decalProjector.uvScale.x < -k_Limit) ? 0f : decalProjector.size.x / decalProjector.uvScale.x, + (decalProjector.uvScale.y > k_Limit || decalProjector.uvScale.y < -k_Limit) ? 0f : decalProjector.size.y / decalProjector.uvScale.y + ); + Vector2 uvCenter = uvSize * .5f - new Vector2(decalProjector.uvBias.x * uvSize.x, decalProjector.uvBias.y * uvSize.y); - // UV - using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position + decalProjector.transform.rotation * (decalProjector.offset - .5f * decalProjector.size), decalProjector.transform.rotation, Vector3.one))) - { - Vector2 UVSize = new Vector2( - (decalProjector.uvScale.x > k_Limit || decalProjector.uvScale.x < -k_Limit) ? 0f : decalProjector.size.x / decalProjector.uvScale.x, - (decalProjector.uvScale.y > k_Limit || decalProjector.uvScale.y < -k_Limit) ? 0f : decalProjector.size.y / decalProjector.uvScale.y - ); - Vector2 UVCenter = UVSize * .5f - new Vector2(decalProjector.uvBias.x * UVSize.x, decalProjector.uvBias.y * UVSize.y); + uvHandles.center = uvCenter; + uvHandles.size = uvSize; - UVHandles.center = UVCenter; - UVHandles.size = UVSize; + EditorGUI.BeginChangeCheck(); + uvHandles.DrawHandle(); + if (EditorGUI.EndChangeCheck()) + { + Undo.RecordObject(decalProjector, "Decal Projector Change"); - EditorGUI.BeginChangeCheck(); - UVHandles.DrawHandle(); - if (EditorGUI.EndChangeCheck()) + Vector2 limit = new Vector2(Mathf.Abs(decalProjector.size.x * k_LimitInv), Mathf.Abs(decalProjector.size.y * k_LimitInv)); + Vector2 uvScale = uvHandles.size; + for (int channel = 0; channel < 2; channel++) { - Undo.RecordObject(decalProjector, "Decal Projector Change"); - - Vector2 limit = new Vector2(Mathf.Abs(decalProjector.size.x * k_LimitInv), Mathf.Abs(decalProjector.size.y * k_LimitInv)); - Vector2 uvScale = UVHandles.size; - for (int channel = 0; channel < 2; channel++) - { - if (Mathf.Abs(uvScale[channel]) > limit[channel]) - uvScale[channel] = decalProjector.size[channel] / uvScale[channel]; - else - uvScale[channel] = Mathf.Sign(decalProjector.size[channel]) * Mathf.Sign(uvScale[channel]) * k_Limit; - } - decalProjector.uvScale = uvScale; - - var newUVStart = UVHandles.center - .5f * UVHandles.size; - decalProjector.uvBias = -new Vector2( - (UVHandles.size.x < k_LimitInv) && (UVHandles.size.x > -k_LimitInv) ? k_Limit * newUVStart.x / decalProjector.size.x : newUVStart.x / UVHandles.size.x, //parenthesis to force format tool - (UVHandles.size.y < k_LimitInv) && (UVHandles.size.y > -k_LimitInv) ? k_Limit * newUVStart.y / decalProjector.size.y : newUVStart.y / UVHandles.size.y //parenthesis to force format tool - ); + if (Mathf.Abs(uvScale[channel]) > limit[channel]) + uvScale[channel] = decalProjector.size[channel] / uvScale[channel]; + else + uvScale[channel] = Mathf.Sign(decalProjector.size[channel]) * Mathf.Sign(uvScale[channel]) * k_Limit; } + decalProjector.uvScale = uvScale; + + var newUVStart = uvHandles.center - .5f * uvHandles.size; + decalProjector.uvBias = -new Vector2( + (uvHandles.size.x < k_LimitInv) && (uvHandles.size.x > -k_LimitInv) ? k_Limit * newUVStart.x / decalProjector.size.x : newUVStart.x / uvHandles.size.x, //parenthesis to force format tool + (uvHandles.size.y < k_LimitInv) && (uvHandles.size.y > -k_LimitInv) ? k_Limit * newUVStart.y / decalProjector.size.y : newUVStart.y / uvHandles.size.y //parenthesis to force format tool + ); } } } + void DrawHandles() + { + DecalProjector decalProjector = target as DecalProjector; + + if (editMode == k_EditShapePreservingUV || editMode == k_EditShapeWithoutPreservingUV) + DrawBoxTransformationHandles(decalProjector); + else if (editMode == k_EditUVAndPivot) + { + DrawPivotHandles(decalProjector); + DrawUVHandles(decalProjector); + } + } + [DrawGizmo(GizmoType.Selected | GizmoType.Active)] static void DrawGizmosSelected(DecalProjector decalProjector, GizmoType gizmoType) { @@ -424,7 +433,6 @@ static void DrawGizmosSelected(DecalProjector decalProjector, GizmoType gizmoTyp } else { - Quaternion arrowRotation = Quaternion.LookRotation(Vector3.down, Vector3.right); float arrowSize = decalProjector.size.z * 0.25f; Handles.ArrowHandleCap(0, projectedPivot, Quaternion.identity, arrowSize, EventType.Repaint); } @@ -438,13 +446,13 @@ static void DrawGizmosSelected(DecalProjector decalProjector, GizmoType gizmoTyp ); Vector2 UVCenter = UVSize * .5f - new Vector2(decalProjector.uvBias.x * UVSize.x, decalProjector.uvBias.y * UVSize.y) - (Vector2)decalProjector.size * .5f; - UVHandles.center = UVCenter; - UVHandles.size = UVSize; - UVHandles.DrawRect(dottedLine: true, screenSpaceSize: k_DotLength); + uvHandles.center = UVCenter; + uvHandles.size = UVSize; + uvHandles.DrawRect(dottedLine: true, screenSpaceSize: k_DotLength); - UVHandles.center = default; - UVHandles.size = decalProjector.size; - UVHandles.DrawRect(dottedLine: false, sickness: 3f); + uvHandles.center = default; + uvHandles.size = decalProjector.size; + uvHandles.DrawRect(dottedLine: false, thickness: 3f); } } } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs index b3c5d1efff6..a32a1694a82 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs @@ -52,12 +52,9 @@ public Color baseColor get { return m_MonochromeHandleColor; } set { - value.a = 1f; - m_MonochromeHandleColor = value; - value.a = 0.7f; - m_WireframeColor = value; - value.a = 0.2f; - m_WireframeColorBehind = value; + m_MonochromeHandleColor = GizmoUtility.GetHandleColor(value); + m_WireframeColor = GizmoUtility.GetWireframeColor(value); + m_WireframeColorBehind = GizmoUtility.GetWireframeColorBehindObjects(value); } } @@ -67,7 +64,7 @@ public DisplacableRectHandles(Color baseColor) } /// Draw the rect. - public void DrawRect(bool dottedLine = false, float sickness = .0f, float screenSpaceSize = 5f) + public void DrawRect(bool dottedLine = false, float thickness = .0f, float screenSpaceSize = 5f) { Vector2 start = center - size * .5f; Vector3[] positions = new Vector3[] @@ -91,10 +88,10 @@ void Draw() Handles.DrawDottedLines(edges, screenSpaceSize); else { - Handles.DrawLine(positions[0], positions[1], sickness); - Handles.DrawLine(positions[1], positions[2], sickness); - Handles.DrawLine(positions[2], positions[3], sickness); - Handles.DrawLine(positions[3], positions[0], sickness); + Handles.DrawLine(positions[0], positions[1], thickness); + Handles.DrawLine(positions[1], positions[2], thickness); + Handles.DrawLine(positions[2], positions[3], thickness); + Handles.DrawLine(positions[3], positions[0], thickness); } } @@ -109,25 +106,10 @@ void Draw() Handles.color = previousColor; } - /// Draw the manipulable handles - public void DrawHandle() + NamedEdge DrawSliders(ref Vector3 leftPosition, ref Vector3 rightPosition, ref Vector3 topPosition, ref Vector3 bottomPosition) { - Event evt = Event.current; - bool useHomothety = evt.shift; - bool useSymetry = evt.alt || evt.command; - // Note: snapping is handled natively on ctrl for each Slider1D - - for (int i = 0, count = m_ControlIDs.Length; i < count; ++i) - m_ControlIDs[i] = GUIUtility.GetControlID("DisplacableRectHandles".GetHashCode() + i, FocusType.Passive); - - Vector3 leftPosition = center + size.x * .5f * Vector2.left; - Vector3 rightPosition = center + size.x * .5f * Vector2.right; - Vector3 topPosition = center + size.y * .5f * Vector2.up; - Vector3 bottomPosition = center + size.y * .5f * Vector2.down; - - var theChangedEdge = NamedEdge.None; - - EditorGUI.BeginChangeCheck(); + NamedEdge theChangedEdge = NamedEdge.None; + using (new Handles.DrawingScope(m_MonochromeHandleColor)) { EditorGUI.BeginChangeCheck(); @@ -150,6 +132,93 @@ public void DrawHandle() if (EditorGUI.EndChangeCheck()) theChangedEdge = NamedEdge.Bottom; } + + return theChangedEdge; + } + + void EnsureEdgeFacesOutsideForHomothety(NamedEdge theChangedEdge, ref Vector3 leftPosition, ref Vector3 rightPosition, ref Vector3 topPosition, ref Vector3 bottomPosition) + { + switch (theChangedEdge) + { + case NamedEdge.Left: + if (rightPosition.x < leftPosition.x) + leftPosition.x = rightPosition.x; + if (topPosition.y < bottomPosition.y) + topPosition.y = bottomPosition.y = center.y; + break; + case NamedEdge.Right: + if (rightPosition.x < leftPosition.x) + rightPosition.x = leftPosition.x; + if (topPosition.y < bottomPosition.y) + topPosition.y = bottomPosition.y = center.y; + break; + case NamedEdge.Top: + if (topPosition.y < bottomPosition.y) + topPosition.y = bottomPosition.y; + if (rightPosition.x < leftPosition.x) + rightPosition.x = leftPosition.x = center.x; + break; + case NamedEdge.Bottom: + if (topPosition.y < bottomPosition.y) + bottomPosition.y = topPosition.y; + if (rightPosition.x < leftPosition.x) + rightPosition.x = leftPosition.x = center.x; + break; + } + } + + void EnsureEdgeFacesOutsideForSymetry(NamedEdge theChangedEdge, ref Vector3 leftPosition, ref Vector3 rightPosition, ref Vector3 topPosition, ref Vector3 bottomPosition) + { + switch (theChangedEdge) + { + case NamedEdge.Left: + case NamedEdge.Right: + if (rightPosition.x < leftPosition.x) + rightPosition.x = leftPosition.x = center.x; + break; + case NamedEdge.Top: + case NamedEdge.Bottom: + if (topPosition.y < bottomPosition.y) + topPosition.y = bottomPosition.y = center.y; + break; + } + } + + void EnsureEdgeFacesOutsideForOtherTransformation(ref Vector2 max, ref Vector2 min) + { + for (int axis = 0; axis < 2; ++axis) + { + if (min[axis] > max[axis]) + { + // Control IDs in m_ControlIDs[0-1] are for positive axes + if (GUIUtility.hotControl == m_ControlIDs[axis]) + max[axis] = min[axis]; + else + min[axis] = max[axis]; + } + } + } + + /// Draw the manipulable handles + public void DrawHandle() + { + Event evt = Event.current; + bool useHomothety = evt.shift; + bool useSymetry = evt.alt || evt.command; + // Note: snapping is handled natively on ctrl for each Slider1D + + for (int i = 0, count = m_ControlIDs.Length; i < count; ++i) + m_ControlIDs[i] = GUIUtility.GetControlID("DisplacableRectHandles".GetHashCode() + i, FocusType.Passive); + + Vector3 leftPosition = center + size.x * .5f * Vector2.left; + Vector3 rightPosition = center + size.x * .5f * Vector2.right; + Vector3 topPosition = center + size.y * .5f * Vector2.up; + Vector3 bottomPosition = center + size.y * .5f * Vector2.down; + + var theChangedEdge = NamedEdge.None; + + EditorGUI.BeginChangeCheck(); + theChangedEdge = DrawSliders(ref leftPosition, ref rightPosition, ref topPosition, ref bottomPosition); if (EditorGUI.EndChangeCheck()) { float delta = 0f; @@ -189,20 +258,7 @@ public void DrawHandle() case NamedEdge.Bottom: topPosition.y -= delta; break; } - //ensure that the rect edges are still facing outside - switch (theChangedEdge) - { - case NamedEdge.Left: - case NamedEdge.Right: - if (rightPosition.x < leftPosition.x) - rightPosition.x = leftPosition.x = center.x; - break; - case NamedEdge.Top: - case NamedEdge.Bottom: - if (topPosition.y < bottomPosition.y) - topPosition.y = bottomPosition.y = center.y; - break; - } + EnsureEdgeFacesOutsideForSymetry(theChangedEdge, ref leftPosition, ref rightPosition, ref topPosition, ref bottomPosition); } if (useHomothety) @@ -222,61 +278,19 @@ public void DrawHandle() break; } - //ensure that the rect edges are still facing outside - switch (theChangedEdge) - { - case NamedEdge.Left: - if (rightPosition.x < leftPosition.x) - leftPosition.x = rightPosition.x; - if (topPosition.y < bottomPosition.y) - topPosition.y = bottomPosition.y = center.y; - break; - case NamedEdge.Right: - if (rightPosition.x < leftPosition.x) - rightPosition.x = leftPosition.x; - if (topPosition.y < bottomPosition.y) - topPosition.y = bottomPosition.y = center.y; - break; - case NamedEdge.Top: - if (topPosition.y < bottomPosition.y) - topPosition.y = bottomPosition.y; - if (rightPosition.x < leftPosition.x) - rightPosition.x = leftPosition.x = center.x; - break; - case NamedEdge.Bottom: - if (topPosition.y < bottomPosition.y) - bottomPosition.y = topPosition.y; - if (rightPosition.x < leftPosition.x) - rightPosition.x = leftPosition.x = center.x; - break; - } + EnsureEdgeFacesOutsideForHomothety(theChangedEdge, ref leftPosition, ref rightPosition, ref topPosition, ref bottomPosition); } var max = new Vector2(rightPosition.x, topPosition.y); var min = new Vector2(leftPosition.x, bottomPosition.y); if (!useSymetry && !useHomothety) - { - //ensure that the rect edges are still facing outside - for (int axis = 0; axis < 2; ++axis) - { - if (min[axis] > max[axis]) - { - // Control IDs in m_ControlIDs[0-3[ are for positive axes - if (GUIUtility.hotControl == m_ControlIDs[axis]) - max[axis] = min[axis]; - else - min[axis] = max[axis]; - } - } - } + EnsureEdgeFacesOutsideForOtherTransformation(ref max, ref min); center = (max + min) * .5f; size = max - min; } } } - - internal string debug => $"center:({center.x},{center.y}) size:({size.x},{size.y})"; } } diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs index 6f0c060f728..08215efe205 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs @@ -67,10 +67,9 @@ public override int GetHashCode() public override bool Equals(object obj) { - if (!(obj is PositionHandleIds)) + if (!(obj is PositionHandleIds o)) return false; - - var o = (PositionHandleIds)obj; + return o.x == x && o.y == y && o.z == z && o.xy == xy; } } From 98b20602d1e17599ff7e90ad9fe44414549aeb2e Mon Sep 17 00:00:00 2001 From: RSlysz Date: Wed, 20 Jan 2021 12:31:01 +0100 Subject: [PATCH 18/20] fix format --- .../Editor/Gizmo/GizmoUtility.cs | 2 ++ com.unity.render-pipelines.high-definition/CHANGELOG.md | 2 +- .../Editor/Material/Decal/DecalProjectorEditor.cs | 4 ++-- .../Editor/Material/Decal/DisplacableRectHandles.cs | 6 +++--- .../Editor/Material/Decal/ProjectedTransform.cs | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/com.unity.render-pipelines.core/Editor/Gizmo/GizmoUtility.cs b/com.unity.render-pipelines.core/Editor/Gizmo/GizmoUtility.cs index ff01839b6af..2e24de36207 100644 --- a/com.unity.render-pipelines.core/Editor/Gizmo/GizmoUtility.cs +++ b/com.unity.render-pipelines.core/Editor/Gizmo/GizmoUtility.cs @@ -10,11 +10,13 @@ public static Color GetHandleColor(Color baseColor) baseColor.a = 1f; return baseColor; } + public static Color GetWireframeColor(Color baseColor) { baseColor.a = .7f; return baseColor; } + public static Color GetWireframeColorBehindObjects(Color baseColor) { baseColor.a = .2f; diff --git a/com.unity.render-pipelines.high-definition/CHANGELOG.md b/com.unity.render-pipelines.high-definition/CHANGELOG.md index 7ce48edf942..538ea16409b 100644 --- a/com.unity.render-pipelines.high-definition/CHANGELOG.md +++ b/com.unity.render-pipelines.high-definition/CHANGELOG.md @@ -36,7 +36,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fixed issues with compositor's undo (cases 1305633, 1307170). ### Changed -- Removed the material pass probe volumes evaluation mode. +- Removed the material pass probe volumes evaluation mode. - Change the source value for the ray tracing frame index iterator from m_FrameCount to the camera frame count (case 1301356). ## [11.0.0] - 2020-10-21 diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs index 73abaa43b14..d8e613c7aa6 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs @@ -339,7 +339,7 @@ void DrawBoxTransformationHandles(DecalProjector decalProjector) } } } - + void DrawPivotHandles(DecalProjector decalProjector) { using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(Vector3.zero, decalProjector.transform.rotation, Vector3.one))) @@ -355,7 +355,7 @@ void DrawPivotHandles(DecalProjector decalProjector) } } } - + void DrawUVHandles(DecalProjector decalProjector) { using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position + decalProjector.transform.rotation * (decalProjector.offset - .5f * decalProjector.size), decalProjector.transform.rotation, Vector3.one))) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs index a32a1694a82..6579041a564 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DisplacableRectHandles.cs @@ -109,7 +109,7 @@ void Draw() NamedEdge DrawSliders(ref Vector3 leftPosition, ref Vector3 rightPosition, ref Vector3 topPosition, ref Vector3 bottomPosition) { NamedEdge theChangedEdge = NamedEdge.None; - + using (new Handles.DrawingScope(m_MonochromeHandleColor)) { EditorGUI.BeginChangeCheck(); @@ -166,7 +166,7 @@ void EnsureEdgeFacesOutsideForHomothety(NamedEdge theChangedEdge, ref Vector3 le break; } } - + void EnsureEdgeFacesOutsideForSymetry(NamedEdge theChangedEdge, ref Vector3 leftPosition, ref Vector3 rightPosition, ref Vector3 topPosition, ref Vector3 bottomPosition) { switch (theChangedEdge) @@ -183,7 +183,7 @@ void EnsureEdgeFacesOutsideForSymetry(NamedEdge theChangedEdge, ref Vector3 left break; } } - + void EnsureEdgeFacesOutsideForOtherTransformation(ref Vector2 max, ref Vector2 min) { for (int axis = 0; axis < 2; ++axis) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs index 08215efe205..5b1dcc86277 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/ProjectedTransform.cs @@ -69,7 +69,7 @@ public override bool Equals(object obj) { if (!(obj is PositionHandleIds o)) return false; - + return o.x == x && o.y == y && o.z == z && o.xy == xy; } } From 607f609ddb95fb25b03306639b33bf437a04775f Mon Sep 17 00:00:00 2001 From: RSlysz Date: Thu, 21 Jan 2021 12:31:09 +0100 Subject: [PATCH 19/20] Add missing API to update pivot from script --- .../Material/Decal/DecalProjectorEditor.cs | 16 ++++++------- .../Runtime/Material/Decal/DecalProjector.cs | 24 +++++++++++++------ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs index d8e613c7aa6..7249f918217 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs @@ -294,7 +294,7 @@ void DrawBoxTransformationHandles(DecalProjector decalProjector) { using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, Vector3.one))) { - Vector3 centerStart = decalProjector.offset; + Vector3 centerStart = decalProjector.pivot; boxHandle.center = centerStart; boxHandle.size = decalProjector.size; @@ -309,7 +309,7 @@ void DrawBoxTransformationHandles(DecalProjector decalProjector) Undo.RecordObject(decalProjector, "Decal Projector Change"); decalProjector.size = boxHandle.size; - decalProjector.offset += boxHandle.center - centerStart; + decalProjector.pivot += boxHandle.center - centerStart; Vector3 boundsSizeCurrentOS = boxHandle.size; Vector3 boundsMinCurrentOS = boxHandle.size * -0.5f + boxHandle.center; @@ -345,12 +345,12 @@ void DrawPivotHandles(DecalProjector decalProjector) using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(Vector3.zero, decalProjector.transform.rotation, Vector3.one))) { EditorGUI.BeginChangeCheck(); - Vector3 newPosition = ProjectedTransform.DrawHandles(decalProjector.transform.position, .5f * decalProjector.size.z - decalProjector.offset.z, decalProjector.transform.rotation); + Vector3 newPosition = ProjectedTransform.DrawHandles(decalProjector.transform.position, .5f * decalProjector.size.z - decalProjector.pivot.z, decalProjector.transform.rotation); if (EditorGUI.EndChangeCheck()) { Undo.RecordObjects(new UnityEngine.Object[] { decalProjector, decalProjector.transform }, "Decal Projector Change"); - decalProjector.offset += Quaternion.Inverse(decalProjector.transform.rotation) * (decalProjector.transform.position - newPosition); + decalProjector.pivot += Quaternion.Inverse(decalProjector.transform.rotation) * (decalProjector.transform.position - newPosition); decalProjector.transform.position = newPosition; } } @@ -358,7 +358,7 @@ void DrawPivotHandles(DecalProjector decalProjector) void DrawUVHandles(DecalProjector decalProjector) { - using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position + decalProjector.transform.rotation * (decalProjector.offset - .5f * decalProjector.size), decalProjector.transform.rotation, Vector3.one))) + using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position + decalProjector.transform.rotation * (decalProjector.pivot - .5f * decalProjector.size), decalProjector.transform.rotation, Vector3.one))) { Vector2 uvSize = new Vector2( (decalProjector.uvScale.x > k_Limit || decalProjector.uvScale.x < -k_Limit) ? 0f : decalProjector.size.x / decalProjector.uvScale.x, @@ -418,14 +418,14 @@ static void DrawGizmosSelected(DecalProjector decalProjector, GizmoType gizmoTyp //draw them scale independent using (new Handles.DrawingScope(fullColor, Matrix4x4.TRS(decalProjector.transform.position, decalProjector.transform.rotation, Vector3.one))) { - boxHandle.center = decalProjector.offset; + boxHandle.center = decalProjector.pivot; boxHandle.size = decalProjector.size; bool isVolumeEditMode = editMode == k_EditShapePreservingUV || editMode == k_EditShapeWithoutPreservingUV; bool isPivotEditMode = editMode == k_EditUVAndPivot; boxHandle.DrawHull(isVolumeEditMode); Vector3 pivot = Vector3.zero; - Vector3 projectedPivot = new Vector3(0, 0, decalProjector.offset.z - .5f * decalProjector.size.z); + Vector3 projectedPivot = new Vector3(0, 0, decalProjector.pivot.z - .5f * decalProjector.size.z); if (isPivotEditMode) { @@ -438,7 +438,7 @@ static void DrawGizmosSelected(DecalProjector decalProjector, GizmoType gizmoTyp } //draw UV and bolder edges - using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position + decalProjector.transform.rotation * new Vector3(decalProjector.offset.x, decalProjector.offset.y, decalProjector.offset.z - .5f * decalProjector.size.z), decalProjector.transform.rotation, Vector3.one))) + using (new Handles.DrawingScope(Matrix4x4.TRS(decalProjector.transform.position + decalProjector.transform.rotation * new Vector3(decalProjector.pivot.x, decalProjector.pivot.y, decalProjector.pivot.z - .5f * decalProjector.size.z), decalProjector.transform.rotation, Vector3.one))) { Vector2 UVSize = new Vector2( (decalProjector.uvScale.x > k_Limit || decalProjector.uvScale.x < -k_Limit) ? 0f : decalProjector.size.x / decalProjector.uvScale.x, diff --git a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.cs b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.cs index 27e9764c59b..ee36a76a410 100644 --- a/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.cs +++ b/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.cs @@ -182,10 +182,10 @@ public DecalLayerEnum decalLayerMask [SerializeField] private Vector3 m_Offset = new Vector3(0, 0, 0.5f); /// - /// Change the offset position. - /// Do not expose: Could be changed by the inspector when manipulating the gizmo. + /// Change the pivot position. + /// It is an offset between the center of the projection and the transform position. /// - internal Vector3 offset + public Vector3 pivot { get { @@ -202,13 +202,11 @@ internal Vector3 offset Vector3 m_Size = new Vector3(1, 1, 1); /// /// The size of the projection volume. + /// See also to rescale relatively to the pivot position. /// public Vector3 size { - get - { - return m_Size; - } + get => m_Size; set { m_Size = value; @@ -216,6 +214,18 @@ public Vector3 size } } + /// + /// Update the pivot to resize centered on the pivot position. + /// + /// The new size. + public void ResizeAroundPivot(Vector3 newSize) + { + for (int axis = 0; axis < 3; ++axis) + if (m_Size[axis] > Mathf.Epsilon) + m_Offset[axis] *= newSize[axis] / m_Size[axis]; + size = newSize; + } + [SerializeField] [Range(0, 1)] private float m_FadeFactor = 1.0f; From 054b033a13fb4ac2d876118b2e37fbfeb386aafb Mon Sep 17 00:00:00 2001 From: RSlysz Date: Fri, 22 Jan 2021 11:19:47 +0100 Subject: [PATCH 20/20] Add falback when swap edit mode on mode 1 --- .../Editor/Material/Decal/DecalProjectorEditor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs index 7249f918217..97396e1feab 100644 --- a/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs +++ b/com.unity.render-pipelines.high-definition/Editor/Material/Decal/DecalProjectorEditor.cs @@ -665,6 +665,7 @@ static void SwappingEditUVMode(ShortcutArguments args) switch (editMode) { case k_EditShapePreservingUV: + case k_EditUVAndPivot: targetMode = k_EditShapeWithoutPreservingUV; break; case k_EditShapeWithoutPreservingUV: