mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-01 08:02:10 +01:00
Usage, optional attributes of a track entry, before endtrack:
uneven <mm> peak deviation of a rail on a 10 m chord, 0-100; normal and switch
unevenup <mm> up and down alone, instead of uneven; normal and switch
unevenside <mm> sideways alone, instead of uneven; normal and switch
unevencross <mm> cross level alone, instead of uneven; normal only
jointdip <mm> depth of the dip at rail joints, every sound distance; normal only,
default 0.4 of the up and down component
Values of uneven follow PLK Id-14 appendix 1: 6 mm is the limit at 160 km/h, 10 at 120,
18 at 80, 35 at 40; half of it for a track in a good state. Example:
uneven 18
unevencross 25
jointdip 6
endtrack
The same fields are in the editor, track panel, section Ride and sound. See
track_uneven_doc.md.
The unevenness is a displacement field over the plan of the scenery, with no random
numbers: one place strays the same every time, and joined tracks, the paths of a switch,
sleepermodel and axles at one place move together. Tracks meet at a joint at the lower of
their values. Joined switches take the lowest of theirs, the tracks joined to them come to
it, and a track with none of a component keeps the switch to its design in it. The clatter
comes from the dipping joints. Curve radius and grade for the physics stay as designed.
Tracks with it get geometry every 2 m on straights: 4x the vertices on Baltyk with all
tracks flagged, 0.2 ms more per frame on td.scn.
166 lines
5.8 KiB
C++
166 lines
5.8 KiB
C++
/*
|
|
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 "utilities/Classes.h"
|
|
#include "rendering/geometrybank.h"
|
|
#include <glm/glm.hpp>
|
|
|
|
struct map_colored_paths {
|
|
std::vector<gfx::geometrybank_handle> switches;
|
|
std::vector<gfx::geometrybank_handle> occupied;
|
|
std::vector<gfx::geometrybank_handle> future;
|
|
std::vector<gfx::geometrybank_handle> highlighted;
|
|
};
|
|
|
|
struct segment_data {
|
|
// types
|
|
enum point {
|
|
start = 0,
|
|
control1,
|
|
control2,
|
|
end
|
|
};
|
|
// members
|
|
std::array<glm::dvec3, 4> points {};
|
|
std::array<float, 2> rolls {};
|
|
float radius {};
|
|
// constructors
|
|
segment_data() = default;
|
|
// methods
|
|
void deserialize( cParser &Input, glm::dvec3 const &Offset );
|
|
};
|
|
|
|
class TSegment
|
|
{ // aproksymacja toru (zwrotnica ma dwa takie, jeden z nich jest aktywny)
|
|
private:
|
|
glm::dvec3 Point1;
|
|
glm::dvec3 CPointOut;
|
|
glm::dvec3 CPointIn;
|
|
glm::dvec3 Point2;
|
|
float fRoll1 { 0.f };
|
|
float fRoll2 { 0.f }; // przechyłka na końcach
|
|
bool m_uneven { false }; // see TrackUneven.h
|
|
double fLength { -1.0 }; // długość policzona
|
|
std::vector<double> fTsBuffer; // wartości parametru krzywej t dla równych odcinków s
|
|
std::vector<double> fTsSlope; // nachylenie dt/du (= dt/ds * fStep) w tych samych punktach
|
|
double fStep = 0.0;
|
|
int iSegCount = 0; // ilość odcinków do rysowania krzywej
|
|
double fDirection = 0.0; // Ra: kąt prostego w planie; dla łuku kąt od Point1
|
|
double fStoop = 0.0; // Ra: kąt wzniesienia; dla łuku od Point1
|
|
glm::dvec3 vA;
|
|
glm::dvec3 vB;
|
|
glm::dvec3 vC; // współczynniki wielomianów trzeciego stopnia vD==Point1
|
|
TTrack *pOwner = nullptr; // wskaźnik na właściciela
|
|
|
|
glm::dvec3 GetFirstDerivative(double const fTime) const;
|
|
double RombergIntegral(double const fA, double const fB) const;
|
|
void InitTFromSInterpolateData();
|
|
double GetTFromS(double const s) const;
|
|
double FastGetTFromS(double const s) const;
|
|
glm::dvec3 RaInterpolate(double const t) const;
|
|
glm::dvec3 RaInterpolate0(double const t) const;
|
|
|
|
// moves a lofted vertex with the unevenness of the track
|
|
void settle_vertex( gfx::basic_vertex &Vertex, glm::dvec3 const &Origin, glm::vec3 const &Position, glm::vec3 const &Parallel, double const Distance ) const;
|
|
// displacement of a point by the unevenness, at a distance along the path
|
|
glm::dvec3 stray( glm::dvec3 const &Point, double const Distance ) const;
|
|
void design_position( double const fDistance, glm::dvec3 &position, glm::vec3 &rotation ) const;
|
|
|
|
public:
|
|
bool bCurve = false;
|
|
|
|
explicit TSegment(TTrack *owner);
|
|
bool Init(glm::dvec3 NewPoint1, glm::dvec3 NewPoint2, double fNewStep, double fNewRoll1 = 0, double fNewRoll2 = 0);
|
|
bool Init(glm::dvec3 &NewPoint1, glm::dvec3 NewCPointOut, glm::dvec3 NewCPointIn, glm::dvec3 &NewPoint2, double fNewStep, double fNewRoll1 = 0, double fNewRoll2 = 0, bool bIsCurve = true);
|
|
double
|
|
ComputeLength() const; // McZapkie-150503
|
|
// finds point on segment closest to specified point in 3d space. returns: point on segment as value in range 0-1
|
|
double
|
|
find_nearest_point( glm::dvec3 const &Point ) const;
|
|
inline
|
|
glm::dvec3
|
|
GetDirection1() const {
|
|
return bCurve ? CPointOut - Point1 : CPointOut; };
|
|
inline
|
|
glm::dvec3
|
|
GetDirection2() const {
|
|
return bCurve ? CPointIn - Point2 : CPointIn; };
|
|
glm::dvec3
|
|
GetDirection(double const fDistance) const;
|
|
inline
|
|
glm::dvec3
|
|
GetDirection() const {
|
|
return CPointOut; };
|
|
glm::dvec3
|
|
FastGetDirection(double const fDistance, double const fOffset) const;
|
|
/*
|
|
Math3D::vector3
|
|
GetPoint(double const fDistance) const;
|
|
*/
|
|
|
|
/// <summary>
|
|
/// ustalenie pozycji osi na torze, przechyłki, pochylenia i kierunku jazdy
|
|
/// </summary>
|
|
/// <param name="fDistance">Distance from p1</param>
|
|
/// <param name="position">Calculated position</param>
|
|
/// <param name="rotation">Calculated rotation</param>
|
|
void RaPositionGet(double const fDistance, glm::dvec3 &position, glm::vec3 &rotation) const;
|
|
// call before Init, it sets the density of the geometry
|
|
void
|
|
set_uneven( bool const Uneven ) {
|
|
m_uneven = Uneven; }
|
|
// second derivative of the displacement along the path; times speed squared: acceleration of an axle
|
|
glm::dvec3
|
|
uneven_bend( double const Distance ) const;
|
|
glm::dvec3 FastGetPoint(double const t) const;
|
|
inline
|
|
glm::dvec3
|
|
FastGetPoint_0() const {
|
|
return Point1; };
|
|
inline
|
|
glm::dvec3
|
|
FastGetPoint_1() const {
|
|
return Point2; };
|
|
inline
|
|
float
|
|
GetRoll(double const Distance) const {
|
|
return std::lerp( fRoll1, fRoll2, static_cast<float>(Distance / fLength) ); }
|
|
inline
|
|
void
|
|
GetRolls(float &r1, float &r2) const {
|
|
// pobranie przechyłek (do generowania trójkątów)
|
|
r1 = fRoll1;
|
|
r2 = fRoll2; }
|
|
|
|
bool
|
|
RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin, gfx::vertex_array const &ShapePoints, bool const Transition, double fTextureLength, double Texturescale = 1.0, int iSkip = 0, int iEnd = 0, std::pair<float, float> fOffsetX = {0.f, 0.f}, glm::vec3 **p = nullptr, bool bRender = true );
|
|
/*
|
|
void
|
|
Render();
|
|
*/
|
|
inline
|
|
double
|
|
GetLength() const {
|
|
return fLength; };
|
|
inline
|
|
int
|
|
RaSegCount() const {
|
|
return fTsBuffer.empty() ? 1 : iSegCount; };
|
|
|
|
void
|
|
render_lines(std::vector<gfx::basic_vertex> &out, float quality = 1.0f) const;
|
|
|
|
glm::vec3
|
|
get_nearest_point(const glm::dvec3 &point, float quality = 1.0f) const;
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|