mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-04 19:59:25 +01:00
refactor(track): the rail layout value types (crossings, sizes, check and guard rails, cuts, bands, fills, treads, layout) and the wheel and rail constants live in world/RailLayout.h in track_rails instead of inside TTrack
This commit is contained in:
@@ -444,7 +444,7 @@ void editor_mode::selftest_step()
|
|||||||
WriteLog(format("SELFTEST crossing %s path %d side %d at %.3f m: %s with %s, 1:%.2f, into %.3f, facing %.3f, nose %d", track->name().c_str(), crossing.path, crossing.side, crossing.at, kind,
|
WriteLog(format("SELFTEST crossing %s path %d side %d at %.3f m: %s with %s, 1:%.2f, into %.3f, facing %.3f, nose %d", track->name().c_str(), crossing.path, crossing.side, crossing.at, kind,
|
||||||
crossing.track->name().c_str(), 1.0 / std::tan(crossing.angle), crossing.into, crossing.facing, crossing.nose ? 1 : 0));
|
crossing.track->name().c_str(), 1.0 / std::tan(crossing.angle), crossing.into, crossing.facing, crossing.nose ? 1 : 0));
|
||||||
}
|
}
|
||||||
auto const gauge = [](TTrack *Track, TTrack::rail_crossing const &Crossing) {
|
auto const gauge = [](TTrack *Track, track_rails::rail_crossing const &Crossing) {
|
||||||
auto const &segment{Track->eType == tt_Switch ? *Track->SwitchExtension->Segments[Crossing.path] : *Track->Segment};
|
auto const &segment{Track->eType == tt_Switch ? *Track->SwitchExtension->Segments[Crossing.path] : *Track->Segment};
|
||||||
glm::dvec3 point, across;
|
glm::dvec3 point, across;
|
||||||
segment.plan_frame(Crossing.at, point, across);
|
segment.plan_frame(Crossing.at, point, across);
|
||||||
|
|||||||
153
world/RailLayout.h
Normal file
153
world/RailLayout.h
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
This Source Code Form is subject to the
|
||||||
|
terms of the Mozilla Public License, v.
|
||||||
|
2.0. If a copy of the MPL was not
|
||||||
|
distributed with this file, You can
|
||||||
|
obtain one at
|
||||||
|
http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <vector>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include "utilities/Classes.h"
|
||||||
|
#include "world/Knots.h"
|
||||||
|
|
||||||
|
class TTrack;
|
||||||
|
|
||||||
|
namespace track_rails {
|
||||||
|
|
||||||
|
double constexpr flangeway { 0.045 };
|
||||||
|
double constexpr blend { 0.015 };
|
||||||
|
double constexpr tread_fade { 0.02 };
|
||||||
|
double constexpr wheel_width { 0.14 };
|
||||||
|
double constexpr back_to_back { 1.36 };
|
||||||
|
double constexpr rolled_band { wheel_width - ( 1.435 - back_to_back ) / 2.0 };
|
||||||
|
double constexpr nose_tip { 0.012 };
|
||||||
|
double constexpr middle_angle { 0.35 };
|
||||||
|
double constexpr wide_angle { 0.785 };
|
||||||
|
|
||||||
|
// where the inner rails of the two paths of a switch cross, found from their gauge lines behind the blades
|
||||||
|
struct switch_frog {
|
||||||
|
bool valid { false };
|
||||||
|
int side[ 2 ] {}; // rail profile of the crossing rail of each path, 1 right, -1 left
|
||||||
|
double at[ 2 ] {}; // distance of the crossing along each path
|
||||||
|
double blades[ 2 ] {}; // distance the blades take along each path
|
||||||
|
double angle { 0.0 };
|
||||||
|
};
|
||||||
|
// where a rail of this track crosses a rail of another one, found from their gauge lines
|
||||||
|
struct rail_crossing {
|
||||||
|
TTrack *track { nullptr };
|
||||||
|
int path { 0 };
|
||||||
|
int side { 0 }; // rail profile of the crossing rail, 1 right, -1 left
|
||||||
|
double at { 0.0 }; // distance of the crossing along the path, past the ends where the track goes on
|
||||||
|
double angle { 0.0 };
|
||||||
|
double into { 0.0 }; // the path direction against the gauge normal of the other rail, above zero: going into the other track
|
||||||
|
double facing { 0.0 }; // the gauge normals of both rails against each other, below zero: an acute frog
|
||||||
|
bool nose { false }; // at an acute frog the rail goes on as the nose rail, the other one as the rail beside it
|
||||||
|
int otherpath { 0 };
|
||||||
|
int otherside { 0 }; // rail profile of the other rail, 1 right, -1 left
|
||||||
|
double otherat { 0.0 }; // distance of the crossing along the other path
|
||||||
|
bool aligned { true }; // both paths run the same way at the crossing
|
||||||
|
TTrack *owner { nullptr };
|
||||||
|
};
|
||||||
|
// the size of the rail profile, out from the gauge face: positive outwards, the side of the head away from the track
|
||||||
|
struct rail_size {
|
||||||
|
double head { 0.0735 }; // how far the head reaches out
|
||||||
|
double height { 0.172 };
|
||||||
|
double low { -0.0385 }; // the reach of the profile inwards
|
||||||
|
double high { 0.1115 }; // the reach of the profile outwards
|
||||||
|
bool grooved { false };
|
||||||
|
double groove { 0.0 };
|
||||||
|
double lip { 0.0 };
|
||||||
|
double rim { 0.0 };
|
||||||
|
double crown { 0.0 };
|
||||||
|
double liptop { 0.0 };
|
||||||
|
double crest { 0.0 };
|
||||||
|
double tread { 0.0735 };
|
||||||
|
double ledge { 0.0 };
|
||||||
|
double web { 0.0365 };
|
||||||
|
double neck { -0.0467 };
|
||||||
|
knots::line field, gauge;
|
||||||
|
};
|
||||||
|
// a check rail beside a rail, how far its ends turn away from the running rail
|
||||||
|
struct check_rail {
|
||||||
|
double from { 0.0 };
|
||||||
|
double to { 0.0 };
|
||||||
|
double flarefrom { 0.0 };
|
||||||
|
double flareto { 0.0 };
|
||||||
|
double frombend { 0.0 };
|
||||||
|
double tobend { 0.0 };
|
||||||
|
};
|
||||||
|
using check_rail_set = std::array<std::array<std::vector<check_rail>, 2>, 2>; // path, right side
|
||||||
|
// a rail broken where another one crosses it: the part coming from below ends at end, the part going on starts at start
|
||||||
|
struct rail_cut {
|
||||||
|
double at { 0.0 };
|
||||||
|
double end { 0.0 };
|
||||||
|
double start { 0.0 };
|
||||||
|
knots::line endoffsets, endextents, startoffsets, startextents;
|
||||||
|
knots::line endrolled, startrolled; // how far out from the gauge line the wheels roll on the head, of the part coming from below and of the part going on
|
||||||
|
glm::dvec2 endmiter { 0.0 };
|
||||||
|
glm::dvec2 startmiter { 0.0 };
|
||||||
|
double endbend { 0.0 };
|
||||||
|
double startbend { 0.0 };
|
||||||
|
knots::line endfit, startfit;
|
||||||
|
knots::line endinner, startinner;
|
||||||
|
bool endcap { true };
|
||||||
|
bool startcap { true };
|
||||||
|
};
|
||||||
|
struct rail_plan {
|
||||||
|
std::vector<rail_cut> cuts;
|
||||||
|
};
|
||||||
|
// guard rails of a crossing at a wide angle: the rail profile laid inside the running rail across the flangeway, broken like the rails
|
||||||
|
struct guard_rail {
|
||||||
|
double from { 0.0 };
|
||||||
|
double to { 0.0 };
|
||||||
|
rail_plan plan;
|
||||||
|
bool flarefrom { true };
|
||||||
|
bool flareto { true };
|
||||||
|
glm::dvec2 frommiter { 0.0 };
|
||||||
|
glm::dvec2 tomiter { 0.0 };
|
||||||
|
bool through { true };
|
||||||
|
};
|
||||||
|
struct rail_band {
|
||||||
|
double at { 0.0 };
|
||||||
|
double into { 0.0 };
|
||||||
|
double facing { 0.0 };
|
||||||
|
double from { 0.0 };
|
||||||
|
double to { 0.0 };
|
||||||
|
bool whole { true };
|
||||||
|
};
|
||||||
|
struct rail_fill {
|
||||||
|
double from { 0.0 };
|
||||||
|
double to { 0.0 };
|
||||||
|
knots::line inner, outer;
|
||||||
|
bool capfrom { false };
|
||||||
|
bool capto { false };
|
||||||
|
double lift { 0.0 };
|
||||||
|
bool web { false };
|
||||||
|
};
|
||||||
|
struct rail_tread {
|
||||||
|
double from { 0.0 };
|
||||||
|
double to { 0.0 };
|
||||||
|
material_handle material { 0 };
|
||||||
|
int anchor { 0 };
|
||||||
|
knots::line edge;
|
||||||
|
knots::line gauge;
|
||||||
|
bool below { false };
|
||||||
|
};
|
||||||
|
struct rail_layout {
|
||||||
|
rail_plan plans[ 2 ][ 2 ]; // path, right side
|
||||||
|
std::vector<rail_band> bands[ 2 ][ 2 ];
|
||||||
|
std::vector<rail_fill> fills[ 2 ][ 2 ];
|
||||||
|
knots::line blocks[ 2 ][ 2 ];
|
||||||
|
std::vector<rail_tread> treads[ 2 ][ 2 ];
|
||||||
|
std::vector<guard_rail> guards[ 2 ][ 2 ];
|
||||||
|
knots::line wingends[ 2 ][ 2 ]; // ends of the wing rails of other rails running along each rail, and which way they run there
|
||||||
|
check_rail_set checks;
|
||||||
|
std::vector<TTrack *> crossed; // tracks whose rails cross the rails of this one
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace track_rails
|
||||||
@@ -2610,10 +2610,10 @@ TTrack::track_rail_profile( int const Profile ) {
|
|||||||
return m_profiles[ Profile ];
|
return m_profiles[ Profile ];
|
||||||
}
|
}
|
||||||
|
|
||||||
TTrack::rail_size
|
track_rails::rail_size
|
||||||
TTrack::rail_dimensions() const {
|
TTrack::rail_dimensions() const {
|
||||||
|
|
||||||
rail_size result;
|
track_rails::rail_size result;
|
||||||
if( m_profiles.empty() ) {
|
if( m_profiles.empty() ) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
135
world/Track.h
135
world/Track.h
@@ -19,6 +19,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include "utilities/Classes.h"
|
#include "utilities/Classes.h"
|
||||||
#include "world/Segment.h"
|
#include "world/Segment.h"
|
||||||
|
#include "world/RailLayout.h"
|
||||||
#include "model/material.h"
|
#include "model/material.h"
|
||||||
#include "scene/scenenode.h"
|
#include "scene/scenenode.h"
|
||||||
#include "utilities/Names.h"
|
#include "utilities/Names.h"
|
||||||
@@ -299,132 +300,12 @@ public:
|
|||||||
int RouteDraw() const;
|
int RouteDraw() const;
|
||||||
void Load(cParser *parser, glm::dvec3 const &pOrigin);
|
void Load(cParser *parser, glm::dvec3 const &pOrigin);
|
||||||
void init_segments( bool const Initial );
|
void init_segments( bool const Initial );
|
||||||
// where the inner rails of the two paths of a switch cross, found from their gauge lines behind the blades
|
track_rails::switch_frog frog() const;
|
||||||
struct switch_frog {
|
std::vector<track_rails::rail_crossing> rail_crossings( bool const Joined = true );
|
||||||
bool valid { false };
|
track_rails::rail_size rail_dimensions() const;
|
||||||
int side[ 2 ] {}; // rail profile of the crossing rail of each path, 1 right, -1 left
|
|
||||||
double at[ 2 ] {}; // distance of the crossing along each path
|
|
||||||
double blades[ 2 ] {}; // distance the blades take along each path
|
|
||||||
double angle { 0.0 };
|
|
||||||
};
|
|
||||||
switch_frog frog() const;
|
|
||||||
// where a rail of this track crosses a rail of another one, found from their gauge lines
|
|
||||||
struct rail_crossing {
|
|
||||||
TTrack *track { nullptr };
|
|
||||||
int path { 0 };
|
|
||||||
int side { 0 }; // rail profile of the crossing rail, 1 right, -1 left
|
|
||||||
double at { 0.0 }; // distance of the crossing along the path, past the ends where the track goes on
|
|
||||||
double angle { 0.0 };
|
|
||||||
double into { 0.0 }; // the path direction against the gauge normal of the other rail, above zero: going into the other track
|
|
||||||
double facing { 0.0 }; // the gauge normals of both rails against each other, below zero: an acute frog
|
|
||||||
bool nose { false }; // at an acute frog the rail goes on as the nose rail, the other one as the rail beside it
|
|
||||||
int otherpath { 0 };
|
|
||||||
int otherside { 0 }; // rail profile of the other rail, 1 right, -1 left
|
|
||||||
double otherat { 0.0 }; // distance of the crossing along the other path
|
|
||||||
bool aligned { true }; // both paths run the same way at the crossing
|
|
||||||
TTrack *owner { nullptr };
|
|
||||||
};
|
|
||||||
std::vector<rail_crossing> rail_crossings( bool const Joined = true );
|
|
||||||
// the size of the rail profile, out from the gauge face: positive outwards, the side of the head away from the track
|
|
||||||
struct rail_size {
|
|
||||||
double head { 0.0735 }; // how far the head reaches out
|
|
||||||
double height { 0.172 };
|
|
||||||
double low { -0.0385 }; // the reach of the profile inwards
|
|
||||||
double high { 0.1115 }; // the reach of the profile outwards
|
|
||||||
bool grooved { false };
|
|
||||||
double groove { 0.0 };
|
|
||||||
double lip { 0.0 };
|
|
||||||
double rim { 0.0 };
|
|
||||||
double crown { 0.0 };
|
|
||||||
double liptop { 0.0 };
|
|
||||||
double crest { 0.0 };
|
|
||||||
double tread { 0.0735 };
|
|
||||||
double ledge { 0.0 };
|
|
||||||
double web { 0.0365 };
|
|
||||||
double neck { -0.0467 };
|
|
||||||
std::vector<glm::dvec2> field, gauge;
|
|
||||||
};
|
|
||||||
rail_size rail_dimensions() const;
|
|
||||||
// a check rail beside a rail, how far its ends turn away from the running rail
|
|
||||||
struct check_rail {
|
|
||||||
double from { 0.0 };
|
|
||||||
double to { 0.0 };
|
|
||||||
double flarefrom { 0.0 };
|
|
||||||
double flareto { 0.0 };
|
|
||||||
double frombend { 0.0 };
|
|
||||||
double tobend { 0.0 };
|
|
||||||
};
|
|
||||||
using check_rail_set = std::array<std::array<std::vector<check_rail>, 2>, 2>; // path, right side
|
|
||||||
// the check rails beside the rails of each path, kept clear of the blades and the rails of other paths running inside them
|
// the check rails beside the rails of each path, kept clear of the blades and the rails of other paths running inside them
|
||||||
check_rail_set check_rails( std::vector<rail_crossing> const &Crossings );
|
track_rails::check_rail_set check_rails( std::vector<track_rails::rail_crossing> const &Crossings );
|
||||||
// a rail broken where another one crosses it: the part coming from below ends at end, the part going on starts at start
|
track_rails::rail_layout plan_rails( bool const Crossings );
|
||||||
struct rail_cut {
|
|
||||||
double at { 0.0 };
|
|
||||||
double end { 0.0 };
|
|
||||||
double start { 0.0 };
|
|
||||||
std::vector<glm::dvec2> endoffsets, endextents, startoffsets, startextents;
|
|
||||||
std::vector<glm::dvec2> endrolled, startrolled; // how far out from the gauge line the wheels roll on the head, of the part coming from below and of the part going on
|
|
||||||
glm::dvec2 endmiter { 0.0 };
|
|
||||||
glm::dvec2 startmiter { 0.0 };
|
|
||||||
double endbend { 0.0 };
|
|
||||||
double startbend { 0.0 };
|
|
||||||
std::vector<glm::dvec2> endfit, startfit;
|
|
||||||
std::vector<glm::dvec2> endinner, startinner;
|
|
||||||
bool endcap { true };
|
|
||||||
bool startcap { true };
|
|
||||||
};
|
|
||||||
struct rail_plan {
|
|
||||||
std::vector<rail_cut> cuts;
|
|
||||||
};
|
|
||||||
// guard rails of a crossing at a wide angle: the rail profile laid inside the running rail across the flangeway, broken like the rails
|
|
||||||
struct guard_rail {
|
|
||||||
double from { 0.0 };
|
|
||||||
double to { 0.0 };
|
|
||||||
rail_plan plan;
|
|
||||||
bool flarefrom { true };
|
|
||||||
bool flareto { true };
|
|
||||||
glm::dvec2 frommiter { 0.0 };
|
|
||||||
glm::dvec2 tomiter { 0.0 };
|
|
||||||
bool through { true };
|
|
||||||
};
|
|
||||||
struct rail_band {
|
|
||||||
double at { 0.0 };
|
|
||||||
double into { 0.0 };
|
|
||||||
double facing { 0.0 };
|
|
||||||
double from { 0.0 };
|
|
||||||
double to { 0.0 };
|
|
||||||
bool whole { true };
|
|
||||||
};
|
|
||||||
struct rail_fill {
|
|
||||||
double from { 0.0 };
|
|
||||||
double to { 0.0 };
|
|
||||||
std::vector<glm::dvec2> inner, outer;
|
|
||||||
bool capfrom { false };
|
|
||||||
bool capto { false };
|
|
||||||
double lift { 0.0 };
|
|
||||||
bool web { false };
|
|
||||||
};
|
|
||||||
struct rail_tread {
|
|
||||||
double from { 0.0 };
|
|
||||||
double to { 0.0 };
|
|
||||||
material_handle material { 0 };
|
|
||||||
int anchor { 0 };
|
|
||||||
std::vector<glm::dvec2> edge;
|
|
||||||
std::vector<glm::dvec2> gauge;
|
|
||||||
bool below { false };
|
|
||||||
};
|
|
||||||
struct rail_layout {
|
|
||||||
rail_plan plans[ 2 ][ 2 ]; // path, right side
|
|
||||||
std::vector<rail_band> bands[ 2 ][ 2 ];
|
|
||||||
std::vector<rail_fill> fills[ 2 ][ 2 ];
|
|
||||||
std::vector<glm::dvec2> blocks[ 2 ][ 2 ];
|
|
||||||
std::vector<rail_tread> treads[ 2 ][ 2 ];
|
|
||||||
std::vector<guard_rail> guards[ 2 ][ 2 ];
|
|
||||||
std::vector<glm::dvec2> wingends[ 2 ][ 2 ]; // ends of the wing rails of other rails running along each rail, and which way they run there
|
|
||||||
check_rail_set checks;
|
|
||||||
std::vector<TTrack *> crossed; // tracks whose rails cross the rails of this one
|
|
||||||
};
|
|
||||||
rail_layout plan_rails( bool const Crossings );
|
|
||||||
void update_location();
|
void update_location();
|
||||||
bool AssignEvents();
|
bool AssignEvents();
|
||||||
bool AssignForcedEvents(basic_event *NewEventPlus, basic_event *NewEventMinus);
|
bool AssignForcedEvents(basic_event *NewEventPlus, basic_event *NewEventMinus);
|
||||||
@@ -521,7 +402,7 @@ private:
|
|||||||
void build_sleeper_transforms();
|
void build_sleeper_transforms();
|
||||||
struct rail_drawing {
|
struct rail_drawing {
|
||||||
gfx::geometrybank_handle bank;
|
gfx::geometrybank_handle bank;
|
||||||
rail_size size;
|
track_rails::rail_size size;
|
||||||
float halfwidth { 0.f };
|
float halfwidth { 0.f };
|
||||||
gfx::vertex_array checkshapes[ 2 ];
|
gfx::vertex_array checkshapes[ 2 ];
|
||||||
gfx::vertex_array plates[ 2 ];
|
gfx::vertex_array plates[ 2 ];
|
||||||
@@ -530,7 +411,7 @@ private:
|
|||||||
};
|
};
|
||||||
rail_drawing make_rail_drawing( gfx::geometrybank_handle const &Bank );
|
rail_drawing make_rail_drawing( gfx::geometrybank_handle const &Bank );
|
||||||
// a rail along a path from a distance on, in parts where other rails cross it, and the check rails beside it. false: no crossing, the rail is laid whole as before
|
// a rail along a path from a distance on, in parts where other rails cross it, and the check rails beside it. false: no crossing, the rail is laid whole as before
|
||||||
bool lay_rail( rail_layout const &Layout, rail_drawing const &Drawing, int const Path, gfx::vertex_array const &Profile, int const Side, float const Texturelength, double const From, bool const Openstart, bool const Openend, geometryhandle_sequence &Geometry, geometryhandle_sequence &Cuts );
|
bool lay_rail( track_rails::rail_layout const &Layout, rail_drawing const &Drawing, int const Path, gfx::vertex_array const &Profile, int const Side, float const Texturelength, double const From, bool const Openstart, bool const Openend, geometryhandle_sequence &Geometry, geometryhandle_sequence &Cuts );
|
||||||
int blade_side( int const Path ) const;
|
int blade_side( int const Path ) const;
|
||||||
material_handle rail_material( int const Path ) const;
|
material_handle rail_material( int const Path ) const;
|
||||||
glm::vec2 tread_band() const;
|
glm::vec2 tread_band() const;
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ double knuckle_bend( double const Into ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// a check rail starting right beside the end of a wing rail running along the same rail, which the wing rail goes on in place of; the far end of it
|
// a check rail starting right beside the end of a wing rail running along the same rail, which the wing rail goes on in place of; the far end of it
|
||||||
bool replaced_check( std::vector<TTrack::check_rail> const &Checks, double const Wingend, double const Direction, double &Far ) {
|
bool replaced_check( std::vector<track_rails::check_rail> const &Checks, double const Wingend, double const Direction, double &Far ) {
|
||||||
|
|
||||||
for( auto const &check : Checks ) {
|
for( auto const &check : Checks ) {
|
||||||
auto const nearend { Direction > 0.0 ? check.from : check.to };
|
auto const nearend { Direction > 0.0 ? check.from : check.to };
|
||||||
@@ -144,9 +144,9 @@ bool replaced_check( std::vector<TTrack::check_rail> const &Checks, double const
|
|||||||
|
|
||||||
struct rails_memo {
|
struct rails_memo {
|
||||||
std::optional<gauge_line> lines[ 2 ][ 2 ][ 2 ]; // path, right side, from the blades
|
std::optional<gauge_line> lines[ 2 ][ 2 ][ 2 ]; // path, right side, from the blades
|
||||||
std::optional<std::vector<TTrack::rail_crossing>> own;
|
std::optional<std::vector<track_rails::rail_crossing>> own;
|
||||||
std::optional<std::vector<TTrack::rail_crossing>> joined;
|
std::optional<std::vector<track_rails::rail_crossing>> joined;
|
||||||
std::optional<TTrack::check_rail_set> checks;
|
std::optional<track_rails::check_rail_set> checks;
|
||||||
};
|
};
|
||||||
std::unordered_map<TTrack const *, rails_memo> memos;
|
std::unordered_map<TTrack const *, rails_memo> memos;
|
||||||
unsigned int memostamp { 0 };
|
unsigned int memostamp { 0 };
|
||||||
@@ -494,7 +494,7 @@ gauge_line const &rail_line( TTrack const &Track, int const Path, int const Side
|
|||||||
return *line;
|
return *line;
|
||||||
}
|
}
|
||||||
|
|
||||||
TTrack::check_rail_set const &rail_checks( TTrack &Track ) {
|
track_rails::check_rail_set const &rail_checks( TTrack &Track ) {
|
||||||
|
|
||||||
auto &checks { memo_of( Track ).checks };
|
auto &checks { memo_of( Track ).checks };
|
||||||
if( false == checks.has_value() ) {
|
if( false == checks.has_value() ) {
|
||||||
@@ -505,7 +505,7 @@ TTrack::check_rail_set const &rail_checks( TTrack &Track ) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::vector<TTrack::rail_crossing> TTrack::rail_crossings( bool const Joined ) {
|
std::vector<track_rails::rail_crossing> TTrack::rail_crossings( bool const Joined ) {
|
||||||
|
|
||||||
std::vector<rail_crossing> result;
|
std::vector<rail_crossing> result;
|
||||||
if( false == cut_rails( *this ) || simulation::Region == nullptr ) {
|
if( false == cut_rails( *this ) || simulation::Region == nullptr ) {
|
||||||
@@ -708,7 +708,7 @@ std::vector<TTrack::rail_crossing> TTrack::rail_crossings( bool const Joined ) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
TTrack::check_rail_set TTrack::check_rails( std::vector<rail_crossing> const &Crossings ) {
|
track_rails::check_rail_set TTrack::check_rails( std::vector<rail_crossing> const &Crossings ) {
|
||||||
|
|
||||||
struct planned {
|
struct planned {
|
||||||
double from { 0.0 };
|
double from { 0.0 };
|
||||||
@@ -864,7 +864,7 @@ TTrack::check_rail_set TTrack::check_rails( std::vector<rail_crossing> const &Cr
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
TTrack::switch_frog TTrack::frog() const {
|
track_rails::switch_frog TTrack::frog() const {
|
||||||
|
|
||||||
switch_frog result;
|
switch_frog result;
|
||||||
if( eType != tt_Switch || false == cut_rails( *this ) ) {
|
if( eType != tt_Switch || false == cut_rails( *this ) ) {
|
||||||
@@ -937,7 +937,7 @@ TTrack::switch_frog TTrack::frog() const {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// a wing rail ending right beside a check rail of the rail it runs along goes on in its place up to the far end of it, past the end of the wing
|
// a wing rail ending right beside a check rail of the rail it runs along goes on in its place up to the far end of it, past the end of the wing
|
||||||
std::vector<glm::dvec2> wing_extension( TTrack &Track, TTrack::check_rail_set const &Checks, int const Path, int const Side, double const At, double const Toward, double const Slope, TTrack &Partner, int const Partnerpath, int const Partnerside, double const Partnerat, double const Partnerdirection ) {
|
std::vector<glm::dvec2> wing_extension( TTrack &Track, track_rails::check_rail_set const &Checks, int const Path, int const Side, double const At, double const Toward, double const Slope, TTrack &Partner, int const Partnerpath, int const Partnerside, double const Partnerat, double const Partnerdirection ) {
|
||||||
|
|
||||||
std::vector<glm::dvec2> knots;
|
std::vector<glm::dvec2> knots;
|
||||||
auto const partnerchecks { &Partner == &Track ? Checks : rail_checks( Partner ) };
|
auto const partnerchecks { &Partner == &Track ? Checks : rail_checks( Partner ) };
|
||||||
@@ -964,7 +964,7 @@ std::vector<glm::dvec2> wing_extension( TTrack &Track, TTrack::check_rail_set co
|
|||||||
}
|
}
|
||||||
|
|
||||||
// acute frog: the rail coming from the throat bends out as a wing rail, the rail going on behind the gap is a leg of the nose
|
// acute frog: the rail coming from the throat bends out as a wing rail, the rail going on behind the gap is a leg of the nose
|
||||||
void acute( TTrack::rail_plan &Plan, double const At, double const Toward, double const Slope, std::vector<glm::dvec2> const &Extension, std::vector<glm::dvec2> const &Legs ) {
|
void acute( track_rails::rail_plan &Plan, double const At, double const Toward, double const Slope, std::vector<glm::dvec2> const &Extension, std::vector<glm::dvec2> const &Legs ) {
|
||||||
|
|
||||||
auto const throat { At + Toward * flangeway / Slope };
|
auto const throat { At + Toward * flangeway / Slope };
|
||||||
auto const flare { At - Toward * wing_reach( Slope ) };
|
auto const flare { At - Toward * wing_reach( Slope ) };
|
||||||
@@ -977,7 +977,7 @@ void acute( TTrack::rail_plan &Plan, double const At, double const Toward, doubl
|
|||||||
rolled.emplace_back( knot.x, rolled_band - knot.y );
|
rolled.emplace_back( knot.x, rolled_band - knot.y );
|
||||||
}
|
}
|
||||||
std::sort( rolled.begin(), rolled.end(), []( glm::dvec2 const &A, glm::dvec2 const &B ) { return A.x < B.x; } );
|
std::sort( rolled.begin(), rolled.end(), []( glm::dvec2 const &A, glm::dvec2 const &B ) { return A.x < B.x; } );
|
||||||
TTrack::rail_cut cut;
|
track_rails::rail_cut cut;
|
||||||
cut.at = At;
|
cut.at = At;
|
||||||
if( Toward < 0.0 ) {
|
if( Toward < 0.0 ) {
|
||||||
cut.end = wingend;
|
cut.end = wingend;
|
||||||
@@ -997,13 +997,13 @@ void acute( TTrack::rail_plan &Plan, double const At, double const Toward, doubl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// obtuse crossing: the rail ends where it meets the other one and starts again pointed past its flangeway, a check rail beside the point guards the gap
|
// obtuse crossing: the rail ends where it meets the other one and starts again pointed past its flangeway, a check rail beside the point guards the gap
|
||||||
void obtuse( TTrack::rail_plan &Plan, double const At, double const Into, TTrack::rail_size const &Size ) {
|
void obtuse( track_rails::rail_plan &Plan, double const At, double const Into, track_rails::rail_size const &Size ) {
|
||||||
|
|
||||||
auto const gap { flangeway / std::abs( Into ) };
|
auto const gap { flangeway / std::abs( Into ) };
|
||||||
auto const full { Size.high + 0.0135 };
|
auto const full { Size.high + 0.0135 };
|
||||||
auto const taper { ( flangeway + full ) / std::abs( Into ) };
|
auto const taper { ( flangeway + full ) / std::abs( Into ) };
|
||||||
auto const bend { knuckle_bend( Into ) };
|
auto const bend { knuckle_bend( Into ) };
|
||||||
TTrack::rail_cut cut;
|
track_rails::rail_cut cut;
|
||||||
cut.at = At;
|
cut.at = At;
|
||||||
if( Into > 0.0 ) {
|
if( Into > 0.0 ) {
|
||||||
cut.end = At;
|
cut.end = At;
|
||||||
@@ -1021,11 +1021,11 @@ void obtuse( TTrack::rail_plan &Plan, double const At, double const Into, TTrack
|
|||||||
}
|
}
|
||||||
|
|
||||||
// crossing at a wide angle: running rails are broken for the flanges of the other track, the ones of the track not going through also where the head of the other rail lies; guard rails give way to the running rails and flangeways of the other track, the ones of the track not going through also to its guard rails
|
// crossing at a wide angle: running rails are broken for the flanges of the other track, the ones of the track not going through also where the head of the other rail lies; guard rails give way to the running rails and flangeways of the other track, the ones of the track not going through also to its guard rails
|
||||||
void wide( TTrack::rail_plan &Plan, double const At, double const Into, double const Facing, double const From, double const To, double const Inner, double const Outer, std::vector<glm::dvec2> const &Fromline = {}, std::vector<glm::dvec2> const &Toline = {} ) {
|
void wide( track_rails::rail_plan &Plan, double const At, double const Into, double const Facing, double const From, double const To, double const Inner, double const Outer, std::vector<glm::dvec2> const &Fromline = {}, std::vector<glm::dvec2> const &Toline = {} ) {
|
||||||
|
|
||||||
auto const low { ( From + std::min( Inner * Facing, Outer * Facing ) - 0.005 ) / Into };
|
auto const low { ( From + std::min( Inner * Facing, Outer * Facing ) - 0.005 ) / Into };
|
||||||
auto const high { ( To + std::max( Inner * Facing, Outer * Facing ) + 0.005 ) / Into };
|
auto const high { ( To + std::max( Inner * Facing, Outer * Facing ) + 0.005 ) / Into };
|
||||||
TTrack::rail_cut cut;
|
track_rails::rail_cut cut;
|
||||||
cut.at = At;
|
cut.at = At;
|
||||||
cut.end = At + std::min( low, high );
|
cut.end = At + std::min( low, high );
|
||||||
cut.start = At + std::max( low, high );
|
cut.start = At + std::max( low, high );
|
||||||
@@ -1056,11 +1056,11 @@ std::vector<glm::dvec2> glue_line( std::vector<glm::dvec2> const &Outline, doubl
|
|||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
TTrack::rail_fill guard_fill( TTrack::guard_rail const &Guard, TTrack::rail_size const &Size ) {
|
track_rails::rail_fill guard_fill( track_rails::guard_rail const &Guard, track_rails::rail_size const &Size ) {
|
||||||
|
|
||||||
auto const offset { Size.web - ( flangeway + Size.head ) };
|
auto const offset { Size.web - ( flangeway + Size.head ) };
|
||||||
auto const flare { std::min( 0.3, 0.25 * ( Guard.to - Guard.from ) ) };
|
auto const flare { std::min( 0.3, 0.25 * ( Guard.to - Guard.from ) ) };
|
||||||
TTrack::rail_fill fill;
|
track_rails::rail_fill fill;
|
||||||
fill.web = true;
|
fill.web = true;
|
||||||
fill.from = Guard.from;
|
fill.from = Guard.from;
|
||||||
fill.to = Guard.to;
|
fill.to = Guard.to;
|
||||||
@@ -1082,17 +1082,17 @@ bool goes_through( TTrack const &Track, TTrack const &Other ) {
|
|||||||
return ( here.x != there.x ? here.x < there.x : here.z < there.z );
|
return ( here.x != there.x ? here.x < there.x : here.z < there.z );
|
||||||
}
|
}
|
||||||
|
|
||||||
TTrack::rail_band groove_band( double const At, double const Into, double const Facing, bool const Through, TTrack::rail_size const &Other ) {
|
track_rails::rail_band groove_band( double const At, double const Into, double const Facing, bool const Through, track_rails::rail_size const &Other ) {
|
||||||
|
|
||||||
auto const seam { 0.001 };
|
auto const seam { 0.001 };
|
||||||
TTrack::rail_band band { At, Into, Facing };
|
track_rails::rail_band band { At, Into, Facing };
|
||||||
band.whole = ( false == Through );
|
band.whole = ( false == Through );
|
||||||
band.from = ( Through ? 0.0 : seam - Other.tread );
|
band.from = ( Through ? 0.0 : seam - Other.tread );
|
||||||
band.to = ( Through ? ( Other.grooved ? -Other.lip : flangeway ) : -Other.ledge - seam );
|
band.to = ( Through ? ( Other.grooved ? -Other.lip : flangeway ) : -Other.ledge - seam );
|
||||||
return band;
|
return band;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vee_fill( std::vector<TTrack::rail_fill> &Fills, double const At, double const Into, double const Facing, TTrack::rail_size const &Own, TTrack::rail_size const &Other, bool const Outwards ) {
|
void vee_fill( std::vector<track_rails::rail_fill> &Fills, double const At, double const Into, double const Facing, track_rails::rail_size const &Own, track_rails::rail_size const &Other, bool const Outwards ) {
|
||||||
|
|
||||||
auto const seam { 0.001 };
|
auto const seam { 0.001 };
|
||||||
auto const sign { Outwards ? 1.0 : -1.0 };
|
auto const sign { Outwards ? 1.0 : -1.0 };
|
||||||
@@ -1110,7 +1110,7 @@ void vee_fill( std::vector<TTrack::rail_fill> &Fills, double const At, double co
|
|||||||
auto const apex { meets( 0.0 ) };
|
auto const apex { meets( 0.0 ) };
|
||||||
auto const end { meets( gap ) };
|
auto const end { meets( gap ) };
|
||||||
auto const reach { seam + rounded / slant };
|
auto const reach { seam + rounded / slant };
|
||||||
TTrack::rail_fill fill;
|
track_rails::rail_fill fill;
|
||||||
fill.from = std::min( apex, end );
|
fill.from = std::min( apex, end );
|
||||||
fill.to = std::max( apex, end );
|
fill.to = std::max( apex, end );
|
||||||
fill.capfrom = ( end < apex );
|
fill.capfrom = ( end < apex );
|
||||||
@@ -1194,7 +1194,7 @@ std::vector<glm::dvec2> tread_edge( TTrack const &Track, int const Path, int con
|
|||||||
return knots;
|
return knots;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<glm::dvec2> nose_extents( TTrack const &Track, int const Path, int const Side, TTrack const &Other, int const Otherpath, int const Otherside, double const At, double const Toward, double const Slope, TTrack::rail_size const &Size ) {
|
std::vector<glm::dvec2> nose_extents( TTrack const &Track, int const Path, int const Side, TTrack const &Other, int const Otherpath, int const Otherside, double const At, double const Toward, double const Slope, track_rails::rail_size const &Size ) {
|
||||||
|
|
||||||
auto const half { Slope / ( 1.0 + std::sqrt( 1.0 + Slope * Slope ) ) };
|
auto const half { Slope / ( 1.0 + std::sqrt( 1.0 + Slope * Slope ) ) };
|
||||||
auto const tip { 0.5 * nose_tip };
|
auto const tip { 0.5 * nose_tip };
|
||||||
@@ -1275,7 +1275,7 @@ material_handle TTrack::shared_tread( int const Path, TTrack const &Other, int c
|
|||||||
return ( track_rails::tread_brightness( theirs, Other.tread_band() ) > track_rails::tread_brightness( own, tread_band() ) ? theirs : own );
|
return ( track_rails::tread_brightness( theirs, Other.tread_band() ) > track_rails::tread_brightness( own, tread_band() ) ? theirs : own );
|
||||||
}
|
}
|
||||||
|
|
||||||
TTrack::rail_layout TTrack::plan_rails( bool const Crossings ) {
|
track_rails::rail_layout TTrack::plan_rails( bool const Crossings ) {
|
||||||
|
|
||||||
rail_layout layout;
|
rail_layout layout;
|
||||||
auto const size { rail_dimensions() };
|
auto const size { rail_dimensions() };
|
||||||
@@ -1366,7 +1366,7 @@ TTrack::rail_layout TTrack::plan_rails( bool const Crossings ) {
|
|||||||
}
|
}
|
||||||
auto const reach { ( flangeway + railhead + 0.3 ) / std::abs( crossing.into ) };
|
auto const reach { ( flangeway + railhead + 0.3 ) / std::abs( crossing.into ) };
|
||||||
auto &spans { guards[ crossing.path ][ crossing.side > 0 ] };
|
auto &spans { guards[ crossing.path ][ crossing.side > 0 ] };
|
||||||
TTrack::guard_rail guard { crossing.at - reach, crossing.at + reach };
|
track_rails::guard_rail guard { crossing.at - reach, crossing.at + reach };
|
||||||
guard.through = through;
|
guard.through = through;
|
||||||
wide( guard.plan, crossing.at, crossing.into, crossing.facing, -other.head, through ? flangeway : flangeway + other.head, guardoffset, guardoffset + railhead, glue_line( other.field, 0.0 ), through ? std::vector<glm::dvec2>{} : glue_line( other.gauge, flangeway + other.head ) );
|
wide( guard.plan, crossing.at, crossing.into, crossing.facing, -other.head, through ? flangeway : flangeway + other.head, guardoffset, guardoffset + railhead, glue_line( other.field, 0.0 ), through ? std::vector<glm::dvec2>{} : glue_line( other.gauge, flangeway + other.head ) );
|
||||||
auto merged { false };
|
auto merged { false };
|
||||||
@@ -1442,7 +1442,7 @@ TTrack::rail_layout TTrack::plan_rails( bool const Crossings ) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if( end.into < 0.0 ) {
|
if( end.into < 0.0 ) {
|
||||||
TTrack::guard_rail guard { glued( start ), glued( end ) };
|
track_rails::guard_rail guard { glued( start ), glued( end ) };
|
||||||
guard.flarefrom = false;
|
guard.flarefrom = false;
|
||||||
guard.flareto = false;
|
guard.flareto = false;
|
||||||
guard.frommiter = gluedmiter( start );
|
guard.frommiter = gluedmiter( start );
|
||||||
|
|||||||
@@ -13,16 +13,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
namespace track_rails {
|
namespace track_rails {
|
||||||
|
|
||||||
double constexpr flangeway { 0.045 };
|
|
||||||
double constexpr blend { 0.015 };
|
|
||||||
double constexpr tread_fade { 0.02 };
|
|
||||||
double constexpr wheel_width { 0.14 };
|
|
||||||
double constexpr back_to_back { 1.36 };
|
|
||||||
double constexpr rolled_band { wheel_width - ( 1.435 - back_to_back ) / 2.0 };
|
|
||||||
double constexpr nose_tip { 0.012 };
|
|
||||||
double constexpr middle_angle { 0.35 };
|
|
||||||
double constexpr wide_angle { 0.785 };
|
|
||||||
|
|
||||||
void forget();
|
void forget();
|
||||||
// how far a wing rail reaches past the crossing point of the rails
|
// how far a wing rail reaches past the crossing point of the rails
|
||||||
double wing_reach( double const Slope );
|
double wing_reach( double const Slope );
|
||||||
|
|||||||
Reference in New Issue
Block a user