public static ShapeExtrusionState Do(Rect dragArea, out Curve2D shape, out float height, out ChiselModel modelBeneathCursor, out Matrix4x4 transformation, Axis axis) { try { if (!s_ExtrusionMode) { // TODO: handle snapping against own points // TODO: handle ability to 'commit' PointDrawing.PointDrawHandle(dragArea, ref s_Points, out s_Transformation, out s_ModelBeneathCursor, releaseOnMouseUp: true, UnitySceneExtensions.SceneHandles.OutlinedDotHandleCap); if (s_Points.Count <= 1) { return(ShapeExtrusionState.HoverMode); } if (s_Points.Count <= 3) { return(ShapeExtrusionState.ShapeMode); } if ((s_Points[s_Points.Count - 2] - s_Points[0]).sqrMagnitude < PointDrawing.kDistanceEpsilon) { s_ExtrusionMode = true; s_Points[s_Points.Count - 1] = s_Points[0]; return(ShapeExtrusionState.Create); } return(ShapeExtrusionState.ShapeMode); } else { var tempPoint = s_Points[s_Points.Count - 1]; var oldMatrix = UnityEditor.Handles.matrix; UnityEditor.Handles.matrix = UnityEditor.Handles.matrix * s_Transformation; var extrusionState = ExtrusionHandle.DoHandle(dragArea, ref tempPoint, axis); UnityEditor.Handles.matrix = oldMatrix; s_Points[s_Points.Count - 1] = tempPoint; switch (extrusionState) { case ExtrusionState.Cancel: { s_ExtrusionMode = false; return(ShapeExtrusionState.Cancel); } case ExtrusionState.Commit: { s_ExtrusionMode = false; return(ShapeExtrusionState.Commit); } case ExtrusionState.Modified: { return(ShapeExtrusionState.Modified); } } return(ShapeExtrusionState.ExtrusionMode); } } finally { modelBeneathCursor = s_ModelBeneathCursor; transformation = s_Transformation; shape = GetShape(); height = GetHeight(axis); } }
public static BoxExtrusionState Do(Rect dragArea, out Bounds bounds, out float height, out ChiselModel modelBeneathCursor, out Matrix4x4 transformation, BoxExtrusionFlags flags, Axis axis, float?snappingSteps = null) { try { if (SceneHandles.InCameraOrbitMode) { return(BoxExtrusionState.None); } if (s_Points.Count <= 2) { PointDrawing.PointDrawHandle(dragArea, ref s_Points, out s_Transformation, out s_ModelBeneathCursor, UnitySceneExtensions.SceneHandles.OutlinedDotHandleCap); if (s_Points.Count <= 1) { return(BoxExtrusionState.HoverMode); } if (s_Points.Count > 2) { s_Points[2] = s_Points[0]; return(BoxExtrusionState.Create); } return(BoxExtrusionState.SquareMode); } else { var tempPoint = s_Points[2]; var oldMatrix = UnityEditor.Handles.matrix; UnityEditor.Handles.matrix = UnityEditor.Handles.matrix * s_Transformation; var extrusionState = ExtrusionHandle.DoHandle(dragArea, ref tempPoint, axis, snappingSteps: snappingSteps); UnityEditor.Handles.matrix = oldMatrix; s_Points[2] = tempPoint; switch (extrusionState) { case ExtrusionState.Cancel: { return(BoxExtrusionState.Cancel); } case ExtrusionState.Commit: { return(BoxExtrusionState.Commit); } case ExtrusionState.Modified: { return(BoxExtrusionState.Modified); } } return(BoxExtrusionState.BoxMode); } } finally { modelBeneathCursor = s_ModelBeneathCursor; bounds = GetBounds(flags, axis); height = GetHeight(axis); var center = bounds.center; if ((flags & BoxExtrusionFlags.GenerateFromCenterY) != BoxExtrusionFlags.GenerateFromCenterY) { center[(int)axis] -= height * 0.5f; } transformation = s_Transformation * Matrix4x4.TRS(center, Quaternion.identity, Vector3.one); center = Vector3.zero; if ((flags & BoxExtrusionFlags.GenerateFromCenterY) != BoxExtrusionFlags.GenerateFromCenterY) { center[(int)axis] = height * 0.5f; } bounds.center = center; } }
public static BoxExtrusionState Do(Rect dragArea, out Bounds bounds, out float height, out ChiselModel modelBeneathCursor, out Matrix4x4 transformation, BoxExtrusionFlags flags, Axis axis, float?snappingSteps = null) { try { if (SceneHandles.InCameraOrbitMode) { return(BoxExtrusionState.None); } if (s_Points.Count <= 2) { PointDrawing.PointDrawHandle(dragArea, ref s_Points, out s_Transformation, out s_ModelBeneathCursor, UnitySceneExtensions.SceneHandles.OutlinedDotHandleCap); if (s_Points.Count <= 1) { return(BoxExtrusionState.HoverMode); } if (s_Points.Count > 2) { s_Points[2] = s_Points[0]; return(BoxExtrusionState.Create); } return(BoxExtrusionState.SquareMode); } else { var tempPoint = s_Points[2]; var oldMatrix = UnityEditor.Handles.matrix; UnityEditor.Handles.matrix = UnityEditor.Handles.matrix * s_Transformation; var extrusionState = ExtrusionHandle.DoHandle(dragArea, ref tempPoint, axis, snappingSteps: snappingSteps); UnityEditor.Handles.matrix = oldMatrix; s_Points[2] = tempPoint; switch (extrusionState) { case ExtrusionState.Cancel: { return(BoxExtrusionState.Cancel); } case ExtrusionState.Commit: { return(BoxExtrusionState.Commit); } case ExtrusionState.Modified: { return(BoxExtrusionState.Modified); } } return(BoxExtrusionState.BoxMode); } } finally { modelBeneathCursor = s_ModelBeneathCursor; bounds = GetBounds(flags, axis); height = GetHeight(axis); var center = bounds.center; if ((flags & BoxExtrusionFlags.GenerateFromCenterY) != BoxExtrusionFlags.GenerateFromCenterY) { center[(int)axis] -= height * 0.5f; } transformation = s_Transformation * Matrix4x4.TRS(center, Quaternion.identity, Vector3.one); #if true //if (height > 0) { if ((flags & BoxExtrusionFlags.AlwaysFaceUp) == BoxExtrusionFlags.AlwaysFaceUp) { var currentUp = transformation.MultiplyVector(Vector3.up); var currentForward = transformation.MultiplyVector(Vector3.forward); var currentRight = transformation.MultiplyVector(Vector3.right); var desiredUp = Grid.ActiveGrid.Up; var dotX = Vector3.Dot(currentRight, desiredUp); var dotY = Vector3.Dot(currentUp, desiredUp); var dotZ = Vector3.Dot(currentForward, desiredUp); var absDotX = Mathf.Abs(dotX); var absDotY = Mathf.Abs(dotY); var absDotZ = Mathf.Abs(dotZ); if (absDotX > absDotZ) { if (absDotX > absDotY) { var size = bounds.size; var t = size.x; size.x = size.y; size.y = t; bounds.size = size; axis = Axis.X; var position = transformation.GetColumn(3); transformation.SetColumn(3, new Vector4(0, 0, 0, 1)); transformation *= Matrix4x4.TRS(position, Quaternion.identity, Vector3.one); transformation *= new Matrix4x4(new Vector4(0, 1, 0, 0), new Vector4(1, 0, 0, 0), new Vector4(0, 0, 1, 0), new Vector4(0, 0, 0, 1)); transformation.SetColumn(3, position); } } else { if (absDotZ > absDotY) { var size = bounds.size; var t = size.z; size.z = size.y; size.y = t; bounds.size = size; axis = Axis.Z; var position = transformation.GetColumn(3); transformation.SetColumn(3, new Vector4(0, 0, 0, 1)); transformation *= Matrix4x4.TRS(position, Quaternion.identity, Vector3.one); transformation *= new Matrix4x4(new Vector4(1, 0, 0, 0), new Vector4(0, 0, 1, 0), new Vector4(0, 1, 0, 0), new Vector4(0, 0, 0, 1)); transformation.SetColumn(3, position); } } } if (!s_ModelBeneathCursor && (flags & BoxExtrusionFlags.AlwaysFaceCameraXZ) == BoxExtrusionFlags.AlwaysFaceCameraXZ) { // TODO: take grid orientation into account to decide what is "X" and what is "Z" var currentForward = transformation.MultiplyVector(Vector3.forward); var currentRight = transformation.MultiplyVector(Vector3.right); var cameraOffset = Camera.current.transform.forward; var cameraForward = (new Vector3(cameraOffset.x, 0, cameraOffset.z)).normalized; var dotZ = Vector3.Dot(currentForward, cameraForward); var dotX = Vector3.Dot(currentRight, cameraForward); var angle = 0; if (Mathf.Abs(dotX) < Mathf.Abs(dotZ)) { if (dotZ > 0) { angle += 180; } } else { if (dotX < 0) { angle += 90; } else { angle -= 90; } if (axis == Axis.X) { axis = Axis.Z; } var size = bounds.size; var t = size.x; size.x = size.z; size.z = t; bounds.size = size; } var position = transformation.GetColumn(3); transformation.SetColumn(3, new Vector4(0, 0, 0, 1)); transformation *= Matrix4x4.TRS(position, Quaternion.identity, Vector3.one); transformation *= Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, angle, 0), Vector3.one); transformation.SetColumn(3, position); } } #endif center = Vector3.zero; if ((flags & BoxExtrusionFlags.GenerateFromCenterY) != BoxExtrusionFlags.GenerateFromCenterY) { center[(int)axis] = height * 0.5f; } bounds.center = center; } }
public static GeneratorModeState Do(Rect dragArea, out Bounds bounds, out float height, out ChiselModel modelBeneathCursor, out Matrix4x4 transformation, PlacementFlags flags, Axis upAxis, float?snappingSteps = null) { // TODO: shift should do SameLengthXZ, shift control includes Y // TODO: fixed height should be possible to change sign // TODO: have some sort of click placement of previously used bounds (alt?) //bounds = s_LastBounds; bool doCommit = false; try { if (SceneHandles.InCameraOrbitMode) { return(GeneratorModeState.None); } height = GetHeight(flags, upAxis); if (s_Points.Count <= 2) { PointDrawing.PointDrawHandle(dragArea, ref s_Points, out s_Transformation, out s_ModelBeneathCursor, releaseOnMouseUp: false, UnitySceneExtensions.SceneHandles.OutlinedDotHandleCap); if (s_Points.Count <= 1) { return(GeneratorModeState.None); } } if (s_Points.Count > 2) { if (!s_ModifyMode) { PointDrawing.Release(); if ((flags & PlacementFlags.HeightEqualsHalfXZ) == PlacementFlags.HeightEqualsHalfXZ || (flags & PlacementFlags.HeightEqualsXZ) == PlacementFlags.HeightEqualsXZ || (flags & PlacementFlags.UseLastHeight) == PlacementFlags.UseLastHeight) { if (height > 0) { s_ModifyMode = false; doCommit = true; return(GeneratorModeState.Commit); } } s_Points[2] = s_Points[1]; s_ModifyMode = true; return(GeneratorModeState.Update); } if (s_ModifyMode) { var oldMatrix = UnityEditor.Handles.matrix; UnityEditor.Handles.matrix *= s_Transformation; var tempPoint = s_Points[2]; var extrusionState = ExtrusionHandle.DoHandle(ref tempPoint, upAxis, snappingSteps: snappingSteps); s_Points[2] = tempPoint; UnityEditor.Handles.matrix = oldMatrix; switch (extrusionState) { case ExtrusionState.Cancel: { s_ModifyMode = false; return(GeneratorModeState.Cancel); } case ExtrusionState.Commit: { s_ModifyMode = false; doCommit = true; return(GeneratorModeState.Commit); } } } } return(GeneratorModeState.Update); } finally { modelBeneathCursor = s_ModelBeneathCursor; bounds = GetBounds(flags, upAxis); height = bounds.size[(int)upAxis]; var center = bounds.center; if ((flags & PlacementFlags.GenerateFromCenterY) != PlacementFlags.GenerateFromCenterY) { center[(int)upAxis] -= height * 0.5f; } transformation = s_Transformation * Matrix4x4.TRS(center, Quaternion.identity, Vector3.one); #if true //if (height > 0) { if ((flags & PlacementFlags.AlwaysFaceUp) == PlacementFlags.AlwaysFaceUp) { var currentUp = transformation.MultiplyVector(Vector3.up); var currentForward = transformation.MultiplyVector(Vector3.forward); var currentRight = transformation.MultiplyVector(Vector3.right); var desiredUp = Grid.ActiveGrid.Up; var dotX = Vector3.Dot(currentRight, desiredUp); var dotY = Vector3.Dot(currentUp, desiredUp); var dotZ = Vector3.Dot(currentForward, desiredUp); var absDotX = Mathf.Abs(dotX); var absDotY = Mathf.Abs(dotY); var absDotZ = Mathf.Abs(dotZ); if (absDotX > absDotZ) { if (absDotX > absDotY) { var size = bounds.size; var t = size.x; size.x = size.y; size.y = t; bounds.size = size; upAxis = Axis.X; var position = transformation.GetColumn(3); transformation.SetColumn(3, new Vector4(0, 0, 0, 1)); transformation *= Matrix4x4.TRS(position, Quaternion.identity, Vector3.one); transformation *= new Matrix4x4(new Vector4(0, 1, 0, 0), new Vector4(1, 0, 0, 0), new Vector4(0, 0, 1, 0), new Vector4(0, 0, 0, 1)); transformation.SetColumn(3, position); } } else { if (absDotZ > absDotY) { var size = bounds.size; var t = size.z; size.z = size.y; size.y = t; bounds.size = size; upAxis = Axis.Z; var position = transformation.GetColumn(3); transformation.SetColumn(3, new Vector4(0, 0, 0, 1)); transformation *= Matrix4x4.TRS(position, Quaternion.identity, Vector3.one); transformation *= new Matrix4x4(new Vector4(1, 0, 0, 0), new Vector4(0, 0, 1, 0), new Vector4(0, 1, 0, 0), new Vector4(0, 0, 0, 1)); transformation.SetColumn(3, position); } } } if (!s_ModelBeneathCursor && (flags & PlacementFlags.AlwaysFaceCameraXZ) == PlacementFlags.AlwaysFaceCameraXZ) { // TODO: take grid orientation into account to decide what is "X" and what is "Z" var currentForward = transformation.MultiplyVector(Vector3.forward); var currentRight = transformation.MultiplyVector(Vector3.right); var cameraOffset = Camera.current.transform.forward; var cameraForward = (new Vector3(cameraOffset.x, 0, cameraOffset.z)).normalized; var dotZ = Vector3.Dot(currentForward, cameraForward); var dotX = Vector3.Dot(currentRight, cameraForward); var angle = 0; if (Mathf.Abs(dotX) < Mathf.Abs(dotZ)) { if (dotZ > 0) { angle += 180; } } else { if (dotX < 0) { angle += 90; } else { angle -= 90; } if (upAxis == Axis.X) { upAxis = Axis.Z; } var size = bounds.size; var t = size.x; size.x = size.z; size.z = t; bounds.size = size; } var position = transformation.GetColumn(3); transformation.SetColumn(3, new Vector4(0, 0, 0, 1)); transformation *= Matrix4x4.TRS(position, Quaternion.identity, Vector3.one); transformation *= Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, angle, 0), Vector3.one); transformation.SetColumn(3, position); } } #endif center = Vector3.zero; if ((flags & PlacementFlags.GenerateFromCenterY) != PlacementFlags.GenerateFromCenterY) { center[(int)upAxis] = height * 0.5f; } else { center[(int)upAxis] = 0; } bounds.center = center; if (doCommit) { s_LastBounds = bounds; s_LastHeight = s_NextHeight; } } }