Skip to content

Commit f5ac38c

Browse files
committed
Clean up the uid storing
1 parent 8da48b3 commit f5ac38c

File tree

13 files changed

+269
-107
lines changed

13 files changed

+269
-107
lines changed

Source/Contrib/TrackViewer/SceneViewer.cs

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -211,13 +211,13 @@ public async Task SetCameraLocation()
211211
TrackViewer.RenderProcess.Viewer.ViewerCamera.SetLocation(mouseLocation);
212212
}
213213

214-
protected bool PickByMouse(out StaticShape pickedObject)
214+
protected bool PickByMouse(out StaticShape pickedObjectOut)
215215
{
216216
var viewer = TrackViewer.RenderProcess.Viewer;
217217

218218
if (viewer == null)
219219
{
220-
pickedObject = null;
220+
pickedObjectOut = null;
221221
return false;
222222
}
223223

@@ -226,47 +226,64 @@ protected bool PickByMouse(out StaticShape pickedObject)
226226
var direction = Vector3.Normalize(viewer.FarPoint - viewer.NearPoint);
227227
var pickRay = new Ray(viewer.NearPoint, direction);
228228

229-
pickedObject = null;
229+
object pickedObject = null;
230230
var pickedDistance = float.MaxValue;
231+
var boundingBoxes = new Orts.Viewer3D.BoundingBox[1];
231232
foreach (var worldFile in viewer.World.Scenery.WorldFiles)
232233
{
233-
foreach (var sceneryObject in worldFile.sceneryObjects)
234+
foreach (var checkedObject in worldFile.sceneryObjects)
234235
{
235-
float? distance = null;
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+
}
236246

237-
if (sceneryObject.BoundingBox is Orts.Viewer3D.BoundingBox boundingBox)
247+
void checkObject(object checkedObject, Orts.Viewer3D.BoundingBox[] checkedBoundingBox, WorldPosition checkedLocation)
248+
{
249+
if (checkedBoundingBox?.Length > 0)
250+
{
251+
foreach (var boundingBox in checkedBoundingBox)
238252
{
239253
// Locate relative to the camera
240-
var dTileX = sceneryObject.Location.TileX - camera.TileX;
241-
var dTileZ = sceneryObject.Location.TileZ - camera.TileZ;
242-
var xnaDTileTranslation = sceneryObject.Location.XNAMatrix;
254+
var dTileX = checkedLocation.TileX - camera.TileX;
255+
var dTileZ = checkedLocation.TileZ - camera.TileZ;
256+
var xnaDTileTranslation = checkedLocation.XNAMatrix;
243257
xnaDTileTranslation.M41 += dTileX * 2048;
244258
xnaDTileTranslation.M43 -= dTileZ * 2048;
259+
xnaDTileTranslation = boundingBox.ComplexTransform * xnaDTileTranslation;
245260

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

249264
var xnabb = new Microsoft.Xna.Framework.BoundingBox(min, max);
250-
distance = pickRay.Intersects(xnabb);
251-
}
252-
else
253-
{
254-
var radius = 10f;
255-
var boundingSphere = new BoundingSphere(camera.XnaLocation(sceneryObject.Location.WorldLocation), radius);
256-
distance = pickRay.Intersects(boundingSphere);
265+
checkDistance(checkedObject, pickRay.Intersects(xnabb));
257266
}
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+
}
258275

259-
if (distance != null)
260-
{
261-
if (distance < pickedDistance)
262-
{
263-
pickedDistance = distance.Value;
264-
pickedObject = sceneryObject;
265-
}
266-
}
276+
void checkDistance(object checkedObject, float? checkedDistance)
277+
{
278+
if (checkedDistance != null && checkedDistance < pickedDistance)
279+
{
280+
pickedDistance = checkedDistance.Value;
281+
pickedObject = checkedObject;
267282
}
268283
}
269-
return pickedObject != null;
284+
285+
pickedObjectOut = pickedObject as StaticShape;
286+
return pickedObjectOut != null;
270287
}
271288

272289
void FillSelectedObjectData()

Source/Orts.Formats.Msts/ShapeDescriptorFile.cs

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
// You should have received a copy of the GNU General Public License
1616
// along with Open Rails. If not, see <http://www.gnu.org/licenses/>.
1717

18-
using System;
18+
using System.Collections.Generic;
1919
using Orts.Parsers.Msts;
2020

2121
namespace Orts.Formats.Msts
@@ -47,6 +47,7 @@ public class SDShape
4747
public SDShape()
4848
{
4949
ESD_Bounding_Box = new ESD_Bounding_Box();
50+
ESD_Complex = new List<ESD_Complex_Box>();
5051
}
5152

5253
public SDShape(STFReader stf)
@@ -63,6 +64,23 @@ public SDShape(STFReader stf)
6364
if (ESD_Bounding_Box.Min == null || ESD_Bounding_Box.Max == null) // ie quietly handle ESD_Bounding_Box()
6465
ESD_Bounding_Box = null;
6566
}),
67+
new STFReader.TokenProcessor("esd_complex", ()=>{
68+
ESD_Complex = new List<ESD_Complex_Box>();
69+
stf.MustMatch("(");
70+
var count = stf.ReadInt(null);
71+
stf.ParseBlock(new[]
72+
{
73+
new STFReader.TokenProcessor("esd_complex_box", () =>
74+
{
75+
if (ESD_Complex.Count >= count)
76+
STFException.TraceWarning(stf, "Skipped extra ESD_Complex_Box");
77+
else
78+
ESD_Complex.Add(new ESD_Complex_Box(stf));
79+
}),
80+
});
81+
if (ESD_Complex.Count < count)
82+
STFException.TraceWarning(stf, (count - ESD_Complex.Count).ToString() + " missing ESD_Complex_Boxes");
83+
}),
6684
new STFReader.TokenProcessor("esd_ortssoundfilename", ()=>{ ESD_SoundFileName = stf.ReadStringBlock(null); }),
6785
new STFReader.TokenProcessor("esd_ortsbellanimationfps", ()=>{ ESD_CustomAnimationFPS = stf.ReadFloatBlock(STFReader.UNITS.Frequency, null); }),
6886
new STFReader.TokenProcessor("esd_ortscustomanimationfps", ()=>{ ESD_CustomAnimationFPS = stf.ReadFloatBlock(STFReader.UNITS.Frequency, null); }),
@@ -73,6 +91,7 @@ public SDShape(STFReader stf)
7391
public int ESD_Detail_Level;
7492
public int ESD_Alternative_Texture;
7593
public ESD_Bounding_Box ESD_Bounding_Box;
94+
public List<ESD_Complex_Box> ESD_Complex;
7695
public bool ESD_No_Visual_Obstruction;
7796
public bool ESD_Snapable;
7897
public bool ESD_SubObj;
@@ -84,8 +103,9 @@ public class ESD_Bounding_Box
84103
{
85104
public ESD_Bounding_Box() // default used for files with no SD file
86105
{
87-
Min = new TWorldPosition(0, 0, 0);
88-
Max = new TWorldPosition(0, 0, 0);
106+
Min = TWorldPosition.Zero;
107+
Max = TWorldPosition.Zero;
108+
Extra = TWorldPosition.Zero;
89109
}
90110

91111
public ESD_Bounding_Box(STFReader stf)
@@ -103,8 +123,61 @@ public ESD_Bounding_Box(STFReader stf)
103123
Z = stf.ReadFloat(STFReader.UNITS.None, null);
104124
Max = new TWorldPosition(X, Y, Z);
105125
// JP2indirt.sd has extra parameters
126+
item = stf.ReadString();
127+
if (item == ")")
128+
{
129+
Extra = TWorldPosition.Zero;
130+
return;
131+
}
132+
stf.StepBackOneItem();
133+
X = stf.ReadFloat(STFReader.UNITS.None, null);
134+
Y = stf.ReadFloat(STFReader.UNITS.None, null);
135+
Z = stf.ReadFloat(STFReader.UNITS.None, null);
136+
Extra = new TWorldPosition(X, Y, Z);
137+
stf.SkipRestOfBlock();
138+
}
139+
public TWorldPosition Min;
140+
public TWorldPosition Max;
141+
public TWorldPosition Extra;
142+
}
143+
144+
public class ESD_Complex_Box
145+
{
146+
public ESD_Complex_Box() // default used for files with no SD file
147+
{
148+
Rotation = TWorldPosition.Zero;
149+
Translation = TWorldPosition.Zero;
150+
Min = TWorldPosition.Zero;
151+
Max = TWorldPosition.Zero;
152+
}
153+
154+
public ESD_Complex_Box(STFReader stf)
155+
{
156+
stf.MustMatch("(");
157+
string item = stf.ReadString();
158+
if (item == ")") return; // quietly return on ESD_Complex_Box()
159+
stf.StepBackOneItem();
160+
float X = stf.ReadFloat(STFReader.UNITS.None, null);
161+
float Y = stf.ReadFloat(STFReader.UNITS.None, null);
162+
float Z = stf.ReadFloat(STFReader.UNITS.None, null);
163+
Rotation = new TWorldPosition(X, Y, Z);
164+
X = stf.ReadFloat(STFReader.UNITS.None, null);
165+
Y = stf.ReadFloat(STFReader.UNITS.None, null);
166+
Z = stf.ReadFloat(STFReader.UNITS.None, null);
167+
Translation = new TWorldPosition(X, Y, Z);
168+
X = stf.ReadFloat(STFReader.UNITS.None, null);
169+
Y = stf.ReadFloat(STFReader.UNITS.None, null);
170+
Z = stf.ReadFloat(STFReader.UNITS.None, null);
171+
Min = new TWorldPosition(X, Y, Z);
172+
X = stf.ReadFloat(STFReader.UNITS.None, null);
173+
Y = stf.ReadFloat(STFReader.UNITS.None, null);
174+
Z = stf.ReadFloat(STFReader.UNITS.None, null);
175+
Max = new TWorldPosition(X, Y, Z);
176+
// JP2indirt.sd has extra parameters
106177
stf.SkipRestOfBlock();
107178
}
179+
public TWorldPosition Rotation;
180+
public TWorldPosition Translation;
108181
public TWorldPosition Min;
109182
public TWorldPosition Max;
110183
}

Source/Orts.Formats.Msts/WorldFile.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,8 @@ public class TWorldPosition
15461546
public float Y;
15471547
public float Z;
15481548

1549+
public static readonly TWorldPosition Zero = new TWorldPosition(0, 0, 0);
1550+
15491551
public TWorldPosition(float x, float y, float z) { X = x; Y = y; Z = z; }
15501552
public TWorldPosition() { X = 0.0f; Y = 0.0f; Z = 0.0f; }
15511553
public TWorldPosition(TWorldPosition p)

Source/RunActivity/Viewer3D/DynamicTrack.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public class DynamicTrack
4343
/// <param name="trackList">DynamicTrackViewer list.</param>
4444
/// <param name="trackObj">Dynamic track section to decompose.</param>
4545
/// <param name="worldMatrix">Position matrix.</param>
46-
public static void Decompose(Viewer viewer, List<DynamicTrackViewer> trackList, DyntrackObj trackObj, WorldPosition worldMatrix, int uid)
46+
public static void Decompose(Viewer viewer, List<DynamicTrackViewer> trackList, DyntrackObj trackObj, WorldPosition worldMatrix)
4747
{
4848
// DYNAMIC TRACK
4949
// =============
@@ -118,7 +118,7 @@ public static void Decompose(Viewer viewer, List<DynamicTrackViewer> trackList,
118118
nextRoot.XNAMatrix.Translation = sectionOrigin + displacement;
119119

120120
// Create a new DynamicTrackViewer for the subsection
121-
trackList.Add(new DynamicTrackViewer(viewer, subsection, root, nextRoot, uid));
121+
trackList.Add(new DynamicTrackViewer(viewer, subsection, root, nextRoot));
122122
localV = localProjectedV; // Next subsection
123123
}
124124
}
@@ -131,7 +131,7 @@ public class DynamicTrackViewer
131131
public DynamicTrackPrimitive Primitive;
132132
public readonly int Uid;
133133

134-
public DynamicTrackViewer(Viewer viewer, DyntrackObj dtrack, WorldPosition position, WorldPosition endPosition, int uid)
134+
public DynamicTrackViewer(Viewer viewer, DyntrackObj dtrack, WorldPosition position, WorldPosition endPosition)
135135
{
136136
Viewer = viewer;
137137
worldPosition = position;
@@ -146,7 +146,7 @@ public DynamicTrackViewer(Viewer viewer, DyntrackObj dtrack, WorldPosition posit
146146

147147
// Instantiate classes
148148
Primitive = new DynamicTrackPrimitive(Viewer, dtrack, worldPosition, endPosition);
149-
Uid = uid;
149+
Uid = (int)dtrack.UID;
150150
}
151151

152152
public DynamicTrackViewer(Viewer viewer, WorldPosition position, WorldPosition endPosition, int uid)

Source/RunActivity/Viewer3D/EditorPrimitives.cs

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919

2020
using Microsoft.Xna.Framework;
2121
using Microsoft.Xna.Framework.Graphics;
22-
using Orts.Viewer3D.Common;
23-
using Orts.Viewer3D.Processes;
2422
using ORTS.Common;
2523
using System;
2624
using System.Collections.Generic;
@@ -33,8 +31,8 @@ public class EditorShapes : StaticShape, IDisposable
3331
public bool MouseCrosshairEnabled { get; set; }
3432
public StaticShape SelectedObject { get; set; }
3533
StaticShape _selectedObject;
36-
BoundingBoxPrimitive SelectedObjectBoundingBoxPrimitive;
37-
List<EditorPrimitive> UnusedPrimitives = new List<EditorPrimitive>();
34+
readonly List<BoundingBoxPrimitive> SelectedObjectBoundingBoxPrimitives = new List<BoundingBoxPrimitive>();
35+
readonly List<EditorPrimitive> UnusedPrimitives = new List<EditorPrimitive>();
3836

3937
public EditorShapes(Viewer viewer) : base(viewer, "", null, ShapeFlags.None, null, -1)
4038
{
@@ -46,18 +44,36 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
4644
if (_selectedObject != SelectedObject)
4745
{
4846
_selectedObject = SelectedObject;
49-
UnusedPrimitives.Add(SelectedObjectBoundingBoxPrimitive);
50-
SelectedObjectBoundingBoxPrimitive = _selectedObject?.BoundingBox == null ? null :
51-
new BoundingBoxPrimitive(Viewer, _selectedObject.BoundingBox.Value, Color.CornflowerBlue);
47+
if (UnusedPrimitives.Count > 0)
48+
{
49+
foreach (var primitive in UnusedPrimitives)
50+
{
51+
//primitive.Dispose();
52+
}
53+
//UnusedPrimitives.Clear();
54+
}
55+
UnusedPrimitives.AddRange(SelectedObjectBoundingBoxPrimitives);
56+
SelectedObjectBoundingBoxPrimitives.Clear();
57+
if (_selectedObject?.BoundingBox?.Length > 0)
58+
{
59+
foreach (var boundingBox in _selectedObject.BoundingBox)
60+
{
61+
SelectedObjectBoundingBoxPrimitives.Add(new BoundingBoxPrimitive(Viewer, boundingBox, Color.CornflowerBlue));
62+
}
63+
}
5264
}
53-
if (SelectedObjectBoundingBoxPrimitive != null)
65+
if (SelectedObjectBoundingBoxPrimitives?.Count > 0)
5466
{
55-
var dTileX = _selectedObject.Location.TileX - Viewer.Camera.TileX;
56-
var dTileZ = _selectedObject.Location.TileZ - Viewer.Camera.TileZ;
57-
var xnaDTileTranslation = _selectedObject.Location.XNAMatrix;
58-
xnaDTileTranslation.M41 += dTileX * 2048;
59-
xnaDTileTranslation.M43 -= dTileZ * 2048;
60-
frame.AddPrimitive(SelectedObjectBoundingBoxPrimitive.Material, SelectedObjectBoundingBoxPrimitive, RenderPrimitiveGroup.Labels, ref xnaDTileTranslation);
67+
foreach (var boundingBox in SelectedObjectBoundingBoxPrimitives)
68+
{
69+
var dTileX = _selectedObject.Location.TileX - Viewer.Camera.TileX;
70+
var dTileZ = _selectedObject.Location.TileZ - Viewer.Camera.TileZ;
71+
var xnaDTileTranslation = _selectedObject.Location.XNAMatrix;
72+
xnaDTileTranslation.M41 += dTileX * 2048;
73+
xnaDTileTranslation.M43 -= dTileZ * 2048;
74+
xnaDTileTranslation = boundingBox.ComplexTransform * xnaDTileTranslation;
75+
frame.AddPrimitive(boundingBox.Material, boundingBox, RenderPrimitiveGroup.Labels, ref xnaDTileTranslation);
76+
}
6177
}
6278
if (MouseCrosshairEnabled)
6379
{
@@ -73,13 +89,25 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
7389
internal override void Mark()
7490
{
7591
MouseCrosshair.Mark();
76-
SelectedObjectBoundingBoxPrimitive.Mark();
92+
if (SelectedObjectBoundingBoxPrimitives?.Count > 0)
93+
{
94+
foreach (var selectedObject in SelectedObjectBoundingBoxPrimitives)
95+
{
96+
selectedObject.Mark();
97+
}
98+
}
7799
}
78100

79101
public void Dispose()
80102
{
81103
MouseCrosshair?.Dispose();
82-
SelectedObjectBoundingBoxPrimitive?.Dispose();
104+
if (SelectedObjectBoundingBoxPrimitives?.Count > 0)
105+
{
106+
foreach (var selectedObject in SelectedObjectBoundingBoxPrimitives)
107+
{
108+
selectedObject.Dispose();
109+
}
110+
}
83111
}
84112
}
85113

@@ -106,6 +134,7 @@ public override void Draw(GraphicsDevice graphicsDevice)
106134
public class BoundingBoxPrimitive : EditorPrimitive
107135
{
108136
static IndexBuffer BoundingBoxIndexBuffer;
137+
public readonly Matrix ComplexTransform;
109138

110139
public BoundingBoxPrimitive(Viewer viewer, BoundingBox boundingBox, Color color)
111140
{
@@ -132,6 +161,7 @@ public BoundingBoxPrimitive(Viewer viewer, BoundingBox boundingBox, Color color)
132161
PrimitiveCount = IndexBuffer.IndexCount / 2;
133162
PrimitiveType = PrimitiveType.LineList;
134163
Material = viewer.MaterialManager.Load("DebugNormals");
164+
ComplexTransform = boundingBox.ComplexTransform;
135165
}
136166
}
137167

0 commit comments

Comments
 (0)