Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
pzgulyas committed Nov 22, 2023
1 parent 392d395 commit 82fde3f
Show file tree
Hide file tree
Showing 8 changed files with 284 additions and 214 deletions.
175 changes: 68 additions & 107 deletions Source/Contrib/TrackViewer/SceneViewer.cs
Expand Up @@ -41,6 +41,7 @@
using System.Threading.Tasks;
using System.IO;
using System.Globalization;
using ORTS.Common.Input;

namespace ORTS.TrackViewer
{
Expand All @@ -53,6 +54,9 @@ public class SceneViewer
public readonly TrackViewer TrackViewer;
SwapChainRenderTarget SwapChain;
internal StaticShape SelectedObject;
internal Orts.Formats.Msts.WorldObject SelectedWorldObject;
Viewer Viewer;
ViewerCamera Camera;

/// <summary>The command-line arguments</summary>
private string[] CommandLineArgs;
Expand Down Expand Up @@ -88,7 +92,6 @@ public SceneViewer(TrackViewer trackViewer, string[] args)
RenderFrame.FinalRenderTarget = SwapChain;

SceneWindow = new SceneWindow(new SceneViewerHwndHost(SwapChainWindow));
//SceneWindow = new SceneWindow(new SceneViewerVisualHost(GameWindow));

// The primary window activation events should not affect RunActivity
TrackViewer.Activated -= TrackViewer.ActivateRunActivity;
Expand All @@ -105,6 +108,8 @@ public SceneViewer(TrackViewer trackViewer, string[] args)
LoadContent();
}

public SceneViewer() { }

/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
Expand All @@ -130,21 +135,48 @@ public void LoadContent()
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public void Update(GameTime gameTime)
{
if (TrackViewer.RenderProcess?.Viewer == null)
Viewer = Viewer ?? TrackViewer.RenderProcess?.Viewer;
if (Viewer == null)
return;
Camera = Camera ?? Viewer.ViewerCamera;

TrackViewer.RenderProcess.Viewer.EditorShapes.MouseCrosshairEnabled = true;
Viewer.EditorShapes.MouseCrosshairEnabled = true;

if (UserInput.IsMouseLeftButtonPressed && UserInput.ModifiersMaskShiftCtrlAlt(false, false, false))
if (UserInput.IsMouseLeftButtonPressed && UserInput.ModifiersMaskShiftCtrlAlt(false, false, false)
&& Camera.PickByMouse(out SelectedObject))
{
if (PickByMouse(out SelectedObject))
{
TrackViewer.RenderProcess.Viewer.EditorShapes.SelectedObject = SelectedObject;
FillSelectedObjectData();
}
SelectedObjectChanged();
}
if (UserInput.IsMouseMiddleButtonPressed && UserInput.ModifiersMaskShiftCtrlAlt(false, false, false))
{
Camera.StoreRotationOrigin(Viewer.TerrainPoint);
Viewer.EditorShapes.CrosshairPositionUpdateEnabled = false;
}
if (UserInput.IsMouseMiddleButtonDown && UserInput.ModifiersMaskShiftCtrlAlt(false, false, false))
{
Camera.RotateByMouse();
}
else
{
Viewer.EditorShapes.CrosshairPositionUpdateEnabled = true;
}
if (UserInput.IsMouseMiddleButtonDown && UserInput.ModifiersMaskShiftCtrlAlt(true, false, false))
{
Camera.PanByMouse();
}
else
{
Camera.ZoomByMouseWheel(1);
}
//SetCameraLocationStatus(TrackViewer.RenderProcess?.Viewer?.Camera?.CameraWorldLocation ?? new WorldLocation());
FillCursorPositionStatus((TrackViewer.RenderProcess?.Viewer?.Camera as ViewerCamera)?.CursorPoint ?? new Vector3());

if (UserInput.IsPressed(UserCommand.EditorUnselectAll))
{
SelectedObject = null;
SelectedObjectChanged();
}

SetCameraLocationStatus(TrackViewer.RenderProcess?.Viewer?.Camera?.CameraWorldLocation ?? new WorldLocation());
//FillCursorPositionStatus(TrackViewer.RenderProcess?.Viewer?.TerrainPoint ?? new Vector3());
}

public void EndDraw()
Expand Down Expand Up @@ -181,8 +213,6 @@ private void SetCameraLocationStatus(WorldLocation cameraLocation)

private void FillCursorPositionStatus(Vector3 cursorPosition)
{
//SceneWindow.tileXZ.Text = string.Format(System.Globalization.CultureInfo.CurrentCulture,
// "{0,-7} {1,-7}", cameraLocation.TileX, cameraLocation.TileZ);
SceneWindow.LocationX.Text = string.Format(CultureInfo.InvariantCulture, "{0,3:F3} ", cursorPosition.X);
SceneWindow.LocationY.Text = string.Format(CultureInfo.InvariantCulture, "{0,3:F3} ", cursorPosition.Y);
SceneWindow.LocationZ.Text = string.Format(CultureInfo.InvariantCulture, "{0,3:F3} ", -cursorPosition.Z);
Expand Down Expand Up @@ -211,100 +241,22 @@ public async Task SetCameraLocation()
TrackViewer.RenderProcess.Viewer.ViewerCamera.SetLocation(mouseLocation);
}

protected bool PickByMouse(out StaticShape pickedObjectOut)
void SelectedObjectChanged()
{
var viewer = TrackViewer.RenderProcess.Viewer;

if (viewer == null)
{
pickedObjectOut = null;
return false;
}

var camera = viewer.Camera;

var direction = Vector3.Normalize(viewer.FarPoint - viewer.NearPoint);
var pickRay = new Ray(viewer.NearPoint, direction);

object pickedObject = null;
var pickedDistance = float.MaxValue;
var boundingBoxes = new Orts.Viewer3D.BoundingBox[1];
foreach (var worldFile in viewer.World.Scenery.WorldFiles)
{
foreach (var checkedObject in worldFile.sceneryObjects)
{
checkObject(checkedObject, checkedObject.BoundingBox, checkedObject.Location);
}
foreach (var checkedObject in worldFile.forestList)
{
var min = new Vector3(-checkedObject.ForestArea.X / 2, -checkedObject.ForestArea.Y / 2, 0);
var max = new Vector3(checkedObject.ForestArea.X / 2, checkedObject.ForestArea.Y / 2, 15);
boundingBoxes[0] = new Orts.Viewer3D.BoundingBox(Matrix.Identity, Matrix.Identity, Vector3.Zero, 0, min, max);
checkObject(checkedObject, boundingBoxes, checkedObject.Position);
}
}

void checkObject(object checkedObject, Orts.Viewer3D.BoundingBox[] checkedBoundingBox, WorldPosition checkedLocation)
{
if (checkedBoundingBox?.Length > 0)
{
foreach (var boundingBox in checkedBoundingBox)
{
// Locate relative to the camera
var dTileX = checkedLocation.TileX - camera.TileX;
var dTileZ = checkedLocation.TileZ - camera.TileZ;
var xnaDTileTranslation = checkedLocation.XNAMatrix;
xnaDTileTranslation.M41 += dTileX * 2048;
xnaDTileTranslation.M43 -= dTileZ * 2048;
xnaDTileTranslation = boundingBox.ComplexTransform * xnaDTileTranslation;

var min = Vector3.Transform(boundingBox.Min, xnaDTileTranslation);
var max = Vector3.Transform(boundingBox.Max, xnaDTileTranslation);

var xnabb = new Microsoft.Xna.Framework.BoundingBox(min, max);
checkDistance(checkedObject, pickRay.Intersects(xnabb));
}
}
else
{
var radius = 10f;
var boundingSphere = new BoundingSphere(camera.XnaLocation(checkedLocation.WorldLocation), radius);
checkDistance(checkedObject, pickRay.Intersects(boundingSphere));
}
}

void checkDistance(object checkedObject, float? checkedDistance)
{
if (checkedDistance != null && checkedDistance < pickedDistance)
{
pickedDistance = checkedDistance.Value;
pickedObject = checkedObject;
}
}

pickedObjectOut = pickedObject as StaticShape;

if (pickedObjectOut != null)
{
var ppp = pickedObjectOut;
var sb = new StringBuilder();
var aaa = TrackViewer.RenderProcess.Viewer.World.Scenery.WorldFiles.Where(w =>
w.TileX == ppp.Location.TileX && w.TileZ == ppp.Location.TileZ).ToArray();
var bbb = aaa[0].MstsWFile;
bbb.Tr_Worldfile.Serialize(sb);
var ccc = sb.ToString();
}
return pickedObjectOut != null;
}

void FillSelectedObjectData()
{
SceneWindow.Filename.Text = SelectedObject != null ? System.IO.Path.GetFileName(SelectedObject.SharedShape.FilePath) : "";
SceneWindow.TileX.Text = SelectedObject?.Location.TileX.ToString(CultureInfo.InvariantCulture).Replace(",", "");
SceneWindow.TileZ.Text = SelectedObject?.Location.TileZ.ToString(CultureInfo.InvariantCulture).Replace(",", "");
SceneWindow.PosX.Text = SelectedObject?.Location.Location.X.ToString("N3", CultureInfo.InvariantCulture).Replace(",", "");
SceneWindow.PosY.Text = SelectedObject?.Location.Location.Y.ToString("N3", CultureInfo.InvariantCulture).Replace(",", "");
SceneWindow.PosZ.Text = SelectedObject?.Location.Location.Z.ToString("N3", CultureInfo.InvariantCulture).Replace(",", "");
Viewer.EditorShapes.SelectedObject = SelectedObject;

SelectedWorldObject = Viewer.World.Scenery.WorldFiles
.SingleOrDefault(w => w.TileX == SelectedObject?.Location.TileX && w.TileZ == SelectedObject?.Location.TileZ)
?.MstsWFile?.Tr_Worldfile
?.SingleOrDefault(o => o.UID == SelectedObject?.Uid);

//SceneWindow.Filename.Text = SelectedObject != null ? System.IO.Path.GetFileName(SelectedObject.SharedShape.FilePath) : "";
//SceneWindow.TileX.Text = SelectedObject?.Location.TileX.ToString(CultureInfo.InvariantCulture).Replace(",", "");
//SceneWindow.TileZ.Text = SelectedObject?.Location.TileZ.ToString(CultureInfo.InvariantCulture).Replace(",", "");
//SceneWindow.PosX.Text = SelectedObject?.Location.Location.X.ToString("N3", CultureInfo.InvariantCulture).Replace(",", "");
//SceneWindow.PosY.Text = SelectedObject?.Location.Location.Y.ToString("N3", CultureInfo.InvariantCulture).Replace(",", "");
//SceneWindow.PosZ.Text = SelectedObject?.Location.Location.Z.ToString("N3", CultureInfo.InvariantCulture).Replace(",", "");
//SceneWindow.Uid.Text = SelectedObject.Uid.ToString(CultureInfo.InvariantCulture).Replace(",", "");
var q = new Quaternion();
if (SelectedObject?.Location.XNAMatrix.Decompose(out var _, out q, out var _) ?? false)
{
Expand All @@ -317,7 +269,16 @@ void FillSelectedObjectData()
{
SceneWindow.RotY.Text = "";
}
SceneWindow.Uid.Text = SelectedObject.Uid.ToString(CultureInfo.InvariantCulture).Replace(",", "");

if (SelectedObject is StaticShape ppp)
{
var sb = new StringBuilder();
var aaa = Viewer.World.Scenery.WorldFiles
.SingleOrDefault(w => w.TileX == SelectedObject.Location.TileX && w.TileZ == SelectedObject.Location.TileZ)
?.MstsWFile?.Tr_Worldfile;
aaa.Serialize(sb);
var ccc = sb.ToString();
}
}

}
Expand Down
7 changes: 5 additions & 2 deletions Source/Contrib/TrackViewer/TrackViewer.cs
Expand Up @@ -324,13 +324,14 @@ private void DrawLoadingMessage(string message)
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
SceneViewer?.Update(gameTime);

if (!this.IsTrackViewerWindowActive)
{
lostFocus = true;
if (this.IsRenderWindowActive)
{
base.Update(gameTime);
SceneViewer?.Update(gameTime);
}
return;
}

Expand Down Expand Up @@ -548,6 +549,8 @@ protected override void Update(GameTime gameTime)
SetTitle();

RenderProcess.IsMouseVisible = true;

SceneViewer?.Update(gameTime);
}

/// <summary>
Expand Down
89 changes: 47 additions & 42 deletions Source/Contrib/TrackViewer/UserInterface/SceneWindow.xaml
Expand Up @@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ORTS.TrackViewer.UserInterface"
xmlns:local="clr-namespace:ORTS.TrackViewer"
mc:Ignorable="d"
Title="Scene View" SizeToContent="WidthAndHeight">
<DockPanel LastChildFill="True">
Expand Down Expand Up @@ -114,47 +114,52 @@
</StatusBar>
<Border BorderThickness="2">
<StackPanel Orientation="Vertical" Width="150">
<TextBox FontWeight="Bold" Name="Filename"/>
<DockPanel>
<TextBlock Text="UID: " PreviewTextInput="UintValidationTextBox"/>
<TextBlock Name="Uid"/>
</DockPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Tile X: " />
<TextBox Grid.Column="1" Name="TileX" PreviewTextInput="IntValidationTextBox"></TextBox>
<TextBlock Grid.Column="2" Text=" Z: " />
<TextBox Grid.Column="3" Name="TileZ" PreviewTextInput="IntValidationTextBox"></TextBox>
</Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="1" Text="Position" HorizontalAlignment="Center"/>
<TextBlock Grid.Row="0" Grid.Column="2" Text="Rotation" HorizontalAlignment="Center"/>
<TextBlock Grid.Row="1" Text="X: "/>
<TextBlock Grid.Row="2" Text="Y: "/>
<TextBlock Grid.Row="3" Text="Z: "/>
<TextBox Grid.Row="1" Grid.Column="1" x:Name="PosX" PreviewTextInput="FloatValidationTextBox"/>
<TextBox Grid.Row="2" Grid.Column="1" x:Name="PosY" PreviewTextInput="FloatValidationTextBox"/>
<TextBox Grid.Row="3" Grid.Column="1" x:Name="PosZ" PreviewTextInput="FloatValidationTextBox"/>
<TextBox Grid.Row="1" Grid.Column="2" x:Name="RotX" PreviewTextInput="FloatValidationTextBox"/>
<TextBox Grid.Row="2" Grid.Column="2" x:Name="RotY" PreviewTextInput="FloatValidationTextBox"/>
<TextBox Grid.Row="3" Grid.Column="2" x:Name="RotZ" PreviewTextInput="FloatValidationTextBox"/>
</Grid>
<StackPanel.DataContext>
<local:SceneViewer/>
</StackPanel.DataContext>
<ItemsControl ItemsSource="{Binding SelectedWorldObject}">
<TextBox FontWeight="Bold" Name="Filename" Text="{Binding SelectedWorldObject.FileName}"/>
<DockPanel>
<TextBlock Text="UID: " PreviewTextInput="UintValidationTextBox"/>
<TextBlock Name="Uid" Text="{Binding SelectedWorldObject.UID}"/>
</DockPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Tile X: " />
<TextBox Grid.Column="1" Name="TileX" PreviewTextInput="IntValidationTextBox" Text="{Binding SelectedObject.Location.TileX}" />
<TextBlock Grid.Column="2" Text=" Z: " />
<TextBox Grid.Column="3" Name="TileZ" PreviewTextInput="IntValidationTextBox" Text="{Binding SelectedObject.Location.TileZ}" />
</Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="1" Text="Position" HorizontalAlignment="Center"/>
<TextBlock Grid.Row="0" Grid.Column="2" Text="Rotation" HorizontalAlignment="Center"/>
<TextBlock Grid.Row="1" Text="X: "/>
<TextBlock Grid.Row="2" Text="Y: "/>
<TextBlock Grid.Row="3" Text="Z: "/>
<TextBox Grid.Row="1" Grid.Column="1" x:Name="PosX" Text="{Binding SelectedObject.Location.Location.X, StringFormat=N3}" PreviewTextInput="FloatValidationTextBox"/>
<TextBox Grid.Row="2" Grid.Column="1" x:Name="PosY" Text="{Binding SelectedObject.Location.Location.Y, StringFormat=N3}" PreviewTextInput="FloatValidationTextBox"/>
<TextBox Grid.Row="3" Grid.Column="1" x:Name="PosZ" Text="{Binding SelectedObject.Location.Location.Z, StringFormat=N3}" PreviewTextInput="FloatValidationTextBox"/>
<TextBox Grid.Row="1" Grid.Column="2" x:Name="RotX" PreviewTextInput="FloatValidationTextBox"/>
<TextBox Grid.Row="2" Grid.Column="2" x:Name="RotY" PreviewTextInput="FloatValidationTextBox"/>
<TextBox Grid.Row="3" Grid.Column="2" x:Name="RotZ" PreviewTextInput="FloatValidationTextBox"/>
</Grid>
</ItemsControl>
</StackPanel>
</Border>
<Grid DockPanel.Dock="Bottom" x:Name="GraphicsHostElement" />
Expand Down

0 comments on commit 82fde3f

Please sign in to comment.