Skip to content

Commit 56bd084

Browse files
committed
Automatic merge of T1.5.1-687-gd279e384a and 18 pull requests
- Pull request #570 at c59c788: Experimental glTF 2.0 support with PBR lighting - Pull request #839 at d00beb9: First phase of https://blueprints.launchpad.net/or/+spec/additional-cruise-control-parameters - Pull request #865 at 67014b7: Dispatcher window improvements - Pull request #874 at f8dbeab: Dynamic brake controller refactoring - Pull request #875 at 43bf33e: Bug fix for https://bugs.launchpad.net/or/+bug/2036346 Player train switching doesn't work with 3D cabs - Pull request #876 at f92de76: docs: add source for documents previously on website to source Documentation folder - Pull request #878 at f9aa2ad: Implement Polach Adhesion - Pull request #882 at d8a1c4d: Blueprint/train car operations UI window - Pull request #883 at edcc2dd: SwitchPanel disconnect/connect handling - Pull request #885 at c81447b: feat: Add notifications to Menu - Pull request #886 at 392d395: Scene viewer extension to TrackViewer - Pull request #887 at 4665bda: docs: Document projects, assemblies, namespaces - Pull request #888 at d7daf62: docs: Document player application model - Pull request #889 at 43341cf: No speed update - Pull request #892 at 1f5ba4c: Signal Function OPP_SIG_ID_TRAINPATH - Pull request #893 at bf8876b: Signal errors - Pull request #894 at 794fddf: Correct Decrease Colour - Pull request #896 at 5866028: First implementation of https://blueprints.launchpad.net/or/+spec/specific-sounds-for-ai-trains
20 parents d221c7f + d279e38 + c59c788 + d00beb9 + 67014b7 + f8dbeab + 43bf33e + f92de76 + f9aa2ad + d8a1c4d + edcc2dd + c81447b + 392d395 + 4665bda + d7daf62 + 43341cf + 1f5ba4c + bf8876b + 794fddf + 5866028 commit 56bd084

File tree

13 files changed

+510
-116
lines changed

13 files changed

+510
-116
lines changed

Source/Contrib/TrackViewer/SceneViewer.cs

Lines changed: 54 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ public async Task SetCameraLocation()
197197
{
198198
if (TrackViewer.RenderProcess.Viewer?.Tiles == null)
199199
{
200-
if (i > 50)
200+
if (i > 300)
201201
return;
202202
await Task.Delay(100);
203203
i++;
@@ -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,75 @@ 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+
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;
270298
}
271299

272300
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
}

0 commit comments

Comments
 (0)