Skip to content

Commit 7a3c94a

Browse files
committed
Automatic merge of T1.6-rc2-26-g74ecafa7f and 10 pull requests
- Pull request #1072 at 076a8d3: Content Creation Shortcuts & Advanced Wagon Shape Interactions - Pull request #1086 at e10390b: Add Settings Exporter tool (copy settings to INI, etc) - Pull request #1091 at ac323a2: Automatic speed control - Pull request #1097 at 63248a0: Fix For Delayed Particle Emitter Spawning - Pull request #1099 at 5e8b056: Fix TCS orders not being sent to pantographs - Pull request #1100 at cccb40a: Updates to German translations - Pull request #1102 at c96c499: Fix Stuck Locomotive Brakes After Initialization - Pull request #1103 at d2fae0f: Fix diverging force when exceeding max speed - Pull request #1082 at 5845a1a: Allow variable water level in glass gauge - Pull request #1081 at 689494b: Brake cuts power unification
12 parents 6753d14 + 74ecafa + 076a8d3 + e10390b + ac323a2 + 63248a0 + 5e8b056 + cccb40a + c96c499 + d2fae0f + 5845a1a + 689494b commit 7a3c94a

File tree

4 files changed

+165
-98
lines changed

4 files changed

+165
-98
lines changed

Source/Documentation/Manual/features-rollingstock.rst

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -741,9 +741,7 @@ To simplify this process, and produce more reasonable dimensions for rolling sto
741741
automatically calculate the dimensions of rolling stock based on the shape file used. Enter
742742
``ORTSAutoSize`` in the Wagon section of an engine or wagon to allow OR to determine
743743
the width, height, and length of the rolling stock based on the dimensions of the main shape file,
744-
ignoring any values entered manually in the MSTS Size parameter. Note that this process is
745-
not aware of any :ref:`shape descriptor overrides <features-shape-manipulation>` so any changes made
746-
to the shape there will not be reflected in the automatically calculated size.
744+
ignoring any values entered manually in the MSTS Size parameter.
747745

748746
``ORTSAutoSize`` accepts 3 (optional) arguments, default units in meters, corresponding to offsets from the
749747
shape's width, height, and length respectively. For example, ``ORTSAutoSize ( 0.1m, -0.2m, -0.18m )``
@@ -754,11 +752,13 @@ arguments can be set to 0, and the length argument adjusted to produce the desir
754752
no arguments are specified (ie: ``ORTSAutoSize ()`` was entered in the Wagon section) then all three
755753
offsets are assumed to be 0 meters.
756754

757-
Note that automatic sizing uses the nearest LOD of the main shape file. LODs for further distances
758-
and freight animation shape files have no effect on the automatic sizing. This method also works best for rolling
759-
stock with standard buffers/couplers on each end. Automatic sizing generally can't produce reasonable results
760-
for articulated rolling stock. And should something go wrong with the shape file causing automatic sizing to fail,
761-
OR will revert to the values entered in the ``Size`` parameter.
755+
Note that automatic sizing uses the nearest LOD of the main shape file and attached freight animations. LODs for further
756+
distances have no effect on the automatic sizing. Freight animations using the ``ShapeHierarchy`` feature are also
757+
skipped due to potential unintended behaviors. :ref:`Shape descriptor overrides <features-shape-manipulation>`
758+
are also not considered at this phase, so if any changes are made in the .sd file, this feature may not provide
759+
good results. This method also works best for rolling stock with standard buffers/couplers on each end.
760+
Automatic sizing generally can't produce reasonable results for articulated rolling stock. And should something go
761+
wrong with the shape file causing automatic sizing to fail, OR will revert to the values entered in the ``Size`` parameter.
762762

763763
Improved wagon alignment tools
764764
------------------------------
@@ -800,9 +800,9 @@ not change the X or Y components. Should no re-centering be required, none will
800800
Some rolling stock will not align correctly when auto-centered. As with ``ORTSAutoSize``, this
801801
feature should be employed on rolling stock with standard buffers or couplers, and will
802802
not produce suitable results for articulated rolling stock or stock with different coupler
803-
types at each end. Only the highest detail LOD of the main shape is used to auto-center the
804-
rolling stock, other LODs and freight animations are ignored. If the process fails, a warning
805-
will be written to the log and the automatic calculation will be skipped.
803+
types at each end. Only the highest detail LOD of the main shape and freight animations are
804+
used, the .sd file is not checked. If the process fails, a warning will be written to the
805+
log and the automatic calculation will be skipped.
806806

807807
Advanced articulation control
808808
-----------------------------

Source/Orts.Formats.Msts/ShapeFile.cs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +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 Microsoft.Xna.Framework;
1819
using Orts.Parsers.Msts;
1920
using System;
2021
using System.Collections.Generic;
@@ -109,7 +110,99 @@ public void ReadAnimationBlock(string orFileName)
109110
file.VerifyEndOfBlock();
110111
}
111112

113+
/// <summary>
114+
/// Determines the corners of the 'bounding box' for the shape
115+
/// </summary>
116+
/// <returns>Two Vector3s, the first measuring the minimum extent of the shape,
117+
/// the second measuring the maximum extent of the shape</returns>
118+
public (Vector3, Vector3) GetBoundingLimits()
119+
{
120+
Vector3 mins = new Vector3(float.PositiveInfinity);
121+
Vector3 maxes = new Vector3(float.NegativeInfinity);
122+
123+
// Determine size specifically for LOD0's (nearest LOD) sub objects
124+
foreach (sub_object subObj in shape.lod_controls[0].distance_levels[0].sub_objects)
125+
{
126+
// Use vertex sets in the sub object to determine which vertices to check
127+
foreach (vertex_set vSet in subObj.vertex_sets)
128+
{
129+
// Use the vertex state used by this vertex set to determine the matrix used
130+
vtx_state vState = shape.vtx_states[vSet.VtxStateIdx];
131+
132+
// The index of the matrix used by this vertex state
133+
int mIndex = vState.imatrix;
134+
135+
// The 'actual' XNA matrix used to determine the vertex transformation
136+
Matrix mat = Matrix.Identity;
137+
138+
// How deep are we in the hierarchy? Set a limit to prevent infinite loops
139+
int depth = 0;
112140

141+
// Determine the overall transformation matrix from the root to the current matrix by following the hierarchy
142+
do
143+
{
144+
matrix m = shape.matrices[mIndex];
145+
146+
// Convert the shape file matrix to an XNA matrix
147+
Matrix matTransform = new Matrix
148+
{
149+
M11 = m.AX,
150+
M12 = m.AY,
151+
M13 = m.AZ, //
152+
M14 = 0,
153+
M21 = m.BX,
154+
M22 = m.BY,
155+
M23 = m.BZ, //
156+
M24 = 0,
157+
M31 = m.CX, //
158+
M32 = m.CY, //
159+
M33 = m.CZ,
160+
M34 = 0,
161+
M41 = m.DX,
162+
M42 = m.DY,
163+
M43 = m.DZ, //
164+
M44 = 1.0f
165+
};
166+
167+
// Add the effect of this transformation to the overall transformation
168+
mat = mat * matTransform;
169+
170+
// Determine the index of the next highest matrix in the hierarchy
171+
mIndex = shape.lod_controls[0].distance_levels[0].distance_level_header.hierarchy[mIndex];
172+
173+
depth++;
174+
} // Keep calculating until we have calculated the root, or until a loop is encountered
175+
while (mIndex > -1 && mIndex != vState.imatrix && mIndex < shape.matrices.Count && depth < 32);
176+
177+
// Determine position of every vertex in this set from point position and tranformed by the matrix
178+
for (int i = vSet.StartVtxIdx; i < vSet.StartVtxIdx + vSet.VtxCount; i++)
179+
{
180+
// Determine vertex position from vertex index and point index
181+
point p = shape.points[subObj.vertices[i].ipoint];
182+
Vector3 pPos = new Vector3(p.X, p.Y, p.Z);
183+
184+
pPos = Vector3.Transform(pPos, mat);
185+
186+
if (pPos.X < mins.X)
187+
mins.X = pPos.X;
188+
if (pPos.X > maxes.X)
189+
maxes.X = pPos.X;
190+
191+
if (pPos.Y < mins.Y)
192+
mins.Y = pPos.Y;
193+
if (pPos.Y > maxes.Y)
194+
maxes.Y = pPos.Y;
195+
196+
if (pPos.Z < mins.Z)
197+
mins.Z = pPos.Z;
198+
if (pPos.Z > maxes.Z)
199+
maxes.Z = pPos.Z;
200+
}
201+
}
202+
}
203+
204+
return (mins, maxes);
205+
}
113206
}
114207

115208
public class shape

0 commit comments

Comments
 (0)