Skip to content

Commit

Permalink
Fixed the undo system
Browse files Browse the repository at this point in the history
  • Loading branch information
pzgulyas committed Nov 30, 2023
1 parent 93a5fa9 commit cd452ee
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 77 deletions.
67 changes: 46 additions & 21 deletions Source/Contrib/TrackViewer/SceneViewer.cs
Expand Up @@ -58,6 +58,7 @@ public class SceneViewer
OrbitingCamera Camera;
Stack<UndoDataSet> UndoStack = new Stack<UndoDataSet>();
Stack<UndoDataSet> RedoStack = new Stack<UndoDataSet>();
EditorState EditorState;

/// <summary>The command-line arguments</summary>
private string[] CommandLineArgs;
Expand Down Expand Up @@ -126,19 +127,27 @@ public void Update(GameTime gameTime)
{
SelectedObject = selectedObject;
SelectedObjectChanged();
EditorState = EditorState.ObjectSelected;
}
}
if (UserInput.IsPressed(UserCommand.EditorUnselectAll))
{
SelectedObject = null;
SelectedObjectChanged();
if (EditorState == EditorState.ObjectSelected || EditorState == EditorState.Default)
{
SetDefaultMode();
}
}
if (UserInput.IsPressed(UserCommand.EditorUndo))
{
UndoCommand();
if (EditorState == EditorState.ObjectSelected || EditorState == EditorState.Default)
{
SetDefaultMode();
UndoCommand();
}
}
if (UserInput.IsPressed(UserCommand.EditorRedo))
{
SetDefaultMode();
RedoCommand();
}

Expand Down Expand Up @@ -198,12 +207,12 @@ public async Task SetCameraLocation()
mouseLocation.Location.Y = elevatedLocation + 15;
Camera.SetLocation(mouseLocation);

var lastView = UndoStack.Count > 0 ? UndoStack.Last(s => s.UndoEvent == UndoEvent.ViewChanged) :
var lastView = UndoStack.Count > 0 ? UndoStack.First(s => s.UndoEvent == UndoEvent.ViewChanged) :
new UndoDataSet()
{
OldCameraLocation = Camera.CameraWorldLocation,
OldCameraRotationXRadians = Camera.GetRotationX(),
OldCameraRotationYRadians = Camera.GetRotationY(),
NewCameraLocation = Camera.CameraWorldLocation,
NewCameraRotationXRadians = Camera.GetRotationX(),
NewCameraRotationYRadians = Camera.GetRotationY(),
};

UndoStack.Push(new UndoDataSet()
Expand All @@ -222,12 +231,16 @@ void UpdateViewUndoState()
{
if (UndoStack.Count == 0)
return;

var lastView = UndoStack.First(s => s.UndoEvent == UndoEvent.ViewChanged);

if (Camera.GetRotationX() == lastView.NewCameraRotationXRadians && Camera.GetRotationY() == lastView.NewCameraRotationYRadians && Camera.CameraWorldLocation == lastView.NewCameraLocation)
return;

var lastView = UndoStack.Last(s => s.UndoEvent == UndoEvent.ViewChanged);
if (lastView == UndoStack.Last())
if (UndoStack.First().UndoEvent == UndoEvent.ViewChanged) // then updatable
{
if (lastView.NewCameraLocation == lastView.OldCameraLocation && (Camera.GetRotationX() != lastView.NewCameraRotationXRadians || Camera.GetRotationY() != lastView.NewCameraRotationYRadians)
|| lastView.NewCameraLocation != lastView.OldCameraLocation && Camera.CameraWorldLocation == lastView.NewCameraLocation)
if ((Camera.GetRotationX() == lastView.NewCameraRotationXRadians && Camera.GetRotationY() == lastView.NewCameraRotationYRadians) ^
(lastView.NewCameraRotationXRadians != lastView.OldCameraRotationXRadians || lastView.NewCameraRotationYRadians != lastView.OldCameraRotationYRadians))
{
// Group rotations and pan-zooms by just updating the last action
lastView.NewCameraRotationXRadians = Camera.GetRotationX();
Expand All @@ -237,7 +250,7 @@ void UpdateViewUndoState()
return;
}
}
if (Camera.GetRotationX() != lastView.NewCameraRotationXRadians || Camera.GetRotationY() != lastView.NewCameraRotationYRadians || Camera.CameraWorldLocation == lastView.NewCameraLocation)
if (Camera.GetRotationX() != lastView.NewCameraRotationXRadians || Camera.GetRotationY() != lastView.NewCameraRotationYRadians || Camera.CameraWorldLocation != lastView.NewCameraLocation)
{
UndoStack.Push(new UndoDataSet()
{
Expand All @@ -253,19 +266,21 @@ void UpdateViewUndoState()
}
}

void SetDefaultMode()
{
SelectedObject = null;
SelectedObjectChanged();
EditorState = EditorState.Default;
}

void UndoCommand()
{
UndoDataSet undoDataSet;
if (UndoStack.Count > 1)
{
undoDataSet = UndoStack.Pop();
var undoDataSet = UndoStack.Pop();
RedoStack.Push(undoDataSet);
UndoRedo(undoDataSet, true);
}
else
{
undoDataSet = UndoStack.Peek();
}
UndoRedo(undoDataSet, true);
}

void RedoCommand()
Expand All @@ -283,8 +298,9 @@ void UndoRedo(UndoDataSet undoDataSet, bool undo)
if (undoDataSet.UndoEvent == UndoEvent.ViewChanged)
{
Camera.SetLocation(undo ? undoDataSet.OldCameraLocation : undoDataSet.NewCameraLocation);
Camera.RotationXTargetRadians = undo ? undoDataSet.OldCameraRotationXRadians : undoDataSet.NewCameraRotationXRadians;
Camera.RotationYTargetRadians = undo ? undoDataSet.OldCameraRotationYRadians : undoDataSet.NewCameraRotationYRadians;
Camera.SetRotation(
undo ? undoDataSet.OldCameraRotationXRadians : undoDataSet.NewCameraRotationXRadians,
undo ? undoDataSet.OldCameraRotationYRadians : undoDataSet.NewCameraRotationYRadians);
}
}

Expand Down Expand Up @@ -370,6 +386,15 @@ public enum UndoEvent
WorldObjectChanged,
}

public enum EditorState
{
Default = 0,
ObjectSelected,
ObjectMovingX,
ObjectMovingY,
ObjectMovingZ,
}

public class SceneViewerHwndHost : HwndHost
{
readonly IntPtr HwndChildHandle;
Expand Down
122 changes: 66 additions & 56 deletions Source/RunActivity/Viewer3D/EditorPrimitives.cs
Expand Up @@ -22,8 +22,6 @@
using ORTS.Common;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace Orts.Viewer3D
Expand All @@ -50,10 +48,10 @@ public class EditorShapes : StaticShape, IDisposable

public EditorShapes(Viewer viewer) : base(viewer, "", null, ShapeFlags.None, null, -1)
{
MouseCrosshair = new MouseCrosshair(Viewer, Color.GreenYellow);
MouseCrosshair = new MouseCrosshair(Viewer, Color.GreenYellow, Color.Red, Color.Cyan);
HandleX = new HandleX(Viewer, Color.Red);
HandleY = new HandleY(Viewer, Color.Blue);
HandleZ = new HandleZ(Viewer, Color.Green);
HandleZ = new HandleZ(Viewer, Color.LightGreen);
}

public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
Expand Down Expand Up @@ -189,26 +187,54 @@ public override void Draw(GraphicsDevice graphicsDevice)
}

[CallOnThread("Loader")]
public class BoundingBoxPrimitive : EditorPrimitive
public class BoxPrimitive : EditorPrimitive
{
static IndexBuffer BoundingBoxIndexBuffer;
public readonly Matrix ComplexTransform;
static IndexBuffer BoxIndexBuffer;

public BoundingBoxPrimitive(Viewer viewer, BoundingBox boundingBox, Color color)
public BoxPrimitive(Viewer viewer, float size, Color color)
: this(viewer, new Vector3(-size / 2), new Vector3(size / 2), color)
{
Material = viewer.MaterialManager.Load("EditorPrimitive");
if (BoxIndexBuffer == null)
{
var indexData = new short[] { 2, 3, 6, 7, 5, 3, 1, 2, 0, 6, 4, 5, 0, 1 };
BoxIndexBuffer = new IndexBuffer(viewer.GraphicsDevice, typeof(short), indexData.Length, BufferUsage.WriteOnly);
BoxIndexBuffer.SetData(indexData);
}
IndexBuffer = BoxIndexBuffer;
PrimitiveCount = IndexBuffer.IndexCount - 2;
PrimitiveType = PrimitiveType.TriangleStrip;
}

protected BoxPrimitive(Viewer viewer, Vector3 min, Vector3 max, Color color)
{
var vertexData = new VertexPositionColor[]
{
new VertexPositionColor(boundingBox.Min, color),
new VertexPositionColor(new Vector3(boundingBox.Min.X, boundingBox.Min.Y, boundingBox.Max.Z), color),
new VertexPositionColor(new Vector3(boundingBox.Min.X, boundingBox.Max.Y, boundingBox.Min.Z), color),
new VertexPositionColor(new Vector3(boundingBox.Min.X, boundingBox.Max.Y, boundingBox.Max.Z), color),
new VertexPositionColor(new Vector3(boundingBox.Max.X, boundingBox.Min.Y, boundingBox.Min.Z), color),
new VertexPositionColor(new Vector3(boundingBox.Max.X, boundingBox.Min.Y, boundingBox.Max.Z), color),
new VertexPositionColor(new Vector3(boundingBox.Max.X, boundingBox.Max.Y, boundingBox.Min.Z), color),
new VertexPositionColor(boundingBox.Max, color)
new VertexPositionColor(min, color),
new VertexPositionColor(new Vector3(min.X, min.Y, max.Z), color),
new VertexPositionColor(new Vector3(min.X, max.Y, min.Z), color),
new VertexPositionColor(new Vector3(min.X, max.Y, max.Z), color),
new VertexPositionColor(new Vector3(max.X, min.Y, min.Z), color),
new VertexPositionColor(new Vector3(max.X, min.Y, max.Z), color),
new VertexPositionColor(new Vector3(max.X, max.Y, min.Z), color),
new VertexPositionColor(max, color)
};
VertexBuffer = new VertexBuffer(viewer.GraphicsDevice, typeof(VertexPositionColor), vertexData.Length, BufferUsage.WriteOnly);
VertexBuffer.SetData(vertexData);
}
}

[CallOnThread("Loader")]
public class BoundingBoxPrimitive : BoxPrimitive
{
static IndexBuffer BoundingBoxIndexBuffer;
public readonly Matrix ComplexTransform;

public BoundingBoxPrimitive(Viewer viewer, BoundingBox boundingBox, Color color)
: base(viewer, boundingBox.Min, boundingBox.Max, color)
{
Material = viewer.MaterialManager.Load("EditorPrimitive");
ComplexTransform = boundingBox.ComplexTransform;
if (BoundingBoxIndexBuffer == null)
{
var indexData = new short[] { 0, 1, 0, 2, 0, 4, 1, 3, 1, 5, 2, 3, 2, 6, 3, 7, 4, 5, 4, 6, 5, 7, 6, 7 };
Expand All @@ -218,23 +244,21 @@ public BoundingBoxPrimitive(Viewer viewer, BoundingBox boundingBox, Color color)
IndexBuffer = BoundingBoxIndexBuffer;
PrimitiveCount = IndexBuffer.IndexCount / 2;
PrimitiveType = PrimitiveType.LineList;
Material = viewer.MaterialManager.Load("EditorPrimitive");
ComplexTransform = boundingBox.ComplexTransform;
}
}

[CallOnThread("Loader")]
public class MouseCrosshair : EditorPrimitive
{
public MouseCrosshair(Viewer viewer, Color color)
public MouseCrosshair(Viewer viewer, Color color, Color northColor, Color southColor)
{
var vertexData = new VertexPositionColor[]
{
new VertexPositionColor(new Vector3(-5, 0, 0), color),
new VertexPositionColor(new Vector3(5, 0, 0), color),
new VertexPositionColor(new Vector3(0, 0, -5), Color.Red),
new VertexPositionColor(new Vector3(0, 0, 5), Color.Cyan),
new VertexPositionColor(new Vector3(0, 0, 0), color),
new VertexPositionColor(new Vector3(0, 0, -5), northColor),
new VertexPositionColor(new Vector3(0, 0, 5), southColor),
new VertexPositionColor(new Vector3(0, -5, 0), color),
new VertexPositionColor(new Vector3(0, 20, 0), color)
};
VertexBuffer = new VertexBuffer(viewer.GraphicsDevice, typeof(VertexPositionColor), vertexData.Length, BufferUsage.WriteOnly);
Expand All @@ -253,54 +277,40 @@ public HandleX(Viewer viewer, Color color)
var vertexData = GetVertexData(color);
VertexBuffer = new VertexBuffer(viewer.GraphicsDevice, typeof(VertexPositionColor), vertexData.Length, BufferUsage.WriteOnly);
VertexBuffer.SetData(vertexData);
PrimitiveCount = VertexBuffer.VertexCount / 2;
PrimitiveType = PrimitiveType.TriangleList;
PrimitiveCount = VertexBuffer.VertexCount - 2;
PrimitiveType = PrimitiveType.TriangleStrip;
Material = viewer.MaterialManager.Load("EditorPrimitive");
}

protected virtual VertexPositionColor[] GetVertexData(Color color) => GetVertexData(0, 1, 2, color);
protected VertexPositionColor[] GetVertexData(int x, int y, int z, Color color)
{
var l = 5f;
var d = 0.1f;
var a = l / 5;
var b = a / 4;
var l = 5f; // total length, meter
var d = 0.1f; // shaft half thickness
var a = l / 5; // arrow head length
var b = a / 4; // arrow head half thickness
var c = l - a;
var data = new float[][]
{
new[] { 0, +d, 0 },
new[] { c, +d, 0 },
new[] { 0, -d, 0 },
// Arrow shaft
new[] { 0, d, 0 },
new[] { c, d, 0 },
new[] { 0, 0, d },
new[] { c, 0, d },
new[] { 0, -d, 0 },
new[] { c, +d, 0 },
new[] { c, -d, 0 },

new[] { 0, 0, +d },
new[] { c, 0, +d },
new[] { 0, 0, -d },
new[] { 0, 0, -d },
new[] { c, 0, +d },
new[] { c, 0, -d },

new[] { l, 0, 0 },
new[] { l - a, +b, +b },
new[] { l - a, -b, +b },
new[] { l, 0, 0 },
new[] { l - a, -b, +b },
new[] { l - a, -b, -b },
new[] { l, 0, 0 },
new[] { l - a, -b, -b },
new[] { l - a, +b, -b },
new[] { l, 0, 0 },
new[] { l - a, +b, -b },
new[] { l - a, +b, +b },

new[] { l - a, +b, +b },
new[] { l - a, +b, -b },
new[] { l - a, -b, -b },
new[] { l - a, -b, -b },
new[] { l - a, +b, -b },
new[] { l - a, -b, +b },
// Arrow head
new[] { l, 0, 0 },
new[] { c, +b, +b },
new[] { c, -b, +b },
new[] { c, -b, -b },
new[] { l, 0, 0 },
new[] { c, +b, -b },
new[] { c, +b, +b },
new[] { c, -b, -b },
};
var vertexData = new VertexPositionColor[data.Length];
for (var i = 0; i < data.Length; i++)
Expand Down

0 comments on commit cd452ee

Please sign in to comment.