16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-19 14:39:18 +02:00

Merge branch 'tmj-dev' into lua

This commit is contained in:
milek7
2017-09-05 20:20:28 +02:00
15 changed files with 254 additions and 179 deletions

View File

@@ -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)