Beispiel #1
0
        private void UndoRedoPerformed()
        {
            LatticeDeformer latticeDeformer = ((LatticeDeformer)target);

            newResolution = latticeDeformer.Resolution;
            CacheResizePositionsFromChange();
        }
Beispiel #2
0
        protected override void OnEnable()
        {
            base.OnEnable();

            properties = new Properties(serializedObject);

            LatticeDeformer latticeDeformer = ((LatticeDeformer)target);

            newResolution = latticeDeformer.Resolution;
            CacheResizePositionsFromChange();

            Undo.undoRedoPerformed += UndoRedoPerformed;
        }
Beispiel #3
0
        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();

            LatticeDeformer latticeDeformer = ((LatticeDeformer)target);

            serializedObject.UpdateIfRequiredOrScript();

            EditorGUI.BeginChangeCheck();

            newResolution = EditorGUILayout.Vector3IntField(Content.Resolution, newResolution);
            // Make sure we have at least two control points per axis
            newResolution = Vector3Int.Max(newResolution, new Vector3Int(2, 2, 2));
            // Don't let the lattice resolution get ridiculously high
            newResolution = Vector3Int.Min(newResolution, new Vector3Int(32, 32, 32));

            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(target, "Update Lattice");
                latticeDeformer.GenerateControlPoints(newResolution, cachedResizePositions, cachedResizeResolution);
                selectedIndices.Clear();
            }

            if (GUILayout.Button("Reset Lattice Points"))
            {
                Undo.RecordObject(target, "Reset Lattice Points");
                latticeDeformer.GenerateControlPoints(newResolution);
                selectedIndices.Clear();

                CacheResizePositionsFromChange();
            }

            if (latticeDeformer.CanAutoFitBounds)
            {
                if (GUILayout.Button("Auto-Fit Bounds"))
                {
                    Undo.RecordObject(latticeDeformer.transform, "Auto-Fit Bounds");
                    latticeDeformer.FitBoundsToParentDeformable();
                }
            }

            serializedObject.ApplyModifiedProperties();

            EditorApplication.QueuePlayerLoopUpdate();
        }
Beispiel #4
0
        private void DrawLattice(LatticeDeformer lattice, DeformHandles.LineMode lineMode)
        {
            var resolution    = lattice.Resolution;
            var controlPoints = lattice.ControlPoints;

            for (int z = 0; z < resolution.z - 1; z++)
            {
                for (int y = 0; y < resolution.y - 1; y++)
                {
                    for (int x = 0; x < resolution.x - 1; x++)
                    {
                        int index000 = lattice.GetIndex(x, y, z);
                        int index100 = lattice.GetIndex(x + 1, y, z);
                        int index010 = lattice.GetIndex(x, y + 1, z);
                        int index110 = lattice.GetIndex(x + 1, y + 1, z);
                        int index001 = lattice.GetIndex(x, y, z + 1);
                        int index101 = lattice.GetIndex(x + 1, y, z + 1);
                        int index011 = lattice.GetIndex(x, y + 1, z + 1);
                        int index111 = lattice.GetIndex(x + 1, y + 1, z + 1);

                        DeformHandles.Line(controlPoints[index000], controlPoints[index100], lineMode);
                        DeformHandles.Line(controlPoints[index010], controlPoints[index110], lineMode);
                        DeformHandles.Line(controlPoints[index001], controlPoints[index101], lineMode);
                        DeformHandles.Line(controlPoints[index011], controlPoints[index111], lineMode);

                        DeformHandles.Line(controlPoints[index000], controlPoints[index010], lineMode);
                        DeformHandles.Line(controlPoints[index100], controlPoints[index110], lineMode);
                        DeformHandles.Line(controlPoints[index001], controlPoints[index011], lineMode);
                        DeformHandles.Line(controlPoints[index101], controlPoints[index111], lineMode);

                        DeformHandles.Line(controlPoints[index000], controlPoints[index001], lineMode);
                        DeformHandles.Line(controlPoints[index100], controlPoints[index101], lineMode);
                        DeformHandles.Line(controlPoints[index010], controlPoints[index011], lineMode);
                        DeformHandles.Line(controlPoints[index110], controlPoints[index111], lineMode);
                    }
                }
            }
        }
Beispiel #5
0
        public override void OnSceneGUI()
        {
            base.OnSceneGUI();

            LatticeDeformer lattice   = target as LatticeDeformer;
            Transform       transform = lattice.transform;

            float3[] controlPoints = lattice.ControlPoints;
            Event    e             = Event.current;

            using (new Handles.DrawingScope(transform.localToWorldMatrix))
            {
                var cachedZTest = Handles.zTest;

                // Change the depth testing to only show handles in front of solid objects (i.e. typical depth testing)
                Handles.zTest = CompareFunction.LessEqual;
                DrawLattice(lattice, DeformHandles.LineMode.Solid);
                // Change the depth testing to only show handles *behind* solid objects
                Handles.zTest = CompareFunction.Greater;
                DrawLattice(lattice, DeformHandles.LineMode.Light);

                // Restore the original z test value now we're done with our drawing
                Handles.zTest = cachedZTest;

                var resolution = lattice.Resolution;
                for (int z = 0; z < resolution.z; z++)
                {
                    for (int y = 0; y < resolution.y; y++)
                    {
                        for (int x = 0; x < resolution.x; x++)
                        {
                            var controlPointHandleID = GUIUtility.GetControlID("LatticeDeformerControlPoint".GetHashCode(), FocusType.Passive);
                            var activeColor          = DeformEditorSettings.SolidHandleColor;
                            var controlPointIndex    = lattice.GetIndex(x, y, z);

                            if (GUIUtility.hotControl == controlPointHandleID || selectedIndices.Contains(controlPointIndex))
                            {
                                activeColor = Handles.selectedColor;
                            }
                            else if (HandleUtility.nearestControl == controlPointHandleID)
                            {
                                activeColor = Handles.preselectionColor;
                            }

                            if (e.type == EventType.MouseDown && HandleUtility.nearestControl == controlPointHandleID && e.button == 0 && MouseActionAllowed)
                            {
                                BeginSelectionChangeRegion();
                                GUIUtility.hotControl      = controlPointHandleID;
                                GUIUtility.keyboardControl = controlPointHandleID;
                                e.Use();

                                bool modifierKeyPressed = e.control || e.shift || e.command;

                                if (modifierKeyPressed && selectedIndices.Contains(controlPointIndex))
                                {
                                    // Pressed a modifier key so toggle the selection
                                    selectedIndices.Remove(controlPointIndex);
                                }
                                else
                                {
                                    if (!modifierKeyPressed)
                                    {
                                        selectedIndices.Clear();
                                    }

                                    if (!selectedIndices.Contains(controlPointIndex))
                                    {
                                        selectedIndices.Add(controlPointIndex);
                                    }
                                }

                                EndSelectionChangeRegion();
                            }

                            if (Tools.current != Tool.None && selectedIndices.Count != 0)
                            {
                                // If the user changes tool, change our internal mode to match but disable the corresponding Unity tool
                                // (e.g. they hit W key or press on the Rotate Tool button on the top left toolbar)
                                activeTool    = Tools.current;
                                Tools.current = Tool.None;
                            }

                            using (new Handles.DrawingScope(activeColor))
                            {
                                var position = controlPoints[controlPointIndex];
                                var size     = HandleUtility.GetHandleSize(position) * DeformEditorSettings.ScreenspaceLatticeHandleCapSize;

                                Handles.DotHandleCap(
                                    controlPointHandleID,
                                    position,
                                    Quaternion.identity,
                                    size,
                                    e.type);
                            }
                        }
                    }
                }
            }

            var defaultControl = DeformUnityObjectSelection.DisableSceneViewObjectSelection();

            if (selectedIndices.Count != 0)
            {
                var currentPivotPosition = float3.zero;

                if (Tools.pivotMode == PivotMode.Center)
                {
                    // Get the average position
                    foreach (var index in selectedIndices)
                    {
                        currentPivotPosition += controlPoints[index];
                    }

                    currentPivotPosition /= selectedIndices.Count;
                }
                else
                {
                    // Match the scene view behaviour that Pivot mode uses the last selected object as pivot
                    currentPivotPosition = controlPoints[selectedIndices.Last()];
                }

                float3 handlePosition = transform.TransformPoint(currentPivotPosition);

                if (e.type == EventType.MouseDown)
                {
                    // Potentially started interacting with a handle so reset everything
                    handleScale = Vector3.one;
                    // Make sure we cache the positions just before the interaction changes them
                    CacheOriginalPositions();
                }

                var originalPivotPosition = float3.zero;

                if (Tools.pivotMode == PivotMode.Center)
                {
                    // Get the average position
                    foreach (var originalPosition in selectedOriginalPositions)
                    {
                        originalPivotPosition += originalPosition;
                    }

                    originalPivotPosition /= selectedIndices.Count;
                }
                else
                {
                    // Match the scene view behaviour that Pivot mode uses the last selected object as pivot
                    originalPivotPosition = selectedOriginalPositions.Last();
                }

                var handleRotation = transform.rotation;
                if (Tools.pivotRotation == PivotRotation.Global)
                {
                    handleRotation = Quaternion.identity;
                }

                if (activeTool == Tool.Move)
                {
                    EditorGUI.BeginChangeCheck();
                    float3 newPosition = Handles.PositionHandle(handlePosition, handleRotation);
                    if (EditorGUI.EndChangeCheck())
                    {
                        Undo.RecordObject(target, "Update Lattice");

                        var delta = newPosition - handlePosition;
                        delta = transform.InverseTransformVector(delta);
                        foreach (var selectedIndex in selectedIndices)
                        {
                            controlPoints[selectedIndex] += delta;
                        }

                        CacheResizePositionsFromChange();
                    }
                }
                else if (activeTool == Tool.Rotate)
                {
                    EditorGUI.BeginChangeCheck();
                    quaternion newRotation = Handles.RotationHandle(handleRotation, handlePosition);
                    if (EditorGUI.EndChangeCheck())
                    {
                        Undo.RecordObject(target, "Update Lattice");

                        for (var index = 0; index < selectedIndices.Count; index++)
                        {
                            if (Tools.pivotRotation == PivotRotation.Global)
                            {
                                controlPoints[selectedIndices[index]] = originalPivotPosition + (float3)transform.InverseTransformDirection(mul(newRotation, transform.TransformDirection(selectedOriginalPositions[index] - originalPivotPosition)));
                            }
                            else
                            {
                                controlPoints[selectedIndices[index]] = originalPivotPosition + mul(mul(inverse(handleRotation), newRotation), (selectedOriginalPositions[index] - originalPivotPosition));
                            }
                        }

                        CacheResizePositionsFromChange();
                    }
                }
                else if (activeTool == Tool.Scale)
                {
                    var size = HandleUtility.GetHandleSize(handlePosition);
                    EditorGUI.BeginChangeCheck();
                    handleScale = Handles.ScaleHandle(handleScale, handlePosition, handleRotation, size);
                    if (EditorGUI.EndChangeCheck())
                    {
                        Undo.RecordObject(target, "Update Lattice");

                        for (var index = 0; index < selectedIndices.Count; index++)
                        {
                            if (Tools.pivotRotation == PivotRotation.Global)
                            {
                                controlPoints[selectedIndices[index]] = originalPivotPosition + (float3)transform.InverseTransformDirection(handleScale * transform.TransformDirection(selectedOriginalPositions[index] - originalPivotPosition));
                            }
                            else
                            {
                                controlPoints[selectedIndices[index]] = originalPivotPosition + handleScale * (selectedOriginalPositions[index] - originalPivotPosition);
                            }
                        }

                        CacheResizePositionsFromChange();
                    }
                }

                Handles.BeginGUI();
                if (GUI.Button(new Rect((EditorGUIUtility.currentViewWidth - 200) / 2, SceneView.currentDrawingSceneView.position.height - 60, 200, 30), Content.StopEditing))
                {
                    DeselectAll();
                }

                Handles.EndGUI();
            }

            if (e.button == 0) // Left Mouse Button
            {
                if (e.type == EventType.MouseDown && HandleUtility.nearestControl == defaultControl && MouseActionAllowed)
                {
                    mouseDownPosition = e.mousePosition;
                    mouseDragState    = MouseDragState.Eligible;
                }
                else if (e.type == EventType.MouseDrag && mouseDragState == MouseDragState.Eligible)
                {
                    mouseDragState = MouseDragState.InProgress;
                    SceneView.currentDrawingSceneView.Repaint();
                }
                else if (GUIUtility.hotControl == 0 &&
                         (e.type == EventType.MouseUp ||
                          (mouseDragState == MouseDragState.InProgress && e.rawType == EventType.MouseUp)))    // Have they released the mouse outside the scene view while doing marquee select?
                {
                    if (mouseDragState == MouseDragState.InProgress)
                    {
                        var mouseUpPosition = e.mousePosition;

                        Rect marqueeRect = Rect.MinMaxRect(Mathf.Min(mouseDownPosition.x, mouseUpPosition.x),
                                                           Mathf.Min(mouseDownPosition.y, mouseUpPosition.y),
                                                           Mathf.Max(mouseDownPosition.x, mouseUpPosition.x),
                                                           Mathf.Max(mouseDownPosition.y, mouseUpPosition.y));

                        BeginSelectionChangeRegion();

                        if (!e.shift && !e.control && !e.command)
                        {
                            selectedIndices.Clear();
                        }

                        for (var index = 0; index < controlPoints.Length; index++)
                        {
                            Camera camera      = SceneView.currentDrawingSceneView.camera;
                            var    screenPoint = DeformEditorGUIUtility.WorldToGUIPoint(camera, transform.TransformPoint(controlPoints[index]));

                            if (screenPoint.z < 0)
                            {
                                // Don't consider points that are behind the camera
                                continue;
                            }

                            if (marqueeRect.Contains(screenPoint))
                            {
                                if (e.control || e.command) // Remove selection
                                {
                                    selectedIndices.Remove(index);
                                }
                                else
                                {
                                    selectedIndices.Add(index);
                                }
                            }
                        }

                        EndSelectionChangeRegion();
                    }
                    else
                    {
                        if (selectedIndices.Count == 0) // This shouldn't be called if you have any points selected (we want to allow you to deselect the points)
                        {
                            DeformUnityObjectSelection.AttemptMouseUpObjectSelection();
                        }
                        else
                        {
                            DeselectAll();
                        }
                    }

                    mouseDragState = MouseDragState.NotActive;
                }
            }

            if (e.type == EventType.Repaint && mouseDragState == MouseDragState.InProgress)
            {
                var mouseUpPosition = e.mousePosition;

                Rect marqueeRect = Rect.MinMaxRect(Mathf.Min(mouseDownPosition.x, mouseUpPosition.x),
                                                   Mathf.Min(mouseDownPosition.y, mouseUpPosition.y),
                                                   Mathf.Max(mouseDownPosition.x, mouseUpPosition.x),
                                                   Mathf.Max(mouseDownPosition.y, mouseUpPosition.y));
                DeformUnityObjectSelection.DrawUnityStyleMarquee(marqueeRect);
                SceneView.RepaintAll();
            }

            // If the lattice is visible, override Unity's built-in Select All so that it selects all control points
            if (DeformUnityObjectSelection.SelectAllPressed)
            {
                BeginSelectionChangeRegion();
                selectedIndices.Clear();
                var resolution = lattice.Resolution;
                for (int z = 0; z < resolution.z; z++)
                {
                    for (int y = 0; y < resolution.y; y++)
                    {
                        for (int x = 0; x < resolution.x; x++)
                        {
                            var controlPointIndex = lattice.GetIndex(x, y, z);
                            selectedIndices.Add(controlPointIndex);
                        }
                    }
                }

                EndSelectionChangeRegion();

                e.Use();
            }

            if (e.type == EventType.KeyDown && e.keyCode == KeyCode.Escape)
            {
                DeselectAll();
            }

            EditorApplication.QueuePlayerLoopUpdate();
        }