mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 18:39:18 +02:00
continued refactoring: lines, terrain models; render culling optimizations and fixes
This commit is contained in:
@@ -232,9 +232,14 @@ void TAnimContainer::UpdateModel() {
|
|||||||
fTranslateSpeed = 0.0; // wyłączenie przeliczania wektora
|
fTranslateSpeed = 0.0; // wyłączenie przeliczania wektora
|
||||||
if (LengthSquared3(vTranslation) <= 0.0001) // jeśli jest w punkcie początkowym
|
if (LengthSquared3(vTranslation) <= 0.0001) // jeśli jest w punkcie początkowym
|
||||||
iAnim &= ~2; // wyłączyć zmianę pozycji submodelu
|
iAnim &= ~2; // wyłączyć zmianę pozycji submodelu
|
||||||
if (evDone)
|
if( evDone ) {
|
||||||
Global::AddToQuery(evDone, NULL); // wykonanie eventu informującego o
|
// wykonanie eventu informującego o zakończeniu
|
||||||
// zakończeniu
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
|
Global::AddToQuery( evDone, NULL );
|
||||||
|
#else
|
||||||
|
simulation::Events.AddToQuery( evDone, nullptr );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fRotateSpeed != 0.0)
|
if (fRotateSpeed != 0.0)
|
||||||
@@ -299,9 +304,14 @@ void TAnimContainer::UpdateModel() {
|
|||||||
if (!anim)
|
if (!anim)
|
||||||
{ // nie potrzeba przeliczać już
|
{ // nie potrzeba przeliczać już
|
||||||
fRotateSpeed = 0.0;
|
fRotateSpeed = 0.0;
|
||||||
if (evDone)
|
if( evDone ) {
|
||||||
Global::AddToQuery(evDone, NULL); // wykonanie eventu informującego o
|
// wykonanie eventu informującego o zakończeniu
|
||||||
// zakończeniu
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
|
Global::AddToQuery( evDone, NULL );
|
||||||
|
#else
|
||||||
|
simulation::Events.AddToQuery( evDone, nullptr );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( fAngleSpeed != 0.f ) {
|
if( fAngleSpeed != 0.f ) {
|
||||||
@@ -330,7 +340,11 @@ void TAnimContainer::PrepareModel()
|
|||||||
fAngleSpeed = 0.0; // wyłączenie przeliczania wektora
|
fAngleSpeed = 0.0; // wyłączenie przeliczania wektora
|
||||||
if( evDone ) {
|
if( evDone ) {
|
||||||
// wykonanie eventu informującego o zakończeniu
|
// wykonanie eventu informującego o zakończeniu
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
Global::AddToQuery( evDone, NULL );
|
Global::AddToQuery( evDone, NULL );
|
||||||
|
#else
|
||||||
|
simulation::Events.AddToQuery( evDone, nullptr );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -149,6 +149,10 @@ public:
|
|||||||
material_data const *
|
material_data const *
|
||||||
Material() const {
|
Material() const {
|
||||||
return &m_materialdata; }
|
return &m_materialdata; }
|
||||||
|
inline
|
||||||
|
TModel3d *
|
||||||
|
Model() {
|
||||||
|
return pModel; }
|
||||||
// members
|
// members
|
||||||
static TAnimContainer *acAnimList; // lista animacji z eventem, które muszą być przeliczane również bez wyświetlania
|
static TAnimContainer *acAnimList; // lista animacji z eventem, które muszą być przeliczane również bez wyświetlania
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// TViewPyramid TCamera::OrgViewPyramid;
|
|
||||||
//={vector3(-1,1,1),vector3(1,1,1),vector3(-1,-1,1),vector3(1,-1,1),vector3(0,0,0)};
|
|
||||||
|
|
||||||
void TCamera::Init(vector3 NPos, vector3 NAngle)
|
void TCamera::Init(vector3 NPos, vector3 NAngle)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -37,8 +34,8 @@ void TCamera::Init(vector3 NPos, vector3 NAngle)
|
|||||||
void TCamera::OnCursorMove(double x, double y)
|
void TCamera::OnCursorMove(double x, double y)
|
||||||
{
|
{
|
||||||
// McZapkie-170402: zeby mysz dzialala zawsze if (Type==tp_Follow)
|
// McZapkie-170402: zeby mysz dzialala zawsze if (Type==tp_Follow)
|
||||||
Pitch += y;
|
Yaw -= x;
|
||||||
Yaw += -x;
|
Pitch -= y;
|
||||||
if (Yaw > M_PI)
|
if (Yaw > M_PI)
|
||||||
Yaw -= 2 * M_PI;
|
Yaw -= 2 * M_PI;
|
||||||
else if (Yaw < -M_PI)
|
else if (Yaw < -M_PI)
|
||||||
@@ -62,7 +59,7 @@ TCamera::OnCommand( command_data const &Command ) {
|
|||||||
|
|
||||||
OnCursorMove(
|
OnCursorMove(
|
||||||
reinterpret_cast<double const &>( Command.param1 ) * 0.005 * Global::fMouseXScale / Global::ZoomFactor,
|
reinterpret_cast<double const &>( Command.param1 ) * 0.005 * Global::fMouseXScale / Global::ZoomFactor,
|
||||||
reinterpret_cast<double const &>( Command.param2 ) * -0.01 * Global::fMouseYScale / Global::ZoomFactor );
|
reinterpret_cast<double const &>( Command.param2 ) * 0.01 * Global::fMouseYScale / Global::ZoomFactor );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
15
DynObj.cpp
15
DynObj.cpp
@@ -5501,3 +5501,18 @@ vehicle_table::update_traction( TDynamicObject *Vehicle ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// legacy method, sends list of vehicles over network
|
||||||
|
void
|
||||||
|
vehicle_table::DynamicList( bool const Onlycontrolled ) const {
|
||||||
|
// odesłanie nazw pojazdów dostępnych na scenerii (nazwy, szczególnie wagonów, mogą się powtarzać!)
|
||||||
|
for( auto const *vehicle : m_items ) {
|
||||||
|
if( ( false == Onlycontrolled )
|
||||||
|
|| ( vehicle->Mechanik != nullptr ) ) {
|
||||||
|
// same nazwy pojazdów
|
||||||
|
multiplayer::WyslijString( vehicle->asName, 6 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// informacja o końcu listy
|
||||||
|
multiplayer::WyslijString( "none", 6 );
|
||||||
|
}
|
||||||
|
|||||||
3
DynObj.h
3
DynObj.h
@@ -495,6 +495,9 @@ public:
|
|||||||
// legacy method, checks for presence and height of traction wire for specified vehicle
|
// legacy method, checks for presence and height of traction wire for specified vehicle
|
||||||
void
|
void
|
||||||
update_traction( TDynamicObject *Vehicle );
|
update_traction( TDynamicObject *Vehicle );
|
||||||
|
// legacy method, sends list of vehicles over network
|
||||||
|
void
|
||||||
|
DynamicList( bool const Onlycontrolled = false ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
40
Event.cpp
40
Event.cpp
@@ -46,8 +46,7 @@ TEvent::~TEvent() {
|
|||||||
switch (Type)
|
switch (Type)
|
||||||
{ // sprzątanie
|
{ // sprzątanie
|
||||||
case tp_Multiple:
|
case tp_Multiple:
|
||||||
// SafeDeleteArray(Params[9].asText); //nie usuwać - nazwa obiektu powiązanego zamieniana na
|
// SafeDeleteArray(Params[9].asText); //nie usuwać - nazwa obiektu powiązanego zamieniana na wskaźnik
|
||||||
// wskaźnik
|
|
||||||
if (iFlags & conditional_memstring) // o ile jest łańcuch do porównania w memcompare
|
if (iFlags & conditional_memstring) // o ile jest łańcuch do porównania w memcompare
|
||||||
SafeDeleteArray(Params[10].asText);
|
SafeDeleteArray(Params[10].asText);
|
||||||
break;
|
break;
|
||||||
@@ -82,8 +81,7 @@ void TEvent::Conditions(cParser *parser, std::string s)
|
|||||||
if (!asNodeName.empty())
|
if (!asNodeName.empty())
|
||||||
{ // podczepienie łańcucha, jeśli nie jest pusty
|
{ // podczepienie łańcucha, jeśli nie jest pusty
|
||||||
// BUG: source of a memory leak -- the array never gets deleted. fix the destructor
|
// BUG: source of a memory leak -- the array never gets deleted. fix the destructor
|
||||||
Params[9].asText = new char[asNodeName.size() + 1]; // usuwane i zamieniane na
|
Params[9].asText = new char[asNodeName.size() + 1]; // usuwane i zamieniane na wskaźnik
|
||||||
// wskaźnik
|
|
||||||
strcpy(Params[9].asText, asNodeName.c_str());
|
strcpy(Params[9].asText, asNodeName.c_str());
|
||||||
}
|
}
|
||||||
parser->getTokens();
|
parser->getTokens();
|
||||||
@@ -860,17 +858,17 @@ event_manager::AddToQuery( TEvent *Event, TDynamicObject *Owner ) {
|
|||||||
}
|
}
|
||||||
//if (DebugModeFlag)
|
//if (DebugModeFlag)
|
||||||
WriteLog(
|
WriteLog(
|
||||||
"EVENT EXECUTED" + ( Owner ? ( " by " + Owner->asName ) : "" ) + ": AddValues & Track command ( "
|
"EVENT EXECUTED" + ( Owner ? ( " by " + Owner->asName ) : "" ) + ": AddValues & Track command - ["
|
||||||
+ std::string( Event->Params[ 0 ].asText ) + " "
|
+ std::string{ Event->Params[ 0 ].asText } + "] ["
|
||||||
+ std::to_string( Event->Params[ 1 ].asdouble ) + " "
|
+ to_string( Event->Params[ 1 ].asdouble, 2 ) + "] ["
|
||||||
+ std::to_string( Event->Params[ 2 ].asdouble ) + " )" );
|
+ to_string( Event->Params[ 2 ].asdouble, 2 ) + " ]" );
|
||||||
}
|
}
|
||||||
//else if (DebugModeFlag)
|
//else if (DebugModeFlag)
|
||||||
WriteLog(
|
WriteLog(
|
||||||
"EVENT EXECUTED" + ( Owner ? ( " by " + Owner->asName ) : "" ) + ": AddValues ( "
|
"EVENT EXECUTED" + ( Owner ? ( " by " + Owner->asName ) : "" ) + ": AddValues - ["
|
||||||
+ std::string( Event->Params[ 0 ].asText ) + " "
|
+ std::string( Event->Params[ 0 ].asText ) + "] ["
|
||||||
+ std::to_string( Event->Params[ 1 ].asdouble ) + " "
|
+ to_string( Event->Params[ 1 ].asdouble, 2 ) + "] ["
|
||||||
+ std::to_string( Event->Params[ 2 ].asdouble ) + " )" );
|
+ to_string( Event->Params[ 2 ].asdouble, 2 ) + "]" );
|
||||||
}
|
}
|
||||||
// jeśli jest kolejny o takiej samej nazwie, to idzie do kolejki (and if there's no joint event it'll be set to null and processing will end here)
|
// jeśli jest kolejny o takiej samej nazwie, to idzie do kolejki (and if there's no joint event it'll be set to null and processing will end here)
|
||||||
do {
|
do {
|
||||||
@@ -975,13 +973,11 @@ event_manager::CheckQuery() {
|
|||||||
break;
|
break;
|
||||||
case tp_GetValues: {
|
case tp_GetValues: {
|
||||||
if( m_workevent->Activator ) {
|
if( m_workevent->Activator ) {
|
||||||
/*
|
|
||||||
// TODO: re-enable when messaging module is in place
|
// TODO: re-enable when messaging module is in place
|
||||||
if( Global::iMultiplayer ) {
|
if( Global::iMultiplayer ) {
|
||||||
// potwierdzenie wykonania dla serwera (odczyt semafora już tak nie działa)
|
// potwierdzenie wykonania dla serwera (odczyt semafora już tak nie działa)
|
||||||
WyslijEvent( tmpEvent->asName, tmpEvent->Activator->name() );
|
multiplayer::WyslijEvent( m_workevent->asName, m_workevent->Activator->name() );
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
m_workevent->Params[ 9 ].asMemCell->PutCommand(
|
m_workevent->Params[ 9 ].asMemCell->PutCommand(
|
||||||
m_workevent->Activator->Mechanik,
|
m_workevent->Activator->Mechanik,
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
@@ -1124,13 +1120,10 @@ event_manager::CheckQuery() {
|
|||||||
m_workevent->Params[ 1 ].asdouble,
|
m_workevent->Params[ 1 ].asdouble,
|
||||||
m_workevent->Params[ 2 ].asdouble );
|
m_workevent->Params[ 2 ].asdouble );
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// TODO: re-enable when messaging module is in place
|
|
||||||
if( Global::iMultiplayer ) {
|
if( Global::iMultiplayer ) {
|
||||||
// dajemy znać do serwera o przełożeniu
|
// dajemy znać do serwera o przełożeniu
|
||||||
WyslijEvent( m_workevent->asName, "" ); // wysłanie nazwy eventu przełączajacego
|
multiplayer::WyslijEvent( m_workevent->asName, "" ); // wysłanie nazwy eventu przełączajacego
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
// Ra: bardziej by się przydała nazwa toru, ale nie ma do niej stąd dostępu
|
// Ra: bardziej by się przydała nazwa toru, ale nie ma do niej stąd dostępu
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1170,21 +1163,18 @@ event_manager::CheckQuery() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// TODO: re-enable when messaging component is in place
|
|
||||||
if( Global::iMultiplayer ) {
|
if( Global::iMultiplayer ) {
|
||||||
// dajemy znać do serwera o wykonaniu
|
// dajemy znać do serwera o wykonaniu
|
||||||
if( ( m_workevent->iFlags & conditional_anyelse ) == 0 ) {
|
if( ( m_workevent->iFlags & conditional_anyelse ) == 0 ) {
|
||||||
// jednoznaczne tylko, gdy nie było else
|
// jednoznaczne tylko, gdy nie było else
|
||||||
if( m_workevent->Activator ) {
|
if( m_workevent->Activator ) {
|
||||||
WyslijEvent( m_workevent->asName, m_workevent->Activator->name() );
|
multiplayer::WyslijEvent( m_workevent->asName, m_workevent->Activator->name() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WyslijEvent( m_workevent->asName, "" );
|
multiplayer::WyslijEvent( m_workevent->asName, "" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1273,8 +1263,8 @@ event_manager::CheckQuery() {
|
|||||||
+ to_string( m_workevent->Params[ 9 ].asMemCell->Value2(), 2 ) + "]" );
|
+ to_string( m_workevent->Params[ 9 ].asMemCell->Value2(), 2 ) + "]" );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO: re-enable when cell manager is in place
|
|
||||||
/*
|
/*
|
||||||
|
// TODO: re-enable when cell manager is in place
|
||||||
// lista wszystkich
|
// lista wszystkich
|
||||||
for( TGroundNode *Current = nRootOfType[ TP_MEMCELL ]; Current; Current = Current->nNext ) {
|
for( TGroundNode *Current = nRootOfType[ TP_MEMCELL ]; Current; Current = Current->nNext ) {
|
||||||
WriteLog( "Memcell \"" + Current->asName + "\": "
|
WriteLog( "Memcell \"" + Current->asName + "\": "
|
||||||
|
|||||||
@@ -1001,13 +1001,12 @@ TDynamicObject *Global::DynamicNearest()
|
|||||||
{ // ustalenie pojazdu najbliższego kamerze
|
{ // ustalenie pojazdu najbliższego kamerze
|
||||||
return pGround->DynamicNearest(pCamera->Pos);
|
return pGround->DynamicNearest(pCamera->Pos);
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
TDynamicObject *Global::CouplerNearest()
|
TDynamicObject *Global::CouplerNearest()
|
||||||
{ // ustalenie pojazdu najbliższego kamerze
|
{ // ustalenie pojazdu najbliższego kamerze
|
||||||
return pGround->CouplerNearest(pCamera->Pos);
|
return pGround->CouplerNearest(pCamera->Pos);
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
bool Global::AddToQuery(TEvent *event, TDynamicObject *who)
|
bool Global::AddToQuery(TEvent *event, TDynamicObject *who)
|
||||||
{
|
{
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
@@ -1016,6 +1015,7 @@ bool Global::AddToQuery(TEvent *event, TDynamicObject *who)
|
|||||||
return simulation::Events.AddToQuery( event, who );
|
return simulation::Events.AddToQuery( event, who );
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool Global::DoEvents()
|
bool Global::DoEvents()
|
||||||
|
|||||||
@@ -299,8 +299,8 @@ class Global
|
|||||||
static std::string GetNextSymbol();
|
static std::string GetNextSymbol();
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
static TDynamicObject * DynamicNearest();
|
static TDynamicObject * DynamicNearest();
|
||||||
#endif
|
|
||||||
static TDynamicObject * CouplerNearest();
|
static TDynamicObject * CouplerNearest();
|
||||||
|
#endif
|
||||||
static bool AddToQuery(TEvent *event, TDynamicObject *who);
|
static bool AddToQuery(TEvent *event, TDynamicObject *who);
|
||||||
static bool DoEvents();
|
static bool DoEvents();
|
||||||
static std::string Bezogonkow(std::string str, bool _ = false);
|
static std::string Bezogonkow(std::string str, bool _ = false);
|
||||||
|
|||||||
31
Ground.cpp
31
Ground.cpp
@@ -243,7 +243,9 @@ void TSubRect::NodeAdd(TGroundNode *Node)
|
|||||||
break;
|
break;
|
||||||
case TP_TRACK: // TODO: tory z cieniem (tunel, canyon) też dać bez łączenia?
|
case TP_TRACK: // TODO: tory z cieniem (tunel, canyon) też dać bez łączenia?
|
||||||
++iTracks; // jeden tor więcej
|
++iTracks; // jeden tor więcej
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
Node->pTrack->RaOwnerSet(this); // do którego sektora ma zgłaszać animację
|
Node->pTrack->RaOwnerSet(this); // do którego sektora ma zgłaszać animację
|
||||||
|
#endif
|
||||||
// NOTE: track merge/sort temporarily disabled to simplify unification of render code
|
// NOTE: track merge/sort temporarily disabled to simplify unification of render code
|
||||||
// TODO: refactor sorting as universal part of drawing process in the renderer
|
// TODO: refactor sorting as universal part of drawing process in the renderer
|
||||||
Node->nNext3 = nRenderRect;
|
Node->nNext3 = nRenderRect;
|
||||||
@@ -340,6 +342,7 @@ TTrack * TSubRect::FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude)
|
|||||||
return NULL;
|
return NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
bool TSubRect::RaTrackAnimAdd(TTrack *t)
|
bool TSubRect::RaTrackAnimAdd(TTrack *t)
|
||||||
{ // aktywacja animacji torów w VBO (zwrotnica, obrotnica)
|
{ // aktywacja animacji torów w VBO (zwrotnica, obrotnica)
|
||||||
if( false == m_geometrycreated ) {
|
if( false == m_geometrycreated ) {
|
||||||
@@ -365,6 +368,7 @@ void TSubRect::RaAnimate( unsigned int const Framestamp ) {
|
|||||||
|
|
||||||
m_framestamp = Framestamp;
|
m_framestamp = Framestamp;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
TTraction * TSubRect::FindTraction(glm::dvec3 const &Point, int &iConnection, TTraction *Exclude)
|
TTraction * TSubRect::FindTraction(glm::dvec3 const &Point, int &iConnection, TTraction *Exclude)
|
||||||
{ // szukanie przęsła w sektorze, którego koniec jest najbliższy (*Point)
|
{ // szukanie przęsła w sektorze, którego koniec jest najbliższy (*Point)
|
||||||
@@ -604,7 +608,7 @@ TGroundNode * TGround::DynamicFind(std::string const &Name)
|
|||||||
return Current;
|
return Current;
|
||||||
return NULL;
|
return NULL;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
void
|
void
|
||||||
TGround::DynamicList(bool all)
|
TGround::DynamicList(bool all)
|
||||||
{ // odesłanie nazw pojazdów dostępnych na scenerii (nazwy, szczególnie wagonów, mogą się
|
{ // odesłanie nazw pojazdów dostępnych na scenerii (nazwy, szczególnie wagonów, mogą się
|
||||||
@@ -614,7 +618,7 @@ TGround::DynamicList(bool all)
|
|||||||
multiplayer::WyslijString(Current->asName, 6); // same nazwy pojazdów
|
multiplayer::WyslijString(Current->asName, 6); // same nazwy pojazdów
|
||||||
multiplayer::WyslijString("none", 6); // informacja o końcu listy
|
multiplayer::WyslijString("none", 6); // informacja o końcu listy
|
||||||
};
|
};
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
// wyszukiwanie obiektu o podanej nazwie i konkretnym typie
|
// wyszukiwanie obiektu o podanej nazwie i konkretnym typie
|
||||||
TGroundNode *
|
TGroundNode *
|
||||||
TGround::FindGroundNode(std::string const &asNameToFind, TGroundNodeType const iNodeType) {
|
TGround::FindGroundNode(std::string const &asNameToFind, TGroundNodeType const iNodeType) {
|
||||||
@@ -648,7 +652,7 @@ TGround::GetRect( double x, double z ) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
// convert tp_terrain model to a series of triangle nodes
|
// convert tp_terrain model to a series of triangle nodes
|
||||||
void
|
void
|
||||||
TGround::convert_terrain( TGroundNode const *Terrain ) {
|
TGround::convert_terrain( TGroundNode const *Terrain ) {
|
||||||
@@ -683,7 +687,7 @@ TGround::convert_terrain( TSubModel const *Submodel ) {
|
|||||||
delete groundnode;
|
delete groundnode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
double fTrainSetVel = 0;
|
double fTrainSetVel = 0;
|
||||||
double fTrainSetDir = 0;
|
double fTrainSetDir = 0;
|
||||||
double fTrainSetDist = 0; // odległość składu od punktu 1 w stronę punktu 2
|
double fTrainSetDist = 0; // odległość składu od punktu 1 w stronę punktu 2
|
||||||
@@ -2766,7 +2770,7 @@ void TGround::InitTraction()
|
|||||||
}
|
}
|
||||||
delete[] nEnds; // nie potrzebne już
|
delete[] nEnds; // nie potrzebne już
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
void TGround::TrackJoin(TGroundNode *Current)
|
void TGround::TrackJoin(TGroundNode *Current)
|
||||||
{ // wyszukiwanie sąsiednich torów do podłączenia (wydzielone na użytek obrotnicy)
|
{ // wyszukiwanie sąsiednich torów do podłączenia (wydzielone na użytek obrotnicy)
|
||||||
TTrack *Track = Current->pTrack;
|
TTrack *Track = Current->pTrack;
|
||||||
@@ -2774,11 +2778,7 @@ void TGround::TrackJoin(TGroundNode *Current)
|
|||||||
int iConnection;
|
int iConnection;
|
||||||
if (!Track->CurrentPrev())
|
if (!Track->CurrentPrev())
|
||||||
{
|
{
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
tmp = FindTrack(Track->CurrentSegment()->FastGetPoint_0(), iConnection, Current); // Current do pominięcia
|
tmp = FindTrack(Track->CurrentSegment()->FastGetPoint_0(), iConnection, Current); // Current do pominięcia
|
||||||
#else
|
|
||||||
std::tie( tmp, iConnection ) = simulation::Region->find_path( Track->CurrentSegment()->FastGetPoint_0(), Track );
|
|
||||||
#endif
|
|
||||||
switch (iConnection)
|
switch (iConnection)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@@ -2791,11 +2791,7 @@ void TGround::TrackJoin(TGroundNode *Current)
|
|||||||
}
|
}
|
||||||
if (!Track->CurrentNext())
|
if (!Track->CurrentNext())
|
||||||
{
|
{
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
tmp = FindTrack(Track->CurrentSegment()->FastGetPoint_1(), iConnection, Current);
|
tmp = FindTrack(Track->CurrentSegment()->FastGetPoint_1(), iConnection, Current);
|
||||||
#else
|
|
||||||
std::tie( tmp, iConnection ) = simulation::Region->find_path( Track->CurrentSegment()->FastGetPoint_1(), Track );
|
|
||||||
#endif
|
|
||||||
switch (iConnection)
|
switch (iConnection)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@@ -2807,7 +2803,7 @@ void TGround::TrackJoin(TGroundNode *Current)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
// McZapkie-070602: wyzwalacze zdarzen
|
// McZapkie-070602: wyzwalacze zdarzen
|
||||||
bool TGround::InitLaunchers()
|
bool TGround::InitLaunchers()
|
||||||
{
|
{
|
||||||
@@ -3755,7 +3751,7 @@ bool TGround::GetTraction(TDynamicObject *model)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -3800,6 +3796,7 @@ TDynamicObject * TGround::DynamicNearest(vector3 pPosition, double distance, boo
|
|||||||
}
|
}
|
||||||
return dyn;
|
return dyn;
|
||||||
};
|
};
|
||||||
|
|
||||||
TDynamicObject * TGround::CouplerNearest(vector3 pPosition, double distance, bool mech)
|
TDynamicObject * TGround::CouplerNearest(vector3 pPosition, double distance, bool mech)
|
||||||
{ // wyszukanie pojazdu, którego sprzęg jest najbliżej względem (pPosition)
|
{ // wyszukanie pojazdu, którego sprzęg jest najbliżej względem (pPosition)
|
||||||
TGroundNode *node;
|
TGroundNode *node;
|
||||||
@@ -3829,6 +3826,7 @@ TDynamicObject * TGround::CouplerNearest(vector3 pPosition, double distance, boo
|
|||||||
}
|
}
|
||||||
return dyn;
|
return dyn;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
void TGround::DynamicRemove(TDynamicObject *dyn)
|
void TGround::DynamicRemove(TDynamicObject *dyn)
|
||||||
{ // Ra: usunięcie pojazdów ze scenerii (gdy dojadą na koniec i nie sa potrzebne)
|
{ // Ra: usunięcie pojazdów ze scenerii (gdy dojadą na koniec i nie sa potrzebne)
|
||||||
@@ -3951,7 +3949,7 @@ void TGround::TerrainWrite()
|
|||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
void TGround::TrackBusyList()
|
void TGround::TrackBusyList()
|
||||||
{ // wysłanie informacji o wszystkich zajętych odcinkach
|
{ // wysłanie informacji o wszystkich zajętych odcinkach
|
||||||
TGroundNode *Current;
|
TGroundNode *Current;
|
||||||
@@ -3987,6 +3985,7 @@ void TGround::IsolatedBusy(const std::string t)
|
|||||||
}
|
}
|
||||||
multiplayer::WyslijString(t, 10); // wolny
|
multiplayer::WyslijString(t, 10); // wolny
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void TGround::Silence(vector3 gdzie)
|
void TGround::Silence(vector3 gdzie)
|
||||||
|
|||||||
21
Ground.h
21
Ground.h
@@ -128,14 +128,8 @@ public:
|
|||||||
void InitNormals();
|
void InitNormals();
|
||||||
void RenderHidden(); // obsługa dźwięków i wyzwalaczy zdarzeń
|
void RenderHidden(); // obsługa dźwięków i wyzwalaczy zdarzeń
|
||||||
};
|
};
|
||||||
/*
|
|
||||||
struct bounding_area {
|
|
||||||
|
|
||||||
glm::vec3 center; // mid point of the rectangle
|
class TSubRect : public CMesh
|
||||||
float radius { 0.0f }; // radius of the bounding sphere
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
class TSubRect : /*public Resource,*/ public CMesh
|
|
||||||
{ // sektor składowy kwadratu kilometrowego
|
{ // sektor składowy kwadratu kilometrowego
|
||||||
public:
|
public:
|
||||||
scene::bounding_area m_area;
|
scene::bounding_area m_area;
|
||||||
@@ -165,8 +159,10 @@ class TSubRect : /*public Resource,*/ public CMesh
|
|||||||
void Sort(); // optymalizacja obiektów w sektorze (sortowanie wg tekstur)
|
void Sort(); // optymalizacja obiektów w sektorze (sortowanie wg tekstur)
|
||||||
TTrack * FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude);
|
TTrack * FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude);
|
||||||
TTraction * FindTraction(glm::dvec3 const &Point, int &iConnection, TTraction *Exclude);
|
TTraction * FindTraction(glm::dvec3 const &Point, int &iConnection, TTraction *Exclude);
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
bool RaTrackAnimAdd(TTrack *t); // zgłoszenie toru do animacji
|
bool RaTrackAnimAdd(TTrack *t); // zgłoszenie toru do animacji
|
||||||
void RaAnimate( unsigned int const Framestamp ); // przeliczenie animacji torów
|
void RaAnimate( unsigned int const Framestamp ); // przeliczenie animacji torów
|
||||||
|
#endif
|
||||||
void RenderSounds(); // dźwięki pojazdów z niewidocznych sektorów
|
void RenderSounds(); // dźwięki pojazdów z niewidocznych sektorów
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -273,9 +269,6 @@ class TGround
|
|||||||
bool CheckQuery();
|
bool CheckQuery();
|
||||||
TGroundNode * DynamicFindAny(std::string const &Name);
|
TGroundNode * DynamicFindAny(std::string const &Name);
|
||||||
TGroundNode * DynamicFind(std::string const &Name);
|
TGroundNode * DynamicFind(std::string const &Name);
|
||||||
#endif
|
|
||||||
void DynamicList(bool all = false);
|
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
TGroundNode * FindGroundNode(std::string const &asNameToFind, TGroundNodeType const iNodeType);
|
TGroundNode * FindGroundNode(std::string const &asNameToFind, TGroundNodeType const iNodeType);
|
||||||
#endif
|
#endif
|
||||||
TGroundRect * GetRect( double x, double z );
|
TGroundRect * GetRect( double x, double z );
|
||||||
@@ -295,25 +288,23 @@ class TGround
|
|||||||
return (int)(x / fSubRectSize + fHalfTotalNumSubRects); };
|
return (int)(x / fSubRectSize + fHalfTotalNumSubRects); };
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TEvent * FindEvent(const std::string &asEventName);
|
TEvent * FindEvent(const std::string &asEventName);
|
||||||
#endif
|
|
||||||
void TrackJoin(TGroundNode *Current);
|
void TrackJoin(TGroundNode *Current);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// convert tp_terrain model to a series of triangle nodes
|
// convert tp_terrain model to a series of triangle nodes
|
||||||
void convert_terrain( TGroundNode const *Terrain );
|
void convert_terrain( TGroundNode const *Terrain );
|
||||||
void convert_terrain( TSubModel const *Submodel );
|
void convert_terrain( TSubModel const *Submodel );
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
void RaTriangleDivider(TGroundNode *node);
|
void RaTriangleDivider(TGroundNode *node);
|
||||||
void Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam);
|
|
||||||
#endif
|
#endif
|
||||||
public:
|
public:
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
|
void DynamicList( bool all = false );
|
||||||
void TrackBusyList();
|
void TrackBusyList();
|
||||||
void IsolatedBusyList();
|
void IsolatedBusyList();
|
||||||
void IsolatedBusy( const std::string t );
|
void IsolatedBusy( const std::string t );
|
||||||
|
|
||||||
void RadioStop(vector3 pPosition);
|
void RadioStop(vector3 pPosition);
|
||||||
TDynamicObject * DynamicNearest(vector3 pPosition, double distance = 20.0, bool mech = false);
|
TDynamicObject * DynamicNearest(vector3 pPosition, double distance = 20.0, bool mech = false);
|
||||||
TDynamicObject * CouplerNearest(vector3 pPosition, double distance = 20.0, bool mech = false);
|
TDynamicObject * CouplerNearest(vector3 pPosition, double distance = 20.0, bool mech = false);
|
||||||
|
#endif
|
||||||
void DynamicRemove(TDynamicObject *dyn);
|
void DynamicRemove(TDynamicObject *dyn);
|
||||||
void TerrainRead(std::string const &f);
|
void TerrainRead(std::string const &f);
|
||||||
void TerrainWrite();
|
void TerrainWrite();
|
||||||
|
|||||||
10
MemCell.cpp
10
MemCell.cpp
@@ -176,8 +176,14 @@ void TMemCell::StopCommandSent()
|
|||||||
if (!bCommand)
|
if (!bCommand)
|
||||||
return;
|
return;
|
||||||
bCommand = false;
|
bCommand = false;
|
||||||
if (OnSent) // jeśli jest event
|
if( OnSent ) {
|
||||||
Global::AddToQuery(OnSent, NULL);
|
// jeśli jest event
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
|
Global::AddToQuery( OnSent, NULL );
|
||||||
|
#else
|
||||||
|
simulation::Events.AddToQuery( OnSent, nullptr );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void TMemCell::AssignEvents(TEvent *e)
|
void TMemCell::AssignEvents(TEvent *e)
|
||||||
|
|||||||
49
Model3d.cpp
49
Model3d.cpp
@@ -19,7 +19,9 @@ Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
|||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
#include "mczapkie/mctools.h"
|
#include "mczapkie/mctools.h"
|
||||||
#include "Usefull.h"
|
#include "Usefull.h"
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
#include "ground.h"
|
#include "ground.h"
|
||||||
|
#endif
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "mtable.h"
|
#include "mtable.h"
|
||||||
@@ -988,11 +990,11 @@ TSubModel::create_geometry( std::size_t &Dataoffset, geometrybank_handle const &
|
|||||||
|
|
||||||
// data offset is used to determine data offset of each submodel into single shared geometry bank
|
// data offset is used to determine data offset of each submodel into single shared geometry bank
|
||||||
// (the offsets are part of legacy system which we now need to work around for backward compatibility)
|
// (the offsets are part of legacy system which we now need to work around for backward compatibility)
|
||||||
|
|
||||||
if( Child )
|
if( Child )
|
||||||
Child->create_geometry( Dataoffset, Bank );
|
Child->create_geometry( Dataoffset, Bank );
|
||||||
|
|
||||||
if( false == Vertices.empty() ) {
|
if( false == Vertices.empty() ) {
|
||||||
|
|
||||||
tVboPtr = static_cast<int>( Dataoffset );
|
tVboPtr = static_cast<int>( Dataoffset );
|
||||||
Dataoffset += Vertices.size();
|
Dataoffset += Vertices.size();
|
||||||
// conveniently all relevant custom node types use GL_POINTS, or we'd have to determine the type on individual basis
|
// conveniently all relevant custom node types use GL_POINTS, or we'd have to determine the type on individual basis
|
||||||
@@ -1003,10 +1005,29 @@ TSubModel::create_geometry( std::size_t &Dataoffset, geometrybank_handle const &
|
|||||||
m_geometry = GfxRenderer.Insert( Vertices, Bank, type );
|
m_geometry = GfxRenderer.Insert( Vertices, Bank, type );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( m_geometry != NULL ) {
|
||||||
|
// calculate bounding radius while we're at it
|
||||||
|
// NOTE: doesn't take into account transformation hierarchy TODO: implement it
|
||||||
|
float squaredradius{ 0.f };
|
||||||
|
for( auto const &vertex : GfxRenderer.Vertices( m_geometry ) ) {
|
||||||
|
squaredradius = static_cast<float>( glm::length2( vertex.position ) );
|
||||||
|
if( squaredradius > m_boundingradius ) {
|
||||||
|
m_boundingradius = squaredradius;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( m_boundingradius > 0.f ) { m_boundingradius = std::sqrt( m_boundingradius ); }
|
||||||
|
if( Parent ) {
|
||||||
|
// propagate radius up the chain
|
||||||
|
Parent->m_boundingradius = std::max(
|
||||||
|
Parent->m_boundingradius,
|
||||||
|
m_boundingradius );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( Next )
|
if( Next )
|
||||||
Next->create_geometry( Dataoffset, Bank );
|
Next->create_geometry( Dataoffset, Bank );
|
||||||
}
|
}
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
// places contained geometry in provided ground node
|
// places contained geometry in provided ground node
|
||||||
void
|
void
|
||||||
TSubModel::convert( TGroundNode &Groundnode ) const {
|
TSubModel::convert( TGroundNode &Groundnode ) const {
|
||||||
@@ -1063,7 +1084,7 @@ TSubModel::convert( TGroundNode &Groundnode ) const {
|
|||||||
Groundnode.fSquareRadius += squareradius;
|
Groundnode.fSquareRadius += squareradius;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
void TSubModel::ColorsSet( glm::vec3 const &Ambient, glm::vec3 const &Diffuse, glm::vec3 const &Specular )
|
void TSubModel::ColorsSet( glm::vec3 const &Ambient, glm::vec3 const &Diffuse, glm::vec3 const &Specular )
|
||||||
{ // ustawienie kolorów dla modelu terenu
|
{ // ustawienie kolorów dla modelu terenu
|
||||||
f4Ambient = glm::vec4( Ambient, 1.0f );
|
f4Ambient = glm::vec4( Ambient, 1.0f );
|
||||||
@@ -1759,18 +1780,11 @@ void TModel3d::Init()
|
|||||||
return; // operacje zostały już wykonane
|
return; // operacje zostały już wykonane
|
||||||
if (Root)
|
if (Root)
|
||||||
{
|
{
|
||||||
if (iFlags & 0x0200) // jeśli wczytano z pliku tekstowego
|
if (iFlags & 0x0200) {
|
||||||
{ // jest jakiś dziwny błąd, że obkręcany ma być tylko ostatni submodel
|
// jeśli wczytano z pliku tekstowego jest jakiś dziwny błąd,
|
||||||
// głównego łańcucha
|
// że obkręcany ma być tylko ostatni submodel głównego łańcucha
|
||||||
// TSubModel *p=Root;
|
// argumet określa, czy wykonać pierwotny obrót
|
||||||
// do
|
Root->InitialRotate(true);
|
||||||
//{p->InitialRotate(true); //ostatniemu należy się konwersja układu
|
|
||||||
// współrzędnych
|
|
||||||
// p=p->NextGet();
|
|
||||||
//}
|
|
||||||
// while (p->NextGet())
|
|
||||||
// Root->InitialRotate(false); //a poprzednim tylko optymalizacja
|
|
||||||
Root->InitialRotate(true); // argumet określa, czy wykonać pierwotny obrót
|
|
||||||
}
|
}
|
||||||
iFlags |= Root->FlagsCheck() | 0x8000; // flagi całego modelu
|
iFlags |= Root->FlagsCheck() | 0x8000; // flagi całego modelu
|
||||||
if (iNumVerts) {
|
if (iNumVerts) {
|
||||||
@@ -1788,11 +1802,6 @@ void TModel3d::Init()
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void TModel3d::BreakHierarhy()
|
|
||||||
{
|
|
||||||
Error("Not implemented yet :(");
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// 2012-02 funkcje do tworzenia terenu z E3D
|
// 2012-02 funkcje do tworzenia terenu z E3D
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|||||||
22
Model3d.h
22
Model3d.h
@@ -50,7 +50,12 @@ enum TAnimType // rodzaj animacji
|
|||||||
at_Undefined = 0x800000FF // animacja chwilowo nieokreślona
|
at_Undefined = 0x800000FF // animacja chwilowo nieokreślona
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
class TGroundNode;
|
class TGroundNode;
|
||||||
|
#endif
|
||||||
|
namespace scene {
|
||||||
|
class shape_node;
|
||||||
|
}
|
||||||
|
|
||||||
class TSubModel
|
class TSubModel
|
||||||
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
|
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
|
||||||
@@ -59,6 +64,7 @@ class TSubModel
|
|||||||
friend class opengl_renderer;
|
friend class opengl_renderer;
|
||||||
friend class TModel3d; // temporary workaround. TODO: clean up class content/hierarchy
|
friend class TModel3d; // temporary workaround. TODO: clean up class content/hierarchy
|
||||||
friend class TDynamicObject; // temporary etc
|
friend class TDynamicObject; // temporary etc
|
||||||
|
friend class scene::shape_node; // temporary etc
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum normalization {
|
enum normalization {
|
||||||
@@ -131,10 +137,8 @@ private:
|
|||||||
|
|
||||||
public: // chwilowo
|
public: // chwilowo
|
||||||
float3 v_TransVector { 0.0f, 0.0f, 0.0f };
|
float3 v_TransVector { 0.0f, 0.0f, 0.0f };
|
||||||
/*
|
|
||||||
basic_vertex *Vertices; // roboczy wskaźnik - wczytanie T3D do VBO
|
|
||||||
*/
|
|
||||||
vertex_array Vertices;
|
vertex_array Vertices;
|
||||||
|
float m_boundingradius { 0 };
|
||||||
size_t iAnimOwner{ 0 }; // roboczy numer egzemplarza, który ustawił animację
|
size_t iAnimOwner{ 0 }; // roboczy numer egzemplarza, który ustawił animację
|
||||||
TAnimType b_aAnim{ at_None }; // kody animacji oddzielnie, bo zerowane
|
TAnimType b_aAnim{ at_None }; // kody animacji oddzielnie, bo zerowane
|
||||||
public:
|
public:
|
||||||
@@ -163,9 +167,6 @@ public:
|
|||||||
TSubModel * NextGet() { return Next; };
|
TSubModel * NextGet() { return Next; };
|
||||||
TSubModel * ChildGet() { return Child; };
|
TSubModel * ChildGet() { return Child; };
|
||||||
int TriangleAdd(TModel3d *m, material_handle tex, int tri);
|
int TriangleAdd(TModel3d *m, material_handle tex, int tri);
|
||||||
/*
|
|
||||||
basic_vertex * TrianglePtr(int tex, int pos, glm::vec3 const &Ambient, glm::vec3 const &Diffuse, glm::vec3 const &Specular );
|
|
||||||
*/
|
|
||||||
void SetRotate(float3 vNewRotateAxis, float fNewAngle);
|
void SetRotate(float3 vNewRotateAxis, float fNewAngle);
|
||||||
void SetRotateXYZ(vector3 vNewAngles);
|
void SetRotateXYZ(vector3 vNewAngles);
|
||||||
void SetRotateXYZ(float3 vNewAngles);
|
void SetRotateXYZ(float3 vNewAngles);
|
||||||
@@ -215,8 +216,9 @@ public:
|
|||||||
std::vector<float4x4>&);
|
std::vector<float4x4>&);
|
||||||
void serialize_geometry( std::ostream &Output ) const;
|
void serialize_geometry( std::ostream &Output ) const;
|
||||||
// places contained geometry in provided ground node
|
// places contained geometry in provided ground node
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
void convert( TGroundNode &Groundnode ) const;
|
void convert( TGroundNode &Groundnode ) const;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class TModel3d : public CMesh
|
class TModel3d : public CMesh
|
||||||
@@ -236,6 +238,11 @@ private:
|
|||||||
std::string asBinary; // nazwa pod którą zapisać model binarny
|
std::string asBinary; // nazwa pod którą zapisać model binarny
|
||||||
std::string m_filename;
|
std::string m_filename;
|
||||||
public:
|
public:
|
||||||
|
float bounding_radius() const {
|
||||||
|
return (
|
||||||
|
Root ?
|
||||||
|
Root->m_boundingradius :
|
||||||
|
0.f ); }
|
||||||
inline TSubModel * GetSMRoot() { return (Root); };
|
inline TSubModel * GetSMRoot() { return (Root); };
|
||||||
TModel3d();
|
TModel3d();
|
||||||
~TModel3d();
|
~TModel3d();
|
||||||
@@ -246,7 +253,6 @@ public:
|
|||||||
void LoadFromBinFile(std::string const &FileName, bool dynamic);
|
void LoadFromBinFile(std::string const &FileName, bool dynamic);
|
||||||
bool LoadFromFile(std::string const &FileName, bool dynamic);
|
bool LoadFromFile(std::string const &FileName, bool dynamic);
|
||||||
void SaveToBinFile(std::string const &FileName);
|
void SaveToBinFile(std::string const &FileName);
|
||||||
void BreakHierarhy();
|
|
||||||
int Flags() const { return iFlags; };
|
int Flags() const { return iFlags; };
|
||||||
void Init();
|
void Init();
|
||||||
std::string NameGet() { return m_filename; };
|
std::string NameGet() { return m_filename; };
|
||||||
|
|||||||
105
Track.cpp
105
Track.cpp
@@ -84,16 +84,14 @@ TIsolated::TIsolated(std::string const &n, TIsolated *i) :
|
|||||||
// utworznie obwodu izolowanego. nothing to do here.
|
// utworznie obwodu izolowanego. nothing to do here.
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: put this in the cleanup routine on exit
|
void TIsolated::DeleteAll() {
|
||||||
/*
|
|
||||||
TIsolated *p=pRoot;
|
while( pRoot ) {
|
||||||
while (pRoot)
|
auto *next = pRoot->Next();
|
||||||
{
|
delete pRoot;
|
||||||
p=pRoot;
|
pRoot = next;
|
||||||
p->pNext=NULL;
|
}
|
||||||
delete p;
|
}
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
TIsolated * TIsolated::Find(std::string const &n)
|
TIsolated * TIsolated::Find(std::string const &n)
|
||||||
{ // znalezienie obiektu albo utworzenie nowego
|
{ // znalezienie obiektu albo utworzenie nowego
|
||||||
@@ -1065,7 +1063,11 @@ bool TTrack::InMovement()
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
void TTrack::RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined)
|
void TTrack::RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined)
|
||||||
|
#else
|
||||||
|
void TTrack::RaAssign( scene::basic_cell *gn, TAnimModel *am, TEvent *done, TEvent *joined )
|
||||||
|
#endif
|
||||||
{ // Ra: wiązanie toru z modelem obrotnicy
|
{ // Ra: wiązanie toru z modelem obrotnicy
|
||||||
if (eType == tt_Table)
|
if (eType == tt_Table)
|
||||||
{
|
{
|
||||||
@@ -2259,7 +2261,7 @@ bool TTrack::Switch(int i, float const t, float const d)
|
|||||||
}
|
}
|
||||||
else if (eType == tt_Table)
|
else if (eType == tt_Table)
|
||||||
{ // blokowanie (0, szukanie torów) lub odblokowanie (1, rozłączenie) obrotnicy
|
{ // blokowanie (0, szukanie torów) lub odblokowanie (1, rozłączenie) obrotnicy
|
||||||
if (i)
|
if (i) // NOTE: this condition seems opposite to intention/comment? TODO: investigate this
|
||||||
{ // 0: rozłączenie sąsiednich torów od obrotnicy
|
{ // 0: rozłączenie sąsiednich torów od obrotnicy
|
||||||
if (trPrev) // jeśli jest tor od Point1 obrotnicy
|
if (trPrev) // jeśli jest tor od Point1 obrotnicy
|
||||||
if (iPrevDirection) // 0:dołączony Point1, 1:dołączony Point2
|
if (iPrevDirection) // 0:dołączony Point1, 1:dołączony Point2
|
||||||
@@ -2276,25 +2278,34 @@ bool TTrack::Switch(int i, float const t, float const d)
|
|||||||
fVelocity = 0.0; // AI, nie ruszaj się!
|
fVelocity = 0.0; // AI, nie ruszaj się!
|
||||||
if (SwitchExtension->pOwner)
|
if (SwitchExtension->pOwner)
|
||||||
SwitchExtension->pOwner->RaTrackAnimAdd(this); // dodanie do listy animacyjnej
|
SwitchExtension->pOwner->RaTrackAnimAdd(this); // dodanie do listy animacyjnej
|
||||||
|
// TODO: unregister path ends in the owner cell
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // 1: ustalenie finalnego położenia (gdy nie było animacji)
|
{ // 1: ustalenie finalnego położenia (gdy nie było animacji)
|
||||||
RaAnimate(); // ostatni etap animowania
|
RaAnimate(); // ostatni etap animowania
|
||||||
// zablokowanie pozycji i połączenie do sąsiednich torów
|
// zablokowanie pozycji i połączenie do sąsiednich torów
|
||||||
|
// TODO: register new position of the path endpoints with the region
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
Global::pGround->TrackJoin(SwitchExtension->pMyNode);
|
Global::pGround->TrackJoin(SwitchExtension->pMyNode);
|
||||||
|
#else
|
||||||
|
simulation::Region->TrackJoin( this );
|
||||||
|
#endif
|
||||||
if (trNext || trPrev)
|
if (trNext || trPrev)
|
||||||
{
|
{
|
||||||
fVelocity = 6.0; // jazda dozwolona
|
fVelocity = 6.0; // jazda dozwolona
|
||||||
if (trPrev)
|
if( ( trPrev )
|
||||||
if (trPrev->fVelocity ==
|
&& ( trPrev->fVelocity == 0.0 ) ) {
|
||||||
0.0) // ustawienie 0 da możliwość zatrzymania AI na obrotnicy
|
// ustawienie 0 da możliwość zatrzymania AI na obrotnicy
|
||||||
trPrev->VelocitySet(6.0); // odblokowanie dołączonego toru do jazdy
|
trPrev->VelocitySet( 6.0 ); // odblokowanie dołączonego toru do jazdy
|
||||||
if (trNext)
|
}
|
||||||
if (trNext->fVelocity == 0.0)
|
if( ( trNext )
|
||||||
trNext->VelocitySet(6.0);
|
&& ( trNext->fVelocity == 0.0 ) ) {
|
||||||
if (SwitchExtension->evPlus) // w starych sceneriach może nie być
|
trNext->VelocitySet( 6.0 );
|
||||||
Global::AddToQuery(SwitchExtension->evPlus,
|
}
|
||||||
NULL); // potwierdzenie wykonania (np. odpala WZ)
|
if( SwitchExtension->evPlus ) { // w starych sceneriach może nie być
|
||||||
|
// potwierdzenie wykonania (np. odpala WZ)
|
||||||
|
Global::AddToQuery( SwitchExtension->evPlus, nullptr );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SwitchExtension->CurrentIndex = i; // zapamiętanie stanu zablokowania
|
SwitchExtension->CurrentIndex = i; // zapamiętanie stanu zablokowania
|
||||||
@@ -2528,7 +2539,11 @@ TTrack * TTrack::RaAnimate()
|
|||||||
cosa = -hlen * std::cos(glm::radians(SwitchExtension->fOffset));
|
cosa = -hlen * std::cos(glm::radians(SwitchExtension->fOffset));
|
||||||
SwitchExtension->vTrans = ac->TransGet();
|
SwitchExtension->vTrans = ac->TransGet();
|
||||||
vector3 middle =
|
vector3 middle =
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
SwitchExtension->pMyNode->pCenter +
|
SwitchExtension->pMyNode->pCenter +
|
||||||
|
#else
|
||||||
|
SwitchExtension->pMyNode->area().center +
|
||||||
|
#endif
|
||||||
SwitchExtension->vTrans; // SwitchExtension->Segments[0]->FastGetPoint(0.5);
|
SwitchExtension->vTrans; // SwitchExtension->Segments[0]->FastGetPoint(0.5);
|
||||||
Segment->Init(middle + vector3(sina, 0.0, cosa),
|
Segment->Init(middle + vector3(sina, 0.0, cosa),
|
||||||
middle - vector3(sina, 0.0, cosa), 5.0); // nowy odcinek
|
middle - vector3(sina, 0.0, cosa), 5.0); // nowy odcinek
|
||||||
@@ -2774,6 +2789,11 @@ TTrack * TTrack::Connected(int s, double &d) const
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
path_table::~path_table() {
|
||||||
|
|
||||||
|
TIsolated::DeleteAll();
|
||||||
|
}
|
||||||
|
|
||||||
// legacy method, initializes tracks after deserialization from scenario file
|
// legacy method, initializes tracks after deserialization from scenario file
|
||||||
void
|
void
|
||||||
path_table::InitTracks() {
|
path_table::InitTracks() {
|
||||||
@@ -2957,3 +2977,46 @@ path_table::InitTracks() {
|
|||||||
isolated = isolated->Next();
|
isolated = isolated->Next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// legacy method, sends list of occupied paths over network
|
||||||
|
void
|
||||||
|
path_table::TrackBusyList() const {
|
||||||
|
// wysłanie informacji o wszystkich zajętych odcinkach
|
||||||
|
for( auto const *path : m_items ) {
|
||||||
|
if( ( false == path->name().empty() ) // musi być nazwa
|
||||||
|
&& ( false == path->Dynamics.empty() ) ) {
|
||||||
|
// zajęty
|
||||||
|
multiplayer::WyslijString( path->name(), 8 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// legacy method, sends list of occupied path sections over network
|
||||||
|
void
|
||||||
|
path_table::IsolatedBusyList() const {
|
||||||
|
// wysłanie informacji o wszystkich odcinkach izolowanych
|
||||||
|
TIsolated *Current;
|
||||||
|
for( Current = TIsolated::Root(); Current; Current = Current->Next() ) {
|
||||||
|
|
||||||
|
if( Current->Busy() ) { multiplayer::WyslijString( Current->asName, 11 ); }
|
||||||
|
else { multiplayer::WyslijString( Current->asName, 10 ); }
|
||||||
|
}
|
||||||
|
multiplayer::WyslijString( "none", 10 ); // informacja o końcu listy
|
||||||
|
}
|
||||||
|
|
||||||
|
// legacy method, sends state of specified path section over network
|
||||||
|
void
|
||||||
|
path_table::IsolatedBusy( std::string const &Name ) const {
|
||||||
|
// wysłanie informacji o odcinku izolowanym (t)
|
||||||
|
// Ra 2014-06: do wyszukania użyć drzewka nazw
|
||||||
|
TIsolated *Current;
|
||||||
|
for( Current = TIsolated::Root(); Current; Current = Current->Next() ) {
|
||||||
|
if( Current->asName == Name ) {
|
||||||
|
if( Current->Busy() ) { multiplayer::WyslijString( Current->asName, 11 ); }
|
||||||
|
else { multiplayer::WyslijString( Current->asName, 10 ); }
|
||||||
|
// nie sprawdzaj dalszych
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
multiplayer::WyslijString( Name, 10 ); // wolny (technically not found but, eh)
|
||||||
|
}
|
||||||
|
|||||||
34
Track.h
34
Track.h
@@ -13,11 +13,15 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
#include "scenenode.h"
|
|
||||||
#include "Segment.h"
|
#include "Segment.h"
|
||||||
#include "material.h"
|
#include "material.h"
|
||||||
|
#include "scenenode.h"
|
||||||
#include "names.h"
|
#include "names.h"
|
||||||
|
|
||||||
|
namespace scene {
|
||||||
|
class basic_cell;
|
||||||
|
}
|
||||||
|
|
||||||
enum TTrackType {
|
enum TTrackType {
|
||||||
tt_Unknown,
|
tt_Unknown,
|
||||||
tt_Normal,
|
tt_Normal,
|
||||||
@@ -71,7 +75,11 @@ class TSwitchExtension
|
|||||||
};
|
};
|
||||||
struct
|
struct
|
||||||
{ // zmienne potrzebne tylko dla obrotnicy/przesuwnicy
|
{ // zmienne potrzebne tylko dla obrotnicy/przesuwnicy
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TGroundNode *pMyNode; // dla obrotnicy do wtórnego podłączania torów
|
TGroundNode *pMyNode; // dla obrotnicy do wtórnego podłączania torów
|
||||||
|
#else
|
||||||
|
scene::basic_cell *pMyNode; // TODO: convert this to observer pattern
|
||||||
|
#endif
|
||||||
// TAnimContainer *pAnim; //animator modelu dla obrotnicy
|
// TAnimContainer *pAnim; //animator modelu dla obrotnicy
|
||||||
TAnimModel *pModel; // na razie model
|
TAnimModel *pModel; // na razie model
|
||||||
};
|
};
|
||||||
@@ -83,7 +91,11 @@ class TSwitchExtension
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
bool bMovement = false; // czy w trakcie animacji
|
bool bMovement = false; // czy w trakcie animacji
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TSubRect *pOwner = nullptr; // sektor, któremu trzeba zgłosić animację
|
TSubRect *pOwner = nullptr; // sektor, któremu trzeba zgłosić animację
|
||||||
|
#else
|
||||||
|
scene::basic_cell *pOwner = nullptr; // TODO: convert this to observer pattern
|
||||||
|
#endif
|
||||||
TTrack *pNextAnim = nullptr; // następny tor do animowania
|
TTrack *pNextAnim = nullptr; // następny tor do animowania
|
||||||
TEvent *evPlus = nullptr,
|
TEvent *evPlus = nullptr,
|
||||||
*evMinus = nullptr; // zdarzenia sygnalizacji rozprucia
|
*evMinus = nullptr; // zdarzenia sygnalizacji rozprucia
|
||||||
@@ -103,6 +115,7 @@ class TIsolated
|
|||||||
TMemCell *pMemCell = nullptr; // automatyczna komórka pamięci, która współpracuje z odcinkiem izolowanym
|
TMemCell *pMemCell = nullptr; // automatyczna komórka pamięci, która współpracuje z odcinkiem izolowanym
|
||||||
TIsolated();
|
TIsolated();
|
||||||
TIsolated(const std::string &n, TIsolated *i);
|
TIsolated(const std::string &n, TIsolated *i);
|
||||||
|
static void DeleteAll();
|
||||||
static TIsolated * Find(const std::string &n); // znalezienie obiektu albo utworzenie nowego
|
static TIsolated * Find(const std::string &n); // znalezienie obiektu albo utworzenie nowego
|
||||||
void Modify(int i, TDynamicObject *o); // dodanie lub odjęcie osi
|
void Modify(int i, TDynamicObject *o); // dodanie lub odjęcie osi
|
||||||
bool Busy() {
|
bool Busy() {
|
||||||
@@ -245,11 +258,20 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
void RenderDynSounds(); // odtwarzanie dźwięków pojazdów jest niezależne od ich wyświetlania
|
void RenderDynSounds(); // odtwarzanie dźwięków pojazdów jest niezależne od ich wyświetlania
|
||||||
|
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
void RaOwnerSet(TSubRect *o) {
|
void RaOwnerSet(TSubRect *o) {
|
||||||
if (SwitchExtension)
|
if (SwitchExtension)
|
||||||
SwitchExtension->pOwner = o; };
|
SwitchExtension->pOwner = o; };
|
||||||
|
#else
|
||||||
|
void RaOwnerSet( scene::basic_cell *o ) {
|
||||||
|
if( SwitchExtension ) { SwitchExtension->pOwner = o; } };
|
||||||
|
#endif
|
||||||
bool InMovement(); // czy w trakcie animacji?
|
bool InMovement(); // czy w trakcie animacji?
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
void RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined);
|
void RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined);
|
||||||
|
#else
|
||||||
|
void RaAssign( scene::basic_cell *gn, TAnimModel *am, TEvent *done, TEvent *joined );
|
||||||
|
#endif
|
||||||
void RaAnimListAdd(TTrack *t);
|
void RaAnimListAdd(TTrack *t);
|
||||||
TTrack * RaAnimate();
|
TTrack * RaAnimate();
|
||||||
|
|
||||||
@@ -278,9 +300,19 @@ public:
|
|||||||
class path_table : public basic_table<TTrack> {
|
class path_table : public basic_table<TTrack> {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
~path_table();
|
||||||
// legacy method, initializes tracks after deserialization from scenario file
|
// legacy method, initializes tracks after deserialization from scenario file
|
||||||
void
|
void
|
||||||
InitTracks();
|
InitTracks();
|
||||||
|
// legacy method, sends list of occupied paths over network
|
||||||
|
void
|
||||||
|
TrackBusyList() const;
|
||||||
|
// legacy method, sends list of occupied path sections over network
|
||||||
|
void
|
||||||
|
IsolatedBusyList() const;
|
||||||
|
// legacy method, sends state of specified path section over network
|
||||||
|
void
|
||||||
|
IsolatedBusy( std::string const &Name ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
78
World.cpp
78
World.cpp
@@ -318,6 +318,8 @@ bool TWorld::Init( GLFWwindow *Window ) {
|
|||||||
Controlled = NULL;
|
Controlled = NULL;
|
||||||
mvControlled = NULL;
|
mvControlled = NULL;
|
||||||
Camera.Type = tp_Free;
|
Camera.Type = tp_Free;
|
||||||
|
DebugCamera = Camera;
|
||||||
|
Global::DebugCameraPosition = DebugCamera.Pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!Global::bMultiplayer) //na razie włączone
|
// if (!Global::bMultiplayer) //na razie włączone
|
||||||
@@ -543,7 +545,7 @@ void TWorld::OnKeyDown(int cKey)
|
|||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TDynamicObject *tmp = Ground.DynamicNearest( Camera.Pos, 50, true ); //łapiemy z obsadą
|
TDynamicObject *tmp = Ground.DynamicNearest( Camera.Pos, 50, true ); //łapiemy z obsadą
|
||||||
#else
|
#else
|
||||||
TDynamicObject *tmp = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 50, true ) );
|
TDynamicObject *tmp = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 50, true, false ) );
|
||||||
#endif
|
#endif
|
||||||
if( ( tmp != nullptr )
|
if( ( tmp != nullptr )
|
||||||
&& ( tmp != Controlled ) ) {
|
&& ( tmp != Controlled ) ) {
|
||||||
@@ -688,8 +690,12 @@ void TWorld::OnKeyDown(int cKey)
|
|||||||
}
|
}
|
||||||
else if( ( cKey == GLFW_KEY_PAUSE ) && ( Global::ctrlState ) && ( Global::shiftState ) ) {
|
else if( ( cKey == GLFW_KEY_PAUSE ) && ( Global::ctrlState ) && ( Global::shiftState ) ) {
|
||||||
//[Ctrl]+[Break] hamowanie wszystkich pojazdów w okolicy // added shift to prevent odd issue with glfw producing pause presses on its own
|
//[Ctrl]+[Break] hamowanie wszystkich pojazdów w okolicy // added shift to prevent odd issue with glfw producing pause presses on its own
|
||||||
if (Controlled->MoverParameters->Radio)
|
if( Controlled->MoverParameters->Radio )
|
||||||
Ground.RadioStop(Camera.Pos);
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
|
Ground.RadioStop( Camera.Pos );
|
||||||
|
#else
|
||||||
|
simulation::Region->RadioStop( Camera.Pos );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (!Global::iPause) //||(cKey==VK_F4)) //podczas pauzy sterownaie nie działa, F4 tak
|
else if (!Global::iPause) //||(cKey==VK_F4)) //podczas pauzy sterownaie nie działa, F4 tak
|
||||||
if (Train)
|
if (Train)
|
||||||
@@ -725,7 +731,7 @@ void TWorld::OnKeyDown(int cKey)
|
|||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TDynamicObject *temp = Global::DynamicNearest();
|
TDynamicObject *temp = Global::DynamicNearest();
|
||||||
#else
|
#else
|
||||||
TDynamicObject *temp = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 20, false ) );
|
TDynamicObject *temp = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 20, false, false ) );
|
||||||
#endif
|
#endif
|
||||||
if (temp)
|
if (temp)
|
||||||
{
|
{
|
||||||
@@ -739,7 +745,11 @@ void TWorld::OnKeyDown(int cKey)
|
|||||||
}
|
}
|
||||||
else if (cKey == Global::Keys[k_EndSign])
|
else if (cKey == Global::Keys[k_EndSign])
|
||||||
{ // Ra 2014-07: zabrane z kabiny
|
{ // Ra 2014-07: zabrane z kabiny
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TDynamicObject *tmp = Global::CouplerNearest(); // domyślnie wyszukuje do 20m
|
TDynamicObject *tmp = Global::CouplerNearest(); // domyślnie wyszukuje do 20m
|
||||||
|
#else
|
||||||
|
TDynamicObject *tmp = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 20, false, true ) );
|
||||||
|
#endif
|
||||||
if (tmp)
|
if (tmp)
|
||||||
{
|
{
|
||||||
int CouplNr = (LengthSquared3(tmp->HeadPosition() - Camera.Pos) >
|
int CouplNr = (LengthSquared3(tmp->HeadPosition() - Camera.Pos) >
|
||||||
@@ -772,7 +782,7 @@ void TWorld::OnKeyDown(int cKey)
|
|||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TDynamicObject *temp = Global::DynamicNearest();
|
TDynamicObject *temp = Global::DynamicNearest();
|
||||||
#else
|
#else
|
||||||
TDynamicObject *temp = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 20, false ) );
|
TDynamicObject *temp = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 20, false, false ) );
|
||||||
#endif
|
#endif
|
||||||
if (temp)
|
if (temp)
|
||||||
{
|
{
|
||||||
@@ -795,7 +805,7 @@ void TWorld::OnKeyDown(int cKey)
|
|||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TDynamicObject *temp = Global::DynamicNearest();
|
TDynamicObject *temp = Global::DynamicNearest();
|
||||||
#else
|
#else
|
||||||
TDynamicObject *temp = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 20, false ) );
|
TDynamicObject *temp = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 20, false, false ) );
|
||||||
#endif
|
#endif
|
||||||
if (temp)
|
if (temp)
|
||||||
{
|
{
|
||||||
@@ -835,6 +845,8 @@ void TWorld::InOutKey( bool const Near )
|
|||||||
Train->Dynamic()->bDisplayCab = false;
|
Train->Dynamic()->bDisplayCab = false;
|
||||||
DistantView( Near );
|
DistantView( Near );
|
||||||
}
|
}
|
||||||
|
DebugCamera = Camera;
|
||||||
|
Global::DebugCameraPosition = DebugCamera.Pos;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // jazda w kabinie
|
{ // jazda w kabinie
|
||||||
@@ -1172,9 +1184,9 @@ TWorld::Update_Camera( double const Deltatime ) {
|
|||||||
if( !d )
|
if( !d )
|
||||||
d = Ground.DynamicNearest( Camera.Pos, 1000 ); // dalej szukanie, jesli bliżej nie ma
|
d = Ground.DynamicNearest( Camera.Pos, 1000 ); // dalej szukanie, jesli bliżej nie ma
|
||||||
#else
|
#else
|
||||||
TDynamicObject *d = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 300, false ) );
|
TDynamicObject *d = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 300, false, false ) );
|
||||||
if( !d )
|
if( !d )
|
||||||
d = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 1000, false ) ); // dalej szukanie, jesli bliżej nie ma
|
d = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 1000, false, false ) ); // dalej szukanie, jesli bliżej nie ma
|
||||||
#endif
|
#endif
|
||||||
if( d && pDynamicNearest ) {
|
if( d && pDynamicNearest ) {
|
||||||
// jeśli jakiś jest znaleziony wcześniej
|
// jeśli jakiś jest znaleziony wcześniej
|
||||||
@@ -1361,7 +1373,7 @@ TWorld::Update_UI() {
|
|||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
Ground.DynamicNearest( Camera.Pos ) :
|
Ground.DynamicNearest( Camera.Pos ) :
|
||||||
#else
|
#else
|
||||||
std::get<TDynamicObject *>( simulation::Region->find_vehicle( Camera.Pos, 20, false ) ) :
|
std::get<TDynamicObject *>( simulation::Region->find_vehicle( Camera.Pos, 20, false, false ) ) :
|
||||||
#endif
|
#endif
|
||||||
Controlled ); // w trybie latania lokalizujemy wg mapy
|
Controlled ); // w trybie latania lokalizujemy wg mapy
|
||||||
|
|
||||||
@@ -1446,7 +1458,7 @@ TWorld::Update_UI() {
|
|||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
Ground.DynamicNearest( Camera.Pos ) :
|
Ground.DynamicNearest( Camera.Pos ) :
|
||||||
#else
|
#else
|
||||||
std::get<TDynamicObject *>( simulation::Region->find_vehicle( Camera.Pos, 20, false ) ) :
|
std::get<TDynamicObject *>( simulation::Region->find_vehicle( Camera.Pos, 20, false, false ) ) :
|
||||||
#endif
|
#endif
|
||||||
Controlled ); // w trybie latania lokalizujemy wg mapy
|
Controlled ); // w trybie latania lokalizujemy wg mapy
|
||||||
|
|
||||||
@@ -1714,7 +1726,7 @@ TWorld::Update_UI() {
|
|||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
Ground.DynamicNearest( Camera.Pos ) :
|
Ground.DynamicNearest( Camera.Pos ) :
|
||||||
#else
|
#else
|
||||||
std::get<TDynamicObject *>( simulation::Region->find_vehicle( Camera.Pos, 20, false ) ) :
|
std::get<TDynamicObject *>( simulation::Region->find_vehicle( Camera.Pos, 20, false, false ) ) :
|
||||||
#endif
|
#endif
|
||||||
Controlled ); // w trybie latania lokalizujemy wg mapy
|
Controlled ); // w trybie latania lokalizujemy wg mapy
|
||||||
if( tmp == nullptr ) {
|
if( tmp == nullptr ) {
|
||||||
@@ -1908,7 +1920,6 @@ void TWorld::OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
|||||||
std::string( pRozkaz->cString + 1, (unsigned)( pRozkaz->cString[ 0 ] ) ) + " rcvd" );
|
std::string( pRozkaz->cString + 1, (unsigned)( pRozkaz->cString[ 0 ] ) ) + " rcvd" );
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
if( Global::iMultiplayer ) {
|
if( Global::iMultiplayer ) {
|
||||||
// WriteLog("Komunikat: "+AnsiString(pRozkaz->Name1));
|
|
||||||
TEvent *e = Ground.FindEvent(
|
TEvent *e = Ground.FindEvent(
|
||||||
std::string( pRozkaz->cString + 1, (unsigned)( pRozkaz->cString[ 0 ] ) ) );
|
std::string( pRozkaz->cString + 1, (unsigned)( pRozkaz->cString[ 0 ] ) ) );
|
||||||
if( e )
|
if( e )
|
||||||
@@ -1918,7 +1929,6 @@ void TWorld::OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if( Global::iMultiplayer ) {
|
if( Global::iMultiplayer ) {
|
||||||
// WriteLog("Komunikat: "+AnsiString(pRozkaz->Name1));
|
|
||||||
auto *event = simulation::Events.FindEvent( std::string( pRozkaz->cString + 1, (unsigned)( pRozkaz->cString[ 0 ] ) ) );
|
auto *event = simulation::Events.FindEvent( std::string( pRozkaz->cString + 1, (unsigned)( pRozkaz->cString[ 0 ] ) ) );
|
||||||
if( event != nullptr ) {
|
if( event != nullptr ) {
|
||||||
if( ( event->Type == tp_Multiple )
|
if( ( event->Type == tp_Multiple )
|
||||||
@@ -2027,7 +2037,6 @@ void TWorld::OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
|||||||
if (t)
|
if (t)
|
||||||
multiplayer::WyslijNamiary(t); // wysłanie informacji o pojeździe
|
multiplayer::WyslijNamiary(t); // wysłanie informacji o pojeździe
|
||||||
#else
|
#else
|
||||||
/*
|
|
||||||
// TODO: re-enable when messaging component is in place
|
// TODO: re-enable when messaging component is in place
|
||||||
auto *vehicle = (
|
auto *vehicle = (
|
||||||
pRozkaz->cString[ 1 ] == '*' ?
|
pRozkaz->cString[ 1 ] == '*' ?
|
||||||
@@ -2036,27 +2045,42 @@ void TWorld::OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
|||||||
if( vehicle != nullptr ) {
|
if( vehicle != nullptr ) {
|
||||||
multiplayer::WyslijNamiary( vehicle ); // wysłanie informacji o pojeździe
|
multiplayer::WyslijNamiary( vehicle ); // wysłanie informacji o pojeździe
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// dla pustego wysyłamy ramki 6 z nazwami pojazdów AI (jeśli potrzebne wszystkie, to rozpoznać np. "*")
|
// dla pustego wysyłamy ramki 6 z nazwami pojazdów AI (jeśli potrzebne wszystkie, to rozpoznać np. "*")
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
Ground.DynamicList();
|
Ground.DynamicList();
|
||||||
|
#else
|
||||||
|
simulation::Vehicles.DynamicList();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 8: // ponowne wysłanie informacji o zajętych odcinkach toru
|
case 8: // ponowne wysłanie informacji o zajętych odcinkach toru
|
||||||
CommLog(Now() + " " + to_string(pRozkaz->iComm) + " all busy track" + " rcvd");
|
CommLog(Now() + " " + to_string(pRozkaz->iComm) + " all busy track" + " rcvd");
|
||||||
Ground.TrackBusyList();
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
|
Ground.TrackBusyList();
|
||||||
|
#else
|
||||||
|
simulation::Paths.TrackBusyList();
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case 9: // ponowne wysłanie informacji o zajętych odcinkach izolowanych
|
case 9: // ponowne wysłanie informacji o zajętych odcinkach izolowanych
|
||||||
CommLog(Now() + " " + to_string(pRozkaz->iComm) + " all busy isolated" + " rcvd");
|
CommLog(Now() + " " + to_string(pRozkaz->iComm) + " all busy isolated" + " rcvd");
|
||||||
Ground.IsolatedBusyList();
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
|
Ground.IsolatedBusyList();
|
||||||
|
#else
|
||||||
|
simulation::Paths.IsolatedBusyList();
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case 10: // badanie zajętości jednego odcinka izolowanego
|
case 10: // badanie zajętości jednego odcinka izolowanego
|
||||||
CommLog(Now() + " " + to_string(pRozkaz->iComm) + " " +
|
CommLog(Now() + " " + to_string(pRozkaz->iComm) + " " +
|
||||||
std::string(pRozkaz->cString + 1, (unsigned)(pRozkaz->cString[0])) + " rcvd");
|
std::string(pRozkaz->cString + 1, (unsigned)(pRozkaz->cString[0])) + " rcvd");
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
Ground.IsolatedBusy(std::string(pRozkaz->cString + 1, (unsigned)(pRozkaz->cString[0])));
|
Ground.IsolatedBusy(std::string(pRozkaz->cString + 1, (unsigned)(pRozkaz->cString[0])));
|
||||||
|
#else
|
||||||
|
simulation::Paths.IsolatedBusy( std::string( pRozkaz->cString + 1, (unsigned)( pRozkaz->cString[ 0 ] ) ) );
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case 11: // ustawienie parametrów ruchu pojazdu
|
case 11: // ustawienie parametrów ruchu pojazdu
|
||||||
// Ground.IsolatedBusy(AnsiString(pRozkaz->cString+1,(unsigned)(pRozkaz->cString[0])));
|
// Ground.IsolatedBusy(AnsiString(pRozkaz->cString+1,(unsigned)(pRozkaz->cString[0])));
|
||||||
@@ -2096,7 +2120,25 @@ void TWorld::OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// TODO: implement
|
if( pRozkaz->cString[ 1 ] ) // jeśli długość nazwy jest niezerowa
|
||||||
|
{ // szukamy pierwszego pojazdu o takiej nazwie i odsyłamy parametry ramką #13
|
||||||
|
auto *lookup = (
|
||||||
|
pRozkaz->cString[ 2 ] == '*' ?
|
||||||
|
simulation::Vehicles.find( Global::asHumanCtrlVehicle ) : // nazwa pojazdu użytkownika
|
||||||
|
simulation::Vehicles.find( std::string( pRozkaz->cString + 2, (unsigned)pRozkaz->cString[ 1 ] ) ) ); // nazwa pojazdu
|
||||||
|
if( lookup == nullptr ) { break; } // nothing found, nothing to do
|
||||||
|
auto *d { lookup };
|
||||||
|
while( d != nullptr ) {
|
||||||
|
d->Damage( pRozkaz->cString[ 0 ] );
|
||||||
|
d = d->Next(); // pozostałe też
|
||||||
|
}
|
||||||
|
d = lookup->Prev();
|
||||||
|
while( d != nullptr ) {
|
||||||
|
d->Damage( pRozkaz->cString[ 0 ] );
|
||||||
|
d = d->Prev(); // w drugą stronę też
|
||||||
|
}
|
||||||
|
multiplayer::WyslijUszkodzenia( lookup->asName, lookup->MoverParameters->EngDmgFlag ); // zwrot informacji o pojeździe
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ WyslijWolny(const std::string &t)
|
|||||||
WyslijString(t, 4); // tor wolny
|
WyslijString(t, 4); // tor wolny
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
void
|
void
|
||||||
WyslijNamiary(TGroundNode *t)
|
WyslijNamiary(TGroundNode *t)
|
||||||
{ // wysłanie informacji o pojeździe - (float), długość ramki będzie zwiększana w miarę potrzeby
|
{ // wysłanie informacji o pojeździe - (float), długość ramki będzie zwiększana w miarę potrzeby
|
||||||
@@ -169,6 +170,84 @@ WyslijNamiary(TGroundNode *t)
|
|||||||
// WriteLog("Ramka poszla!");
|
// WriteLog("Ramka poszla!");
|
||||||
CommLog( Now() + " " + std::to_string(r.iComm) + " " + t->asName + " sent");
|
CommLog( Now() + " " + std::to_string(r.iComm) + " " + t->asName + " sent");
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void
|
||||||
|
WyslijNamiary(TDynamicObject const *Vehicle)
|
||||||
|
{ // wysłanie informacji o pojeździe - (float), długość ramki będzie zwiększana w miarę potrzeby
|
||||||
|
// WriteLog("Wysylam pojazd");
|
||||||
|
DaneRozkaz r;
|
||||||
|
r.iSygn = MAKE_ID4( 'E', 'U', '0', '7' );
|
||||||
|
r.iComm = 7; // 7 - dane pojazdu
|
||||||
|
int i = 32;
|
||||||
|
size_t j = Vehicle->asName.length();
|
||||||
|
r.iPar[0] = i; // ilość danych liczbowych
|
||||||
|
r.fPar[1] = Global::fTimeAngleDeg / 360.0; // aktualny czas (1.0=doba)
|
||||||
|
r.fPar[2] = Vehicle->MoverParameters->Loc.X; // pozycja X
|
||||||
|
r.fPar[3] = Vehicle->MoverParameters->Loc.Y; // pozycja Y
|
||||||
|
r.fPar[4] = Vehicle->MoverParameters->Loc.Z; // pozycja Z
|
||||||
|
r.fPar[5] = Vehicle->MoverParameters->V; // prędkość ruchu X
|
||||||
|
r.fPar[6] = Vehicle->MoverParameters->nrot * M_PI *
|
||||||
|
Vehicle->MoverParameters->WheelDiameter; // prędkość obrotowa kóŁ
|
||||||
|
r.fPar[7] = 0; // prędkość ruchu Z
|
||||||
|
r.fPar[8] = Vehicle->MoverParameters->AccS; // przyspieszenie X
|
||||||
|
r.fPar[9] = Vehicle->MoverParameters->AccN; // przyspieszenie Y //na razie nie
|
||||||
|
r.fPar[10] = Vehicle->MoverParameters->AccV; // przyspieszenie Z
|
||||||
|
r.fPar[11] = Vehicle->MoverParameters->DistCounter; // przejechana odległość w km
|
||||||
|
r.fPar[12] = Vehicle->MoverParameters->PipePress; // ciśnienie w PG
|
||||||
|
r.fPar[13] = Vehicle->MoverParameters->ScndPipePress; // ciśnienie w PZ
|
||||||
|
r.fPar[14] = Vehicle->MoverParameters->BrakePress; // ciśnienie w CH
|
||||||
|
r.fPar[15] = Vehicle->MoverParameters->Compressor; // ciśnienie w ZG
|
||||||
|
r.fPar[16] = Vehicle->MoverParameters->Itot; // Prąd całkowity
|
||||||
|
r.iPar[17] = Vehicle->MoverParameters->MainCtrlPos; // Pozycja NJ
|
||||||
|
r.iPar[18] = Vehicle->MoverParameters->ScndCtrlPos; // Pozycja NB
|
||||||
|
r.iPar[19] = Vehicle->MoverParameters->MainCtrlActualPos; // Pozycja jezdna
|
||||||
|
r.iPar[20] = Vehicle->MoverParameters->ScndCtrlActualPos; // Pozycja bocznikowania
|
||||||
|
r.iPar[21] = Vehicle->MoverParameters->ScndCtrlActualPos; // Pozycja bocznikowania
|
||||||
|
r.iPar[22] = Vehicle->MoverParameters->ResistorsFlag * 1 +
|
||||||
|
Vehicle->MoverParameters->ConverterFlag * 2 +
|
||||||
|
+Vehicle->MoverParameters->CompressorFlag * 4 +
|
||||||
|
Vehicle->MoverParameters->Mains * 8 +
|
||||||
|
+Vehicle->MoverParameters->DoorLeftOpened * 16 +
|
||||||
|
Vehicle->MoverParameters->DoorRightOpened * 32 +
|
||||||
|
+Vehicle->MoverParameters->FuseFlag * 64 +
|
||||||
|
Vehicle->MoverParameters->DepartureSignal * 128;
|
||||||
|
// WriteLog("Zapisalem stare");
|
||||||
|
// WriteLog("Mam patykow "+IntToStr(t->DynamicObject->iAnimType[ANIM_PANTS]));
|
||||||
|
for (int p = 0; p < 4; p++)
|
||||||
|
{
|
||||||
|
// WriteLog("Probuje pant "+IntToStr(p));
|
||||||
|
if (p < Vehicle->iAnimType[ANIM_PANTS])
|
||||||
|
{
|
||||||
|
r.fPar[23 + p] = Vehicle->pants[p].fParamPants->PantWys; // stan pantografów 4
|
||||||
|
// WriteLog("Zapisalem pant "+IntToStr(p));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r.fPar[23 + p] = -2;
|
||||||
|
// WriteLog("Nie mam pant "+IntToStr(p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// WriteLog("Zapisalem pantografy");
|
||||||
|
for (int p = 0; p < 3; p++)
|
||||||
|
r.fPar[27 + p] =
|
||||||
|
Vehicle->MoverParameters->ShowCurrent(p + 1); // amperomierze kolejnych grup
|
||||||
|
// WriteLog("zapisalem prady");
|
||||||
|
r.iPar[30] = Vehicle->MoverParameters->WarningSignal; // trabienie
|
||||||
|
r.fPar[31] = Vehicle->MoverParameters->RunningTraction.TractionVoltage; // napiecie WN
|
||||||
|
// WriteLog("Parametry gotowe");
|
||||||
|
i <<= 2; // ilość bajtów
|
||||||
|
r.cString[i] = char(j); // na końcu nazwa, żeby jakoś zidentyfikować
|
||||||
|
strcpy(r.cString + i + 1, Vehicle->asName.c_str()); // zakończony zerem
|
||||||
|
COPYDATASTRUCT cData;
|
||||||
|
cData.dwData = MAKE_ID4( 'E', 'U', '0', '7' ); // sygnatura
|
||||||
|
cData.cbData = (DWORD)(10 + i + j); // 8+licznik i zero kończące
|
||||||
|
cData.lpData = &r;
|
||||||
|
// WriteLog("Ramka gotowa");
|
||||||
|
Navigate( "TEU07SRK", WM_COPYDATA, (WPARAM)glfwGetWin32Window( Global::window ), (LPARAM)&cData );
|
||||||
|
// WriteLog("Ramka poszla!");
|
||||||
|
CommLog( Now() + " " + std::to_string(r.iComm) + " " + Vehicle->asName + " sent");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
WyslijObsadzone()
|
WyslijObsadzone()
|
||||||
|
|||||||
@@ -11,7 +11,11 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
class TGroundNode;
|
class TGroundNode;
|
||||||
|
#else
|
||||||
|
class TDynamicObject;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace multiplayer {
|
namespace multiplayer {
|
||||||
|
|
||||||
@@ -40,7 +44,11 @@ void Navigate( std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lPa
|
|||||||
void WyslijEvent( const std::string &e, const std::string &d );
|
void WyslijEvent( const std::string &e, const std::string &d );
|
||||||
void WyslijString( const std::string &t, int n );
|
void WyslijString( const std::string &t, int n );
|
||||||
void WyslijWolny( const std::string &t );
|
void WyslijWolny( const std::string &t );
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
void WyslijNamiary( TGroundNode *t );
|
void WyslijNamiary( TGroundNode *t );
|
||||||
|
#else
|
||||||
|
void WyslijNamiary( TDynamicObject const *Vehicle );
|
||||||
|
#endif
|
||||||
void WyslijParam( int nr, int fl );
|
void WyslijParam( int nr, int fl );
|
||||||
void WyslijUszkodzenia( const std::string &t, char fl );
|
void WyslijUszkodzenia( const std::string &t, char fl );
|
||||||
void WyslijObsadzone(); // -> skladanie wielu pojazdow
|
void WyslijObsadzone(); // -> skladanie wielu pojazdow
|
||||||
|
|||||||
109
renderer.cpp
109
renderer.cpp
@@ -349,6 +349,15 @@ opengl_renderer::Render() {
|
|||||||
void
|
void
|
||||||
opengl_renderer::Render_pass( rendermode const Mode ) {
|
opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||||
|
|
||||||
|
#ifdef EU07_USE_DEBUG_CAMERA
|
||||||
|
// setup world camera for potential visualization
|
||||||
|
setup_pass(
|
||||||
|
m_worldcamera,
|
||||||
|
rendermode::color,
|
||||||
|
0.f,
|
||||||
|
1.0,
|
||||||
|
true );
|
||||||
|
#endif
|
||||||
setup_pass( m_renderpass, Mode );
|
setup_pass( m_renderpass, Mode );
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
|
|
||||||
@@ -365,14 +374,6 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
#endif
|
#endif
|
||||||
shadowcamera = m_renderpass.camera; // cache shadow camera placement for visualization
|
shadowcamera = m_renderpass.camera; // cache shadow camera placement for visualization
|
||||||
setup_pass( m_renderpass, Mode ); // restore draw mode. TBD, TODO: render mode stack
|
setup_pass( m_renderpass, Mode ); // restore draw mode. TBD, TODO: render mode stack
|
||||||
#ifdef EU07_USE_DEBUG_CAMERA
|
|
||||||
setup_pass(
|
|
||||||
m_worldcamera,
|
|
||||||
rendermode::color,
|
|
||||||
0.f,
|
|
||||||
1.0,
|
|
||||||
true );
|
|
||||||
#endif
|
|
||||||
// setup shadowmap matrix
|
// setup shadowmap matrix
|
||||||
m_shadowtexturematrix =
|
m_shadowtexturematrix =
|
||||||
//bias from [-1, 1] to [0, 1] };
|
//bias from [-1, 1] to [0, 1] };
|
||||||
@@ -383,7 +384,6 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
glm::mat4{ glm::mat3{ shadowcamera.modelview() } },
|
glm::mat4{ glm::mat3{ shadowcamera.modelview() } },
|
||||||
glm::vec3{ m_renderpass.camera.position() - shadowcamera.position() } );
|
glm::vec3{ m_renderpass.camera.position() - shadowcamera.position() } );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( true == m_environmentcubetexturesupport )
|
if( ( true == m_environmentcubetexturesupport )
|
||||||
&& ( true == World.InitPerformed() ) ) {
|
&& ( true == World.InitPerformed() ) ) {
|
||||||
// potentially update environmental cube map
|
// potentially update environmental cube map
|
||||||
@@ -391,7 +391,6 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
setup_pass( m_renderpass, Mode ); // restore draw mode. TBD, TODO: render mode stack
|
setup_pass( m_renderpass, Mode ); // restore draw mode. TBD, TODO: render mode stack
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::glViewport( 0, 0, Global::iWindowWidth, Global::iWindowHeight );
|
::glViewport( 0, 0, Global::iWindowWidth, Global::iWindowHeight );
|
||||||
|
|
||||||
if( World.InitPerformed() ) {
|
if( World.InitPerformed() ) {
|
||||||
@@ -420,7 +419,9 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
::glColor4f( 1.f, 0.9f, 0.8f, 1.f );
|
::glColor4f( 1.f, 0.9f, 0.8f, 1.f );
|
||||||
::glDisable( GL_LIGHTING );
|
::glDisable( GL_LIGHTING );
|
||||||
::glDisable( GL_TEXTURE_2D );
|
::glDisable( GL_TEXTURE_2D );
|
||||||
shadowcamera.draw( m_renderpass.camera.position() - shadowcamera.position() );
|
if( true == Global::RenderShadows ) {
|
||||||
|
shadowcamera.draw( m_renderpass.camera.position() - shadowcamera.position() );
|
||||||
|
}
|
||||||
if( DebugCameraFlag ) {
|
if( DebugCameraFlag ) {
|
||||||
::glColor4f( 0.8f, 1.f, 0.9f, 1.f );
|
::glColor4f( 0.8f, 1.f, 0.9f, 1.f );
|
||||||
m_worldcamera.camera.draw( m_renderpass.camera.position() - m_worldcamera.camera.position() );
|
m_worldcamera.camera.draw( m_renderpass.camera.position() - m_worldcamera.camera.position() );
|
||||||
@@ -1920,7 +1921,7 @@ opengl_renderer::Render( section_sequence::iterator First, section_sequence::ite
|
|||||||
// render
|
// render
|
||||||
#ifdef EU07_USE_DEBUG_CULLING
|
#ifdef EU07_USE_DEBUG_CULLING
|
||||||
// debug
|
// debug
|
||||||
float const width = scene::EU07_SECTIONSIZE * 0.5f;
|
float const width = section->m_area.radius;
|
||||||
float const height = scene::EU07_SECTIONSIZE * 0.2f;
|
float const height = scene::EU07_SECTIONSIZE * 0.2f;
|
||||||
glDisable( GL_LIGHTING );
|
glDisable( GL_LIGHTING );
|
||||||
glDisable( GL_TEXTURE_2D );
|
glDisable( GL_TEXTURE_2D );
|
||||||
@@ -2008,11 +2009,10 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
|
|||||||
// first pass draws elements which we know are located in section banks, to reduce vbo switching
|
// first pass draws elements which we know are located in section banks, to reduce vbo switching
|
||||||
while( First != Last ) {
|
while( First != Last ) {
|
||||||
|
|
||||||
auto const *cell = First->second;
|
auto *cell = First->second;
|
||||||
/*
|
// przeliczenia animacji torów w sektorze
|
||||||
// przeliczenia animacji torów w sektorze
|
cell->RaAnimate( m_framestamp );
|
||||||
Groundsubcell->RaAnimate( m_framestamp );
|
|
||||||
*/
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::color: {
|
case rendermode::color: {
|
||||||
// since all shapes of the section share center point we can optimize out a few calls here
|
// since all shapes of the section share center point we can optimize out a few calls here
|
||||||
@@ -2023,7 +2023,7 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
|
|||||||
// render
|
// render
|
||||||
#ifdef EU07_USE_DEBUG_CULLING
|
#ifdef EU07_USE_DEBUG_CULLING
|
||||||
// debug
|
// debug
|
||||||
float const width = scene::EU07_CELLSIZE * 0.5f;
|
float const width = cell->m_area.radius;
|
||||||
float const height = scene::EU07_CELLSIZE * 0.15f;
|
float const height = scene::EU07_CELLSIZE * 0.15f;
|
||||||
glDisable( GL_LIGHTING );
|
glDisable( GL_LIGHTING );
|
||||||
glDisable( GL_TEXTURE_2D );
|
glDisable( GL_TEXTURE_2D );
|
||||||
@@ -2149,25 +2149,8 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
|
|||||||
|
|
||||||
void
|
void
|
||||||
opengl_renderer::Render( scene::shape_node const &Shape, bool const Ignorerange ) {
|
opengl_renderer::Render( scene::shape_node const &Shape, bool const Ignorerange ) {
|
||||||
/*
|
|
||||||
double distancesquared;
|
auto const &data { Shape.data() };
|
||||||
switch( m_renderpass.draw_mode ) {
|
|
||||||
case rendermode::shadows: {
|
|
||||||
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
|
||||||
distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
distancesquared = SquareMagnitude( ( Node->pCenter - m_renderpass.camera.position() ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( ( distancesquared < Node->fSquareMinRadius )
|
|
||||||
|| ( distancesquared >= Node->fSquareRadius ) ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
auto const &data{ Shape.data() };
|
|
||||||
|
|
||||||
if( false == Ignorerange ) {
|
if( false == Ignorerange ) {
|
||||||
double distancesquared;
|
double distancesquared;
|
||||||
@@ -3075,8 +3058,8 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
|
|
||||||
// render
|
// render
|
||||||
m_geometry.draw( Node->Piece->geometry );
|
m_geometry.draw( Node->Piece->geometry );
|
||||||
// ++m_debugstats.lines;
|
++m_debugstats.lines;
|
||||||
// ++m_debugstats.drawcalls;
|
++m_debugstats.drawcalls;
|
||||||
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
@@ -3183,8 +3166,9 @@ opengl_renderer::Render_Alpha( cell_sequence::reverse_iterator First, cell_seque
|
|||||||
while( first != Last ) {
|
while( first != Last ) {
|
||||||
|
|
||||||
auto const *cell = first->second;
|
auto const *cell = first->second;
|
||||||
// TODO: include lines here
|
|
||||||
if( false == cell->m_traction.empty() ) {
|
if( ( false == cell->m_traction.empty()
|
||||||
|
|| ( false == cell->m_lines.empty() ) ) ) {
|
||||||
// since all shapes of the cell share center point we can optimize out a few calls here
|
// since all shapes of the cell share center point we can optimize out a few calls here
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
auto const originoffset { cell->m_area.center - m_renderpass.camera.position() };
|
auto const originoffset { cell->m_area.center - m_renderpass.camera.position() };
|
||||||
@@ -3196,6 +3180,7 @@ opengl_renderer::Render_Alpha( cell_sequence::reverse_iterator First, cell_seque
|
|||||||
Bind_Material( null_handle );
|
Bind_Material( null_handle );
|
||||||
// render
|
// render
|
||||||
for( auto *traction : cell->m_traction ) { Render_Alpha( traction ); }
|
for( auto *traction : cell->m_traction ) { Render_Alpha( traction ); }
|
||||||
|
for( auto &lines : cell->m_lines ) { Render_Alpha( lines ); }
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
::glLineWidth( 1.0 );
|
::glLineWidth( 1.0 );
|
||||||
if( !Global::bSmoothTraction ) {
|
if( !Global::bSmoothTraction ) {
|
||||||
@@ -3287,6 +3272,48 @@ opengl_renderer::Render_Alpha( TTraction *Traction ) {
|
|||||||
++m_debugstats.traction;
|
++m_debugstats.traction;
|
||||||
++m_debugstats.drawcalls;
|
++m_debugstats.drawcalls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
opengl_renderer::Render_Alpha( scene::lines_node const &Lines ) {
|
||||||
|
|
||||||
|
auto const &data { Lines.data() };
|
||||||
|
|
||||||
|
double distancesquared;
|
||||||
|
switch( m_renderpass.draw_mode ) {
|
||||||
|
case rendermode::shadows: {
|
||||||
|
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
||||||
|
distancesquared = SquareMagnitude( ( data.area.center - Global::pCameraPosition ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
distancesquared = SquareMagnitude( ( data.area.center - m_renderpass.camera.position() ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( ( distancesquared < data.rangesquared_min )
|
||||||
|
|| ( distancesquared >= data.rangesquared_max ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// setup
|
||||||
|
auto const distance { static_cast<float>( std::sqrt( distancesquared ) ) };
|
||||||
|
auto const linealpha = (
|
||||||
|
data.line_width > 0.f ?
|
||||||
|
10.f * data.line_width
|
||||||
|
/ std::max(
|
||||||
|
0.5f * data.area.radius + 1.f,
|
||||||
|
distance - ( 0.5f * data.area.radius ) ) :
|
||||||
|
1.f ); // negative width means the lines are always opague
|
||||||
|
::glColor4fv(
|
||||||
|
glm::value_ptr(
|
||||||
|
glm::vec4{
|
||||||
|
glm::vec3{ data.lighting.diffuse * Global::DayLight.ambient }, // w zaleznosci od koloru swiatla
|
||||||
|
std::min( 1.f, linealpha ) } ) );
|
||||||
|
::glLineWidth( clamp( 0.5f * linealpha + data.line_width * data.area.radius / 1000.f, 1.f, 8.f ) );
|
||||||
|
// render
|
||||||
|
m_geometry.draw( data.geometry );
|
||||||
|
++m_debugstats.lines;
|
||||||
|
++m_debugstats.drawcalls;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
bool
|
bool
|
||||||
opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||||
|
|||||||
@@ -340,6 +340,8 @@ private:
|
|||||||
Render_Alpha( TAnimModel *Instance );
|
Render_Alpha( TAnimModel *Instance );
|
||||||
void
|
void
|
||||||
Render_Alpha( TTraction *Traction );
|
Render_Alpha( TTraction *Traction );
|
||||||
|
void
|
||||||
|
Render_Alpha( scene::lines_node const &Lines );
|
||||||
#endif
|
#endif
|
||||||
bool
|
bool
|
||||||
Render_Alpha( TDynamicObject *Dynamic );
|
Render_Alpha( TDynamicObject *Dynamic );
|
||||||
|
|||||||
298
scene.cpp
298
scene.cpp
@@ -130,6 +130,44 @@ basic_cell::update_traction( TDynamicObject *Vehicle, int const Pantographindex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// legacy method, triggers radio-stop procedure for all vehicles located on paths in the cell
|
||||||
|
void
|
||||||
|
basic_cell::radio_stop() {
|
||||||
|
|
||||||
|
for( auto *path : m_paths ) {
|
||||||
|
path->RadioStop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// legacy method, adds specified path to the list of pieces undergoing state change
|
||||||
|
bool
|
||||||
|
basic_cell::RaTrackAnimAdd( TTrack *Track ) {
|
||||||
|
|
||||||
|
if( false == m_geometrycreated ) {
|
||||||
|
// nie ma animacji, gdy nie widać
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (tTrackAnim)
|
||||||
|
tTrackAnim->RaAnimListAdd(Track);
|
||||||
|
else
|
||||||
|
tTrackAnim = Track;
|
||||||
|
return false; // będzie animowane...
|
||||||
|
}
|
||||||
|
|
||||||
|
// legacy method, updates geometry for pieces in the animation list
|
||||||
|
void
|
||||||
|
basic_cell::RaAnimate( unsigned int const Framestamp ) {
|
||||||
|
|
||||||
|
if( ( tTrackAnim == nullptr )
|
||||||
|
|| ( Framestamp == m_framestamp ) ) {
|
||||||
|
// nie ma nic do animowania
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tTrackAnim = tTrackAnim->RaAnimate(); // przeliczenie animacji kolejnego
|
||||||
|
|
||||||
|
m_framestamp = Framestamp;
|
||||||
|
}
|
||||||
|
|
||||||
// adds provided shape to the cell
|
// adds provided shape to the cell
|
||||||
void
|
void
|
||||||
basic_cell::insert( shape_node Shape ) {
|
basic_cell::insert( shape_node Shape ) {
|
||||||
@@ -160,15 +198,51 @@ basic_cell::insert( shape_node Shape ) {
|
|||||||
shapes.emplace_back( Shape );
|
shapes.emplace_back( Shape );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// adds provided lines to the cell
|
||||||
|
void
|
||||||
|
basic_cell::insert( lines_node Lines ) {
|
||||||
|
|
||||||
|
m_active = true;
|
||||||
|
|
||||||
|
auto const &linesdata { Lines.data() };
|
||||||
|
for( auto &targetlines : m_lines ) {
|
||||||
|
// try to merge shapes with matching view ranges...
|
||||||
|
auto const &targetlinesdata { targetlines.data() };
|
||||||
|
if( ( linesdata.rangesquared_min == targetlinesdata.rangesquared_min )
|
||||||
|
&& ( linesdata.rangesquared_max == targetlinesdata.rangesquared_max )
|
||||||
|
// ...and located close to each other (within arbitrary limit of 10m)
|
||||||
|
&& ( glm::length( linesdata.area.center - targetlinesdata.area.center ) < 10.0 ) ) {
|
||||||
|
|
||||||
|
if( true == targetlines.merge( Lines ) ) {
|
||||||
|
// if the shape was merged there's nothing left to do
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// otherwise add the shape to the relevant list
|
||||||
|
Lines.origin( m_area.center );
|
||||||
|
m_lines.emplace_back( Lines );
|
||||||
|
}
|
||||||
|
|
||||||
// adds provided path to the cell
|
// adds provided path to the cell
|
||||||
void
|
void
|
||||||
basic_cell::insert( TTrack *Path ) {
|
basic_cell::insert( TTrack *Path ) {
|
||||||
|
|
||||||
m_active = true;
|
m_active = true;
|
||||||
|
|
||||||
// TODO: add animation hook
|
|
||||||
Path->origin( m_area.center );
|
Path->origin( m_area.center );
|
||||||
m_paths.emplace_back( Path );
|
m_paths.emplace_back( Path );
|
||||||
|
// animation hook
|
||||||
|
#ifndef EU07_USE_OLD_GROUNDCODE
|
||||||
|
Path->RaOwnerSet( this );
|
||||||
|
#endif
|
||||||
|
// re-calculate cell radius, in case track extends outside the cell's boundaries
|
||||||
|
auto endpoints = Path->endpoints();
|
||||||
|
for( auto &endpoint : endpoints ) {
|
||||||
|
m_area.radius = std::max<float>(
|
||||||
|
m_area.radius,
|
||||||
|
glm::length( m_area.center - endpoint ) + 25.f ); // extra margin to prevent driven vehicle from flicking
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds provided traction piece to the cell
|
// adds provided traction piece to the cell
|
||||||
@@ -179,6 +253,13 @@ basic_cell::insert( TTraction *Traction ) {
|
|||||||
|
|
||||||
Traction->origin( m_area.center );
|
Traction->origin( m_area.center );
|
||||||
m_traction.emplace_back( Traction );
|
m_traction.emplace_back( Traction );
|
||||||
|
// re-calculate cell radius, in case traction piece extends outside the cell's boundaries
|
||||||
|
auto endpoints = Traction->endpoints();
|
||||||
|
for( auto &endpoint : endpoints ) {
|
||||||
|
m_area.radius = std::max<float>(
|
||||||
|
m_area.radius,
|
||||||
|
glm::length( m_area.center - endpoint ) ); // adding arbitrary safety margin
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds provided model instance to the cell
|
// adds provided model instance to the cell
|
||||||
@@ -203,6 +284,15 @@ basic_cell::insert( TAnimModel *Instance ) {
|
|||||||
// opaque pieces
|
// opaque pieces
|
||||||
m_instancesopaque.emplace_back( Instance );
|
m_instancesopaque.emplace_back( Instance );
|
||||||
}
|
}
|
||||||
|
// re-calculate cell radius, in case model extends outside the cell's boundaries
|
||||||
|
if( Instance->Model() ) {
|
||||||
|
auto const modelradius{ Instance->Model()->bounding_radius() };
|
||||||
|
if( modelradius > 0.f ) {
|
||||||
|
m_area.radius = std::max<float>(
|
||||||
|
m_area.radius,
|
||||||
|
glm::length( m_area.center - Instance->location() ) + modelradius ); // adding arbitrary safety margin
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds provided sound instance to the cell
|
// adds provided sound instance to the cell
|
||||||
@@ -251,7 +341,7 @@ basic_cell::register_end( TTraction *Traction ) {
|
|||||||
|
|
||||||
// find a vehicle located nearest to specified point, within specified radius, optionally ignoring vehicles without drivers. reurns: located vehicle and distance
|
// find a vehicle located nearest to specified point, within specified radius, optionally ignoring vehicles without drivers. reurns: located vehicle and distance
|
||||||
std::tuple<TDynamicObject *, float>
|
std::tuple<TDynamicObject *, float>
|
||||||
basic_cell::find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled ) {
|
basic_cell::find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler ) {
|
||||||
|
|
||||||
TDynamicObject *vehiclenearest { nullptr };
|
TDynamicObject *vehiclenearest { nullptr };
|
||||||
float leastdistance { std::numeric_limits<float>::max() };
|
float leastdistance { std::numeric_limits<float>::max() };
|
||||||
@@ -264,7 +354,16 @@ basic_cell::find( glm::dvec3 const &Point, float const Radius, bool const Onlyco
|
|||||||
&& ( vehicle->Mechanik == nullptr ) ) {
|
&& ( vehicle->Mechanik == nullptr ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
distance = glm::length2( glm::dvec3{ vehicle->GetPosition() } - Point );
|
if( false == Findbycoupler ) {
|
||||||
|
// basic search, checks vehicles' center points
|
||||||
|
distance = glm::length2( glm::dvec3{ vehicle->GetPosition() } - Point );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// alternative search, checks positions of vehicles' couplers
|
||||||
|
distance = std::min(
|
||||||
|
glm::length2( glm::dvec3{ vehicle->HeadPosition() } - Point ),
|
||||||
|
glm::length2( glm::dvec3{ vehicle->RearPosition() } - Point ) );
|
||||||
|
}
|
||||||
if( ( distance > distancecutoff )
|
if( ( distance > distancecutoff )
|
||||||
|| ( distance > leastdistance ) ){
|
|| ( distance > leastdistance ) ){
|
||||||
continue;
|
continue;
|
||||||
@@ -372,10 +471,13 @@ basic_cell::create_geometry( geometrybank_handle const &Bank ) {
|
|||||||
for( auto *path : m_paths ) { path->create_geometry( Bank ); }
|
for( auto *path : m_paths ) { path->create_geometry( Bank ); }
|
||||||
for( auto *traction : m_traction ) { traction->create_geometry( Bank ); }
|
for( auto *traction : m_traction ) { traction->create_geometry( Bank ); }
|
||||||
#endif
|
#endif
|
||||||
|
for( auto &lines : m_lines ) { lines.create_geometry( Bank ); }
|
||||||
// arrange content by assigned materials to minimize state switching
|
// arrange content by assigned materials to minimize state switching
|
||||||
std::sort(
|
std::sort(
|
||||||
std::begin( m_paths ), std::end( m_paths ),
|
std::begin( m_paths ), std::end( m_paths ),
|
||||||
TTrack::sort_by_material );
|
TTrack::sort_by_material );
|
||||||
|
|
||||||
|
m_geometrycreated = true; // helper for legacy animation code, get rid of it after refactoring
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -384,11 +486,9 @@ basic_cell::create_geometry( geometrybank_handle const &Bank ) {
|
|||||||
void
|
void
|
||||||
basic_section::update( glm::dvec3 const &Location, float const Radius ) {
|
basic_section::update( glm::dvec3 const &Location, float const Radius ) {
|
||||||
|
|
||||||
auto const squaredradii { std::pow( ( 0.5 * M_SQRT2 * EU07_CELLSIZE + 0.25 * EU07_CELLSIZE ) + Radius, 2 ) };
|
|
||||||
|
|
||||||
for( auto &cell : m_cells ) {
|
for( auto &cell : m_cells ) {
|
||||||
|
|
||||||
if( glm::length2( cell.area().center - Location ) < squaredradii ) {
|
if( glm::length2( cell.area().center - Location ) < ( ( cell.area().radius + Radius ) * ( cell.area().radius + Radius ) ) ) {
|
||||||
// we reject cells which aren't within our area of interest
|
// we reject cells which aren't within our area of interest
|
||||||
cell.update();
|
cell.update();
|
||||||
}
|
}
|
||||||
@@ -408,16 +508,28 @@ basic_section::update_traction( TDynamicObject *Vehicle, int const Pantographind
|
|||||||
auto const pantographposition = position + ( vLeft * pantograph->vPos.z ) + ( vUp * pantograph->vPos.y ) + ( vFront * pantograph->vPos.x );
|
auto const pantographposition = position + ( vLeft * pantograph->vPos.z ) + ( vUp * pantograph->vPos.y ) + ( vFront * pantograph->vPos.x );
|
||||||
|
|
||||||
auto const radius { 0.0 }; // { EU07_CELLSIZE * 0.5 }; // experimentally limited, check if it has any negative effect
|
auto const radius { 0.0 }; // { EU07_CELLSIZE * 0.5 }; // experimentally limited, check if it has any negative effect
|
||||||
auto const squaredradii { std::pow( ( 0.5 * M_SQRT2 * EU07_CELLSIZE + 0.25 * EU07_CELLSIZE ) + radius, 2 ) };
|
|
||||||
|
|
||||||
for( auto &cell : m_cells ) {
|
for( auto &cell : m_cells ) {
|
||||||
// we reject early cells which aren't within our area of interest
|
// we reject early cells which aren't within our area of interest
|
||||||
if( glm::length2( cell.area().center - pantographposition ) < squaredradii ) {
|
if( glm::length2( cell.area().center - pantographposition ) < ( ( cell.area().radius + radius ) * ( cell.area().radius + radius ) ) ) {
|
||||||
cell.update_traction( Vehicle, Pantographindex );
|
cell.update_traction( Vehicle, Pantographindex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// legacy method, triggers radio-stop procedure for all vehicles in 2km radius around specified location
|
||||||
|
void
|
||||||
|
basic_section::radio_stop( glm::dvec3 const &Location, float const Radius ) {
|
||||||
|
|
||||||
|
for( auto &cell : m_cells ) {
|
||||||
|
|
||||||
|
if( glm::length2( cell.area().center - Location ) < ( ( cell.area().radius + Radius ) * ( cell.area().radius + Radius ) ) ) {
|
||||||
|
// we reject cells which aren't within our area of interest
|
||||||
|
cell.radio_stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// adds provided shape to the section
|
// adds provided shape to the section
|
||||||
void
|
void
|
||||||
basic_section::insert( shape_node Shape ) {
|
basic_section::insert( shape_node Shape ) {
|
||||||
@@ -444,9 +556,16 @@ basic_section::insert( shape_node Shape ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// adds provided lines to the section
|
||||||
|
void
|
||||||
|
basic_section::insert( lines_node Lines ) {
|
||||||
|
|
||||||
|
cell( Lines.data().area.center ).insert( Lines );
|
||||||
|
}
|
||||||
|
|
||||||
// find a vehicle located nearest to specified point, within specified radius, optionally ignoring vehicles without drivers. reurns: located vehicle and distance
|
// find a vehicle located nearest to specified point, within specified radius, optionally ignoring vehicles without drivers. reurns: located vehicle and distance
|
||||||
std::tuple<TDynamicObject *, float>
|
std::tuple<TDynamicObject *, float>
|
||||||
basic_section::find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled ) {
|
basic_section::find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler ) {
|
||||||
|
|
||||||
// go through sections within radius of interest, and pick the nearest candidate
|
// go through sections within radius of interest, and pick the nearest candidate
|
||||||
TDynamicObject
|
TDynamicObject
|
||||||
@@ -456,14 +575,12 @@ basic_section::find( glm::dvec3 const &Point, float const Radius, bool const Onl
|
|||||||
distancefound,
|
distancefound,
|
||||||
distancenearest { std::numeric_limits<float>::max() };
|
distancenearest { std::numeric_limits<float>::max() };
|
||||||
|
|
||||||
auto const squaredradii { std::pow( ( 0.5 * M_SQRT2 * EU07_CELLSIZE + 0.25 * EU07_CELLSIZE ) + Radius, 2 ) };
|
|
||||||
|
|
||||||
for( auto &cell : m_cells ) {
|
for( auto &cell : m_cells ) {
|
||||||
// we reject early cells which aren't within our area of interest
|
// we reject early cells which aren't within our area of interest
|
||||||
if( glm::length2( cell.area().center - Point ) > squaredradii ) {
|
if( glm::length2( cell.area().center - Point ) > ( ( cell.area().radius + Radius ) * ( cell.area().radius + Radius ) ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
std::tie( vehiclefound, distancefound ) = cell.find( Point, Radius, Onlycontrolled );
|
std::tie( vehiclefound, distancefound ) = cell.find( Point, Radius, Onlycontrolled, Findbycoupler );
|
||||||
if( ( vehiclefound != nullptr )
|
if( ( vehiclefound != nullptr )
|
||||||
&& ( distancefound < distancenearest ) ) {
|
&& ( distancefound < distancenearest ) ) {
|
||||||
|
|
||||||
@@ -503,11 +620,10 @@ basic_section::find( glm::dvec3 const &Point, TTraction const *Other, int const
|
|||||||
endpointnearest { -1 };
|
endpointnearest { -1 };
|
||||||
|
|
||||||
auto const radius { 0.0 }; // { EU07_CELLSIZE * 0.5 }; // experimentally limited, check if it has any negative effect
|
auto const radius { 0.0 }; // { EU07_CELLSIZE * 0.5 }; // experimentally limited, check if it has any negative effect
|
||||||
auto const squaredradii { std::pow( ( 0.5 * M_SQRT2 * EU07_CELLSIZE + 0.25 * EU07_CELLSIZE ) + radius, 2 ) };
|
|
||||||
|
|
||||||
for( auto &cell : m_cells ) {
|
for( auto &cell : m_cells ) {
|
||||||
// we reject early cells which aren't within our area of interest
|
// we reject early cells which aren't within our area of interest
|
||||||
if( glm::length2( cell.area().center - Point ) > squaredradii ) {
|
if( glm::length2( cell.area().center - Point ) > ( ( cell.area().radius + radius ) * ( cell.area().radius + radius ) ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
std::tie( tractionfound, endpointfound, distancefound ) = cell.find( Point, Other, Currentdirection );
|
std::tie( tractionfound, endpointfound, distancefound ) = cell.find( Point, Other, Currentdirection );
|
||||||
@@ -618,8 +734,49 @@ basic_region::update_traction( TDynamicObject *Vehicle, int const Pantographinde
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// legacy method, links specified path piece with potential neighbours
|
||||||
void
|
void
|
||||||
basic_region::insert_shape( shape_node Shape, scratch_data &Scratchpad ) {
|
basic_region::TrackJoin( TTrack *Track ) {
|
||||||
|
// wyszukiwanie sąsiednich torów do podłączenia (wydzielone na użytek obrotnicy)
|
||||||
|
TTrack *matchingtrack;
|
||||||
|
int endpointid;
|
||||||
|
if( Track->CurrentPrev() == nullptr ) {
|
||||||
|
std::tie( matchingtrack, endpointid ) = find_path( Track->CurrentSegment()->FastGetPoint_0(), Track );
|
||||||
|
switch( endpointid ) {
|
||||||
|
case 0:
|
||||||
|
Track->ConnectPrevPrev( matchingtrack, 0 );
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Track->ConnectPrevNext( matchingtrack, 1 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( Track->CurrentNext() == nullptr ) {
|
||||||
|
std::tie( matchingtrack, endpointid ) = find_path( Track->CurrentSegment()->FastGetPoint_1(), Track );
|
||||||
|
switch( endpointid ) {
|
||||||
|
case 0:
|
||||||
|
Track->ConnectNextPrev( matchingtrack, 0 );
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Track->ConnectNextNext( matchingtrack, 1 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// legacy method, triggers radio-stop procedure for all vehicles in 2km radius around specified location
|
||||||
|
void
|
||||||
|
basic_region::RadioStop( glm::dvec3 const &Location ) {
|
||||||
|
|
||||||
|
auto const range = 2000.f;
|
||||||
|
auto const §ionlist = sections( Location, range );
|
||||||
|
for( auto *section : sectionlist ) {
|
||||||
|
section->radio_stop( Location, range );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
basic_region::insert_shape( shape_node Shape, scratch_data &Scratchpad, bool const Transform ) {
|
||||||
|
|
||||||
// shape might need to be split into smaller pieces, so we create list of nodes instead of just single one
|
// shape might need to be split into smaller pieces, so we create list of nodes instead of just single one
|
||||||
// using deque so we can do single pass iterating and addding generated pieces without invalidating anything
|
// using deque so we can do single pass iterating and addding generated pieces without invalidating anything
|
||||||
@@ -628,38 +785,41 @@ basic_region::insert_shape( shape_node Shape, scratch_data &Scratchpad ) {
|
|||||||
if( shape.m_data.vertices.empty() ) { return; }
|
if( shape.m_data.vertices.empty() ) { return; }
|
||||||
|
|
||||||
// adjust input if necessary:
|
// adjust input if necessary:
|
||||||
if( Scratchpad.location_rotation != glm::vec3( 0, 0, 0 ) ) {
|
if( true == Transform ) {
|
||||||
// rotate...
|
// shapes generated from legacy terrain come with world space coordinates and don't need processing
|
||||||
auto const rotation = glm::radians( Scratchpad.location_rotation );
|
if( Scratchpad.location_rotation != glm::vec3( 0, 0, 0 ) ) {
|
||||||
for( auto &vertex : shape.m_data.vertices ) {
|
// rotate...
|
||||||
vertex.position = glm::rotateZ<double>( vertex.position, rotation.z );
|
auto const rotation = glm::radians( Scratchpad.location_rotation );
|
||||||
vertex.position = glm::rotateX<double>( vertex.position, rotation.x );
|
for( auto &vertex : shape.m_data.vertices ) {
|
||||||
vertex.position = glm::rotateY<double>( vertex.position, rotation.y );
|
vertex.position = glm::rotateZ<double>( vertex.position, rotation.z );
|
||||||
vertex.normal = glm::rotateZ( vertex.normal, rotation.z );
|
vertex.position = glm::rotateX<double>( vertex.position, rotation.x );
|
||||||
vertex.normal = glm::rotateX( vertex.normal, rotation.x );
|
vertex.position = glm::rotateY<double>( vertex.position, rotation.y );
|
||||||
vertex.normal = glm::rotateY( vertex.normal, rotation.y );
|
vertex.normal = glm::rotateZ( vertex.normal, rotation.z );
|
||||||
|
vertex.normal = glm::rotateX( vertex.normal, rotation.x );
|
||||||
|
vertex.normal = glm::rotateY( vertex.normal, rotation.y );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if( ( false == Scratchpad.location_offset.empty() )
|
||||||
if( ( false == Scratchpad.location_offset.empty() )
|
&& ( Scratchpad.location_offset.top() != glm::dvec3( 0, 0, 0 ) ) ) {
|
||||||
&& ( Scratchpad.location_offset.top() != glm::dvec3( 0, 0, 0 ) ) ) {
|
// ...and move
|
||||||
// ...and move
|
auto const offset = Scratchpad.location_offset.top();
|
||||||
auto const offset = Scratchpad.location_offset.top();
|
for( auto &vertex : shape.m_data.vertices ) {
|
||||||
for( auto &vertex : shape.m_data.vertices ) {
|
vertex.position += offset;
|
||||||
vertex.position += offset;
|
}
|
||||||
}
|
}
|
||||||
}
|
// calculate bounding area
|
||||||
// calculate bounding area
|
for( auto const &vertex : shape.m_data.vertices ) {
|
||||||
for( auto const &vertex : shape.m_data.vertices ) {
|
shape.m_data.area.center += vertex.position;
|
||||||
shape.m_data.area.center += vertex.position;
|
}
|
||||||
}
|
shape.m_data.area.center /= shape.m_data.vertices.size();
|
||||||
shape.m_data.area.center /= shape.m_data.vertices.size();
|
// trim the shape if needed. trimmed parts will be added to list as separate nodes
|
||||||
// trim the shape if needed. trimmed parts will be added to list as separate nodes
|
for( std::size_t index = 0; index < shapes.size(); ++index ) {
|
||||||
for( std::size_t index = 0; index < shapes.size(); ++index ) {
|
while( true == RaTriangleDivider( shapes[ index ], shapes ) ) {
|
||||||
while( true == RaTriangleDivider( shapes[ index ], shapes ) ) {
|
; // all work is done during expression check
|
||||||
; // all work is done during expression check
|
}
|
||||||
|
// with the trimming done we can calculate shape's bounding radius
|
||||||
|
shape.compute_radius();
|
||||||
}
|
}
|
||||||
// with the trimming done we can calculate shape's bounding radius
|
|
||||||
shape.compute_radius();
|
|
||||||
}
|
}
|
||||||
// move the data into appropriate section(s)
|
// move the data into appropriate section(s)
|
||||||
for( auto &shape : shapes ) {
|
for( auto &shape : shapes ) {
|
||||||
@@ -679,6 +839,50 @@ basic_region::insert_shape( shape_node Shape, scratch_data &Scratchpad ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inserts provided lines in the region
|
||||||
|
void
|
||||||
|
basic_region::insert_lines( lines_node Lines, scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
|
if( Lines.m_data.vertices.empty() ) { return; }
|
||||||
|
// transform point coordinates if needed
|
||||||
|
if( Scratchpad.location_rotation != glm::vec3( 0, 0, 0 ) ) {
|
||||||
|
// rotate...
|
||||||
|
auto const rotation = glm::radians( Scratchpad.location_rotation );
|
||||||
|
for( auto &vertex : Lines.m_data.vertices ) {
|
||||||
|
vertex.position = glm::rotateZ<double>( vertex.position, rotation.z );
|
||||||
|
vertex.position = glm::rotateX<double>( vertex.position, rotation.x );
|
||||||
|
vertex.position = glm::rotateY<double>( vertex.position, rotation.y );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( ( false == Scratchpad.location_offset.empty() )
|
||||||
|
&& ( Scratchpad.location_offset.top() != glm::dvec3( 0, 0, 0 ) ) ) {
|
||||||
|
// ...and move
|
||||||
|
auto const offset = Scratchpad.location_offset.top();
|
||||||
|
for( auto &vertex : Lines.m_data.vertices ) {
|
||||||
|
vertex.position += offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// calculate bounding area
|
||||||
|
for( auto const &vertex : Lines.m_data.vertices ) {
|
||||||
|
Lines.m_data.area.center += vertex.position;
|
||||||
|
}
|
||||||
|
Lines.m_data.area.center /= Lines.m_data.vertices.size();
|
||||||
|
Lines.compute_radius();
|
||||||
|
// move the data into appropriate section
|
||||||
|
if( point_inside( Lines.m_data.area.center ) ) {
|
||||||
|
// NOTE: nodes placed outside of region boundaries are discarded
|
||||||
|
section( Lines.m_data.area.center ).insert( Lines );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ErrorLog(
|
||||||
|
"Bad scenario: lines node" + (
|
||||||
|
Lines.m_name.empty() ?
|
||||||
|
"" :
|
||||||
|
" \"" + Lines.m_name + "\"" )
|
||||||
|
+ " placed in location outside region bounds (" + to_string( Lines.m_data.area.center ) + ")" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// inserts provided track in the region
|
// inserts provided track in the region
|
||||||
void
|
void
|
||||||
basic_region::insert_path( TTrack *Path, scratch_data &Scratchpad ) {
|
basic_region::insert_path( TTrack *Path, scratch_data &Scratchpad ) {
|
||||||
@@ -776,7 +980,7 @@ basic_region::insert_launcher( TEventLauncher *Launcher, scratch_data &Scratchpa
|
|||||||
|
|
||||||
// find a vehicle located neares to specified location, within specified radius, optionally discarding vehicles without drivers
|
// find a vehicle located neares to specified location, within specified radius, optionally discarding vehicles without drivers
|
||||||
std::tuple<TDynamicObject *, float>
|
std::tuple<TDynamicObject *, float>
|
||||||
basic_region::find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled ) {
|
basic_region::find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler ) {
|
||||||
|
|
||||||
auto const §ionlist = sections( Point, Radius );
|
auto const §ionlist = sections( Point, Radius );
|
||||||
// go through sections within radius of interest, and pick the nearest candidate
|
// go through sections within radius of interest, and pick the nearest candidate
|
||||||
@@ -788,7 +992,7 @@ basic_region::find_vehicle( glm::dvec3 const &Point, float const Radius, bool co
|
|||||||
nearestdistance { std::numeric_limits<float>::max() };
|
nearestdistance { std::numeric_limits<float>::max() };
|
||||||
|
|
||||||
for( auto *section : sectionlist ) {
|
for( auto *section : sectionlist ) {
|
||||||
std::tie( foundvehicle, founddistance ) = section->find( Point, Radius, Onlycontrolled );
|
std::tie( foundvehicle, founddistance ) = section->find( Point, Radius, Onlycontrolled, Findbycoupler );
|
||||||
if( ( foundvehicle != nullptr )
|
if( ( foundvehicle != nullptr )
|
||||||
&& ( founddistance < nearestdistance ) ) {
|
&& ( founddistance < nearestdistance ) ) {
|
||||||
|
|
||||||
|
|||||||
58
scene.h
58
scene.h
@@ -61,9 +61,21 @@ public:
|
|||||||
// legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
|
// legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
|
||||||
void
|
void
|
||||||
update_traction( TDynamicObject *Vehicle, int const Pantographindex );
|
update_traction( TDynamicObject *Vehicle, int const Pantographindex );
|
||||||
|
// legacy method, triggers radio-stop procedure for all vehicles located on paths in the cell
|
||||||
|
void
|
||||||
|
radio_stop();
|
||||||
|
// legacy method, adds specified path to the list of pieces undergoing state change
|
||||||
|
bool
|
||||||
|
RaTrackAnimAdd( TTrack *Track );
|
||||||
|
// legacy method, updates geometry for pieces in the animation list
|
||||||
|
void
|
||||||
|
RaAnimate( unsigned int const Framestamp );
|
||||||
// adds provided shape to the cell
|
// adds provided shape to the cell
|
||||||
void
|
void
|
||||||
insert( shape_node Shape );
|
insert( shape_node Shape );
|
||||||
|
// adds provided lines to the cell
|
||||||
|
void
|
||||||
|
insert( lines_node Lines );
|
||||||
// adds provided path to the cell
|
// adds provided path to the cell
|
||||||
void
|
void
|
||||||
insert( TTrack *Path );
|
insert( TTrack *Path );
|
||||||
@@ -85,9 +97,9 @@ public:
|
|||||||
// registers provided traction piece in the lookup directory of the cell
|
// registers provided traction piece in the lookup directory of the cell
|
||||||
void
|
void
|
||||||
register_end( TTraction *Traction );
|
register_end( TTraction *Traction );
|
||||||
// find a vehicle located nearest to specified point, within specified radius, optionally ignoring vehicles without drivers. reurns: located vehicle and distance
|
// find a vehicle located nearest to specified point, within specified radius. reurns: located vehicle and distance
|
||||||
std::tuple<TDynamicObject *, float>
|
std::tuple<TDynamicObject *, float>
|
||||||
find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled );
|
find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler );
|
||||||
// finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint
|
// finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint
|
||||||
std::tuple<TTrack *, int>
|
std::tuple<TTrack *, int>
|
||||||
find( glm::dvec3 const &Point, TTrack const *Exclude );
|
find( glm::dvec3 const &Point, TTrack const *Exclude );
|
||||||
@@ -111,19 +123,19 @@ public:
|
|||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
using shapenode_sequence = std::vector<shape_node>;
|
using shapenode_sequence = std::vector<shape_node>;
|
||||||
|
using linesnode_sequence = std::vector<lines_node>;
|
||||||
using path_sequence = std::vector<TTrack *>;
|
using path_sequence = std::vector<TTrack *>;
|
||||||
// using path_set = std::unordered_set<TTrack *>;
|
|
||||||
using traction_sequence = std::vector<TTraction *>;
|
using traction_sequence = std::vector<TTraction *>;
|
||||||
// using traction_set = std::unordered_set<TTraction *>;
|
|
||||||
using instance_sequence = std::vector<TAnimModel *>;
|
using instance_sequence = std::vector<TAnimModel *>;
|
||||||
using sound_sequence = std::vector<TTextSound *>;
|
using sound_sequence = std::vector<TTextSound *>;
|
||||||
using eventlauncher_sequence = std::vector<TEventLauncher *>;
|
using eventlauncher_sequence = std::vector<TEventLauncher *>;
|
||||||
// members
|
// members
|
||||||
scene::bounding_area m_area { glm::dvec3(), static_cast<float>( 0.5 * M_SQRT2 * EU07_CELLSIZE + 0.25 * EU07_CELLSIZE ) };
|
scene::bounding_area m_area { glm::dvec3(), static_cast<float>( 0.5 * M_SQRT2 * EU07_CELLSIZE ) };
|
||||||
bool m_active { false }; // whether the cell holds any actual data
|
bool m_active { false }; // whether the cell holds any actual data
|
||||||
// content
|
// content
|
||||||
shapenode_sequence m_shapesopaque; // opaque pieces of geometry
|
shapenode_sequence m_shapesopaque; // opaque pieces of geometry
|
||||||
shapenode_sequence m_shapestranslucent; // translucent pieces of geometry
|
shapenode_sequence m_shapestranslucent; // translucent pieces of geometry
|
||||||
|
linesnode_sequence m_lines;
|
||||||
path_sequence m_paths; // path pieces
|
path_sequence m_paths; // path pieces
|
||||||
instance_sequence m_instancesopaque;
|
instance_sequence m_instancesopaque;
|
||||||
instance_sequence m_instancetranslucent;
|
instance_sequence m_instancetranslucent;
|
||||||
@@ -135,6 +147,10 @@ private:
|
|||||||
path_sequence paths;
|
path_sequence paths;
|
||||||
traction_sequence traction;
|
traction_sequence traction;
|
||||||
} m_directories;
|
} m_directories;
|
||||||
|
// animation of owned items (legacy code, clean up along with track refactoring)
|
||||||
|
bool m_geometrycreated { false };
|
||||||
|
unsigned int m_framestamp { 0 }; // id of last rendered gfx frame
|
||||||
|
TTrack *tTrackAnim = nullptr; // obiekty do przeliczenia animacji
|
||||||
};
|
};
|
||||||
|
|
||||||
// basic scene partitioning structure, holds terrain geometry and collection of cells
|
// basic scene partitioning structure, holds terrain geometry and collection of cells
|
||||||
@@ -150,22 +166,33 @@ public:
|
|||||||
// legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
|
// legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
|
||||||
void
|
void
|
||||||
update_traction( TDynamicObject *Vehicle, int const Pantographindex );
|
update_traction( TDynamicObject *Vehicle, int const Pantographindex );
|
||||||
|
// legacy method, triggers radio-stop procedure for all vehicles in 2km radius around specified location
|
||||||
|
void
|
||||||
|
radio_stop( glm::dvec3 const &Location, float const Radius );
|
||||||
// adds provided shape to the section
|
// adds provided shape to the section
|
||||||
void
|
void
|
||||||
insert( shape_node Shape );
|
insert( shape_node Shape );
|
||||||
|
// adds provided lines to the section
|
||||||
|
void
|
||||||
|
insert( lines_node Lines );
|
||||||
// adds provided node to the section
|
// adds provided node to the section
|
||||||
template <class Type_>
|
template <class Type_>
|
||||||
void
|
void
|
||||||
insert( Type_ *Node ) {
|
insert( Type_ *Node ) {
|
||||||
cell( Node->location() ).insert( Node ); }
|
auto &targetcell { cell( Node->location() ) };
|
||||||
|
targetcell.insert( Node );
|
||||||
|
// some node types can extend bounding area of the target cell
|
||||||
|
m_area.radius = std::max<float>(
|
||||||
|
m_area.radius,
|
||||||
|
glm::length( m_area.center - targetcell.area().center ) + targetcell.area().radius ); }
|
||||||
// registers provided node in the lookup directory of the section enclosing specified point
|
// registers provided node in the lookup directory of the section enclosing specified point
|
||||||
template <class Type_>
|
template <class Type_>
|
||||||
void
|
void
|
||||||
register_node( Type_ *Node, glm::dvec3 const &Point ) {
|
register_node( Type_ *Node, glm::dvec3 const &Point ) {
|
||||||
cell( Point ).register_end( Node ); }
|
cell( Point ).register_end( Node ); }
|
||||||
// find a vehicle located nearest to specified point, within specified radius, optionally ignoring vehicles without drivers. reurns: located vehicle and distance
|
// find a vehicle located nearest to specified point, within specified radius. reurns: located vehicle and distance
|
||||||
std::tuple<TDynamicObject *, float>
|
std::tuple<TDynamicObject *, float>
|
||||||
find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled );
|
find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler );
|
||||||
// finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint
|
// finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint
|
||||||
std::tuple<TTrack *, int>
|
std::tuple<TTrack *, int>
|
||||||
find( glm::dvec3 const &Point, TTrack const *Exclude );
|
find( glm::dvec3 const &Point, TTrack const *Exclude );
|
||||||
@@ -223,9 +250,18 @@ public:
|
|||||||
// legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
|
// legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
|
||||||
void
|
void
|
||||||
update_traction( TDynamicObject *Vehicle, int const Pantographindex );
|
update_traction( TDynamicObject *Vehicle, int const Pantographindex );
|
||||||
|
// legacy method, links specified path piece with potential neighbours
|
||||||
|
void
|
||||||
|
TrackJoin( TTrack *Track );
|
||||||
|
// legacy method, triggers radio-stop procedure for all vehicles in 2km radius around specified location
|
||||||
|
void
|
||||||
|
RadioStop( glm::dvec3 const &Location );
|
||||||
// inserts provided shape in the region
|
// inserts provided shape in the region
|
||||||
void
|
void
|
||||||
insert_shape( shape_node Shape, scratch_data &Scratchpad );
|
insert_shape( shape_node Shape, scratch_data &Scratchpad, bool const Transform );
|
||||||
|
// inserts provided lines in the region
|
||||||
|
void
|
||||||
|
insert_lines( lines_node Lines, scratch_data &Scratchpad );
|
||||||
// inserts provided track in the region
|
// inserts provided track in the region
|
||||||
void
|
void
|
||||||
insert_path( TTrack *Path, scratch_data &Scratchpad );
|
insert_path( TTrack *Path, scratch_data &Scratchpad );
|
||||||
@@ -241,9 +277,9 @@ public:
|
|||||||
// inserts provided event launcher in the region
|
// inserts provided event launcher in the region
|
||||||
void
|
void
|
||||||
insert_launcher( TEventLauncher *Launcher, scratch_data &Scratchpad );
|
insert_launcher( TEventLauncher *Launcher, scratch_data &Scratchpad );
|
||||||
// find a vehicle located nearest to specified point, within specified radius, optionally ignoring vehicles without drivers. reurns: located vehicle and distance
|
// find a vehicle located nearest to specified point, within specified radius. reurns: located vehicle and distance
|
||||||
std::tuple<TDynamicObject *, float>
|
std::tuple<TDynamicObject *, float>
|
||||||
find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled );
|
find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler );
|
||||||
// finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint
|
// finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint
|
||||||
std::tuple<TTrack *, int>
|
std::tuple<TTrack *, int>
|
||||||
find_path( glm::dvec3 const &Point, TTrack const *Exclude );
|
find_path( glm::dvec3 const &Point, TTrack const *Exclude );
|
||||||
|
|||||||
206
scenenode.cpp
206
scenenode.cpp
@@ -207,6 +207,65 @@ shape_node::deserialize( cParser &Input, scene::node_data const &Nodedata ) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// imports data from provided submodel
|
||||||
|
shape_node &
|
||||||
|
shape_node::convert( TSubModel const *Submodel ) {
|
||||||
|
|
||||||
|
m_name = Submodel->pName;
|
||||||
|
m_data.lighting.ambient = Submodel->f4Ambient;
|
||||||
|
m_data.lighting.diffuse = Submodel->f4Diffuse;
|
||||||
|
m_data.lighting.specular = Submodel->f4Specular;
|
||||||
|
m_data.material = Submodel->m_material;
|
||||||
|
m_data.translucent = ( true == GfxRenderer.Material( m_data.material ).has_alpha );
|
||||||
|
// NOTE: we set unlimited view range typical for terrain, because we don't expect to convert any other 3d models
|
||||||
|
m_data.rangesquared_max = std::numeric_limits<double>::max();
|
||||||
|
|
||||||
|
if( Submodel->m_geometry == null_handle ) { return *this; }
|
||||||
|
|
||||||
|
int vertexcount { 0 };
|
||||||
|
std::vector<world_vertex> importedvertices;
|
||||||
|
world_vertex vertex, vertex1, vertex2;
|
||||||
|
for( auto const &sourcevertex : GfxRenderer.Vertices( Submodel->m_geometry ) ) {
|
||||||
|
vertex.position = sourcevertex.position;
|
||||||
|
vertex.normal = sourcevertex.normal;
|
||||||
|
vertex.texture = sourcevertex.texture;
|
||||||
|
if( vertexcount == 0 ) { vertex1 = vertex; }
|
||||||
|
else if( vertexcount == 1 ) { vertex2 = vertex; }
|
||||||
|
else if( vertexcount >= 2 ) {
|
||||||
|
if( false == degenerate( vertex1.position, vertex2.position, vertex.position ) ) {
|
||||||
|
importedvertices.emplace_back( vertex1 );
|
||||||
|
importedvertices.emplace_back( vertex2 );
|
||||||
|
importedvertices.emplace_back( vertex );
|
||||||
|
}
|
||||||
|
// start a new triangle
|
||||||
|
vertexcount = -1;
|
||||||
|
}
|
||||||
|
++vertexcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( true == importedvertices.empty() ) { return *this; }
|
||||||
|
|
||||||
|
// assign imported geometry to the node...
|
||||||
|
m_data.vertices.swap( importedvertices );
|
||||||
|
// ...and calculate center...
|
||||||
|
for( auto const &vertex : m_data.vertices ) {
|
||||||
|
m_data.area.center += vertex.position;
|
||||||
|
}
|
||||||
|
m_data.area.center /= m_data.vertices.size();
|
||||||
|
// ...and bounding area
|
||||||
|
double squareradius { 0.0 };
|
||||||
|
for( auto const &vertex : m_data.vertices ) {
|
||||||
|
squareradius = std::max(
|
||||||
|
squareradius,
|
||||||
|
glm::length2( vertex.position - m_data.area.center ) );
|
||||||
|
}
|
||||||
|
m_data.area.radius = std::max<float>(
|
||||||
|
m_data.area.radius,
|
||||||
|
std::sqrt( squareradius ) );
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
// adds content of provided node to already enclosed geometry. returns: true if merge could be performed
|
// adds content of provided node to already enclosed geometry. returns: true if merge could be performed
|
||||||
bool
|
bool
|
||||||
shape_node::merge( shape_node &Shape ) {
|
shape_node::merge( shape_node &Shape ) {
|
||||||
@@ -260,6 +319,151 @@ shape_node::compute_radius() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// restores content of the node from provded input stream
|
||||||
|
lines_node &
|
||||||
|
lines_node::deserialize( cParser &Input, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
|
// import common data
|
||||||
|
m_name = Nodedata.name;
|
||||||
|
m_data.rangesquared_min = Nodedata.range_min * Nodedata.range_min;
|
||||||
|
m_data.rangesquared_max = (
|
||||||
|
Nodedata.range_max >= 0.0 ?
|
||||||
|
Nodedata.range_max * Nodedata.range_max :
|
||||||
|
std::numeric_limits<double>::max() );
|
||||||
|
|
||||||
|
// material
|
||||||
|
Input.getTokens( 3, false );
|
||||||
|
Input
|
||||||
|
>> m_data.lighting.diffuse.r
|
||||||
|
>> m_data.lighting.diffuse.g
|
||||||
|
>> m_data.lighting.diffuse.b;
|
||||||
|
m_data.lighting.diffuse /= 255.f;
|
||||||
|
m_data.lighting.diffuse.a = 1.f;
|
||||||
|
Input.getTokens( 1, false );
|
||||||
|
Input
|
||||||
|
>> m_data.line_width;
|
||||||
|
m_data.line_width = std::min( 30.f, m_data.line_width ); // 30 pix equals rougly width of a signal pole viewed from ~1m away
|
||||||
|
|
||||||
|
// geometry
|
||||||
|
enum subtype {
|
||||||
|
lines,
|
||||||
|
line_strip,
|
||||||
|
line_loop
|
||||||
|
} const nodetype = (
|
||||||
|
Nodedata.type == "lines" ? lines :
|
||||||
|
Nodedata.type == "line_strip" ? line_strip :
|
||||||
|
line_loop );
|
||||||
|
std::size_t vertexcount { 0 };
|
||||||
|
world_vertex vertex, vertex0, vertex1;
|
||||||
|
std::string token = Input.getToken<std::string>();
|
||||||
|
do {
|
||||||
|
vertex.position.x = std::atof( token.c_str() );
|
||||||
|
Input.getTokens( 2, false );
|
||||||
|
Input
|
||||||
|
>> vertex.position.y
|
||||||
|
>> vertex.position.z;
|
||||||
|
// convert all data to gl_lines to allow data merge for matching nodes
|
||||||
|
switch( nodetype ) {
|
||||||
|
case lines: {
|
||||||
|
m_data.vertices.emplace_back( vertex );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case line_strip: {
|
||||||
|
if( vertexcount > 0 ) {
|
||||||
|
m_data.vertices.emplace_back( vertex1 );
|
||||||
|
m_data.vertices.emplace_back( vertex );
|
||||||
|
}
|
||||||
|
vertex1 = vertex;
|
||||||
|
++vertexcount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case line_loop: {
|
||||||
|
if( vertexcount == 0 ) {
|
||||||
|
vertex0 = vertex;
|
||||||
|
vertex1 = vertex;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_data.vertices.emplace_back( vertex1 );
|
||||||
|
m_data.vertices.emplace_back( vertex );
|
||||||
|
}
|
||||||
|
vertex1 = vertex;
|
||||||
|
++vertexcount;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: { break; }
|
||||||
|
}
|
||||||
|
token = Input.getToken<std::string>();
|
||||||
|
|
||||||
|
} while( token != "endline" );
|
||||||
|
// add closing line for the loop
|
||||||
|
if( ( nodetype == line_loop )
|
||||||
|
&& ( vertexcount > 2 ) ) {
|
||||||
|
m_data.vertices.emplace_back( vertex1 );
|
||||||
|
m_data.vertices.emplace_back( vertex0 );
|
||||||
|
}
|
||||||
|
if( m_data.vertices.size() % 2 != 0 ) {
|
||||||
|
ErrorLog( "Lines node specified odd number of vertices, encountered in file \"" + Input.Name() + "\" (line " + std::to_string( Input.Line() - 1 ) + ")" );
|
||||||
|
m_data.vertices.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// adds content of provided node to already enclosed geometry. returns: true if merge could be performed
|
||||||
|
bool
|
||||||
|
lines_node::merge( lines_node &Lines ) {
|
||||||
|
|
||||||
|
if( ( m_data.line_width != Lines.m_data.line_width )
|
||||||
|
|| ( m_data.lighting != Lines.m_data.lighting ) ) {
|
||||||
|
// can't merge nodes with different appearance
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// add geometry from provided node
|
||||||
|
m_data.area.center =
|
||||||
|
interpolate(
|
||||||
|
m_data.area.center, Lines.m_data.area.center,
|
||||||
|
static_cast<float>( Lines.m_data.vertices.size() ) / ( Lines.m_data.vertices.size() + m_data.vertices.size() ) );
|
||||||
|
m_data.vertices.insert(
|
||||||
|
std::end( m_data.vertices ),
|
||||||
|
std::begin( Lines.m_data.vertices ), std::end( Lines.m_data.vertices ) );
|
||||||
|
// NOTE: we could recalculate radius with something other than brute force, but it'll do
|
||||||
|
compute_radius();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generates renderable version of held non-instanced geometry in specified geometry bank
|
||||||
|
void
|
||||||
|
lines_node::create_geometry( geometrybank_handle const &Bank ) {
|
||||||
|
|
||||||
|
vertex_array vertices; vertices.reserve( m_data.vertices.size() );
|
||||||
|
|
||||||
|
for( auto const &vertex : m_data.vertices ) {
|
||||||
|
vertices.emplace_back(
|
||||||
|
vertex.position - m_data.origin,
|
||||||
|
vertex.normal,
|
||||||
|
vertex.texture );
|
||||||
|
}
|
||||||
|
m_data.geometry = GfxRenderer.Insert( vertices, Bank, GL_LINES );
|
||||||
|
std::vector<world_vertex>().swap( m_data.vertices ); // hipster shrink_to_fit
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculates node's bounding radius
|
||||||
|
void
|
||||||
|
lines_node::compute_radius() {
|
||||||
|
|
||||||
|
auto squaredradius { 0.0 };
|
||||||
|
for( auto const &vertex : m_data.vertices ) {
|
||||||
|
squaredradius = std::max(
|
||||||
|
squaredradius,
|
||||||
|
glm::length2( vertex.position - m_data.area.center ) );
|
||||||
|
}
|
||||||
|
m_data.area.radius = static_cast<float>( std::sqrt( squaredradius ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
memory_node &
|
memory_node &
|
||||||
memory_node::deserialize( cParser &Input, node_data const &Nodedata ) {
|
memory_node::deserialize( cParser &Input, node_data const &Nodedata ) {
|
||||||
@@ -279,6 +483,8 @@ memory_node::deserialize( cParser &Input, node_data const &Nodedata ) {
|
|||||||
*/
|
*/
|
||||||
} // scene
|
} // scene
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace editor {
|
namespace editor {
|
||||||
|
|
||||||
basic_node::basic_node( scene::node_data const &Nodedata ) :
|
basic_node::basic_node( scene::node_data const &Nodedata ) :
|
||||||
|
|||||||
57
scenenode.h
57
scenenode.h
@@ -15,6 +15,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "vertex.h"
|
#include "vertex.h"
|
||||||
#include "openglgeometrybank.h"
|
#include "openglgeometrybank.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
#include "model3d.h"
|
||||||
|
|
||||||
struct lighting_data {
|
struct lighting_data {
|
||||||
|
|
||||||
@@ -104,6 +105,9 @@ public:
|
|||||||
// restores content of the node from provded input stream
|
// restores content of the node from provded input stream
|
||||||
shape_node &
|
shape_node &
|
||||||
deserialize( cParser &Input, scene::node_data const &Nodedata );
|
deserialize( cParser &Input, scene::node_data const &Nodedata );
|
||||||
|
// imports data from provided submodel
|
||||||
|
shape_node &
|
||||||
|
convert( TSubModel const *Submodel );
|
||||||
// adds content of provided node to already enclosed geometry. returns: true if merge could be performed
|
// adds content of provided node to already enclosed geometry. returns: true if merge could be performed
|
||||||
bool
|
bool
|
||||||
merge( shape_node &Shape );
|
merge( shape_node &Shape );
|
||||||
@@ -132,6 +136,59 @@ private:
|
|||||||
shapenode_data m_data;
|
shapenode_data m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// holds a group of untextured lines
|
||||||
|
class lines_node {
|
||||||
|
|
||||||
|
friend class basic_region; // region might want to modify node content when it's being inserted
|
||||||
|
|
||||||
|
public:
|
||||||
|
// types
|
||||||
|
struct linesnode_data {
|
||||||
|
// placement and visibility
|
||||||
|
scene::bounding_area area; // bounding area, in world coordinates
|
||||||
|
bool visible { true }; // visibility flag
|
||||||
|
double rangesquared_min { 0.0 }; // visibility range, min
|
||||||
|
double rangesquared_max { 0.0 }; // visibility range, max
|
||||||
|
// material data
|
||||||
|
lighting_data lighting;
|
||||||
|
float line_width; // thickness of stored lines
|
||||||
|
// geometry data
|
||||||
|
std::vector<world_vertex> vertices; // world space source data of the geometry
|
||||||
|
glm::dvec3 origin; // world position of the relative coordinate system origin
|
||||||
|
geometry_handle geometry { 0, 0 }; // relative origin-centered chunk of geometry held by gfx renderer
|
||||||
|
};
|
||||||
|
|
||||||
|
// methods
|
||||||
|
// restores content of the node from provded input stream
|
||||||
|
lines_node &
|
||||||
|
deserialize( cParser &Input, scene::node_data const &Nodedata );
|
||||||
|
// adds content of provided node to already enclosed geometry. returns: true if merge could be performed
|
||||||
|
bool
|
||||||
|
merge( lines_node &Lines );
|
||||||
|
// generates renderable version of held non-instanced geometry in specified geometry bank
|
||||||
|
void
|
||||||
|
create_geometry( geometrybank_handle const &Bank );
|
||||||
|
// calculates shape's bounding radius
|
||||||
|
void
|
||||||
|
compute_radius();
|
||||||
|
// set visibility
|
||||||
|
void
|
||||||
|
visible( bool State ) {
|
||||||
|
m_data.visible = State; }
|
||||||
|
// set origin point
|
||||||
|
void
|
||||||
|
origin( glm::dvec3 Origin ) {
|
||||||
|
m_data.origin = Origin; }
|
||||||
|
// data access
|
||||||
|
linesnode_data const &
|
||||||
|
data() const {
|
||||||
|
return m_data; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// members
|
||||||
|
std::string m_name;
|
||||||
|
linesnode_data m_data;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// holds geometry for specific piece of track/road/waterway
|
// holds geometry for specific piece of track/road/waterway
|
||||||
|
|||||||
@@ -352,7 +352,29 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
|
|
||||||
if( nodedata.range_min < 0.0 ) {
|
if( nodedata.range_min < 0.0 ) {
|
||||||
// convert and import 3d terrain
|
// convert and import 3d terrain
|
||||||
// TODO: implement this
|
auto *instance { deserialize_model( Input, Scratchpad, nodedata ) };
|
||||||
|
// model import can potentially fail
|
||||||
|
if( instance == nullptr ) { return; }
|
||||||
|
// go through submodels, and import them as shapes
|
||||||
|
auto const cellcount = instance->TerrainCount() + 1; // zliczenie submodeli
|
||||||
|
for( auto i = 1; i < cellcount; ++i ) {
|
||||||
|
auto *submodel = instance->TerrainSquare( i - 1 );
|
||||||
|
simulation::Region->insert_shape(
|
||||||
|
scene::shape_node().convert( submodel ),
|
||||||
|
Scratchpad,
|
||||||
|
false );
|
||||||
|
// if there's more than one group of triangles in the cell they're held as children of the primary submodel
|
||||||
|
submodel = submodel->ChildGet();
|
||||||
|
while( submodel != nullptr ) {
|
||||||
|
simulation::Region->insert_shape(
|
||||||
|
scene::shape_node().convert( submodel ),
|
||||||
|
Scratchpad,
|
||||||
|
false );
|
||||||
|
submodel = submodel->NextGet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// with the import done we can get rid of the source model
|
||||||
|
delete instance;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// regular instance of 3d mesh
|
// regular instance of 3d mesh
|
||||||
@@ -372,14 +394,20 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
|| ( nodedata.type == "triangle_strip" )
|
|| ( nodedata.type == "triangle_strip" )
|
||||||
|| ( nodedata.type == "triangle_fan" ) ) {
|
|| ( nodedata.type == "triangle_fan" ) ) {
|
||||||
|
|
||||||
simulation::Region->insert_shape( scene::shape_node().deserialize( Input, nodedata ), Scratchpad );
|
simulation::Region->insert_shape(
|
||||||
|
scene::shape_node().deserialize(
|
||||||
|
Input, nodedata ),
|
||||||
|
Scratchpad,
|
||||||
|
true );
|
||||||
}
|
}
|
||||||
else if( ( nodedata.type == "lines" )
|
else if( ( nodedata.type == "lines" )
|
||||||
|| ( nodedata.type == "line_strip" )
|
|| ( nodedata.type == "line_strip" )
|
||||||
|| ( nodedata.type == "line_loop" ) ) {
|
|| ( nodedata.type == "line_loop" ) ) {
|
||||||
|
|
||||||
// TODO: implement
|
simulation::Region->insert_lines(
|
||||||
skip_until( Input, "endline" );
|
scene::lines_node().deserialize(
|
||||||
|
Input, nodedata ),
|
||||||
|
Scratchpad );
|
||||||
}
|
}
|
||||||
else if( nodedata.type == "memcell" ) {
|
else if( nodedata.type == "memcell" ) {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user