Skip to content

Commit 228f0f0

Browse files
committed
Refactoring
1 parent 392d395 commit 228f0f0

File tree

8 files changed

+271
-209
lines changed

8 files changed

+271
-209
lines changed

Source/Contrib/TrackViewer/SceneViewer.cs

Lines changed: 46 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
using System.Threading.Tasks;
4242
using System.IO;
4343
using System.Globalization;
44+
using ORTS.Common.Input;
4445

4546
namespace ORTS.TrackViewer
4647
{
@@ -53,6 +54,9 @@ public class SceneViewer
5354
public readonly TrackViewer TrackViewer;
5455
SwapChainRenderTarget SwapChain;
5556
internal StaticShape SelectedObject;
57+
internal Orts.Formats.Msts.WorldObject SelectedWorldObject;
58+
Viewer Viewer;
59+
ViewerCamera Camera;
5660

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

9094
SceneWindow = new SceneWindow(new SceneViewerHwndHost(SwapChainWindow));
91-
//SceneWindow = new SceneWindow(new SceneViewerVisualHost(GameWindow));
9295

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

111+
public SceneViewer() { }
112+
108113
/// <summary>
109114
/// Allows the game to perform any initialization it needs to before starting to run.
110115
/// This is where it can query for any required services and load any non-graphic
@@ -130,21 +135,26 @@ public void LoadContent()
130135
/// <param name="gameTime">Provides a snapshot of timing values.</param>
131136
public void Update(GameTime gameTime)
132137
{
133-
if (TrackViewer.RenderProcess?.Viewer == null)
138+
Viewer = Viewer ?? TrackViewer.RenderProcess?.Viewer;
139+
if (Viewer == null)
134140
return;
141+
Camera = Camera ?? Viewer.ViewerCamera;
135142

136-
TrackViewer.RenderProcess.Viewer.EditorShapes.MouseCrosshairEnabled = true;
143+
Viewer.EditorShapes.MouseCrosshairEnabled = true;
137144

138-
if (UserInput.IsMouseLeftButtonPressed && UserInput.ModifiersMaskShiftCtrlAlt(false, false, false))
145+
if (UserInput.IsMouseLeftButtonPressed && UserInput.ModifiersMaskShiftCtrlAlt(false, false, false)
146+
&& Camera.PickByMouse(out SelectedObject))
139147
{
140-
if (PickByMouse(out SelectedObject))
141-
{
142-
TrackViewer.RenderProcess.Viewer.EditorShapes.SelectedObject = SelectedObject;
143-
FillSelectedObjectData();
144-
}
148+
SelectedObjectChanged();
145149
}
146-
//SetCameraLocationStatus(TrackViewer.RenderProcess?.Viewer?.Camera?.CameraWorldLocation ?? new WorldLocation());
147-
FillCursorPositionStatus((TrackViewer.RenderProcess?.Viewer?.Camera as ViewerCamera)?.CursorPoint ?? new Vector3());
150+
if (UserInput.IsPressed(UserCommand.EditorUnselectAll))
151+
{
152+
SelectedObject = null;
153+
SelectedObjectChanged();
154+
}
155+
156+
SetCameraLocationStatus(Camera?.CameraWorldLocation ?? new WorldLocation());
157+
//FillCursorPositionStatus(Viewer?.TerrainPoint ?? new Vector3());
148158
}
149159

150160
public void EndDraw()
@@ -181,8 +191,6 @@ private void SetCameraLocationStatus(WorldLocation cameraLocation)
181191

182192
private void FillCursorPositionStatus(Vector3 cursorPosition)
183193
{
184-
//SceneWindow.tileXZ.Text = string.Format(System.Globalization.CultureInfo.CurrentCulture,
185-
// "{0,-7} {1,-7}", cameraLocation.TileX, cameraLocation.TileZ);
186194
SceneWindow.LocationX.Text = string.Format(CultureInfo.InvariantCulture, "{0,3:F3} ", cursorPosition.X);
187195
SceneWindow.LocationY.Text = string.Format(CultureInfo.InvariantCulture, "{0,3:F3} ", cursorPosition.Y);
188196
SceneWindow.LocationZ.Text = string.Format(CultureInfo.InvariantCulture, "{0,3:F3} ", -cursorPosition.Z);
@@ -211,100 +219,22 @@ public async Task SetCameraLocation()
211219
TrackViewer.RenderProcess.Viewer.ViewerCamera.SetLocation(mouseLocation);
212220
}
213221

214-
protected bool PickByMouse(out StaticShape pickedObjectOut)
215-
{
216-
var viewer = TrackViewer.RenderProcess.Viewer;
217-
218-
if (viewer == null)
219-
{
220-
pickedObjectOut = null;
221-
return false;
222-
}
223-
224-
var camera = viewer.Camera;
225-
226-
var direction = Vector3.Normalize(viewer.FarPoint - viewer.NearPoint);
227-
var pickRay = new Ray(viewer.NearPoint, direction);
228-
229-
object pickedObject = null;
230-
var pickedDistance = float.MaxValue;
231-
var boundingBoxes = new Orts.Viewer3D.BoundingBox[1];
232-
foreach (var worldFile in viewer.World.Scenery.WorldFiles)
233-
{
234-
foreach (var checkedObject in worldFile.sceneryObjects)
235-
{
236-
checkObject(checkedObject, checkedObject.BoundingBox, checkedObject.Location);
237-
}
238-
foreach (var checkedObject in worldFile.forestList)
239-
{
240-
var min = new Vector3(-checkedObject.ForestArea.X / 2, -checkedObject.ForestArea.Y / 2, 0);
241-
var max = new Vector3(checkedObject.ForestArea.X / 2, checkedObject.ForestArea.Y / 2, 15);
242-
boundingBoxes[0] = new Orts.Viewer3D.BoundingBox(Matrix.Identity, Matrix.Identity, Vector3.Zero, 0, min, max);
243-
checkObject(checkedObject, boundingBoxes, checkedObject.Position);
244-
}
245-
}
246-
247-
void checkObject(object checkedObject, Orts.Viewer3D.BoundingBox[] checkedBoundingBox, WorldPosition checkedLocation)
248-
{
249-
if (checkedBoundingBox?.Length > 0)
250-
{
251-
foreach (var boundingBox in checkedBoundingBox)
252-
{
253-
// Locate relative to the camera
254-
var dTileX = checkedLocation.TileX - camera.TileX;
255-
var dTileZ = checkedLocation.TileZ - camera.TileZ;
256-
var xnaDTileTranslation = checkedLocation.XNAMatrix;
257-
xnaDTileTranslation.M41 += dTileX * 2048;
258-
xnaDTileTranslation.M43 -= dTileZ * 2048;
259-
xnaDTileTranslation = boundingBox.ComplexTransform * xnaDTileTranslation;
260-
261-
var min = Vector3.Transform(boundingBox.Min, xnaDTileTranslation);
262-
var max = Vector3.Transform(boundingBox.Max, xnaDTileTranslation);
263-
264-
var xnabb = new Microsoft.Xna.Framework.BoundingBox(min, max);
265-
checkDistance(checkedObject, pickRay.Intersects(xnabb));
266-
}
267-
}
268-
else
269-
{
270-
var radius = 10f;
271-
var boundingSphere = new BoundingSphere(camera.XnaLocation(checkedLocation.WorldLocation), radius);
272-
checkDistance(checkedObject, pickRay.Intersects(boundingSphere));
273-
}
274-
}
275-
276-
void checkDistance(object checkedObject, float? checkedDistance)
277-
{
278-
if (checkedDistance != null && checkedDistance < pickedDistance)
279-
{
280-
pickedDistance = checkedDistance.Value;
281-
pickedObject = checkedObject;
282-
}
283-
}
284-
285-
pickedObjectOut = pickedObject as StaticShape;
286-
287-
if (pickedObjectOut != null)
288-
{
289-
var ppp = pickedObjectOut;
290-
var sb = new StringBuilder();
291-
var aaa = TrackViewer.RenderProcess.Viewer.World.Scenery.WorldFiles.Where(w =>
292-
w.TileX == ppp.Location.TileX && w.TileZ == ppp.Location.TileZ).ToArray();
293-
var bbb = aaa[0].MstsWFile;
294-
bbb.Tr_Worldfile.Serialize(sb);
295-
var ccc = sb.ToString();
296-
}
297-
return pickedObjectOut != null;
298-
}
299-
300-
void FillSelectedObjectData()
222+
void SelectedObjectChanged()
301223
{
302-
SceneWindow.Filename.Text = SelectedObject != null ? System.IO.Path.GetFileName(SelectedObject.SharedShape.FilePath) : "";
303-
SceneWindow.TileX.Text = SelectedObject?.Location.TileX.ToString(CultureInfo.InvariantCulture).Replace(",", "");
304-
SceneWindow.TileZ.Text = SelectedObject?.Location.TileZ.ToString(CultureInfo.InvariantCulture).Replace(",", "");
305-
SceneWindow.PosX.Text = SelectedObject?.Location.Location.X.ToString("N3", CultureInfo.InvariantCulture).Replace(",", "");
306-
SceneWindow.PosY.Text = SelectedObject?.Location.Location.Y.ToString("N3", CultureInfo.InvariantCulture).Replace(",", "");
307-
SceneWindow.PosZ.Text = SelectedObject?.Location.Location.Z.ToString("N3", CultureInfo.InvariantCulture).Replace(",", "");
224+
Viewer.EditorShapes.SelectedObject = SelectedObject;
225+
226+
SelectedWorldObject = Viewer.World.Scenery.WorldFiles
227+
.SingleOrDefault(w => w.TileX == SelectedObject?.Location.TileX && w.TileZ == SelectedObject?.Location.TileZ)
228+
?.MstsWFile?.Tr_Worldfile
229+
?.SingleOrDefault(o => o.UID == SelectedObject?.Uid);
230+
231+
//SceneWindow.Filename.Text = SelectedObject != null ? System.IO.Path.GetFileName(SelectedObject.SharedShape.FilePath) : "";
232+
//SceneWindow.TileX.Text = SelectedObject?.Location.TileX.ToString(CultureInfo.InvariantCulture).Replace(",", "");
233+
//SceneWindow.TileZ.Text = SelectedObject?.Location.TileZ.ToString(CultureInfo.InvariantCulture).Replace(",", "");
234+
//SceneWindow.PosX.Text = SelectedObject?.Location.Location.X.ToString("N3", CultureInfo.InvariantCulture).Replace(",", "");
235+
//SceneWindow.PosY.Text = SelectedObject?.Location.Location.Y.ToString("N3", CultureInfo.InvariantCulture).Replace(",", "");
236+
//SceneWindow.PosZ.Text = SelectedObject?.Location.Location.Z.ToString("N3", CultureInfo.InvariantCulture).Replace(",", "");
237+
//SceneWindow.Uid.Text = SelectedObject.Uid.ToString(CultureInfo.InvariantCulture).Replace(",", "");
308238
var q = new Quaternion();
309239
if (SelectedObject?.Location.XNAMatrix.Decompose(out var _, out q, out var _) ?? false)
310240
{
@@ -317,7 +247,16 @@ void FillSelectedObjectData()
317247
{
318248
SceneWindow.RotY.Text = "";
319249
}
320-
SceneWindow.Uid.Text = SelectedObject.Uid.ToString(CultureInfo.InvariantCulture).Replace(",", "");
250+
251+
if (SelectedObject is StaticShape ppp)
252+
{
253+
var sb = new StringBuilder();
254+
var aaa = Viewer.World.Scenery.WorldFiles
255+
.SingleOrDefault(w => w.TileX == SelectedObject.Location.TileX && w.TileZ == SelectedObject.Location.TileZ)
256+
?.MstsWFile?.Tr_Worldfile;
257+
aaa.Serialize(sb);
258+
var ccc = sb.ToString();
259+
}
321260
}
322261

323262
}

Source/Contrib/TrackViewer/TrackViewer.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,9 @@ protected override void Update(GameTime gameTime)
330330
{
331331
lostFocus = true;
332332
if (this.IsRenderWindowActive)
333+
{
333334
base.Update(gameTime);
335+
}
334336
return;
335337
}
336338

Source/Contrib/TrackViewer/UserInterface/SceneWindow.xaml

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
44
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
55
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6-
xmlns:local="clr-namespace:ORTS.TrackViewer.UserInterface"
6+
xmlns:local="clr-namespace:ORTS.TrackViewer"
77
mc:Ignorable="d"
88
Title="Scene View" SizeToContent="WidthAndHeight">
99
<DockPanel LastChildFill="True">
@@ -114,47 +114,52 @@
114114
</StatusBar>
115115
<Border BorderThickness="2">
116116
<StackPanel Orientation="Vertical" Width="150">
117-
<TextBox FontWeight="Bold" Name="Filename"/>
118-
<DockPanel>
119-
<TextBlock Text="UID: " PreviewTextInput="UintValidationTextBox"/>
120-
<TextBlock Name="Uid"/>
121-
</DockPanel>
122-
<Grid>
123-
<Grid.ColumnDefinitions>
124-
<ColumnDefinition Width="Auto"/>
125-
<ColumnDefinition Width="*"/>
126-
<ColumnDefinition Width="Auto"/>
127-
<ColumnDefinition Width="*"/>
128-
</Grid.ColumnDefinitions>
129-
<TextBlock Grid.Column="0" Text="Tile X: " />
130-
<TextBox Grid.Column="1" Name="TileX" PreviewTextInput="IntValidationTextBox"></TextBox>
131-
<TextBlock Grid.Column="2" Text=" Z: " />
132-
<TextBox Grid.Column="3" Name="TileZ" PreviewTextInput="IntValidationTextBox"></TextBox>
133-
</Grid>
134-
<Grid>
135-
<Grid.RowDefinitions>
136-
<RowDefinition Height="Auto" />
137-
<RowDefinition Height="Auto" />
138-
<RowDefinition Height="Auto" />
139-
<RowDefinition Height="Auto" />
140-
</Grid.RowDefinitions>
141-
<Grid.ColumnDefinitions>
142-
<ColumnDefinition Width="Auto" />
143-
<ColumnDefinition Width="*" />
144-
<ColumnDefinition Width="*" />
145-
</Grid.ColumnDefinitions>
146-
<TextBlock Grid.Row="0" Grid.Column="1" Text="Position" HorizontalAlignment="Center"/>
147-
<TextBlock Grid.Row="0" Grid.Column="2" Text="Rotation" HorizontalAlignment="Center"/>
148-
<TextBlock Grid.Row="1" Text="X: "/>
149-
<TextBlock Grid.Row="2" Text="Y: "/>
150-
<TextBlock Grid.Row="3" Text="Z: "/>
151-
<TextBox Grid.Row="1" Grid.Column="1" x:Name="PosX" PreviewTextInput="FloatValidationTextBox"/>
152-
<TextBox Grid.Row="2" Grid.Column="1" x:Name="PosY" PreviewTextInput="FloatValidationTextBox"/>
153-
<TextBox Grid.Row="3" Grid.Column="1" x:Name="PosZ" PreviewTextInput="FloatValidationTextBox"/>
154-
<TextBox Grid.Row="1" Grid.Column="2" x:Name="RotX" PreviewTextInput="FloatValidationTextBox"/>
155-
<TextBox Grid.Row="2" Grid.Column="2" x:Name="RotY" PreviewTextInput="FloatValidationTextBox"/>
156-
<TextBox Grid.Row="3" Grid.Column="2" x:Name="RotZ" PreviewTextInput="FloatValidationTextBox"/>
157-
</Grid>
117+
<StackPanel.DataContext>
118+
<local:SceneViewer/>
119+
</StackPanel.DataContext>
120+
<ItemsControl ItemsSource="{Binding SelectedWorldObject}">
121+
<TextBox FontWeight="Bold" Name="Filename" Text="{Binding SelectedWorldObject.FileName}"/>
122+
<DockPanel>
123+
<TextBlock Text="UID: " PreviewTextInput="UintValidationTextBox"/>
124+
<TextBlock Name="Uid" Text="{Binding SelectedWorldObject.UID}"/>
125+
</DockPanel>
126+
<Grid>
127+
<Grid.ColumnDefinitions>
128+
<ColumnDefinition Width="Auto"/>
129+
<ColumnDefinition Width="*"/>
130+
<ColumnDefinition Width="Auto"/>
131+
<ColumnDefinition Width="*"/>
132+
</Grid.ColumnDefinitions>
133+
<TextBlock Grid.Column="0" Text="Tile X: " />
134+
<TextBox Grid.Column="1" Name="TileX" PreviewTextInput="IntValidationTextBox" Text="{Binding SelectedObject.Location.TileX}" />
135+
<TextBlock Grid.Column="2" Text=" Z: " />
136+
<TextBox Grid.Column="3" Name="TileZ" PreviewTextInput="IntValidationTextBox" Text="{Binding SelectedObject.Location.TileZ}" />
137+
</Grid>
138+
<Grid>
139+
<Grid.RowDefinitions>
140+
<RowDefinition Height="Auto" />
141+
<RowDefinition Height="Auto" />
142+
<RowDefinition Height="Auto" />
143+
<RowDefinition Height="Auto" />
144+
</Grid.RowDefinitions>
145+
<Grid.ColumnDefinitions>
146+
<ColumnDefinition Width="Auto" />
147+
<ColumnDefinition Width="*" />
148+
<ColumnDefinition Width="*" />
149+
</Grid.ColumnDefinitions>
150+
<TextBlock Grid.Row="0" Grid.Column="1" Text="Position" HorizontalAlignment="Center"/>
151+
<TextBlock Grid.Row="0" Grid.Column="2" Text="Rotation" HorizontalAlignment="Center"/>
152+
<TextBlock Grid.Row="1" Text="X: "/>
153+
<TextBlock Grid.Row="2" Text="Y: "/>
154+
<TextBlock Grid.Row="3" Text="Z: "/>
155+
<TextBox Grid.Row="1" Grid.Column="1" x:Name="PosX" Text="{Binding SelectedObject.Location.Location.X, StringFormat=N3}" PreviewTextInput="FloatValidationTextBox"/>
156+
<TextBox Grid.Row="2" Grid.Column="1" x:Name="PosY" Text="{Binding SelectedObject.Location.Location.Y, StringFormat=N3}" PreviewTextInput="FloatValidationTextBox"/>
157+
<TextBox Grid.Row="3" Grid.Column="1" x:Name="PosZ" Text="{Binding SelectedObject.Location.Location.Z, StringFormat=N3}" PreviewTextInput="FloatValidationTextBox"/>
158+
<TextBox Grid.Row="1" Grid.Column="2" x:Name="RotX" PreviewTextInput="FloatValidationTextBox"/>
159+
<TextBox Grid.Row="2" Grid.Column="2" x:Name="RotY" PreviewTextInput="FloatValidationTextBox"/>
160+
<TextBox Grid.Row="3" Grid.Column="2" x:Name="RotZ" PreviewTextInput="FloatValidationTextBox"/>
161+
</Grid>
162+
</ItemsControl>
158163
</StackPanel>
159164
</Border>
160165
<Grid DockPanel.Dock="Bottom" x:Name="GraphicsHostElement" />

Source/ORTS.Common/Input/UserCommand.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,13 +239,17 @@ public enum UserCommand
239239
[GetString("Control Cruise Control Mode Decrease")] ControlCruiseControlModeDecrease,
240240
[GetString("Control Train Type Change (Passenger/Cargo)")] ControlTrainTypePaxCargo,
241241
[GetString("Control Selected Speed To Zero")] ControlSpeedRegulatorSelectedSpeedToZero,
242-
//Distributed power
242+
243+
// Distributed power
243244
[GetString("Control DP Move To Front")] ControlDPMoveToFront,
244245
[GetString("Control DP Move To Back")] ControlDPMoveToBack,
245246
[GetString("Control DP Traction")] ControlDPTraction,
246247
[GetString("Control DP Idle")] ControlDPIdle,
247248
[GetString("Control DP Brake")] ControlDPBrake,
248249
[GetString("Control DP More")] ControlDPMore,
249250
[GetString("Control DP Less")] ControlDPLess,
251+
252+
// Editor
253+
[GetString("Editor Unselect All")] EditorUnselectAll,
250254
}
251255
}

Source/ORTS.Settings/InputSettings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,8 @@ static void InitializeCommands(UserCommandInput[] Commands)
536536
Commands[(int)UserCommand.GameSwitchManualMode] = new UserCommandKeyInput(0x32, KeyModifiers.Control);
537537
Commands[(int)UserCommand.GameSwitchPicked] = new UserCommandKeyInput(0x22, KeyModifiers.Alt);
538538
Commands[(int)UserCommand.GameUncoupleWithMouse] = new UserCommandKeyInput(0x16);
539+
540+
Commands[(int)UserCommand.EditorUnselectAll] = new UserCommandKeyInput(0x01);
539541
}
540542
#endregion
541543

0 commit comments

Comments
 (0)