mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-19 05:29:17 +02:00
Merge branch 'tmj-dev' into lua
This commit is contained in:
108
Segment.cpp
108
Segment.cpp
@@ -21,20 +21,17 @@ http://mozilla.org/MPL/2.0/.
|
||||
// 110806 Ra: odwrócone mapowanie wzdłuż - Point1 == 1.0
|
||||
|
||||
TSegment::TSegment(TTrack *owner) :
|
||||
pOwner( owner )
|
||||
{
|
||||
fAngle[ 0 ] = 0.0;
|
||||
fAngle[ 1 ] = 0.0;
|
||||
};
|
||||
pOwner( owner )
|
||||
{}
|
||||
|
||||
TSegment::~TSegment()
|
||||
{
|
||||
SafeDeleteArray(fTsBuffer);
|
||||
};
|
||||
}
|
||||
|
||||
bool TSegment::Init(vector3 NewPoint1, vector3 NewPoint2, double fNewStep, double fNewRoll1, double fNewRoll2)
|
||||
bool TSegment::Init(Math3D::vector3 NewPoint1, Math3D::vector3 NewPoint2, double fNewStep, double fNewRoll1, double fNewRoll2)
|
||||
{ // wersja dla prostego - wyliczanie punktów kontrolnych
|
||||
vector3 dir;
|
||||
Math3D::vector3 dir;
|
||||
|
||||
// NOTE: we're enforcing division also for straight track, to ensure dense enough mesh for per-vertex lighting
|
||||
/*
|
||||
@@ -55,9 +52,7 @@ bool TSegment::Init(vector3 NewPoint1, vector3 NewPoint2, double fNewStep, doubl
|
||||
}
|
||||
};
|
||||
|
||||
bool TSegment::Init(vector3 &NewPoint1, vector3 NewCPointOut, vector3 NewCPointIn,
|
||||
vector3 &NewPoint2, double fNewStep, double fNewRoll1, double fNewRoll2,
|
||||
bool bIsCurve)
|
||||
bool TSegment::Init( Math3D::vector3 &NewPoint1, Math3D::vector3 NewCPointOut, Math3D::vector3 NewCPointIn, Math3D::vector3 &NewPoint2, double fNewStep, double fNewRoll1, double fNewRoll2, bool bIsCurve)
|
||||
{ // wersja uniwersalna (dla krzywej i prostego)
|
||||
Point1 = NewPoint1;
|
||||
CPointOut = NewCPointOut;
|
||||
@@ -77,7 +72,7 @@ bool TSegment::Init(vector3 &NewPoint1, vector3 NewCPointOut, vector3 NewCPointI
|
||||
// mieć moment wypoziomowania, ale musi on być również podniesiony.
|
||||
if (fRoll1 != 0.0)
|
||||
{ // tylko jeśli jest przechyłka
|
||||
double w1 = fabs(sin(fRoll1) * 0.75); // 0.5*w2+0.0325; //0.75m dla 1.435
|
||||
double w1 = std::abs(std::sin(fRoll1) * 0.75); // 0.5*w2+0.0325; //0.75m dla 1.435
|
||||
Point1.y += w1; // modyfikacja musi być przed policzeniem dalszych parametrów
|
||||
if (bCurve)
|
||||
CPointOut.y += w1; // prosty ma wektory jednostkowe
|
||||
@@ -85,7 +80,7 @@ bool TSegment::Init(vector3 &NewPoint1, vector3 NewCPointOut, vector3 NewCPointI
|
||||
}
|
||||
if (fRoll2 != 0.0)
|
||||
{
|
||||
double w2 = fabs(sin(fRoll2) * 0.75); // 0.5*w2+0.0325; //0.75m dla 1.435
|
||||
double w2 = std::abs(std::sin(fRoll2) * 0.75); // 0.5*w2+0.0325; //0.75m dla 1.435
|
||||
Point2.y += w2; // modyfikacja musi być przed policzeniem dalszych parametrów
|
||||
if (bCurve)
|
||||
CPointIn.y += w2; // prosty ma wektory jednostkowe
|
||||
@@ -137,12 +132,12 @@ bool TSegment::Init(vector3 &NewPoint1, vector3 NewCPointOut, vector3 NewCPointI
|
||||
return true;
|
||||
}
|
||||
|
||||
vector3 TSegment::GetFirstDerivative(double fTime)
|
||||
Math3D::vector3 TSegment::GetFirstDerivative(double const fTime) const
|
||||
{
|
||||
|
||||
double fOmTime = 1.0 - fTime;
|
||||
double fPowTime = fTime;
|
||||
vector3 kResult = fOmTime * (CPointOut - Point1);
|
||||
Math3D::vector3 kResult = fOmTime * (CPointOut - Point1);
|
||||
|
||||
// int iDegreeM1 = 3 - 1;
|
||||
|
||||
@@ -156,7 +151,7 @@ vector3 TSegment::GetFirstDerivative(double fTime)
|
||||
return kResult;
|
||||
}
|
||||
|
||||
double TSegment::RombergIntegral(double fA, double fB)
|
||||
double TSegment::RombergIntegral(double const fA, double const fB) const
|
||||
{
|
||||
double fH = fB - fA;
|
||||
|
||||
@@ -188,7 +183,7 @@ double TSegment::RombergIntegral(double fA, double fB)
|
||||
return ms_apfRom[0][ms_iOrder - 1];
|
||||
}
|
||||
|
||||
double TSegment::GetTFromS(double s)
|
||||
double TSegment::GetTFromS(double const s) const
|
||||
{
|
||||
// initial guess for Newton's method
|
||||
double fTolerance = 0.001;
|
||||
@@ -216,41 +211,83 @@ double TSegment::GetTFromS(double s)
|
||||
return fTime;
|
||||
};
|
||||
|
||||
vector3 TSegment::RaInterpolate(double t)
|
||||
Math3D::vector3 TSegment::RaInterpolate(double const t) const
|
||||
{ // wyliczenie XYZ na krzywej Beziera z użyciem współczynników
|
||||
return t * (t * (t * vA + vB) + vC) + Point1; // 9 mnożeń, 9 dodawań
|
||||
};
|
||||
|
||||
vector3 TSegment::RaInterpolate0(double t)
|
||||
Math3D::vector3 TSegment::RaInterpolate0(double const t) const
|
||||
{ // wyliczenie XYZ na krzywej Beziera, na użytek liczenia długości nie jest dodawane Point1
|
||||
return t * (t * (t * vA + vB) + vC); // 9 mnożeń, 6 dodawań
|
||||
};
|
||||
|
||||
double TSegment::ComputeLength() // McZapkie-150503: dlugosc miedzy punktami krzywej
|
||||
double TSegment::ComputeLength() const // McZapkie-150503: dlugosc miedzy punktami krzywej
|
||||
{ // obliczenie długości krzywej Beziera za pomocą interpolacji odcinkami
|
||||
// Ra: zamienić na liczenie rekurencyjne średniej z cięciwy i łamanej po kontrolnych
|
||||
// Ra: koniec rekurencji jeśli po podziale suma długości nie różni się więcej niż 0.5mm od
|
||||
// poprzedniej
|
||||
// Ra: ewentualnie rozpoznać łuk okręgu płaskiego i liczyć ze wzoru na długość łuku
|
||||
double t, l = 0;
|
||||
vector3 last = vector3(0, 0, 0); // długość liczona po przesunięciu odcinka do początku układu
|
||||
vector3 tmp = Point2 - Point1;
|
||||
Math3D::vector3 last = Math3D::vector3(0, 0, 0); // długość liczona po przesunięciu odcinka do początku układu
|
||||
Math3D::vector3 tmp = Point2 - Point1;
|
||||
int m = 20.0 * tmp.Length(); // było zawsze do 10000, teraz jest liczone odcinkami po około 5cm
|
||||
for (int i = 1; i <= m; i++)
|
||||
{
|
||||
t = double(i) / double(m); // wyznaczenie parametru na krzywej z przedziału (0,1>
|
||||
// tmp=Interpolate(t,p1,cp1,cp2,p2);
|
||||
tmp = RaInterpolate0(t); // obliczenie punktu dla tego parametru
|
||||
t = vector3(tmp - last).Length(); // obliczenie długości wektora
|
||||
t = Math3D::vector3(tmp - last).Length(); // obliczenie długości wektora
|
||||
l += t; // zwiększenie wyliczanej długości
|
||||
last = tmp;
|
||||
}
|
||||
return (l);
|
||||
}
|
||||
|
||||
// finds point on segment closest to specified point in 3d space. returns: point on segment as value in range 0-1
|
||||
double
|
||||
TSegment::find_nearest_point( glm::dvec3 const &Point ) const {
|
||||
|
||||
if( ( false == bCurve ) || ( iSegCount == 1 ) ) {
|
||||
// for straight track just treat it as a single segment
|
||||
return
|
||||
nearest_segment_point(
|
||||
glm::dvec3{ FastGetPoint_0() },
|
||||
glm::dvec3{ FastGetPoint_1() },
|
||||
Point );
|
||||
}
|
||||
else {
|
||||
// for curves iterate through segment chunks, and find the one which gives us the least distance to the specified point
|
||||
double distance = std::numeric_limits<double>::max();
|
||||
double nearest;
|
||||
// NOTE: we're reusing already created segment chunks, which are created based on splinefidelity setting
|
||||
// this means depending on splinefidelity the results can be potentially slightly different
|
||||
for( int segmentidx = 0; segmentidx < iSegCount; ++segmentidx ) {
|
||||
|
||||
auto const segmentpoint =
|
||||
clamp(
|
||||
nearest_segment_point(
|
||||
glm::dvec3{ FastGetPoint( fTsBuffer[ segmentidx ] ) },
|
||||
glm::dvec3{ FastGetPoint( fTsBuffer[ segmentidx + 1 ] ) },
|
||||
Point ) // point in range 0-1 on current segment
|
||||
* ( fTsBuffer[ segmentidx + 1 ] - fTsBuffer[ segmentidx ] ) // segment length
|
||||
+ fTsBuffer[ segmentidx ], // segment offset
|
||||
0.0, 1.0 ); // we clamp the range in case there's some floating point math inaccuracies
|
||||
|
||||
auto const segmentdistance = glm::length2( Point - glm::dvec3{ FastGetPoint( segmentpoint ) } );
|
||||
if( segmentdistance < distance ) {
|
||||
|
||||
nearest = segmentpoint;
|
||||
distance = segmentdistance;
|
||||
}
|
||||
}
|
||||
//
|
||||
return nearest;
|
||||
}
|
||||
}
|
||||
|
||||
const double fDirectionOffset = 0.1; // długość wektora do wyliczenia kierunku
|
||||
|
||||
vector3 TSegment::GetDirection(double fDistance)
|
||||
Math3D::vector3 TSegment::GetDirection(double const fDistance) const
|
||||
{ // takie toporne liczenie pochodnej dla podanego dystansu od Point1
|
||||
double t1 = GetTFromS(fDistance - fDirectionOffset);
|
||||
if (t1 <= 0.0)
|
||||
@@ -261,7 +298,7 @@ vector3 TSegment::GetDirection(double fDistance)
|
||||
return (FastGetPoint(t2) - FastGetPoint(t1));
|
||||
}
|
||||
|
||||
vector3 TSegment::FastGetDirection(double fDistance, double fOffset)
|
||||
Math3D::vector3 TSegment::FastGetDirection(double fDistance, double fOffset)
|
||||
{ // takie toporne liczenie pochodnej dla parametru 0.0÷1.0
|
||||
double t1 = fDistance - fOffset;
|
||||
if (t1 <= 0.0)
|
||||
@@ -272,7 +309,7 @@ vector3 TSegment::FastGetDirection(double fDistance, double fOffset)
|
||||
return (FastGetPoint(t2) - FastGetPoint(t1));
|
||||
}
|
||||
|
||||
vector3 TSegment::GetPoint(double fDistance)
|
||||
Math3D::vector3 TSegment::GetPoint(double const fDistance) const
|
||||
{ // wyliczenie współrzędnych XYZ na torze w odległości (fDistance) od Point1
|
||||
if (bCurve)
|
||||
{ // można by wprowadzić uproszczony wzór dla okręgów płaskich
|
||||
@@ -287,7 +324,7 @@ vector3 TSegment::GetPoint(double fDistance)
|
||||
}
|
||||
};
|
||||
|
||||
void TSegment::RaPositionGet(double fDistance, vector3 &p, vector3 &a)
|
||||
void TSegment::RaPositionGet(double const fDistance, Math3D::vector3 &p, Math3D::vector3 &a) const
|
||||
{ // ustalenie pozycji osi na torze, przechyłki, pochylenia i kierunku jazdy
|
||||
if (bCurve)
|
||||
{ // można by wprowadzić uproszczony wzór dla okręgów płaskich
|
||||
@@ -309,13 +346,16 @@ void TSegment::RaPositionGet(double fDistance, vector3 &p, vector3 &a)
|
||||
}
|
||||
};
|
||||
|
||||
vector3 TSegment::FastGetPoint(double t)
|
||||
Math3D::vector3 TSegment::FastGetPoint(double const t) const
|
||||
{
|
||||
// return (bCurve?Interpolate(t,Point1,CPointOut,CPointIn,Point2):((1.0-t)*Point1+(t)*Point2));
|
||||
return (bCurve ? RaInterpolate(t) : ((1.0 - t) * Point1 + (t)*Point2));
|
||||
return (
|
||||
( ( true == bCurve ) || ( iSegCount == 1 ) ) ?
|
||||
RaInterpolate( t ) :
|
||||
interpolate( Point1, Point2, t ) );
|
||||
}
|
||||
|
||||
bool TSegment::RenderLoft( vertex_array &Output, Math3D::vector3 const &Origin, const vector6 *ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale, int iSkip, int iEnd, double fOffsetX, vector3 **p, bool bRender)
|
||||
bool TSegment::RenderLoft( vertex_array &Output, Math3D::vector3 const &Origin, const vector6 *ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale, int iSkip, int iEnd, double fOffsetX, Math3D::vector3 **p, bool bRender)
|
||||
{ // generowanie trójkątów dla odcinka trajektorii ruchu
|
||||
// standardowo tworzy triangle_strip dla prostego albo ich zestaw dla łuku
|
||||
// po modyfikacji - dla ujemnego (iNumShapePoints) w dodatkowych polach tabeli
|
||||
@@ -325,7 +365,7 @@ bool TSegment::RenderLoft( vertex_array &Output, Math3D::vector3 const &Origin,
|
||||
if( !fTsBuffer )
|
||||
return false; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
|
||||
|
||||
vector3 pos1, pos2, dir, parallel1, parallel2, pt, norm;
|
||||
Math3D::vector3 pos1, pos2, dir, parallel1, parallel2, pt, norm;
|
||||
double s, step, fOffset, tv1, tv2, t, fEnd;
|
||||
bool const trapez = iNumShapePoints < 0; // sygnalizacja trapezowatości
|
||||
iNumShapePoints = std::abs( iNumShapePoints );
|
||||
@@ -341,7 +381,7 @@ bool TSegment::RenderLoft( vertex_array &Output, Math3D::vector3 const &Origin,
|
||||
fOffset = 0.1 / fLength; // pierwsze 10cm
|
||||
pos1 = FastGetPoint( t ); // wektor początku segmentu
|
||||
dir = FastGetDirection( t, fOffset ); // wektor kierunku
|
||||
parallel1 = Normalize( vector3( -dir.z, 0.0, dir.x ) ); // wektor poprzeczny
|
||||
parallel1 = Normalize( Math3D::vector3( -dir.z, 0.0, dir.x ) ); // wektor poprzeczny
|
||||
if( iEnd == 0 )
|
||||
iEnd = iSegCount;
|
||||
fEnd = fLength * double( iEnd ) / double( iSegCount );
|
||||
@@ -371,7 +411,7 @@ bool TSegment::RenderLoft( vertex_array &Output, Math3D::vector3 const &Origin,
|
||||
t = fTsBuffer[ i ]; // szybsze od GetTFromS(s);
|
||||
pos2 = FastGetPoint( t );
|
||||
dir = FastGetDirection( t, fOffset ); // nowy wektor kierunku
|
||||
parallel2 = Normalize( vector3( -dir.z, 0.0, dir.x ) ); // wektor poprzeczny
|
||||
parallel2 = Normalize( Math3D::vector3( -dir.z, 0.0, dir.x ) ); // wektor poprzeczny
|
||||
|
||||
if( trapez ) {
|
||||
for( int j = 0; j < iNumShapePoints; ++j ) {
|
||||
@@ -453,7 +493,7 @@ bool TSegment::RenderLoft( vertex_array &Output, Math3D::vector3 const &Origin,
|
||||
|
||||
void TSegment::Render()
|
||||
{
|
||||
vector3 pt;
|
||||
Math3D::vector3 pt;
|
||||
GfxRenderer.Bind_Material( null_handle );
|
||||
|
||||
if (bCurve)
|
||||
|
||||
Reference in New Issue
Block a user