mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 23:49:17 +02:00
continued refactoring: traction, events, event launchers, sounds; additional diagnostics timers, minor performance enhancements and bug fixes
This commit is contained in:
24
Driver.cpp
24
Driver.cpp
@@ -2985,20 +2985,27 @@ void TController::RecognizeCommand()
|
|||||||
c->Command = ""; // usunięcie obsłużonej komendy
|
c->Command = ""; // usunięcie obsłużonej komendy
|
||||||
}
|
}
|
||||||
|
|
||||||
void TController::PutCommand(std::string NewCommand, double NewValue1, double NewValue2,
|
void TController::PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation, TStopReason reason)
|
||||||
const TLocation &NewLocation, TStopReason reason)
|
|
||||||
{ // wysłanie komendy przez event PutValues, jak pojazd ma obsadę, to wysyła tutaj, a nie do pojazdu
|
{ // wysłanie komendy przez event PutValues, jak pojazd ma obsadę, to wysyła tutaj, a nie do pojazdu
|
||||||
// bezpośrednio
|
// bezpośrednio
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
vector3 sl;
|
vector3 sl;
|
||||||
sl.x = -NewLocation.X; // zamiana na współrzędne scenerii
|
sl.x = -NewLocation.X; // zamiana na współrzędne scenerii
|
||||||
sl.z = NewLocation.Y;
|
sl.z = NewLocation.Y;
|
||||||
sl.y = NewLocation.Z;
|
sl.y = NewLocation.Z;
|
||||||
|
#else
|
||||||
|
// zamiana na współrzędne scenerii
|
||||||
|
glm::dvec3 sl { -NewLocation.X, NewLocation.Y, NewLocation.Z };
|
||||||
|
#endif
|
||||||
if (!PutCommand(NewCommand, NewValue1, NewValue2, &sl, reason))
|
if (!PutCommand(NewCommand, NewValue1, NewValue2, &sl, reason))
|
||||||
mvOccupied->PutCommand(NewCommand, NewValue1, NewValue2, NewLocation);
|
mvOccupied->PutCommand(NewCommand, NewValue1, NewValue2, NewLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TController::PutCommand(std::string NewCommand, double NewValue1, double NewValue2,
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
const vector3 *NewLocation, TStopReason reason)
|
bool TController::PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const vector3 *NewLocation, TStopReason reason)
|
||||||
|
#else
|
||||||
|
bool TController::PutCommand( std::string NewCommand, double NewValue1, double NewValue2, glm::dvec3 const *NewLocation, TStopReason reason )
|
||||||
|
#endif
|
||||||
{ // analiza komendy
|
{ // analiza komendy
|
||||||
if (NewCommand == "CabSignal")
|
if (NewCommand == "CabSignal")
|
||||||
{ // SHP wyzwalane jest przez człon z obsadą, ale obsługiwane przez silnikowy
|
{ // SHP wyzwalane jest przez człon z obsadą, ale obsługiwane przez silnikowy
|
||||||
@@ -4229,13 +4236,12 @@ TController::UpdateSituation(double dt) {
|
|||||||
~(Obey_train | Shunt))) // jedzie w dowolnym trybie albo Wait_for_orders
|
~(Obey_train | Shunt))) // jedzie w dowolnym trybie albo Wait_for_orders
|
||||||
if (fabs(VelSignal) >=
|
if (fabs(VelSignal) >=
|
||||||
1.0) // 0.1 nie wysyła się do samochodow, bo potem nie ruszą
|
1.0) // 0.1 nie wysyła się do samochodow, bo potem nie ruszą
|
||||||
PutCommand("SetVelocity", VelSignal, VelNext,
|
PutCommand("SetVelocity", VelSignal, VelNext, nullptr); // komenda robi dodatkowe operacje
|
||||||
NULL); // komenda robi dodatkowe operacje
|
|
||||||
break;
|
break;
|
||||||
case cm_ShuntVelocity: // od wersji 357 Tm nie budzi wyłączonej lokomotywy
|
case cm_ShuntVelocity: // od wersji 357 Tm nie budzi wyłączonej lokomotywy
|
||||||
if (!(OrderList[OrderPos] &
|
if (!(OrderList[OrderPos] &
|
||||||
~(Obey_train | Shunt))) // jedzie w dowolnym trybie albo Wait_for_orders
|
~(Obey_train | Shunt))) // jedzie w dowolnym trybie albo Wait_for_orders
|
||||||
PutCommand("ShuntVelocity", VelSignal, VelNext, NULL);
|
PutCommand("ShuntVelocity", VelSignal, VelNext, nullptr);
|
||||||
else if (iCoupler) // jeśli jedzie w celu połączenia
|
else if (iCoupler) // jeśli jedzie w celu połączenia
|
||||||
SetVelocity(VelSignal, VelNext);
|
SetVelocity(VelSignal, VelNext);
|
||||||
break;
|
break;
|
||||||
@@ -5306,7 +5312,11 @@ TTrack * TController::BackwardTraceRoute(double &fDistance, double &fDirection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sprawdzanie zdarzeń semaforów i ograniczeń szlakowych
|
// sprawdzanie zdarzeń semaforów i ograniczeń szlakowych
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
void TController::SetProximityVelocity(double dist, double vel, const vector3 *pos)
|
void TController::SetProximityVelocity(double dist, double vel, const vector3 *pos)
|
||||||
|
#else
|
||||||
|
void TController::SetProximityVelocity( double dist, double vel, glm::dvec3 const *pos )
|
||||||
|
#endif
|
||||||
{ // Ra:przeslanie do AI prędkości
|
{ // Ra:przeslanie do AI prędkości
|
||||||
/*
|
/*
|
||||||
//!!!! zastąpić prawidłową reakcją AI na SetProximityVelocity !!!!
|
//!!!! zastąpić prawidłową reakcją AI na SetProximityVelocity !!!!
|
||||||
|
|||||||
14
Driver.h
14
Driver.h
@@ -313,10 +313,12 @@ private:
|
|||||||
public:
|
public:
|
||||||
Mtable::TTrainParameters *Timetable() {
|
Mtable::TTrainParameters *Timetable() {
|
||||||
return TrainParams; };
|
return TrainParams; };
|
||||||
void PutCommand(std::string NewCommand, double NewValue1, double NewValue2,
|
void PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation, TStopReason reason = stopComm);
|
||||||
const TLocation &NewLocation, TStopReason reason = stopComm);
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
bool PutCommand(std::string NewCommand, double NewValue1, double NewValue2,
|
bool PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const vector3 *NewLocation, TStopReason reason = stopComm);
|
||||||
const vector3 *NewLocation, TStopReason reason = stopComm);
|
#else
|
||||||
|
bool PutCommand( std::string NewCommand, double NewValue1, double NewValue2, glm::dvec3 const *NewLocation, TStopReason reason = stopComm );
|
||||||
|
#endif
|
||||||
void UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę
|
void UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę
|
||||||
// procedury dotyczace rozkazow dla maszynisty
|
// procedury dotyczace rozkazow dla maszynisty
|
||||||
// uaktualnia informacje o prędkości
|
// uaktualnia informacje o prędkości
|
||||||
@@ -376,7 +378,11 @@ private:
|
|||||||
bool BackwardTrackBusy(TTrack *Track);
|
bool BackwardTrackBusy(TTrack *Track);
|
||||||
TEvent *CheckTrackEventBackward(double fDirection, TTrack *Track);
|
TEvent *CheckTrackEventBackward(double fDirection, TTrack *Track);
|
||||||
TTrack *BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, TEvent *&Event);
|
TTrack *BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, TEvent *&Event);
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
void SetProximityVelocity(double dist, double vel, const vector3 *pos);
|
void SetProximityVelocity(double dist, double vel, const vector3 *pos);
|
||||||
|
#else
|
||||||
|
void SetProximityVelocity( double dist, double vel, glm::dvec3 const *pos );
|
||||||
|
#endif
|
||||||
TCommandType BackwardScan();
|
TCommandType BackwardScan();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
208
DynObj.cpp
208
DynObj.cpp
@@ -2613,77 +2613,36 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
NoVoltTime = 0;
|
NoVoltTime = 0;
|
||||||
tmpTraction.TractionVoltage = v;
|
tmpTraction.TractionVoltage = v;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
NoVoltTime += dt;
|
||||||
/*
|
if( NoVoltTime > 0.2 ) {
|
||||||
if (MoverParameters->Vel>0.1f) //jeśli jedzie
|
// jeśli brak zasilania dłużej niż 0.2 sekundy (25km/h pod izolatorem daje 0.15s)
|
||||||
if (NoVoltTime==0.0) //tylko przy pierwszym zaniku napięcia
|
// Ra 2F1H: prowizorka, trzeba przechować napięcie, żeby nie wywalało WS pod izolatorem
|
||||||
|
if( MoverParameters->Vel > 0.5 ) {
|
||||||
|
// jeśli jedzie
|
||||||
|
// Ra 2014-07: doraźna blokada logowania zimnych lokomotyw - zrobić to trzeba inaczej
|
||||||
if( MoverParameters->PantFrontUp || MoverParameters->PantRearUp )
|
if( MoverParameters->PantFrontUp || MoverParameters->PantRearUp )
|
||||||
//if
|
|
||||||
((pants[0].fParamPants->PantTraction>1.0)||(pants[1].fParamPants->PantTraction>1.0))
|
|
||||||
{//wspomagacz usuwania problemów z siecią
|
|
||||||
if (!Global::iPause)
|
|
||||||
{//Ra: tymczasowa teleportacja do miejsca, gdzie brakuje prądu
|
|
||||||
Global::SetCameraPosition(vPosition+vector3(0,0,5)); //nowa
|
|
||||||
pozycja dla
|
|
||||||
generowania obiektów
|
|
||||||
Global::pCamera->Init(vPosition+vector3(0,0,5),Global::pFreeCameraInitAngle[0]);
|
|
||||||
//przestawienie
|
|
||||||
}
|
|
||||||
Global:l::pGround->Silence(Global::pCamera->Pos); //wyciszenie
|
|
||||||
wszystkiego
|
|
||||||
z poprzedniej pozycji
|
|
||||||
Globa:iPause|=1; //tymczasowe zapauzowanie, gdy problem z
|
|
||||||
siecią
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
NoVoltTime = NoVoltTime + dt;
|
|
||||||
if (NoVoltTime > 0.2) // jeśli brak zasilania dłużej niż 0.2 sekundy (25km/h pod
|
|
||||||
// izolatorem daje 0.15s)
|
|
||||||
{ // Ra 2F1H: prowizorka, trzeba przechować napięcie, żeby nie wywalało
|
|
||||||
// WS pod
|
|
||||||
// izolatorem
|
|
||||||
if (MoverParameters->Vel > 0.5) // jeśli jedzie
|
|
||||||
if (MoverParameters->PantFrontUp ||
|
|
||||||
MoverParameters->PantRearUp) // Ra 2014-07: doraźna blokada logowania
|
|
||||||
// zimnych lokomotyw - zrobić to trzeba
|
|
||||||
// inaczej
|
|
||||||
// if (NoVoltTime>0.02) //tu można ograniczyć czas rozłączenia
|
// if (NoVoltTime>0.02) //tu można ograniczyć czas rozłączenia
|
||||||
// if (DebugModeFlag) //logowanie nie zawsze
|
// if (DebugModeFlag) //logowanie nie zawsze
|
||||||
if ((MoverParameters->Mains) &&
|
if( ( MoverParameters->Mains )
|
||||||
((MoverParameters->EngineType != ElectricInductionMotor)
|
&& ( ( MoverParameters->EngineType != ElectricInductionMotor )
|
||||||
|| (MoverParameters->GetTrainsetVoltage() < 0.1f)))
|
|| ( MoverParameters->GetTrainsetVoltage() < 0.1f ) ) ) {
|
||||||
{ // Ra 15-01: logować tylko, jeśli WS załączony
|
// Ra 15-01: logować tylko, jeśli WS załączony
|
||||||
// yB 16-03: i nie jest to asynchron zasilany z daleka
|
// yB 16-03: i nie jest to asynchron zasilany z daleka
|
||||||
// if (MoverParameters->PantFrontUp&&pants)
|
|
||||||
// Ra 15-01: bezwzględne współrzędne pantografu nie są dostępne,
|
// Ra 15-01: bezwzględne współrzędne pantografu nie są dostępne,
|
||||||
// więc lepiej się tego nie zaloguje
|
// więc lepiej się tego nie zaloguje
|
||||||
ErrorLog("Voltage loss: by " + MoverParameters->Name + " at " +
|
ErrorLog(
|
||||||
to_string(vPosition.x, 2, 7) + " " +
|
"Bad traction: " + MoverParameters->Name
|
||||||
to_string(vPosition.y, 2, 7) + " " +
|
+ " lost power for " + to_string( NoVoltTime, 2 ) + " sec. at "
|
||||||
to_string(vPosition.z, 2, 7) + ", time " +
|
+ to_string( glm::dvec3{ vPosition } ) );
|
||||||
to_string(NoVoltTime, 2, 7));
|
|
||||||
// if (MoverParameters->PantRearUp)
|
|
||||||
// if (iAnimType[ANIM_PANTS]>1)
|
|
||||||
// if (pants[1])
|
|
||||||
// ErrorLog("Voltage loss: by "+MoverParameters->Name+" at
|
|
||||||
// "+FloatToStrF(vPosition.x,ffFixed,7,2)+"
|
|
||||||
// "+FloatToStrF(vPosition.y,ffFixed,7,2)+"
|
|
||||||
// "+FloatToStrF(vPosition.z,ffFixed,7,2)+", time
|
|
||||||
// "+FloatToStrF(NoVoltTime,ffFixed,7,2));
|
|
||||||
}
|
}
|
||||||
// Ra 2F1H: nie było sensu wpisywać tu zera po upływie czasu, bo
|
}
|
||||||
// zmienna była
|
// Ra 2F1H: nie było sensu wpisywać tu zera po upływie czasu, bo zmienna była
|
||||||
// tymczasowa, a napięcie zerowane od razu
|
// tymczasowa, a napięcie zerowane od razu
|
||||||
tmpTraction.TractionVoltage = 0; // Ra 2013-12: po co tak?
|
tmpTraction.TractionVoltage = 0; // Ra 2013-12: po co tak?
|
||||||
// pControlled->MainSwitch(false); //może tak?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// else //Ra: nie no, trzeba podnieść pantografy, jak nie będzie drutu, to
|
|
||||||
// będą miały prąd
|
|
||||||
// po osiągnięciu 1.4m
|
|
||||||
// tmpTraction.TractionVoltage=0.95*MoverParameters->EnginePowerSource.MaxVoltage;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tmpTraction.TractionVoltage = 0.95 * MoverParameters->EnginePowerSource.MaxVoltage;
|
tmpTraction.TractionVoltage = 0.95 * MoverParameters->EnginePowerSource.MaxVoltage;
|
||||||
@@ -3199,22 +3158,22 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
else if ( ( true == MoverParameters->PantRearUp )
|
else if ( ( true == MoverParameters->PantRearUp )
|
||||||
&& ( PantDiff < 0.01 ) )
|
&& ( PantDiff < 0.01 ) )
|
||||||
{
|
{
|
||||||
if ((MoverParameters->PantRearVolt == 0.0) &&
|
if( ( MoverParameters->PantRearVolt == 0.0 )
|
||||||
(MoverParameters->PantFrontVolt == 0.0))
|
&& ( MoverParameters->PantFrontVolt == 0.0 ) ) {
|
||||||
sPantUp.Play( vol, 0, MechInside, vPosition );
|
sPantUp.Play( vol, 0, MechInside, vPosition );
|
||||||
if (p->hvPowerWire) // TODO: wyliczyć trzeba prąd przypadający na
|
}
|
||||||
// pantograf i
|
if (p->hvPowerWire) {
|
||||||
// wstawić do GetVoltage()
|
// TODO: wyliczyć trzeba prąd przypadający na pantograf i wstawić do GetVoltage()
|
||||||
{
|
MoverParameters->PantRearVolt = p->hvPowerWire->VoltageGet( MoverParameters->Voltage, fPantCurrent );
|
||||||
MoverParameters->PantRearVolt =
|
|
||||||
p->hvPowerWire->VoltageGet(MoverParameters->Voltage, fPantCurrent);
|
|
||||||
fCurrent -= fPantCurrent; // taki prąd płynie przez powyższy pantograf
|
fCurrent -= fPantCurrent; // taki prąd płynie przez powyższy pantograf
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
MoverParameters->PantRearVolt = 0.0;
|
MoverParameters->PantRearVolt = 0.0;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
|
// Global::iPause ^= 2;
|
||||||
MoverParameters->PantRearVolt = 0.0;
|
MoverParameters->PantRearVolt = 0.0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
} // pozostałe na razie nie obsługiwane
|
} // pozostałe na razie nie obsługiwane
|
||||||
if( MoverParameters->PantPress > (
|
if( MoverParameters->PantPress > (
|
||||||
@@ -3281,8 +3240,8 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
p->fAngleU = acos((p->fLenL1 * cos(k) + p->fHoriz) / p->fLenU1); // górne ramię
|
p->fAngleU = acos((p->fLenL1 * cos(k) + p->fHoriz) / p->fLenU1); // górne ramię
|
||||||
// wyliczyć aktualną wysokość z wzoru sinusowego
|
// wyliczyć aktualną wysokość z wzoru sinusowego
|
||||||
// h=a*sin()+b*sin()
|
// h=a*sin()+b*sin()
|
||||||
p->PantWys = p->fLenL1 * sin(k) + p->fLenU1 * sin(p->fAngleU) +
|
// wysokość całości
|
||||||
p->fHeight; // wysokość całości
|
p->PantWys = p->fLenL1 * sin(k) + p->fLenU1 * sin(p->fAngleU) + p->fHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // koniec pętli po pantografach
|
} // koniec pętli po pantografach
|
||||||
@@ -4438,10 +4397,8 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
|||||||
// pants[i].fParamPants->vPos.z=0; //niezerowe dla pantografów
|
// pants[i].fParamPants->vPos.z=0; //niezerowe dla pantografów
|
||||||
// asymetrycznych
|
// asymetrycznych
|
||||||
pants[ i ].fParamPants->PantTraction = pants[ i ].fParamPants->PantWys;
|
pants[ i ].fParamPants->PantTraction = pants[ i ].fParamPants->PantWys;
|
||||||
pants[ i ].fParamPants->fWidth =
|
// połowa szerokości ślizgu; jest w "Power: CSW="
|
||||||
0.5 *
|
pants[ i ].fParamPants->fWidth = 0.5 * MoverParameters->EnginePowerSource.CollectorParameters.CSW;
|
||||||
MoverParameters->EnginePowerSource.CollectorParameters
|
|
||||||
.CSW; // połowa szerokości ślizgu; jest w "Power: CSW="
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4932,7 +4889,12 @@ void TDynamicObject::RadioStop()
|
|||||||
if( ( MoverParameters->SecuritySystem.RadioStop )
|
if( ( MoverParameters->SecuritySystem.RadioStop )
|
||||||
&& ( MoverParameters->Radio ) ) {
|
&& ( MoverParameters->Radio ) ) {
|
||||||
// jeśli pojazd ma RadioStop i jest on aktywny
|
// jeśli pojazd ma RadioStop i jest on aktywny
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
Mechanik->PutCommand( "Emergency_brake", 1.0, 1.0, &vPosition, stopRadio );
|
Mechanik->PutCommand( "Emergency_brake", 1.0, 1.0, &vPosition, stopRadio );
|
||||||
|
#else
|
||||||
|
// HAX cast until math types unification
|
||||||
|
Mechanik->PutCommand( "Emergency_brake", 1.0, 1.0, &static_cast<glm::dvec3>(vPosition), stopRadio );
|
||||||
|
#endif
|
||||||
// add onscreen notification for human driver
|
// add onscreen notification for human driver
|
||||||
// TODO: do it selectively for the 'local' driver once the multiplayer is in
|
// TODO: do it selectively for the 'local' driver once the multiplayer is in
|
||||||
if( false == Mechanik->AIControllFlag ) {
|
if( false == Mechanik->AIControllFlag ) {
|
||||||
@@ -5404,10 +5366,8 @@ vehicle_table::update( double Deltatime, int Iterationcount ) {
|
|||||||
for( auto *vehicle : m_items ) {
|
for( auto *vehicle : m_items ) {
|
||||||
// Ra: zmienić warunek na sprawdzanie pantografów w jednej zmiennej: czy pantografy i czy podniesione
|
// Ra: zmienić warunek na sprawdzanie pantografów w jednej zmiennej: czy pantografy i czy podniesione
|
||||||
if( vehicle->MoverParameters->EnginePowerSource.SourceType == CurrentCollector ) {
|
if( vehicle->MoverParameters->EnginePowerSource.SourceType == CurrentCollector ) {
|
||||||
/*
|
|
||||||
// TODO: re-implement
|
// TODO: re-implement
|
||||||
GetTraction( vehicle );
|
update_traction( vehicle );
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
vehicle->MoverParameters->ComputeConstans();
|
vehicle->MoverParameters->ComputeConstans();
|
||||||
vehicle->CoupleDist();
|
vehicle->CoupleDist();
|
||||||
@@ -5447,3 +5407,97 @@ vehicle_table::update( double Deltatime, int Iterationcount ) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// legacy method, checks for presence and height of traction wire for specified vehicle
|
||||||
|
void
|
||||||
|
vehicle_table::update_traction( TDynamicObject *Vehicle ) {
|
||||||
|
|
||||||
|
auto const vFront = glm::make_vec3( Vehicle->VectorFront().getArray() ); // wektor normalny dla płaszczyzny ruchu pantografu
|
||||||
|
auto const vUp = glm::make_vec3( Vehicle->VectorUp().getArray() ); // wektor pionu pudła (pochylony od pionu na przechyłce)
|
||||||
|
auto const vLeft = glm::make_vec3( Vehicle->VectorLeft().getArray() ); // wektor odległości w bok (odchylony od poziomu na przechyłce)
|
||||||
|
auto const position = glm::dvec3 { Vehicle->GetPosition() }; // współrzędne środka pojazdu
|
||||||
|
|
||||||
|
for( int pantographindex = 0; pantographindex < Vehicle->iAnimType[ ANIM_PANTS ]; ++pantographindex ) {
|
||||||
|
// pętla po pantografach
|
||||||
|
auto pantograph { Vehicle->pants[ pantographindex ].fParamPants };
|
||||||
|
if( true == (
|
||||||
|
pantographindex == TMoverParameters::side::front ?
|
||||||
|
Vehicle->MoverParameters->PantFrontUp :
|
||||||
|
Vehicle->MoverParameters->PantRearUp ) ) {
|
||||||
|
// jeśli pantograf podniesiony
|
||||||
|
auto const pant0 { position + ( vLeft * pantograph->vPos.z ) + ( vUp * pantograph->vPos.y ) + ( vFront * pantograph->vPos.x ) };
|
||||||
|
if( pantograph->hvPowerWire != nullptr ) {
|
||||||
|
// jeżeli znamy drut z poprzedniego przebiegu
|
||||||
|
for( int attempts = 0; attempts < 30; ++attempts ) {
|
||||||
|
// powtarzane aż do znalezienia odpowiedniego odcinka na liście dwukierunkowej
|
||||||
|
if( pantograph->hvPowerWire->iLast & 0x3 ) {
|
||||||
|
// dla ostatniego i przedostatniego przęsła wymuszamy szukanie innego
|
||||||
|
// nie to, że nie ma, ale trzeba sprawdzić inne
|
||||||
|
pantograph->hvPowerWire = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( pantograph->hvPowerWire->hvParallel ) {
|
||||||
|
// jeśli przęsło tworzy bieżnię wspólną, to trzeba sprawdzić pozostałe
|
||||||
|
// nie to, że nie ma, ale trzeba sprawdzić inne
|
||||||
|
pantograph->hvPowerWire = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// obliczamy wyraz wolny równania płaszczyzny (to miejsce nie jest odpowienie)
|
||||||
|
// podstawiamy równanie parametryczne drutu do równania płaszczyzny pantografu
|
||||||
|
auto const fRaParam =
|
||||||
|
-( glm::dot( pantograph->hvPowerWire->pPoint1, vFront ) - glm::dot( pant0, vFront ) )
|
||||||
|
/ glm::dot( pantograph->hvPowerWire->vParametric, vFront );
|
||||||
|
|
||||||
|
if( fRaParam < -0.001 ) {
|
||||||
|
// histereza rzędu 7cm na 70m typowego przęsła daje 1 promil
|
||||||
|
pantograph->hvPowerWire = pantograph->hvPowerWire->hvNext[ 0 ];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( fRaParam > 1.001 ) {
|
||||||
|
pantograph->hvPowerWire = pantograph->hvPowerWire->hvNext[ 1 ];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// jeśli t jest w przedziale, wyznaczyć odległość wzdłuż wektorów vUp i vLeft
|
||||||
|
// punkt styku płaszczyzny z drutem (dla generatora łuku el.)
|
||||||
|
auto const vStyk { pantograph->hvPowerWire->pPoint1 + fRaParam * pantograph->hvPowerWire->vParametric };
|
||||||
|
auto const vGdzie { vStyk - pant0 }; // wektor
|
||||||
|
// odległość w pionie musi być w zasięgu ruchu "pionowego" pantografu
|
||||||
|
// musi się mieścić w przedziale ruchu pantografu
|
||||||
|
auto const fVertical { glm::dot( vGdzie, vUp ) };
|
||||||
|
// odległość w bok powinna być mniejsza niż pół szerokości pantografu
|
||||||
|
// to się musi mieścić w przedziale zależnym od szerokości pantografu
|
||||||
|
auto const fHorizontal { std::abs( glm::dot( vGdzie, vLeft ) ) - pantograph->fWidth };
|
||||||
|
// jeśli w pionie albo w bok jest za daleko, to dany drut jest nieużyteczny
|
||||||
|
if( fHorizontal <= 0.0 ) {
|
||||||
|
// koniec pętli, aktualny drut pasuje
|
||||||
|
pantograph->PantTraction = fVertical;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// the wire is outside contact area and as of now we don't have good detection of parallel sections
|
||||||
|
// as such there's no guaratee there isn't parallel section present.
|
||||||
|
// therefore we don't bother checking if the wire is still within range of guide horns
|
||||||
|
// but simply force area search for potential better option
|
||||||
|
pantograph->hvPowerWire = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pantograph->hvPowerWire == nullptr ) {
|
||||||
|
// look in the region for a suitable traction piece if we don't already have any
|
||||||
|
simulation::Region->update_traction( Vehicle, pantographindex );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( pantograph->hvPowerWire == nullptr )
|
||||||
|
&& ( false == Global::bLiveTraction ) ) {
|
||||||
|
// jeśli drut nie znaleziony ale można oszukiwać to dajemy coś tam dla picu
|
||||||
|
Vehicle->pants[ pantographindex ].fParamPants->PantTraction = 1.4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// pantograph is down
|
||||||
|
pantograph->hvPowerWire = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
3
DynObj.h
3
DynObj.h
@@ -492,6 +492,9 @@ public:
|
|||||||
// legacy method, calculates changes in simulation state over specified time
|
// legacy method, calculates changes in simulation state over specified time
|
||||||
void
|
void
|
||||||
update( double dt, int iter );
|
update( double dt, int iter );
|
||||||
|
// legacy method, checks for presence and height of traction wire for specified vehicle
|
||||||
|
void
|
||||||
|
update_traction( TDynamicObject *Vehicle );
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
40
EvLaunch.cpp
40
EvLaunch.cpp
@@ -17,36 +17,14 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "EvLaunch.h"
|
#include "EvLaunch.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
#include "Usefull.h"
|
|
||||||
#include "McZapkie/mctools.h"
|
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
#include "MemCell.h"
|
#include "MemCell.h"
|
||||||
#include "mtable.h"
|
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
|
|
||||||
using namespace Mtable;
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
TEventLauncher::TEventLauncher()
|
|
||||||
{ // ustawienie początkowych wartości dla wszystkich zmiennych
|
|
||||||
iKey = 0;
|
|
||||||
DeltaTime = -1;
|
|
||||||
UpdatedTime = 0;
|
|
||||||
fVal1 = fVal2 = 0;
|
|
||||||
iHour = iMinute = -1; // takiego czasu nigdy nie będzie
|
|
||||||
dRadius = 0;
|
|
||||||
Event1 = Event2 = NULL;
|
|
||||||
MemCell = NULL;
|
|
||||||
iCheckMask = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEventLauncher::Init()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// encodes expected key in a short, where low byte represents the actual key,
|
// encodes expected key in a short, where low byte represents the actual key,
|
||||||
// and the high byte holds modifiers: 0x1 = shift, 0x2 = ctrl, 0x4 = alt
|
// and the high byte holds modifiers: 0x1 = shift, 0x2 = ctrl, 0x4 = alt
|
||||||
int vk_to_glfw_key( int const Keycode ) {
|
int vk_to_glfw_key( int const Keycode ) {
|
||||||
@@ -145,7 +123,7 @@ bool TEventLauncher::Load(cParser *parser)
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool TEventLauncher::Render()
|
bool TEventLauncher::check_conditions()
|
||||||
{ //"renderowanie" wyzwalacza
|
{ //"renderowanie" wyzwalacza
|
||||||
bool bCond = false;
|
bool bCond = false;
|
||||||
if (iKey != 0)
|
if (iKey != 0)
|
||||||
@@ -199,13 +177,13 @@ bool TEventLauncher::Render()
|
|||||||
return bCond; // sprawdzanie dRadius w Ground.cpp
|
return bCond; // sprawdzanie dRadius w Ground.cpp
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TEventLauncher::IsGlobal()
|
// sprawdzenie, czy jest globalnym wyzwalaczem czasu
|
||||||
{ // sprawdzenie, czy jest globalnym wyzwalaczem czasu
|
bool TEventLauncher::IsGlobal() const {
|
||||||
if (DeltaTime == 0)
|
|
||||||
if (iHour >= 0)
|
return ( ( DeltaTime == 0 )
|
||||||
if (iMinute >= 0)
|
&& ( iHour >= 0 )
|
||||||
if (dRadius < 0.0) // bez ograniczenia zasięgu
|
&& ( iMinute >= 0 )
|
||||||
return true;
|
&& ( dRadius < 0.0 ) ); // bez ograniczenia zasięgu
|
||||||
return false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
53
EvLaunch.h
53
EvLaunch.h
@@ -10,32 +10,43 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "Classes.h"
|
|
||||||
|
|
||||||
class TEventLauncher
|
#include "Classes.h"
|
||||||
{
|
#include "scenenode.h"
|
||||||
private:
|
|
||||||
int iKey;
|
class TEventLauncher : public editor::basic_node {
|
||||||
double DeltaTime;
|
|
||||||
double UpdatedTime;
|
|
||||||
double fVal1;
|
|
||||||
double fVal2;
|
|
||||||
std::string szText;
|
|
||||||
int iHour, iMinute; // minuta uruchomienia
|
|
||||||
public:
|
public:
|
||||||
double dRadius;
|
// constructor
|
||||||
|
TEventLauncher( scene::node_data const &Nodedata ) : basic_node( Nodedata ) {}
|
||||||
|
// legacy constructor
|
||||||
|
TEventLauncher() = default;
|
||||||
|
|
||||||
|
// methods
|
||||||
|
bool Load( cParser *parser );
|
||||||
|
// checks conditions associated with the event. returns: true if the conditions are met
|
||||||
|
bool check_conditions();
|
||||||
|
bool IsGlobal() const;
|
||||||
|
// members
|
||||||
std::string asEvent1Name;
|
std::string asEvent1Name;
|
||||||
std::string asEvent2Name;
|
std::string asEvent2Name;
|
||||||
std::string asMemCellName;
|
std::string asMemCellName;
|
||||||
TEvent *Event1;
|
TEvent *Event1 { nullptr };
|
||||||
TEvent *Event2;
|
TEvent *Event2 { nullptr };
|
||||||
TMemCell *MemCell;
|
TMemCell *MemCell { nullptr };
|
||||||
int iCheckMask;
|
int iCheckMask { 0 };
|
||||||
TEventLauncher();
|
double dRadius { 0.0 };
|
||||||
void Init();
|
|
||||||
bool Load(cParser *parser);
|
private:
|
||||||
bool Render();
|
// members
|
||||||
bool IsGlobal();
|
int iKey { 0 };
|
||||||
|
double DeltaTime { -1.0 };
|
||||||
|
double UpdatedTime { 0.0 };
|
||||||
|
double fVal1 { 0.0 };
|
||||||
|
double fVal2 { 0.0 };
|
||||||
|
std::string szText;
|
||||||
|
int iHour { -1 };
|
||||||
|
int iMinute { -1 }; // minuta uruchomienia
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
292
Event.cpp
292
Event.cpp
@@ -727,6 +727,32 @@ event_manager::~event_manager() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// adds specified event launcher to the list of global launchers
|
||||||
|
void
|
||||||
|
event_manager::queue( TEventLauncher *Launcher ) {
|
||||||
|
|
||||||
|
m_launcherqueue.emplace_back( Launcher );
|
||||||
|
}
|
||||||
|
|
||||||
|
// legacy method, updates event queues
|
||||||
|
void
|
||||||
|
event_manager::update() {
|
||||||
|
|
||||||
|
// process currently queued events
|
||||||
|
CheckQuery();
|
||||||
|
// test list of global events for possible new additions to the queue
|
||||||
|
for( auto *launcher : m_launcherqueue ) {
|
||||||
|
|
||||||
|
if( true == launcher->check_conditions() ) {
|
||||||
|
// NOTE: we're presuming global events aren't going to use event2
|
||||||
|
WriteLog( "Eventlauncher " + launcher->name() );
|
||||||
|
if( launcher->Event1 ) {
|
||||||
|
Global::AddToQuery( launcher->Event1, nullptr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// adds provided event to the collection. returns: true on success
|
// adds provided event to the collection. returns: true on success
|
||||||
// TODO: return handle instead of pointer
|
// TODO: return handle instead of pointer
|
||||||
bool
|
bool
|
||||||
@@ -826,7 +852,11 @@ event_manager::AddToQuery( TEvent *Event, TDynamicObject *Owner ) {
|
|||||||
for( auto dynamic : Event->Params[ 6 ].asTrack->Dynamics ) {
|
for( auto dynamic : Event->Params[ 6 ].asTrack->Dynamics ) {
|
||||||
Event->Params[ 5 ].asMemCell->PutCommand(
|
Event->Params[ 5 ].asMemCell->PutCommand(
|
||||||
dynamic->Mechanik,
|
dynamic->Mechanik,
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
&Event->Params[ 4 ].nGroundNode->pCenter );
|
&Event->Params[ 4 ].nGroundNode->pCenter );
|
||||||
|
#else
|
||||||
|
Event->Params[ 4 ].asLocation );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
//if (DebugModeFlag)
|
//if (DebugModeFlag)
|
||||||
WriteLog(
|
WriteLog(
|
||||||
@@ -924,7 +954,11 @@ event_manager::CheckQuery() {
|
|||||||
for( auto dynamic : m_workevent->Params[ 6 ].asTrack->Dynamics ) {
|
for( auto dynamic : m_workevent->Params[ 6 ].asTrack->Dynamics ) {
|
||||||
m_workevent->Params[ 5 ].asMemCell->PutCommand(
|
m_workevent->Params[ 5 ].asMemCell->PutCommand(
|
||||||
dynamic->Mechanik,
|
dynamic->Mechanik,
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
&m_workevent->Params[ 4 ].nGroundNode->pCenter );
|
&m_workevent->Params[ 4 ].nGroundNode->pCenter );
|
||||||
|
#else
|
||||||
|
m_workevent->Params[ 4 ].asLocation );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
//if (DebugModeFlag)
|
//if (DebugModeFlag)
|
||||||
WriteLog("Type: UpdateValues & Track command - [" +
|
WriteLog("Type: UpdateValues & Track command - [" +
|
||||||
@@ -950,7 +984,11 @@ event_manager::CheckQuery() {
|
|||||||
*/
|
*/
|
||||||
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
|
||||||
&m_workevent->Params[ 8 ].nGroundNode->pCenter );
|
&m_workevent->Params[ 8 ].nGroundNode->pCenter );
|
||||||
|
#else
|
||||||
|
m_workevent->Params[ 8 ].asLocation );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
WriteLog( "Type: GetValues" );
|
WriteLog( "Type: GetValues" );
|
||||||
break;
|
break;
|
||||||
@@ -1273,263 +1311,263 @@ void
|
|||||||
event_manager::InitEvents() {
|
event_manager::InitEvents() {
|
||||||
|
|
||||||
//łączenie eventów z pozostałymi obiektami
|
//łączenie eventów z pozostałymi obiektami
|
||||||
for( auto *Current : m_events ) {
|
for( auto *event : m_events ) {
|
||||||
|
|
||||||
switch (Current->Type) {
|
switch( event->Type ) {
|
||||||
|
|
||||||
case tp_AddValues: // sumowanie wartości
|
case tp_AddValues: // sumowanie wartości
|
||||||
case tp_UpdateValues: { // zmiana wartości
|
case tp_UpdateValues: { // zmiana wartości
|
||||||
auto *cell = simulation::Memory.find( Current->asNodeName ); // nazwa komórki powiązanej z eventem
|
auto *cell = simulation::Memory.find( event->asNodeName ); // nazwa komórki powiązanej z eventem
|
||||||
if( cell != nullptr ) { // McZapkie-100302
|
if( cell != nullptr ) { // McZapkie-100302
|
||||||
if( Current->iFlags & ( conditional_trackoccupied | conditional_trackfree ) ) {
|
if( event->iFlags & ( conditional_trackoccupied | conditional_trackfree ) ) {
|
||||||
// jeśli chodzi o zajetosc toru (tor może być inny, niż wpisany w komórce)
|
// jeśli chodzi o zajetosc toru (tor może być inny, niż wpisany w komórce)
|
||||||
// nazwa toru ta sama, co nazwa komórki
|
// nazwa toru ta sama, co nazwa komórki
|
||||||
Current->Params[ 9 ].asTrack = simulation::Paths.find( Current->asNodeName );
|
event->Params[ 9 ].asTrack = simulation::Paths.find( event->asNodeName );
|
||||||
if( Current->Params[ 9 ].asTrack == nullptr ) {
|
if( event->Params[ 9 ].asTrack == nullptr ) {
|
||||||
ErrorLog( "Bad event: track \"" + Current->asNodeName + "\" referenced in event \"" + Current->asName + "\" doesn't exist" );
|
ErrorLog( "Bad event: track \"" + event->asNodeName + "\" referenced in event \"" + event->asName + "\" doesn't exist" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Current->Params[ 4 ].asLocation = &( cell->location() );
|
event->Params[ 4 ].asLocation = &( cell->location() );
|
||||||
Current->Params[ 5 ].asMemCell = cell; // komórka do aktualizacji
|
event->Params[ 5 ].asMemCell = cell; // komórka do aktualizacji
|
||||||
if( Current->iFlags & ( conditional_memcompare ) ) {
|
if( event->iFlags & ( conditional_memcompare ) ) {
|
||||||
// komórka do badania warunku
|
// komórka do badania warunku
|
||||||
Current->Params[ 9 ].asMemCell = cell;
|
event->Params[ 9 ].asMemCell = cell;
|
||||||
}
|
}
|
||||||
if( false == cell->asTrackName.empty() ) {
|
if( false == cell->asTrackName.empty() ) {
|
||||||
// tor powiązany z komórką powiązaną z eventem
|
// tor powiązany z komórką powiązaną z eventem
|
||||||
// tu potrzebujemy wskaźnik do komórki w (tmp)
|
// tu potrzebujemy wskaźnik do komórki w (tmp)
|
||||||
Current->Params[ 6 ].asTrack = simulation::Paths.find( cell->asTrackName );
|
event->Params[ 6 ].asTrack = simulation::Paths.find( cell->asTrackName );
|
||||||
if( Current->Params[ 6 ].asTrack == nullptr ) {
|
if( event->Params[ 6 ].asTrack == nullptr ) {
|
||||||
ErrorLog( "Bad memcell: track \"" + cell->asTrackName + "\" referenced in memcell \"" + cell->name() + "\" doesn't exist" );
|
ErrorLog( "Bad memcell: track \"" + cell->asTrackName + "\" referenced in memcell \"" + cell->name() + "\" doesn't exist" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Current->Params[ 6 ].asTrack = nullptr;
|
event->Params[ 6 ].asTrack = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// nie ma komórki, to nie będzie działał poprawnie
|
// nie ma komórki, to nie będzie działał poprawnie
|
||||||
Current->m_ignored = true; // deaktywacja
|
event->m_ignored = true; // deaktywacja
|
||||||
ErrorLog( "Bad event: event \"" + Current->asName + "\" cannot find memcell \"" + Current->asNodeName + "\"" );
|
ErrorLog( "Bad event: event \"" + event->asName + "\" cannot find memcell \"" + event->asNodeName + "\"" );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tp_LogValues: {
|
case tp_LogValues: {
|
||||||
// skojarzenie z memcell
|
// skojarzenie z memcell
|
||||||
if( Current->asNodeName.empty() ) { // brak skojarzenia daje logowanie wszystkich
|
if( event->asNodeName.empty() ) { // brak skojarzenia daje logowanie wszystkich
|
||||||
Current->Params[ 9 ].asMemCell = nullptr;
|
event->Params[ 9 ].asMemCell = nullptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case tp_GetValues:
|
case tp_GetValues:
|
||||||
case tp_WhoIs: {
|
case tp_WhoIs: {
|
||||||
auto *cell = simulation::Memory.find( Current->asNodeName );
|
auto *cell = simulation::Memory.find( event->asNodeName );
|
||||||
if( cell != nullptr ) {
|
if( cell != nullptr ) {
|
||||||
Current->Params[ 8 ].asLocation = &( cell->location() );
|
event->Params[ 8 ].asLocation = &( cell->location() );
|
||||||
Current->Params[ 9 ].asMemCell = cell;
|
event->Params[ 9 ].asMemCell = cell;
|
||||||
if( ( Current->Type == tp_GetValues )
|
if( ( event->Type == tp_GetValues )
|
||||||
&& ( cell->IsVelocity() ) ) {
|
&& ( cell->IsVelocity() ) ) {
|
||||||
// jeśli odczyt komórki a komórka zawiera komendę SetVelocity albo ShuntVelocity
|
// jeśli odczyt komórki a komórka zawiera komendę SetVelocity albo ShuntVelocity
|
||||||
// to event nie będzie dodawany do kolejki
|
// to event nie będzie dodawany do kolejki
|
||||||
Current->bEnabled = false;
|
event->bEnabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// nie ma komórki, to nie będzie działał poprawnie
|
// nie ma komórki, to nie będzie działał poprawnie
|
||||||
Current->m_ignored = true; // deaktywacja
|
event->m_ignored = true; // deaktywacja
|
||||||
ErrorLog( "Bad event: event \"" + Current->asName + "\" cannot find memcell \"" + Current->asNodeName + "\"" );
|
ErrorLog( "Bad event: event \"" + event->asName + "\" cannot find memcell \"" + event->asNodeName + "\"" );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tp_CopyValues: {
|
case tp_CopyValues: {
|
||||||
// skopiowanie komórki do innej
|
// skopiowanie komórki do innej
|
||||||
auto *cell = simulation::Memory.find( Current->asNodeName ); // komórka docelowa
|
auto *cell = simulation::Memory.find( event->asNodeName ); // komórka docelowa
|
||||||
if( cell != nullptr ) {
|
if( cell != nullptr ) {
|
||||||
Current->Params[ 4 ].asLocation = &( cell->location() );
|
event->Params[ 4 ].asLocation = &( cell->location() );
|
||||||
Current->Params[ 5 ].asMemCell = cell; // komórka docelowa
|
event->Params[ 5 ].asMemCell = cell; // komórka docelowa
|
||||||
if( false == cell->asTrackName.empty() ) {
|
if( false == cell->asTrackName.empty() ) {
|
||||||
// tor powiązany z komórką powiązaną z eventem
|
// tor powiązany z komórką powiązaną z eventem
|
||||||
// tu potrzebujemy wskaźnik do komórki w (tmp)
|
// tu potrzebujemy wskaźnik do komórki w (tmp)
|
||||||
Current->Params[ 6 ].asTrack = simulation::Paths.find( cell->asTrackName );
|
event->Params[ 6 ].asTrack = simulation::Paths.find( cell->asTrackName );
|
||||||
if( Current->Params[ 6 ].asTrack == nullptr ) {
|
if( event->Params[ 6 ].asTrack == nullptr ) {
|
||||||
ErrorLog( "Bad memcell: track \"" + cell->asTrackName + "\" referenced in memcell \"" + cell->name() + "\" doesn't exists" );
|
ErrorLog( "Bad memcell: track \"" + cell->asTrackName + "\" referenced in memcell \"" + cell->name() + "\" doesn't exists" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Current->Params[ 6 ].asTrack = nullptr;
|
event->Params[ 6 ].asTrack = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorLog( "Bad event: copyvalues event \"" + Current->asName + "\" cannot find memcell \"" + Current->asNodeName + "\"" );
|
ErrorLog( "Bad event: copyvalues event \"" + event->asName + "\" cannot find memcell \"" + event->asNodeName + "\"" );
|
||||||
}
|
}
|
||||||
std::string const cellastext { Current->Params[ 9 ].asText };
|
std::string const cellastext { event->Params[ 9 ].asText };
|
||||||
cell = simulation::Memory.find( Current->Params[ 9 ].asText ); // komórka źódłowa
|
cell = simulation::Memory.find( event->Params[ 9 ].asText ); // komórka źódłowa
|
||||||
SafeDeleteArray( Current->Params[ 9 ].asText ); // usunięcie nazwy komórki
|
SafeDeleteArray( event->Params[ 9 ].asText ); // usunięcie nazwy komórki
|
||||||
if( cell != nullptr ) {
|
if( cell != nullptr ) {
|
||||||
Current->Params[ 8 ].asLocation = &( cell->location() );
|
event->Params[ 8 ].asLocation = &( cell->location() );
|
||||||
Current->Params[ 9 ].asMemCell = cell; // komórka źródłowa
|
event->Params[ 9 ].asMemCell = cell; // komórka źródłowa
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorLog( "Bad event: copyvalues event \"" + Current->asName + "\" cannot find memcell \"" + cellastext + "\"" );
|
ErrorLog( "Bad event: copyvalues event \"" + event->asName + "\" cannot find memcell \"" + cellastext + "\"" );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tp_Animation: {
|
case tp_Animation: {
|
||||||
// animacja modelu
|
// animacja modelu
|
||||||
// retrieve target name parameter
|
// retrieve target name parameter
|
||||||
std::string const cellastext = Current->Params[ 9 ].asText;
|
std::string const cellastext = event->Params[ 9 ].asText;
|
||||||
SafeDeleteArray( Current->Params[ 9 ].asText );
|
SafeDeleteArray( event->Params[ 9 ].asText );
|
||||||
// egzemplarz modelu do animowania
|
// egzemplarz modelu do animowania
|
||||||
auto *instance = simulation::Instances.find( Current->asNodeName );
|
auto *instance = simulation::Instances.find( event->asNodeName );
|
||||||
if( instance != nullptr ) {
|
if( instance != nullptr ) {
|
||||||
if( Current->Params[ 0 ].asInt == 4 ) {
|
if( event->Params[ 0 ].asInt == 4 ) {
|
||||||
// model dla całomodelowych animacji
|
// model dla całomodelowych animacji
|
||||||
Current->Params[ 9 ].asModel = instance;
|
event->Params[ 9 ].asModel = instance;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// standardowo przypisanie submodelu
|
// standardowo przypisanie submodelu
|
||||||
Current->Params[ 9 ].asAnimContainer = instance->GetContainer( cellastext ); // submodel
|
event->Params[ 9 ].asAnimContainer = instance->GetContainer( cellastext ); // submodel
|
||||||
if( Current->Params[ 9 ].asAnimContainer ) {
|
if( event->Params[ 9 ].asAnimContainer ) {
|
||||||
Current->Params[ 9 ].asAnimContainer->WillBeAnimated(); // oflagowanie animacji
|
event->Params[ 9 ].asAnimContainer->WillBeAnimated(); // oflagowanie animacji
|
||||||
if( Current->Params[ 9 ].asAnimContainer->Event() == nullptr ) {
|
if( event->Params[ 9 ].asAnimContainer->Event() == nullptr ) {
|
||||||
// nie szukać, gdy znaleziony
|
// nie szukać, gdy znaleziony
|
||||||
Current->Params[ 9 ].asAnimContainer->EventAssign(
|
event->Params[ 9 ].asAnimContainer->EventAssign(
|
||||||
FindEvent( Current->asNodeName + "." + cellastext + ":done" ) );
|
FindEvent( event->asNodeName + "." + cellastext + ":done" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorLog( "Bad event: animation event \"" + Current->asName + "\" cannot find model instance \"" + Current->asNodeName + "\"" );
|
ErrorLog( "Bad event: animation event \"" + event->asName + "\" cannot find model instance \"" + event->asNodeName + "\"" );
|
||||||
}
|
}
|
||||||
Current->asNodeName = "";
|
event->asNodeName = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tp_Lights: {
|
case tp_Lights: {
|
||||||
// zmiana świeteł modelu
|
// zmiana świeteł modelu
|
||||||
auto *instance = simulation::Instances.find( Current->asNodeName );
|
auto *instance = simulation::Instances.find( event->asNodeName );
|
||||||
if( instance != nullptr )
|
if( instance != nullptr )
|
||||||
Current->Params[ 9 ].asModel = instance;
|
event->Params[ 9 ].asModel = instance;
|
||||||
else
|
else
|
||||||
ErrorLog( "Bad event: lights event \"" + Current->asName + "\" cannot find model instance \"" + Current->asNodeName + "\"" );
|
ErrorLog( "Bad event: lights event \"" + event->asName + "\" cannot find model instance \"" + event->asNodeName + "\"" );
|
||||||
Current->asNodeName = "";
|
event->asNodeName = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tp_Visible: {
|
case tp_Visible: {
|
||||||
// ukrycie albo przywrócenie obiektu
|
// ukrycie albo przywrócenie obiektu
|
||||||
editor::basic_node *node = simulation::Instances.find( Current->asNodeName ); // najpierw model
|
editor::basic_node *node = simulation::Instances.find( event->asNodeName ); // najpierw model
|
||||||
if( node == nullptr ) {
|
if( node == nullptr ) {
|
||||||
// albo tory?
|
// albo tory?
|
||||||
node = simulation::Paths.find( Current->asNodeName );
|
node = simulation::Paths.find( event->asNodeName );
|
||||||
}
|
}
|
||||||
if( node == nullptr ) {
|
if( node == nullptr ) {
|
||||||
// może druty?
|
// może druty?
|
||||||
node = simulation::Traction.find( Current->asNodeName );
|
node = simulation::Traction.find( event->asNodeName );
|
||||||
}
|
}
|
||||||
if( node != nullptr )
|
if( node != nullptr )
|
||||||
Current->Params[ 9 ].asEditorNode = node;
|
event->Params[ 9 ].asEditorNode = node;
|
||||||
else
|
else
|
||||||
ErrorLog( "Bad event: visibility event \"" + Current->asName + "\" cannot find item \"" + Current->asNodeName + "\"" );
|
ErrorLog( "Bad event: visibility event \"" + event->asName + "\" cannot find item \"" + event->asNodeName + "\"" );
|
||||||
Current->asNodeName = "";
|
event->asNodeName = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tp_Switch: {
|
case tp_Switch: {
|
||||||
// przełożenie zwrotnicy albo zmiana stanu obrotnicy
|
// przełożenie zwrotnicy albo zmiana stanu obrotnicy
|
||||||
auto *track = simulation::Paths.find( Current->asNodeName );
|
auto *track = simulation::Paths.find( event->asNodeName );
|
||||||
if( track != nullptr ) {
|
if( track != nullptr ) {
|
||||||
// dowiązanie toru
|
// dowiązanie toru
|
||||||
if( track->iAction == NULL ) {
|
if( track->iAction == NULL ) {
|
||||||
// jeśli nie jest zwrotnicą ani obrotnicą to będzie się zmieniał stan uszkodzenia
|
// jeśli nie jest zwrotnicą ani obrotnicą to będzie się zmieniał stan uszkodzenia
|
||||||
track->iAction |= 0x100;
|
track->iAction |= 0x100;
|
||||||
}
|
}
|
||||||
Current->Params[ 9 ].asTrack = track;
|
event->Params[ 9 ].asTrack = track;
|
||||||
if( ( Current->Params[ 0 ].asInt == 0 )
|
if( ( event->Params[ 0 ].asInt == 0 )
|
||||||
&& ( Current->Params[ 2 ].asdouble >= 0.0 ) ) {
|
&& ( event->Params[ 2 ].asdouble >= 0.0 ) ) {
|
||||||
// jeśli przełącza do stanu 0 & jeśli jest zdefiniowany dodatkowy ruch iglic
|
// jeśli przełącza do stanu 0 & jeśli jest zdefiniowany dodatkowy ruch iglic
|
||||||
// przesłanie parametrów
|
// przesłanie parametrów
|
||||||
Current->Params[ 9 ].asTrack->Switch(
|
event->Params[ 9 ].asTrack->Switch(
|
||||||
Current->Params[ 0 ].asInt,
|
event->Params[ 0 ].asInt,
|
||||||
Current->Params[ 1 ].asdouble,
|
event->Params[ 1 ].asdouble,
|
||||||
Current->Params[ 2 ].asdouble );
|
event->Params[ 2 ].asdouble );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorLog( "Bad event: switch event \"" + Current->asName + "\" cannot find track \"" + Current->asNodeName + "\"" );
|
ErrorLog( "Bad event: switch event \"" + event->asName + "\" cannot find track \"" + event->asNodeName + "\"" );
|
||||||
}
|
}
|
||||||
Current->asNodeName = "";
|
event->asNodeName = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tp_Sound: {
|
case tp_Sound: {
|
||||||
// odtworzenie dźwięku
|
// odtworzenie dźwięku
|
||||||
auto *sound = simulation::Sounds.find( Current->asNodeName );
|
auto *sound = simulation::Sounds.find( event->asNodeName );
|
||||||
if( sound != nullptr )
|
if( sound != nullptr )
|
||||||
Current->Params[ 9 ].tsTextSound = sound;
|
event->Params[ 9 ].tsTextSound = sound;
|
||||||
else
|
else
|
||||||
ErrorLog( "Bad event: sound event \"" + Current->asName + "\" cannot find static sound \"" + Current->asNodeName + "\"" );
|
ErrorLog( "Bad event: sound event \"" + event->asName + "\" cannot find static sound \"" + event->asNodeName + "\"" );
|
||||||
Current->asNodeName = "";
|
event->asNodeName = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tp_TrackVel: {
|
case tp_TrackVel: {
|
||||||
// ustawienie prędkości na torze
|
// ustawienie prędkości na torze
|
||||||
if( false == Current->asNodeName.empty() ) {
|
if( false == event->asNodeName.empty() ) {
|
||||||
auto *track = simulation::Paths.find( Current->asNodeName );
|
auto *track = simulation::Paths.find( event->asNodeName );
|
||||||
if( track != nullptr ) {
|
if( track != nullptr ) {
|
||||||
// flaga zmiany prędkości toru jest istotna dla skanowania
|
// flaga zmiany prędkości toru jest istotna dla skanowania
|
||||||
track->iAction |= 0x200;
|
track->iAction |= 0x200;
|
||||||
Current->Params[ 9 ].asTrack = track;
|
event->Params[ 9 ].asTrack = track;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorLog( "Bad event: track velocity event \"" + Current->asName + "\" cannot find track \"" + Current->asNodeName + "\"" );
|
ErrorLog( "Bad event: track velocity event \"" + event->asName + "\" cannot find track \"" + event->asNodeName + "\"" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Current->asNodeName = "";
|
event->asNodeName = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tp_DynVel: {
|
case tp_DynVel: {
|
||||||
// komunikacja z pojazdem o konkretnej nazwie
|
// komunikacja z pojazdem o konkretnej nazwie
|
||||||
if( Current->asNodeName == "activator" )
|
if( event->asNodeName == "activator" )
|
||||||
Current->Params[ 9 ].asDynamic = nullptr;
|
event->Params[ 9 ].asDynamic = nullptr;
|
||||||
else {
|
else {
|
||||||
auto *vehicle = simulation::Vehicles.find( Current->asNodeName );
|
auto *vehicle = simulation::Vehicles.find( event->asNodeName );
|
||||||
if( vehicle != nullptr )
|
if( vehicle != nullptr )
|
||||||
Current->Params[ 9 ].asDynamic = vehicle;
|
event->Params[ 9 ].asDynamic = vehicle;
|
||||||
else
|
else
|
||||||
Error( "Bad event: vehicle velocity event \"" + Current->asName + "\" cannot find vehicle \"" + Current->asNodeName + "\"" );
|
ErrorLog( "Bad event: vehicle velocity event \"" + event->asName + "\" cannot find vehicle \"" + event->asNodeName + "\"" );
|
||||||
}
|
}
|
||||||
Current->asNodeName = "";
|
event->asNodeName = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tp_Multiple: {
|
case tp_Multiple: {
|
||||||
std::string cellastext;
|
std::string cellastext;
|
||||||
if( Current->Params[ 9 ].asText != nullptr ) { // przepisanie nazwy do bufora
|
if( event->Params[ 9 ].asText != nullptr ) { // przepisanie nazwy do bufora
|
||||||
cellastext = Current->Params[ 9 ].asText;
|
cellastext = event->Params[ 9 ].asText;
|
||||||
SafeDeleteArray( Current->Params[ 9 ].asText );
|
SafeDeleteArray( event->Params[ 9 ].asText );
|
||||||
Current->Params[ 9 ].asPointer = nullptr; // zerowanie wskaźnika, aby wykryć brak obeiktu
|
event->Params[ 9 ].asPointer = nullptr; // zerowanie wskaźnika, aby wykryć brak obeiktu
|
||||||
}
|
}
|
||||||
if( Current->iFlags & ( conditional_trackoccupied | conditional_trackfree ) ) {
|
if( event->iFlags & ( conditional_trackoccupied | conditional_trackfree ) ) {
|
||||||
// jeśli chodzi o zajetosc toru
|
// jeśli chodzi o zajetosc toru
|
||||||
Current->Params[ 9 ].asTrack = simulation::Paths.find( cellastext );
|
event->Params[ 9 ].asTrack = simulation::Paths.find( cellastext );
|
||||||
if( Current->Params[ 9 ].asTrack == nullptr ) {
|
if( event->Params[ 9 ].asTrack == nullptr ) {
|
||||||
ErrorLog( "Bad event: multi-event \"" + Current->asName + "\" cannot find track \"" + cellastext + "\"" );
|
ErrorLog( "Bad event: multi-event \"" + event->asName + "\" cannot find track \"" + cellastext + "\"" );
|
||||||
Current->iFlags &= ~( conditional_trackoccupied | conditional_trackfree ); // zerowanie flag
|
event->iFlags &= ~( conditional_trackoccupied | conditional_trackfree ); // zerowanie flag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( Current->iFlags & ( conditional_memstring | conditional_memval1 | conditional_memval2 ) ) {
|
else if( event->iFlags & ( conditional_memstring | conditional_memval1 | conditional_memval2 ) ) {
|
||||||
// jeśli chodzi o komorke pamieciową
|
// jeśli chodzi o komorke pamieciową
|
||||||
Current->Params[ 9 ].asMemCell = simulation::Memory.find( cellastext );
|
event->Params[ 9 ].asMemCell = simulation::Memory.find( cellastext );
|
||||||
if( Current->Params[ 9 ].asMemCell == nullptr ) {
|
if( event->Params[ 9 ].asMemCell == nullptr ) {
|
||||||
ErrorLog( "Bad event: multi-event \"" + Current->asName + "\" cannot find memory cell \"" + cellastext + "\"" );
|
ErrorLog( "Bad event: multi-event \"" + event->asName + "\" cannot find memory cell \"" + cellastext + "\"" );
|
||||||
Current->iFlags &= ~( conditional_memstring | conditional_memval1 | conditional_memval2 );
|
event->iFlags &= ~( conditional_memstring | conditional_memval1 | conditional_memval2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for( int i = 0; i < 8; ++i ) {
|
for( int i = 0; i < 8; ++i ) {
|
||||||
if( Current->Params[ i ].asText != nullptr ) {
|
if( event->Params[ i ].asText != nullptr ) {
|
||||||
cellastext = Current->Params[ i ].asText;
|
cellastext = event->Params[ i ].asText;
|
||||||
SafeDeleteArray( Current->Params[ i ].asText );
|
SafeDeleteArray( event->Params[ i ].asText );
|
||||||
Current->Params[ i ].asEvent = FindEvent( cellastext );
|
event->Params[ i ].asEvent = FindEvent( cellastext );
|
||||||
if( Current->Params[ i ].asEvent == nullptr ) {
|
if( event->Params[ i ].asEvent == nullptr ) {
|
||||||
// Ra: tylko w logu informacja o braku
|
// Ra: tylko w logu informacja o braku
|
||||||
ErrorLog( "Bad event: multi-event \"" + Current->asName + "\" cannot find event \"" + cellastext + "\"" );
|
ErrorLog( "Bad event: multi-event \"" + event->asName + "\" cannot find event \"" + cellastext + "\"" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1537,14 +1575,14 @@ event_manager::InitEvents() {
|
|||||||
}
|
}
|
||||||
case tp_Voltage: {
|
case tp_Voltage: {
|
||||||
// zmiana napięcia w zasilaczu (TractionPowerSource)
|
// zmiana napięcia w zasilaczu (TractionPowerSource)
|
||||||
if( false == Current->asNodeName.empty() ) {
|
if( false == event->asNodeName.empty() ) {
|
||||||
auto *powersource = simulation::Powergrid.find( Current->asNodeName ); // podłączenie zasilacza
|
auto *powersource = simulation::Powergrid.find( event->asNodeName ); // podłączenie zasilacza
|
||||||
if( powersource != nullptr )
|
if( powersource != nullptr )
|
||||||
Current->Params[ 9 ].psPower = powersource;
|
event->Params[ 9 ].psPower = powersource;
|
||||||
else
|
else
|
||||||
ErrorLog( "Bad event: voltage event \"" + Current->asName + "\" cannot find power source \"" + Current->asNodeName + "\"" );
|
ErrorLog( "Bad event: voltage event \"" + event->asName + "\" cannot find power source \"" + event->asNodeName + "\"" );
|
||||||
}
|
}
|
||||||
Current->asNodeName = "";
|
event->asNodeName = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tp_Message: {
|
case tp_Message: {
|
||||||
@@ -1554,7 +1592,37 @@ event_manager::InitEvents() {
|
|||||||
|
|
||||||
} // switch
|
} // switch
|
||||||
|
|
||||||
if( Current->fDelay < 0 ) { AddToQuery( Current, nullptr ); }
|
if( event->fDelay < 0 ) { AddToQuery( event, nullptr ); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// legacy method, initializes event launchers after deserialization from scenario file
|
||||||
|
void
|
||||||
|
event_manager::InitLaunchers() {
|
||||||
|
|
||||||
|
for( auto *launcher : m_launchers.sequence() ) {
|
||||||
|
|
||||||
|
if( launcher->iCheckMask != 0 ) {
|
||||||
|
if( launcher->asMemCellName != "none" ) {
|
||||||
|
// jeśli jest powiązana komórka pamięci
|
||||||
|
launcher->MemCell = simulation::Memory.find( launcher->asMemCellName );
|
||||||
|
if( launcher->MemCell == nullptr ) {
|
||||||
|
ErrorLog( "Bad scenario: event launcher \"" + launcher->name() + "\" cannot find memcell \"" + launcher->asMemCellName + "\"" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
launcher->MemCell = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
launcher->Event1 = (
|
||||||
|
launcher->asEvent1Name != "none" ?
|
||||||
|
simulation::Events.FindEvent( launcher->asEvent1Name ) :
|
||||||
|
nullptr );
|
||||||
|
launcher->Event2 = (
|
||||||
|
launcher->asEvent2Name != "none" ?
|
||||||
|
simulation::Events.FindEvent( launcher->asEvent2Name ) :
|
||||||
|
nullptr );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
Event.h
11
Event.h
@@ -63,7 +63,9 @@ union TParam
|
|||||||
{
|
{
|
||||||
void *asPointer;
|
void *asPointer;
|
||||||
TMemCell *asMemCell;
|
TMemCell *asMemCell;
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
TGroundNode *nGroundNode;
|
TGroundNode *nGroundNode;
|
||||||
|
#endif
|
||||||
editor::basic_node *asEditorNode;
|
editor::basic_node *asEditorNode;
|
||||||
glm::dvec3 const *asLocation;
|
glm::dvec3 const *asLocation;
|
||||||
TTrack *asTrack;
|
TTrack *asTrack;
|
||||||
@@ -125,6 +127,12 @@ public:
|
|||||||
// destructor
|
// destructor
|
||||||
~event_manager();
|
~event_manager();
|
||||||
// methods
|
// methods
|
||||||
|
// adds specified event launcher to the list of global launchers
|
||||||
|
void
|
||||||
|
queue( TEventLauncher *Launcher );
|
||||||
|
// legacy method, updates event queues
|
||||||
|
void
|
||||||
|
update();
|
||||||
// adds provided event to the collection. returns: true on success
|
// adds provided event to the collection. returns: true on success
|
||||||
// TBD, TODO: return handle to the event
|
// TBD, TODO: return handle to the event
|
||||||
bool
|
bool
|
||||||
@@ -144,6 +152,9 @@ public:
|
|||||||
// legacy method, initializes events after deserialization from scenario file
|
// legacy method, initializes events after deserialization from scenario file
|
||||||
void
|
void
|
||||||
InitEvents();
|
InitEvents();
|
||||||
|
// legacy method, initializes event launchers after deserialization from scenario file
|
||||||
|
void
|
||||||
|
InitLaunchers();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
|
|||||||
32
Ground.cpp
32
Ground.cpp
@@ -190,7 +190,7 @@ void TGroundNode::RenderHidden()
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case TP_EVLAUNCH:
|
case TP_EVLAUNCH:
|
||||||
if (EvLaunch->Render())
|
if (EvLaunch->check_conditions())
|
||||||
if ((EvLaunch->dRadius < 0) || (mgn < EvLaunch->dRadius))
|
if ((EvLaunch->dRadius < 0) || (mgn < EvLaunch->dRadius))
|
||||||
{
|
{
|
||||||
WriteLog("Eventlauncher " + asName);
|
WriteLog("Eventlauncher " + asName);
|
||||||
@@ -1006,7 +1006,6 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
case TP_EVLAUNCH:
|
case TP_EVLAUNCH:
|
||||||
parser->getTokens(3);
|
parser->getTokens(3);
|
||||||
*parser
|
*parser
|
||||||
@@ -1018,7 +1017,6 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
tmp->EvLaunch = new TEventLauncher();
|
tmp->EvLaunch = new TEventLauncher();
|
||||||
tmp->EvLaunch->Load(parser);
|
tmp->EvLaunch->Load(parser);
|
||||||
break;
|
break;
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
case TP_TRACK:
|
case TP_TRACK:
|
||||||
tmp->pTrack = new TTrack( tmp->asName );
|
tmp->pTrack = new TTrack( tmp->asName );
|
||||||
if (Global::iWriteLogEnabled & 4)
|
if (Global::iWriteLogEnabled & 4)
|
||||||
@@ -1600,7 +1598,6 @@ TEvent * TGround::FindEvent(const std::string &asEventName)
|
|||||||
lookup->second :
|
lookup->second :
|
||||||
nullptr );
|
nullptr );
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void TGround::FirstInit()
|
void TGround::FirstInit()
|
||||||
{ // ustalanie zależności na scenerii przed wczytaniem pojazdów
|
{ // ustalanie zależności na scenerii przed wczytaniem pojazdów
|
||||||
@@ -1668,18 +1665,14 @@ void TGround::FirstInit()
|
|||||||
|
|
||||||
WriteLog("InitNormals OK");
|
WriteLog("InitNormals OK");
|
||||||
|
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
InitTracks(); //łączenie odcinków ze sobą i przyklejanie eventów
|
InitTracks(); //łączenie odcinków ze sobą i przyklejanie eventów
|
||||||
WriteLog("InitTracks OK");
|
WriteLog("InitTracks OK");
|
||||||
InitTraction(); //łączenie drutów ze sobą
|
InitTraction(); //łączenie drutów ze sobą
|
||||||
WriteLog("InitTraction OK");
|
WriteLog("InitTraction OK");
|
||||||
InitEvents();
|
InitEvents();
|
||||||
WriteLog( "InitEvents OK" );
|
WriteLog( "InitEvents OK" );
|
||||||
#endif
|
|
||||||
|
|
||||||
InitLaunchers();
|
InitLaunchers();
|
||||||
WriteLog("InitLaunchers OK");
|
WriteLog("InitLaunchers OK");
|
||||||
|
|
||||||
WriteLog("FirstInit is done");
|
WriteLog("FirstInit is done");
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1839,7 +1832,6 @@ bool TGround::Init(std::string File)
|
|||||||
}
|
}
|
||||||
else if (str == "event")
|
else if (str == "event")
|
||||||
{
|
{
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
TEvent *tmp = new TEvent();
|
TEvent *tmp = new TEvent();
|
||||||
tmp->Load(&parser, pOrigin);
|
tmp->Load(&parser, pOrigin);
|
||||||
if (tmp->Type == tp_Unknown)
|
if (tmp->Type == tp_Unknown)
|
||||||
@@ -1904,7 +1896,6 @@ bool TGround::Init(std::string File)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if (str == "rotate")
|
else if (str == "rotate")
|
||||||
{
|
{
|
||||||
@@ -2126,14 +2117,13 @@ bool TGround::Init(std::string File)
|
|||||||
|
|
||||||
if (!bInitDone)
|
if (!bInitDone)
|
||||||
FirstInit(); // jeśli nie było w scenerii
|
FirstInit(); // jeśli nie było w scenerii
|
||||||
#ifdef EU07_USE_OLD_TERRAINCODE
|
|
||||||
if (Global::pTerrainCompact)
|
if (Global::pTerrainCompact)
|
||||||
TerrainWrite(); // Ra: teraz można zapisać teren w jednym pliku
|
TerrainWrite(); // Ra: teraz można zapisać teren w jednym pliku
|
||||||
#endif
|
|
||||||
Global::iPause &= ~0x10; // koniec pauzy wczytywania
|
Global::iPause &= ~0x10; // koniec pauzy wczytywania
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
bool TGround::InitEvents()
|
bool TGround::InitEvents()
|
||||||
{ //łączenie eventów z pozostałymi obiektami
|
{ //łączenie eventów z pozostałymi obiektami
|
||||||
TGroundNode *tmp, *trk;
|
TGroundNode *tmp, *trk;
|
||||||
@@ -2816,7 +2806,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()
|
||||||
{
|
{
|
||||||
@@ -2837,26 +2827,16 @@ bool TGround::InitLaunchers()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
EventLauncher->MemCell = nullptr;
|
EventLauncher->MemCell = nullptr;
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
EventLauncher->Event1 = ( EventLauncher->asEvent1Name != "none") ?
|
EventLauncher->Event1 = ( EventLauncher->asEvent1Name != "none") ?
|
||||||
FindEvent(EventLauncher->asEvent1Name) :
|
FindEvent(EventLauncher->asEvent1Name) :
|
||||||
nullptr;
|
nullptr;
|
||||||
EventLauncher->Event2 = ( EventLauncher->asEvent2Name != "none") ?
|
EventLauncher->Event2 = ( EventLauncher->asEvent2Name != "none") ?
|
||||||
FindEvent(EventLauncher->asEvent2Name) :
|
FindEvent(EventLauncher->asEvent2Name) :
|
||||||
nullptr;
|
nullptr;
|
||||||
#else
|
|
||||||
EventLauncher->Event1 = ( EventLauncher->asEvent1Name != "none") ?
|
|
||||||
simulation::Events.FindEvent(EventLauncher->asEvent1Name) :
|
|
||||||
nullptr;
|
|
||||||
EventLauncher->Event2 = ( EventLauncher->asEvent2Name != "none") ?
|
|
||||||
simulation::Events.FindEvent(EventLauncher->asEvent2Name) :
|
|
||||||
nullptr;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
TTrack * TGround::FindTrack(vector3 Point, int &iConnection, TGroundNode *Exclude)
|
TTrack * TGround::FindTrack(vector3 Point, int &iConnection, TGroundNode *Exclude)
|
||||||
{ // wyszukiwanie innego toru kończącego się w (Point)
|
{ // wyszukiwanie innego toru kończącego się w (Point)
|
||||||
TTrack *tmp;
|
TTrack *tmp;
|
||||||
@@ -3539,7 +3519,7 @@ TGround::Update_Hidden() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
// Winger 170204 - szukanie trakcji nad pantografami
|
// Winger 170204 - szukanie trakcji nad pantografami
|
||||||
bool TGround::GetTraction(TDynamicObject *model)
|
bool TGround::GetTraction(TDynamicObject *model)
|
||||||
{ // aktualizacja drutu zasilającego dla każdego pantografu, żeby odczytać napięcie
|
{ // aktualizacja drutu zasilającego dla każdego pantografu, żeby odczytać napięcie
|
||||||
@@ -3774,7 +3754,7 @@ bool TGround::GetTraction(TDynamicObject *model)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
void TGround::Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam)
|
void TGround::Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
|||||||
6
Ground.h
6
Ground.h
@@ -277,15 +277,13 @@ class TGround
|
|||||||
TGround();
|
TGround();
|
||||||
~TGround();
|
~TGround();
|
||||||
void Free();
|
void Free();
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
bool Init( std::string File );
|
bool Init( std::string File );
|
||||||
void FirstInit();
|
void FirstInit();
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
void InitTracks();
|
void InitTracks();
|
||||||
void InitTraction();
|
void InitTraction();
|
||||||
bool InitEvents();
|
bool InitEvents();
|
||||||
#endif
|
|
||||||
bool InitLaunchers();
|
bool InitLaunchers();
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
TTrack * FindTrack(vector3 Point, int &iConnection, TGroundNode *Exclude);
|
TTrack * FindTrack(vector3 Point, int &iConnection, TGroundNode *Exclude);
|
||||||
TTraction * FindTraction(glm::dvec3 const &Point, int &iConnection, TGroundNode *Exclude);
|
TTraction * FindTraction(glm::dvec3 const &Point, int &iConnection, TGroundNode *Exclude);
|
||||||
TTraction * TractionNearestFind(glm::dvec3 &p, int dir, TGroundNode *n);
|
TTraction * TractionNearestFind(glm::dvec3 &p, int dir, TGroundNode *n);
|
||||||
@@ -295,9 +293,7 @@ class TGround
|
|||||||
void UpdatePhys(double dt, int iter); // aktualizacja fizyki stałym krokiem
|
void UpdatePhys(double dt, int iter); // aktualizacja fizyki stałym krokiem
|
||||||
bool Update(double dt, int iter); // aktualizacja przesunięć zgodna z FPS
|
bool Update(double dt, int iter); // aktualizacja przesunięć zgodna z FPS
|
||||||
void Update_Hidden(); // updates invisible elements of the scene
|
void Update_Hidden(); // updates invisible elements of the scene
|
||||||
#endif
|
|
||||||
bool GetTraction(TDynamicObject *model);
|
bool GetTraction(TDynamicObject *model);
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
|
||||||
bool AddToQuery( TEvent *Event, TDynamicObject *Node );
|
bool AddToQuery( TEvent *Event, TDynamicObject *Node );
|
||||||
bool CheckQuery();
|
bool CheckQuery();
|
||||||
TGroundNode * DynamicFindAny(std::string const &Name);
|
TGroundNode * DynamicFindAny(std::string const &Name);
|
||||||
|
|||||||
@@ -129,7 +129,11 @@ bool TMemCell::Load(cParser *parser)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
void TMemCell::PutCommand(TController *Mech, vector3 *Loc)
|
void TMemCell::PutCommand(TController *Mech, vector3 *Loc)
|
||||||
|
#else
|
||||||
|
void TMemCell::PutCommand( TController *Mech, glm::dvec3 const *Loc )
|
||||||
|
#endif
|
||||||
{ // wysłanie zawartości komórki do AI
|
{ // wysłanie zawartości komórki do AI
|
||||||
if (Mech)
|
if (Mech)
|
||||||
Mech->PutCommand(szText, fValue1, fValue2, Loc);
|
Mech->PutCommand(szText, fValue1, fValue2, Loc);
|
||||||
|
|||||||
@@ -37,7 +37,11 @@ class TMemCell : public editor::basic_node {
|
|||||||
bool
|
bool
|
||||||
Load(cParser *parser);
|
Load(cParser *parser);
|
||||||
void
|
void
|
||||||
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
PutCommand( TController *Mech, Math3D::vector3 *Loc );
|
PutCommand( TController *Mech, Math3D::vector3 *Loc );
|
||||||
|
#else
|
||||||
|
PutCommand( TController *Mech, glm::dvec3 const *Loc );
|
||||||
|
#endif
|
||||||
bool
|
bool
|
||||||
Compare( std::string const &szTestText, double const fTestValue1, double const fTestValue2, int const CheckMask );
|
Compare( std::string const &szTestText, double const fTestValue1, double const fTestValue2, int const CheckMask );
|
||||||
std::string const &
|
std::string const &
|
||||||
|
|||||||
7
Names.h
7
Names.h
@@ -108,4 +108,11 @@ protected:
|
|||||||
// members
|
// members
|
||||||
type_sequence m_items;
|
type_sequence m_items;
|
||||||
type_map m_itemmap;
|
type_map m_itemmap;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// data access
|
||||||
|
typename type_sequence &
|
||||||
|
sequence() {
|
||||||
|
return m_items; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
|
||||||
namespace Timer
|
namespace Timer {
|
||||||
{
|
|
||||||
|
subsystem_stopwatches subsystem;
|
||||||
|
|
||||||
double DeltaTime, DeltaRenderTime;
|
double DeltaTime, DeltaRenderTime;
|
||||||
double fFPS{ 0.0f };
|
double fFPS{ 0.0f };
|
||||||
|
|||||||
36
Timer.h
36
Timer.h
@@ -9,8 +9,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Timer
|
namespace Timer {
|
||||||
{
|
|
||||||
|
|
||||||
double GetTime();
|
double GetTime();
|
||||||
|
|
||||||
@@ -28,6 +27,39 @@ double GetFPS();
|
|||||||
void ResetTimers();
|
void ResetTimers();
|
||||||
|
|
||||||
void UpdateTimers(bool pause);
|
void UpdateTimers(bool pause);
|
||||||
|
|
||||||
|
class stopwatch {
|
||||||
|
|
||||||
|
public:
|
||||||
|
void
|
||||||
|
start() {
|
||||||
|
m_start = std::chrono::steady_clock::now(); }
|
||||||
|
void
|
||||||
|
stop() {
|
||||||
|
m_accumulator = 0.95f * m_accumulator + std::chrono::duration_cast<std::chrono::microseconds>( ( std::chrono::steady_clock::now() - m_start ) ).count() / 1000.f; }
|
||||||
|
float
|
||||||
|
average() const {
|
||||||
|
return m_accumulator / 20.f;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::chrono::time_point<std::chrono::steady_clock> m_start { std::chrono::steady_clock::now() };
|
||||||
|
float m_accumulator { 1000.f / 30.f * 20.f }; // 20 last samples, initial 'neutral' rate of 30 fps
|
||||||
|
};
|
||||||
|
|
||||||
|
struct subsystem_stopwatches {
|
||||||
|
stopwatch gfx_total;
|
||||||
|
stopwatch gfx_color;
|
||||||
|
stopwatch gfx_shadows;
|
||||||
|
stopwatch gfx_reflections;
|
||||||
|
stopwatch gfx_swap;
|
||||||
|
stopwatch sim_total;
|
||||||
|
stopwatch sim_dynamics;
|
||||||
|
stopwatch sim_events;
|
||||||
|
stopwatch sim_ai;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern subsystem_stopwatches subsystem;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
20
World.cpp
20
World.cpp
@@ -953,6 +953,7 @@ void TWorld::FollowView(bool wycisz) {
|
|||||||
bool TWorld::Update() {
|
bool TWorld::Update() {
|
||||||
|
|
||||||
Timer::UpdateTimers(Global::iPause != 0);
|
Timer::UpdateTimers(Global::iPause != 0);
|
||||||
|
Timer::subsystem.sim_total.start();
|
||||||
|
|
||||||
if( (Global::iPause == false)
|
if( (Global::iPause == false)
|
||||||
|| (m_init == false) ) {
|
|| (m_init == false) ) {
|
||||||
@@ -1026,6 +1027,7 @@ bool TWorld::Update() {
|
|||||||
// this means at count > 20 simulation and render are going to desync. is that right?
|
// this means at count > 20 simulation and render are going to desync. is that right?
|
||||||
// NOTE: experimentally changing this to prevent the desync.
|
// NOTE: experimentally changing this to prevent the desync.
|
||||||
// TODO: test what happens if we hit more than 20 * 0.01 sec slices, i.e. less than 5 fps
|
// TODO: test what happens if we hit more than 20 * 0.01 sec slices, i.e. less than 5 fps
|
||||||
|
Timer::subsystem.sim_dynamics.start();
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
if( true == Global::FullPhysics ) {
|
if( true == Global::FullPhysics ) {
|
||||||
// mixed calculation mode, steps calculated in ~0.05s chunks
|
// mixed calculation mode, steps calculated in ~0.05s chunks
|
||||||
@@ -1067,6 +1069,7 @@ bool TWorld::Update() {
|
|||||||
simulation::State.update( stepdeltatime, updatecount );
|
simulation::State.update( stepdeltatime, updatecount );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Timer::subsystem.sim_dynamics.stop();
|
||||||
|
|
||||||
// secondary fixed step simulation time routines
|
// secondary fixed step simulation time routines
|
||||||
while( m_secondaryupdateaccumulator >= m_secondaryupdaterate ) {
|
while( m_secondaryupdateaccumulator >= m_secondaryupdaterate ) {
|
||||||
@@ -1110,7 +1113,7 @@ bool TWorld::Update() {
|
|||||||
Ground.CheckQuery();
|
Ground.CheckQuery();
|
||||||
Ground.Update_Hidden();
|
Ground.Update_Hidden();
|
||||||
#else
|
#else
|
||||||
simulation::Events.CheckQuery();
|
simulation::Events.update();
|
||||||
simulation::Region->update();
|
simulation::Region->update();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1144,6 +1147,8 @@ bool TWorld::Update() {
|
|||||||
|
|
||||||
Update_Camera( dt );
|
Update_Camera( dt );
|
||||||
|
|
||||||
|
Timer::subsystem.sim_total.stop();
|
||||||
|
|
||||||
GfxRenderer.Update( dt );
|
GfxRenderer.Update( dt );
|
||||||
ResourceSweep();
|
ResourceSweep();
|
||||||
|
|
||||||
@@ -1659,20 +1664,14 @@ TWorld::Update_UI() {
|
|||||||
"VBO" :
|
"VBO" :
|
||||||
"Display Lists" )
|
"Display Lists" )
|
||||||
+ " ";
|
+ " ";
|
||||||
// dump last opengl error, if any
|
|
||||||
GLenum glerror = ::glGetError();
|
|
||||||
if( glerror != GL_NO_ERROR ) {
|
|
||||||
std::string glerrorstring( (char *)::gluErrorString( glerror ) );
|
|
||||||
win1250_to_ascii( glerrorstring );
|
|
||||||
Global::LastGLError = std::to_string( glerror ) + " (" + glerrorstring + ")";
|
|
||||||
}
|
|
||||||
if( false == Global::LastGLError.empty() ) {
|
if( false == Global::LastGLError.empty() ) {
|
||||||
uitextline2 +=
|
uitextline2 +=
|
||||||
"Last openGL error: "
|
"Last openGL error: "
|
||||||
+ Global::LastGLError;
|
+ Global::LastGLError;
|
||||||
}
|
}
|
||||||
// renderer stats
|
// renderer stats
|
||||||
uitextline3 = GfxRenderer.Info();
|
uitextline3 = GfxRenderer.info_times();
|
||||||
|
uitextline4 = GfxRenderer.info_stats();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1683,6 +1682,9 @@ TWorld::Update_UI() {
|
|||||||
if( Global::iMultiplayer ) {
|
if( Global::iMultiplayer ) {
|
||||||
uitextline1 += " (multiplayer mode is active)";
|
uitextline1 += " (multiplayer mode is active)";
|
||||||
}
|
}
|
||||||
|
uitextline3 =
|
||||||
|
"vehicles: " + to_string( Timer::subsystem.sim_dynamics.average(), 2 ) + " msec"
|
||||||
|
+ " update total: " + to_string( Timer::subsystem.sim_total.average(), 2 ) + " msec";
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
190
renderer.cpp
190
renderer.cpp
@@ -315,23 +315,32 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
|||||||
bool
|
bool
|
||||||
opengl_renderer::Render() {
|
opengl_renderer::Render() {
|
||||||
|
|
||||||
if( m_drawstart != std::chrono::steady_clock::time_point() ) {
|
Timer::subsystem.gfx_total.stop();
|
||||||
m_drawtime = std::max( 20.f, 0.95f * m_drawtime + std::chrono::duration_cast<std::chrono::microseconds>( ( std::chrono::steady_clock::now() - m_drawstart ) ).count() / 1000.f );
|
Timer::subsystem.gfx_total.start(); // note: gfx_total is actually frame total, clean this up
|
||||||
}
|
Timer::subsystem.gfx_color.start();
|
||||||
m_drawstart = std::chrono::steady_clock::now();
|
|
||||||
auto const drawstartcolorpass = m_drawstart;
|
|
||||||
|
|
||||||
m_renderpass.draw_mode = rendermode::none; // force setup anew
|
m_renderpass.draw_mode = rendermode::none; // force setup anew
|
||||||
m_debuginfo.clear();
|
m_debugtimestext.clear();
|
||||||
++m_framestamp;
|
m_debugstats = debug_stats();
|
||||||
Render_pass( rendermode::color );
|
Render_pass( rendermode::color );
|
||||||
|
Timer::subsystem.gfx_color.stop();
|
||||||
|
|
||||||
|
Timer::subsystem.gfx_swap.start();
|
||||||
|
glfwSwapBuffers( m_window );
|
||||||
|
Timer::subsystem.gfx_swap.stop();
|
||||||
|
|
||||||
m_drawcount = m_cellqueue.size();
|
m_drawcount = m_cellqueue.size();
|
||||||
// accumulate last 20 frames worth of render time (cap at 1000 fps to prevent calculations going awry)
|
m_debugtimestext
|
||||||
m_drawtimecolorpass = std::max( 20.f, 0.95f * m_drawtimecolorpass + std::chrono::duration_cast<std::chrono::microseconds>( ( std::chrono::steady_clock::now() - drawstartcolorpass ) ).count() / 1000.f );
|
+= "frame: " + to_string( Timer::subsystem.gfx_color.average(), 2 ) + " msec (" + std::to_string( m_cellqueue.size() ) + " sectors) "
|
||||||
m_debuginfo += "frame total: " + to_string( m_drawtimecolorpass / 20.f, 2 ) + " msec (" + std::to_string( m_cellqueue.size() ) + " sectors) ";
|
+= "gpu side: " + to_string( Timer::subsystem.gfx_swap.average(), 2 ) + " msec "
|
||||||
|
+= "(" + to_string( Timer::subsystem.gfx_color.average() + Timer::subsystem.gfx_swap.average(), 2 ) + " msec total)";
|
||||||
|
m_debugstatstext =
|
||||||
|
"drawcalls: " + to_string( m_debugstats.drawcalls )
|
||||||
|
+ "; dyn: " + to_string( m_debugstats.dynamics ) + " mod: " + to_string( m_debugstats.models ) + " sub: " + to_string( m_debugstats.submodels )
|
||||||
|
+ "; trk: " + to_string( m_debugstats.paths ) + " shp: " + to_string( m_debugstats.shapes )
|
||||||
|
+ " trc: " + to_string( m_debugstats.traction ) + " lin: " + to_string( m_debugstats.lines );
|
||||||
|
|
||||||
glfwSwapBuffers( m_window );
|
++m_framestamp;
|
||||||
|
|
||||||
return true; // for now always succeed
|
return true; // for now always succeed
|
||||||
}
|
}
|
||||||
@@ -464,7 +473,7 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
|
|
||||||
if( World.InitPerformed() ) {
|
if( World.InitPerformed() ) {
|
||||||
// setup
|
// setup
|
||||||
auto const shadowdrawstart = std::chrono::steady_clock::now();
|
Timer::subsystem.gfx_shadows.start();
|
||||||
|
|
||||||
::glBindFramebufferEXT( GL_FRAMEBUFFER, m_shadowframebuffer );
|
::glBindFramebufferEXT( GL_FRAMEBUFFER, m_shadowframebuffer );
|
||||||
|
|
||||||
@@ -500,9 +509,8 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
::glDisable( GL_SCISSOR_TEST );
|
::glDisable( GL_SCISSOR_TEST );
|
||||||
|
|
||||||
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // switch back to primary render target
|
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // switch back to primary render target
|
||||||
|
Timer::subsystem.gfx_shadows.stop();
|
||||||
m_drawtimeshadowpass = 0.95f * m_drawtimeshadowpass + std::chrono::duration_cast<std::chrono::microseconds>( ( std::chrono::steady_clock::now() - shadowdrawstart ) ).count() / 1000.f;
|
m_debugtimestext += "shadows: " + to_string( Timer::subsystem.gfx_shadows.average(), 2 ) + " msec (" + std::to_string( m_cellqueue.size() ) + " sectors) ";
|
||||||
m_debuginfo += "shadows: " + to_string( m_drawtimeshadowpass / 20.f, 2 ) + " msec (" + std::to_string( m_cellqueue.size() ) + " sectors) ";
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -602,7 +610,7 @@ bool
|
|||||||
opengl_renderer::Render_reflections() {
|
opengl_renderer::Render_reflections() {
|
||||||
|
|
||||||
auto const &time = simulation::Time.data();
|
auto const &time = simulation::Time.data();
|
||||||
auto const timestamp = time.wDay * 60 * 24 + time.wHour * 60 + time.wMinute;
|
auto const timestamp = time.wDay * 24 * 60 + time.wHour * 60 + time.wMinute;
|
||||||
if( ( timestamp - m_environmentupdatetime < 5 )
|
if( ( timestamp - m_environmentupdatetime < 5 )
|
||||||
&& ( glm::length( m_renderpass.camera.position() - m_environmentupdatelocation ) < 1000.0 ) ) {
|
&& ( glm::length( m_renderpass.camera.position() - m_environmentupdatelocation ) < 1000.0 ) ) {
|
||||||
// run update every 5+ mins of simulation time, or at least 1km from the last location
|
// run update every 5+ mins of simulation time, or at least 1km from the last location
|
||||||
@@ -1477,12 +1485,6 @@ opengl_renderer::Render( TGroundRect *Groundcell ) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef EU07_USE_OLD_TERRAINCODE
|
|
||||||
if( Groundcell->nTerrain ) {
|
|
||||||
|
|
||||||
Render( Groundcell->nTerrain );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// add the subcells of the cell to the draw queue
|
// add the subcells of the cell to the draw queue
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
@@ -1645,16 +1647,7 @@ opengl_renderer::Render( scene::basic_region *Region ) {
|
|||||||
Update_Lights( simulation::Lights );
|
Update_Lights( simulation::Lights );
|
||||||
|
|
||||||
Render( std::begin( m_sectionqueue ), std::end( m_sectionqueue ) );
|
Render( std::begin( m_sectionqueue ), std::end( m_sectionqueue ) );
|
||||||
/*
|
// draw queue is filled while rendering sections
|
||||||
// draw queue was filled while rendering content of ground cells. now sort the nodes based on their distance to viewer...
|
|
||||||
// TODO: move sorting for translucent phase, for opaque geometry render cells in initial order to reduce vbo switching
|
|
||||||
std::sort(
|
|
||||||
std::begin( m_cellqueue ),
|
|
||||||
std::end( m_cellqueue ),
|
|
||||||
[]( distancecell_pair const &Left, distancecell_pair const &Right ) {
|
|
||||||
return ( Left.first < Right.first ); } );
|
|
||||||
*/
|
|
||||||
// ...then render the opaque content of the visible cells.
|
|
||||||
Render( std::begin( m_cellqueue ), std::end( m_cellqueue ) );
|
Render( std::begin( m_cellqueue ), std::end( m_cellqueue ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1749,7 +1742,7 @@ opengl_renderer::Render( section_sequence::iterator First, section_sequence::ite
|
|||||||
glEnable( GL_LIGHTING );
|
glEnable( GL_LIGHTING );
|
||||||
#endif
|
#endif
|
||||||
// shapes
|
// shapes
|
||||||
for( auto const &shape : section->m_shapes ) { Render( shape ); }
|
for( auto const &shape : section->m_shapes ) { Render( shape, true ); }
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
}
|
}
|
||||||
@@ -1852,7 +1845,7 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
|
|||||||
glEnable( GL_LIGHTING );
|
glEnable( GL_LIGHTING );
|
||||||
#endif
|
#endif
|
||||||
// opaque non-instanced shapes
|
// opaque non-instanced shapes
|
||||||
for( auto const &shape : cell->m_shapesopaque ) { Render( shape ); }
|
for( auto const &shape : cell->m_shapesopaque ) { Render( shape, false ); }
|
||||||
// tracks
|
// tracks
|
||||||
// TODO: update after path node refactoring
|
// TODO: update after path node refactoring
|
||||||
for( auto *path : cell->m_paths ) { Render( path ); }
|
for( auto *path : cell->m_paths ) { Render( path ); }
|
||||||
@@ -1871,7 +1864,7 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
|
|||||||
|
|
||||||
// render
|
// render
|
||||||
// opaque non-instanced shapes
|
// opaque non-instanced shapes
|
||||||
for( auto const &shape : cell->m_shapesopaque ) { Render( shape ); }
|
for( auto const &shape : cell->m_shapesopaque ) { Render( shape, false ); }
|
||||||
// TODO: add other content types
|
// TODO: add other content types
|
||||||
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
@@ -1887,7 +1880,7 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
|
|||||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||||
// render
|
// render
|
||||||
// opaque non-instanced shapes
|
// opaque non-instanced shapes
|
||||||
for( auto const &shape : cell->m_shapesopaque ) { Render( shape ); }
|
for( auto const &shape : cell->m_shapesopaque ) { Render( shape, false ); }
|
||||||
// tracks
|
// tracks
|
||||||
// TODO: add path to the node picking list
|
// TODO: add path to the node picking list
|
||||||
for( auto *path : cell->m_paths ) { Render( path ); }
|
for( auto *path : cell->m_paths ) { Render( path ); }
|
||||||
@@ -1922,6 +1915,7 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
|
|||||||
Render( dynamic );
|
Render( dynamic );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case rendermode::pickscenery: {
|
case rendermode::pickscenery: {
|
||||||
// opaque parts of instanced models
|
// opaque parts of instanced models
|
||||||
@@ -1944,9 +1938,46 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
opengl_renderer::Render( scene::shape_node const &Shape ) {
|
opengl_renderer::Render( scene::shape_node const &Shape, bool const Ignorerange ) {
|
||||||
|
/*
|
||||||
|
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( ( 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() };
|
auto const &data{ Shape.data() };
|
||||||
|
|
||||||
|
if( false == Ignorerange ) {
|
||||||
|
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
|
// setup
|
||||||
Bind_Material( data.material );
|
Bind_Material( data.material );
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
@@ -1971,6 +2002,9 @@ opengl_renderer::Render( scene::shape_node const &Shape ) {
|
|||||||
}
|
}
|
||||||
// render
|
// render
|
||||||
m_geometry.draw( data.geometry );
|
m_geometry.draw( data.geometry );
|
||||||
|
// debug data
|
||||||
|
++m_debugstats.shapes;
|
||||||
|
++m_debugstats.drawcalls;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2021,19 +2055,7 @@ opengl_renderer::Render( TAnimModel *Instance ) {
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
opengl_renderer::Render( TGroundNode *Node ) {
|
opengl_renderer::Render( TGroundNode *Node ) {
|
||||||
#ifdef EU07_USE_OLD_TERRAINCODE
|
|
||||||
switch (Node->iType)
|
|
||||||
{ // obiekty renderowane niezależnie od odległości
|
|
||||||
case TP_SUBMODEL:
|
|
||||||
::glPushMatrix();
|
|
||||||
auto const originoffset = Node->pCenter - m_renderpass.camera.position();
|
|
||||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
|
||||||
TSubModel::fSquareDist = 0;
|
|
||||||
Render( Node->smTerrain );
|
|
||||||
::glPopMatrix();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
double distancesquared;
|
double distancesquared;
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows: {
|
||||||
@@ -2073,6 +2095,9 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
|||||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||||
// render
|
// render
|
||||||
Render( Node->pTrack );
|
Render( Node->pTrack );
|
||||||
|
// debug
|
||||||
|
++m_debugstats.paths;
|
||||||
|
++m_debugstats.drawcalls;
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
return true;
|
return true;
|
||||||
@@ -2155,7 +2180,9 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
|||||||
}
|
}
|
||||||
// render
|
// render
|
||||||
m_geometry.draw( Node->Piece->geometry );
|
m_geometry.draw( Node->Piece->geometry );
|
||||||
|
// debug
|
||||||
|
// ++m_debugstats.lines;
|
||||||
|
// ++m_debugstats.drawcalls;
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
|
|
||||||
@@ -2201,6 +2228,9 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
|||||||
}
|
}
|
||||||
// render
|
// render
|
||||||
m_geometry.draw( Node->Piece->geometry );
|
m_geometry.draw( Node->Piece->geometry );
|
||||||
|
// debug
|
||||||
|
++m_debugstats.shapes;
|
||||||
|
++m_debugstats.drawcalls;
|
||||||
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
@@ -2236,6 +2266,9 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
|||||||
if( false == Dynamic->renderme ) {
|
if( false == Dynamic->renderme ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// debug data
|
||||||
|
++m_debugstats.dynamics;
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
|
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
|
||||||
glm::dvec3 const originoffset = Dynamic->vPosition - m_renderpass.camera.position();
|
glm::dvec3 const originoffset = Dynamic->vPosition - m_renderpass.camera.position();
|
||||||
@@ -2437,6 +2470,9 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, float c
|
|||||||
// render
|
// render
|
||||||
Render( Model->Root );
|
Render( Model->Root );
|
||||||
|
|
||||||
|
// debug data
|
||||||
|
++m_debugstats.models;
|
||||||
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -2468,6 +2504,10 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
&& ( TSubModel::fSquareDist >= Submodel->fSquareMinDist )
|
&& ( TSubModel::fSquareDist >= Submodel->fSquareMinDist )
|
||||||
&& ( TSubModel::fSquareDist < Submodel->fSquareMaxDist ) ) {
|
&& ( TSubModel::fSquareDist < Submodel->fSquareMaxDist ) ) {
|
||||||
|
|
||||||
|
// debug data
|
||||||
|
++m_debugstats.submodels;
|
||||||
|
++m_debugstats.drawcalls;
|
||||||
|
|
||||||
if( Submodel->iFlags & 0xC000 ) {
|
if( Submodel->iFlags & 0xC000 ) {
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
if( Submodel->fMatrix )
|
if( Submodel->fMatrix )
|
||||||
@@ -2717,6 +2757,9 @@ opengl_renderer::Render( TTrack *Track ) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++m_debugstats.paths;
|
||||||
|
++m_debugstats.drawcalls;
|
||||||
|
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::color:
|
case rendermode::color:
|
||||||
case rendermode::reflections: {
|
case rendermode::reflections: {
|
||||||
@@ -2867,7 +2910,7 @@ opengl_renderer::Render_Alpha( cell_sequence::reverse_iterator First, cell_seque
|
|||||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||||
// render
|
// render
|
||||||
// NOTE: we can reuse the method used to draw opaque geometry
|
// NOTE: we can reuse the method used to draw opaque geometry
|
||||||
for( auto const &shape : cell->m_shapestranslucent ) { Render( shape ); }
|
for( auto const &shape : cell->m_shapestranslucent ) { Render( shape, false ); }
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
}
|
}
|
||||||
@@ -3003,6 +3046,9 @@ opengl_renderer::Render_Alpha( TTraction *Traction ) {
|
|||||||
|
|
||||||
// render
|
// render
|
||||||
m_geometry.draw( Traction->m_geometry );
|
m_geometry.draw( Traction->m_geometry );
|
||||||
|
// debug data
|
||||||
|
++m_debugstats.traction;
|
||||||
|
++m_debugstats.drawcalls;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
bool
|
bool
|
||||||
@@ -3056,6 +3102,9 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
|
|
||||||
// render
|
// render
|
||||||
m_geometry.draw( Node->hvTraction->m_geometry );
|
m_geometry.draw( Node->hvTraction->m_geometry );
|
||||||
|
// debug data
|
||||||
|
++m_debugstats.traction;
|
||||||
|
++m_debugstats.drawcalls;
|
||||||
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
@@ -3116,6 +3165,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.drawcalls;
|
||||||
|
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
@@ -3141,7 +3192,9 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
|
|
||||||
// render
|
// render
|
||||||
m_geometry.draw( Node->Piece->geometry );
|
m_geometry.draw( Node->Piece->geometry );
|
||||||
|
// debug data
|
||||||
|
++m_debugstats.shapes;
|
||||||
|
++m_debugstats.drawcalls;
|
||||||
// post-render cleanup
|
// post-render cleanup
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
|
|
||||||
@@ -3285,6 +3338,10 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
|||||||
&& ( TSubModel::fSquareDist >= Submodel->fSquareMinDist )
|
&& ( TSubModel::fSquareDist >= Submodel->fSquareMinDist )
|
||||||
&& ( TSubModel::fSquareDist < Submodel->fSquareMaxDist ) ) {
|
&& ( TSubModel::fSquareDist < Submodel->fSquareMaxDist ) ) {
|
||||||
|
|
||||||
|
// debug data
|
||||||
|
++m_debugstats.submodels;
|
||||||
|
++m_debugstats.drawcalls;
|
||||||
|
|
||||||
if( Submodel->iFlags & 0xC000 ) {
|
if( Submodel->iFlags & 0xC000 ) {
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
if( Submodel->fMatrix )
|
if( Submodel->fMatrix )
|
||||||
@@ -3580,10 +3637,10 @@ opengl_renderer::Update( double const Deltatime ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_updateaccumulator = 0.0;
|
m_updateaccumulator = 0.0;
|
||||||
m_framerate = 1000.f / ( m_drawtime / 20.f );
|
m_framerate = 1000.f / ( Timer::subsystem.gfx_total.average() );
|
||||||
|
|
||||||
// adjust draw ranges etc, based on recent performance
|
// adjust draw ranges etc, based on recent performance
|
||||||
auto const framerate = 1000.f / (m_drawtimecolorpass / 20.f);
|
auto const framerate = 1000.f / Timer::subsystem.gfx_color.average();
|
||||||
|
|
||||||
float targetfactor;
|
float targetfactor;
|
||||||
if( framerate > 90.0 ) { targetfactor = 3.0f; }
|
if( framerate > 90.0 ) { targetfactor = 3.0f; }
|
||||||
@@ -3620,7 +3677,7 @@ opengl_renderer::Update( double const Deltatime ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( true == DebugModeFlag ) {
|
if( true == DebugModeFlag ) {
|
||||||
m_debuginfo += m_textures.info();
|
m_debugtimestext += m_textures.info();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( true == Global::ControlPicking )
|
if( ( true == Global::ControlPicking )
|
||||||
@@ -3639,13 +3696,26 @@ opengl_renderer::Update( double const Deltatime ) {
|
|||||||
else {
|
else {
|
||||||
m_picksceneryitem = nullptr;
|
m_picksceneryitem = nullptr;
|
||||||
}
|
}
|
||||||
};
|
// dump last opengl error, if any
|
||||||
|
auto const glerror = ::glGetError();
|
||||||
|
if( glerror != GL_NO_ERROR ) {
|
||||||
|
std::string glerrorstring( ( char * )::gluErrorString( glerror ) );
|
||||||
|
win1250_to_ascii( glerrorstring );
|
||||||
|
Global::LastGLError = std::to_string( glerror ) + " (" + glerrorstring + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// debug performance string
|
// debug performance string
|
||||||
std::string const &
|
std::string const &
|
||||||
opengl_renderer::Info() const {
|
opengl_renderer::info_times() const {
|
||||||
|
|
||||||
return m_debuginfo;
|
return m_debugtimestext;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string const &
|
||||||
|
opengl_renderer::info_stats() const {
|
||||||
|
|
||||||
|
return m_debugstatstext;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
25
renderer.h
25
renderer.h
@@ -203,7 +203,9 @@ public:
|
|||||||
Update_Pick_Node();
|
Update_Pick_Node();
|
||||||
// debug performance string
|
// debug performance string
|
||||||
std::string const &
|
std::string const &
|
||||||
Info() const;
|
info_times() const;
|
||||||
|
std::string const &
|
||||||
|
info_stats() const;
|
||||||
|
|
||||||
// members
|
// members
|
||||||
GLenum static const sunlight{ GL_LIGHT0 };
|
GLenum static const sunlight{ GL_LIGHT0 };
|
||||||
@@ -227,6 +229,17 @@ private:
|
|||||||
diffuse
|
diffuse
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct debug_stats {
|
||||||
|
int dynamics { 0 };
|
||||||
|
int models { 0 };
|
||||||
|
int submodels { 0 };
|
||||||
|
int paths { 0 };
|
||||||
|
int traction { 0 };
|
||||||
|
int shapes { 0 };
|
||||||
|
int lines { 0 };
|
||||||
|
int drawcalls { 0 };
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
using distancesubcell_pair = std::pair< double, TSubRect * >;
|
using distancesubcell_pair = std::pair< double, TSubRect * >;
|
||||||
#else
|
#else
|
||||||
@@ -289,7 +302,7 @@ private:
|
|||||||
void
|
void
|
||||||
Render( cell_sequence::iterator First, cell_sequence::iterator Last );
|
Render( cell_sequence::iterator First, cell_sequence::iterator Last );
|
||||||
void
|
void
|
||||||
Render( scene::shape_node const &Shape );
|
Render( scene::shape_node const &Shape, bool const Ignorerange );
|
||||||
void
|
void
|
||||||
Render( TAnimModel *Instance );
|
Render( TAnimModel *Instance );
|
||||||
#endif
|
#endif
|
||||||
@@ -383,14 +396,12 @@ private:
|
|||||||
units_state m_unitstate;
|
units_state m_unitstate;
|
||||||
|
|
||||||
unsigned int m_framestamp; // id of currently rendered gfx frame
|
unsigned int m_framestamp; // id of currently rendered gfx frame
|
||||||
float m_drawtime { 1000.f / 30.f * 20.f }; // start with presumed 'neutral' average of 30 fps
|
|
||||||
std::chrono::steady_clock::time_point m_drawstart; // cached start time of previous frame
|
|
||||||
float m_framerate;
|
float m_framerate;
|
||||||
float m_drawtimecolorpass { 1000.f / 30.f * 20.f };
|
|
||||||
float m_drawtimeshadowpass { 0.f };
|
|
||||||
double m_updateaccumulator { 0.0 };
|
double m_updateaccumulator { 0.0 };
|
||||||
std::string m_debuginfo;
|
std::string m_debugtimestext;
|
||||||
std::string m_pickdebuginfo;
|
std::string m_pickdebuginfo;
|
||||||
|
debug_stats m_debugstats;
|
||||||
|
std::string m_debugstatstext;
|
||||||
|
|
||||||
glm::vec4 m_baseambient { 0.0f, 0.0f, 0.0f, 1.0f };
|
glm::vec4 m_baseambient { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||||
glm::vec4 m_shadowcolor { 0.65f, 0.65f, 0.65f, 1.f };
|
glm::vec4 m_shadowcolor { 0.65f, 0.65f, 0.65f, 1.f };
|
||||||
|
|||||||
298
scene.cpp
298
scene.cpp
@@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "scene.h"
|
#include "scene.h"
|
||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
#include "timer.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
|
|
||||||
@@ -19,12 +20,32 @@ namespace scene {
|
|||||||
// legacy method, updates sounds and polls event launchers within radius around specified point
|
// legacy method, updates sounds and polls event launchers within radius around specified point
|
||||||
void
|
void
|
||||||
basic_cell::update() {
|
basic_cell::update() {
|
||||||
/*
|
|
||||||
// renderowanie obiektów aktywnych a niewidocznych
|
// sounds
|
||||||
for( auto node = subcell->nRenderHidden; node; node = node->nNext3 ) {
|
auto const deltatime = Timer::GetDeltaTime();
|
||||||
node->RenderHidden();
|
for( auto *sound : m_sounds ) {
|
||||||
|
|
||||||
|
if( ( sound->GetStatus() & DSBSTATUS_PLAYING ) == DSBPLAY_LOOPING ) {
|
||||||
|
sound->Play( 1, DSBPLAY_LOOPING, true, sound->vSoundPosition );
|
||||||
|
sound->AdjFreq( 1.0, deltatime );
|
||||||
}
|
}
|
||||||
*/
|
}
|
||||||
|
// event launchers
|
||||||
|
for( auto *launcher : m_eventlaunchers ) {
|
||||||
|
if( ( true == launcher->check_conditions() )
|
||||||
|
&& ( SquareMagnitude( launcher->location() - Global::pCameraPosition ) < launcher->dRadius ) ) {
|
||||||
|
|
||||||
|
WriteLog( "Eventlauncher " + launcher->name() );
|
||||||
|
if( ( true == Global::shiftState )
|
||||||
|
&& ( launcher->Event2 != nullptr ) ) {
|
||||||
|
simulation::Events.AddToQuery( launcher->Event2, nullptr );
|
||||||
|
}
|
||||||
|
else if( launcher->Event1 ) {
|
||||||
|
simulation::Events.AddToQuery( launcher->Event1, nullptr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TBD, TODO: move to sound renderer
|
// TBD, TODO: move to sound renderer
|
||||||
for( auto *path : m_paths ) {
|
for( auto *path : m_paths ) {
|
||||||
// dźwięki pojazdów, również niewidocznych
|
// dźwięki pojazdów, również niewidocznych
|
||||||
@@ -32,6 +53,83 @@ basic_cell::update() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
|
||||||
|
void
|
||||||
|
basic_cell::update_traction( TDynamicObject *Vehicle, int const Pantographindex ) {
|
||||||
|
// Winger 170204 - szukanie trakcji nad pantografami
|
||||||
|
auto const vFront = glm::make_vec3( Vehicle->VectorFront().getArray() ); // wektor normalny dla płaszczyzny ruchu pantografu
|
||||||
|
auto const vUp = glm::make_vec3( Vehicle->VectorUp().getArray() ); // wektor pionu pudła (pochylony od pionu na przechyłce)
|
||||||
|
auto const vLeft = glm::make_vec3( Vehicle->VectorLeft().getArray() ); // wektor odległości w bok (odchylony od poziomu na przechyłce)
|
||||||
|
auto const position = glm::dvec3 { Vehicle->GetPosition() }; // współrzędne środka pojazdu
|
||||||
|
|
||||||
|
auto pantograph = Vehicle->pants[ Pantographindex ].fParamPants;
|
||||||
|
auto const pantographposition = position + ( vLeft * pantograph->vPos.z ) + ( vUp * pantograph->vPos.y ) + ( vFront * pantograph->vPos.x );
|
||||||
|
|
||||||
|
for( auto *traction : m_traction ) {
|
||||||
|
|
||||||
|
// współczynniki równania parametrycznego
|
||||||
|
auto const paramfrontdot = glm::dot( traction->vParametric, vFront );
|
||||||
|
auto const fRaParam =
|
||||||
|
-( glm::dot( traction->pPoint1, vFront ) - glm::dot( pantographposition, vFront ) )
|
||||||
|
/ ( paramfrontdot != 0.0 ?
|
||||||
|
paramfrontdot :
|
||||||
|
0.001 ); // div0 trap
|
||||||
|
|
||||||
|
if( ( fRaParam < -0.001 )
|
||||||
|
|| ( fRaParam > 1.001 ) ) { continue; }
|
||||||
|
// jeśli tylko jest w przedziale, wyznaczyć odległość wzdłuż wektorów vUp i vLeft
|
||||||
|
// punkt styku płaszczyzny z drutem (dla generatora łuku el.)
|
||||||
|
auto const vStyk = traction->pPoint1 + fRaParam * traction->vParametric;
|
||||||
|
// wektor musi się mieścić w przedziale ruchu pantografu
|
||||||
|
auto const vGdzie = vStyk - pantographposition;
|
||||||
|
auto fVertical = glm::dot( vGdzie, vUp );
|
||||||
|
if( fVertical >= 0.0 ) {
|
||||||
|
// jeśli ponad pantografem (bo może łapać druty spod wiaduktu)
|
||||||
|
auto const fHorizontal = std::abs( glm::dot( vGdzie, vLeft ) ) - pantograph->fWidth;
|
||||||
|
|
||||||
|
if( ( Global::bEnableTraction )
|
||||||
|
&& ( fVertical < pantograph->PantWys - 0.15 ) ) {
|
||||||
|
// jeśli drut jest niżej niż 15cm pod ślizgiem przełączamy w tryb połamania, o ile jedzie;
|
||||||
|
// (bEnableTraction) aby dało się jeździć na koślawych sceneriach
|
||||||
|
// i do tego jeszcze wejdzie pod ślizg
|
||||||
|
if( fHorizontal <= 0.0 ) {
|
||||||
|
// 0.635 dla AKP-1 AKP-4E
|
||||||
|
pantograph->PantWys = -1.0; // ujemna liczba oznacza połamanie
|
||||||
|
pantograph->hvPowerWire = nullptr; // bo inaczej się zasila w nieskończoność z połamanego
|
||||||
|
if( Vehicle->MoverParameters->EnginePowerSource.CollectorParameters.CollectorsNo > 0 ) {
|
||||||
|
// liczba pantografów teraz będzie mniejsza
|
||||||
|
--Vehicle->MoverParameters->EnginePowerSource.CollectorParameters.CollectorsNo;
|
||||||
|
}
|
||||||
|
if( DebugModeFlag ) {
|
||||||
|
ErrorLog( "Bad traction: " + Vehicle->name() + " broke pantograph at " + to_string( pantographposition ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( fVertical < pantograph->PantTraction ) {
|
||||||
|
// ale niżej, niż poprzednio znaleziony
|
||||||
|
if( fHorizontal <= 0.0 ) {
|
||||||
|
// 0.635 dla AKP-1 AKP-4E
|
||||||
|
// to się musi mieścić w przedziale zaleznym od szerokości pantografu
|
||||||
|
pantograph->hvPowerWire = traction; // jakiś znaleziony
|
||||||
|
pantograph->PantTraction = fVertical; // zapamiętanie nowej wysokości
|
||||||
|
}
|
||||||
|
else if( fHorizontal < pantograph->fWidthExtra ) {
|
||||||
|
// czy zmieścił się w zakresie nabieżnika? problem jest, gdy nowy drut jest wyżej,
|
||||||
|
// wtedy pantograf odłącza się od starego, a na podniesienie do nowego potrzebuje czasu
|
||||||
|
// korekta wysokości o nabieżnik - drut nad nabieżnikiem jest geometrycznie jakby nieco wyżej
|
||||||
|
fVertical += 0.15 * fHorizontal / pantograph->fWidthExtra;
|
||||||
|
if( fVertical < pantograph->PantTraction ) {
|
||||||
|
// gdy po korekcie jest niżej, niż poprzednio znaleziony
|
||||||
|
// gdyby to wystarczyło, to możemy go uznać
|
||||||
|
pantograph->hvPowerWire = traction; // może być
|
||||||
|
pantograph->PantTraction = fVertical; // na razie liniowo na nabieżniku, dokładność poprawi się później
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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 ) {
|
||||||
@@ -107,18 +205,48 @@ basic_cell::insert( TAnimModel *Instance ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// adds provided sound instance to the cell
|
||||||
|
void
|
||||||
|
basic_cell::insert( TTextSound *Sound ) {
|
||||||
|
|
||||||
|
m_active = true;
|
||||||
|
|
||||||
|
m_sounds.emplace_back( Sound );
|
||||||
|
}
|
||||||
|
|
||||||
|
// adds provided sound instance to the cell
|
||||||
|
void
|
||||||
|
basic_cell::insert( TEventLauncher *Launcher ) {
|
||||||
|
|
||||||
|
m_active = true;
|
||||||
|
|
||||||
|
m_eventlaunchers.emplace_back( Launcher );
|
||||||
|
}
|
||||||
|
|
||||||
// registers provided path in the lookup directory of the cell
|
// registers provided path in the lookup directory of the cell
|
||||||
void
|
void
|
||||||
basic_cell::register_end( TTrack *Path ) {
|
basic_cell::register_end( TTrack *Path ) {
|
||||||
|
|
||||||
m_directories.paths.emplace( Path );
|
m_directories.paths.emplace_back( Path );
|
||||||
|
// eliminate potential duplicates
|
||||||
|
m_directories.paths.erase(
|
||||||
|
std::unique(
|
||||||
|
std::begin( m_directories.paths ),
|
||||||
|
std::end( m_directories.paths ) ),
|
||||||
|
std::end( m_directories.paths ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// registers provided traction piece in the lookup directory of the cell
|
// registers provided traction piece in the lookup directory of the cell
|
||||||
void
|
void
|
||||||
basic_cell::register_end( TTraction *Traction ) {
|
basic_cell::register_end( TTraction *Traction ) {
|
||||||
|
|
||||||
m_directories.traction.emplace( Traction );
|
m_directories.traction.emplace_back( Traction );
|
||||||
|
// eliminate potential duplicates
|
||||||
|
m_directories.traction.erase(
|
||||||
|
std::unique(
|
||||||
|
std::begin( m_directories.traction ),
|
||||||
|
std::end( m_directories.traction ) ),
|
||||||
|
std::end( m_directories.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
|
||||||
@@ -263,6 +391,29 @@ basic_section::update( glm::dvec3 const &Location, float const Radius ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// legacy method, finds and assigns traction piece(s) to pantographs of provided vehicle
|
||||||
|
void
|
||||||
|
basic_section::update_traction( TDynamicObject *Vehicle, int const Pantographindex ) {
|
||||||
|
|
||||||
|
auto const vFront = glm::make_vec3( Vehicle->VectorFront().getArray() ); // wektor normalny dla płaszczyzny ruchu pantografu
|
||||||
|
auto const vUp = glm::make_vec3( Vehicle->VectorUp().getArray() ); // wektor pionu pudła (pochylony od pionu na przechyłce)
|
||||||
|
auto const vLeft = glm::make_vec3( Vehicle->VectorLeft().getArray() ); // wektor odległości w bok (odchylony od poziomu na przechyłce)
|
||||||
|
auto const position = glm::dvec3{ Vehicle->GetPosition() }; // współrzędne środka pojazdu
|
||||||
|
|
||||||
|
auto pantograph = Vehicle->pants[ Pantographindex ].fParamPants;
|
||||||
|
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 squaredradii { std::pow( ( 0.5 * M_SQRT2 * EU07_CELLSIZE + 0.25 * EU07_CELLSIZE ) + radius, 2 ) };
|
||||||
|
|
||||||
|
for( auto &cell : m_cells ) {
|
||||||
|
// we reject early cells which aren't within our area of interest
|
||||||
|
if( glm::length2( cell.area().center - pantographposition ) < squaredradii ) {
|
||||||
|
cell.update_traction( Vehicle, Pantographindex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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 ) {
|
||||||
@@ -289,47 +440,6 @@ basic_section::insert( shape_node Shape ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds provided path to the section
|
|
||||||
void
|
|
||||||
basic_section::insert( TTrack *Path ) {
|
|
||||||
|
|
||||||
// pass the node to the appropriate partitioning cell
|
|
||||||
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
|
||||||
cell( Path->location() ).insert( Path );
|
|
||||||
}
|
|
||||||
|
|
||||||
// adds provided path to the section
|
|
||||||
void
|
|
||||||
basic_section::insert( TTraction *Traction ) {
|
|
||||||
|
|
||||||
// pass the node to the appropriate partitioning cell
|
|
||||||
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
|
||||||
cell( Traction->location() ).insert( Traction );
|
|
||||||
}
|
|
||||||
|
|
||||||
// adds provided model instance to the section
|
|
||||||
void
|
|
||||||
basic_section::insert( TAnimModel *Instance ) {
|
|
||||||
|
|
||||||
// pass the node to the appropriate partitioning cell
|
|
||||||
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
|
||||||
cell( Instance->location() ).insert( Instance );
|
|
||||||
}
|
|
||||||
|
|
||||||
// registers specified end point of the provided path in the lookup directory of the region
|
|
||||||
void
|
|
||||||
basic_section::register_end( TTrack *Path, glm::dvec3 const &Point ) {
|
|
||||||
|
|
||||||
cell( Point ).register_end( Path );
|
|
||||||
}
|
|
||||||
|
|
||||||
// registers specified end point of the provided traction piece in the lookup directory of the region
|
|
||||||
void
|
|
||||||
basic_section::register_end( TTraction *Traction, glm::dvec3 const &Point ) {
|
|
||||||
|
|
||||||
cell( Point ).register_end( 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_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 ) {
|
||||||
@@ -467,26 +577,11 @@ basic_section::cell( glm::dvec3 const &Location ) {
|
|||||||
basic_region::basic_region() {
|
basic_region::basic_region() {
|
||||||
|
|
||||||
m_sections.fill( nullptr );
|
m_sections.fill( nullptr );
|
||||||
/*
|
|
||||||
// initialize centers of sections:
|
|
||||||
// calculate center of 'top left' region section...
|
|
||||||
auto const centeroffset = -( EU07_REGIONSIDESECTIONCOUNT / 2 * EU07_SECTIONSIZE ) + EU07_SECTIONSIZE / 2;
|
|
||||||
glm::dvec3 regioncornercenter { centeroffset, 0, centeroffset };
|
|
||||||
auto row { 0 }, column { 0 };
|
|
||||||
// ...move through section array assigning centers left to right, front/top to back/bottom
|
|
||||||
for( auto §ion : m_sections ) {
|
|
||||||
section.center( regioncornercenter + glm::dvec3{ column * EU07_SECTIONSIZE, 0.0, row * EU07_SECTIONSIZE } );
|
|
||||||
if( ++column >= EU07_REGIONSIDESECTIONCOUNT ) {
|
|
||||||
++row;
|
|
||||||
column = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
basic_region::~basic_region() {
|
basic_region::~basic_region() {
|
||||||
|
|
||||||
for( auto section : m_sections ) { if( section != nullptr ) { delete section; } }
|
for( auto *section : m_sections ) { if( section != nullptr ) { delete section; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
// legacy method, updates sounds and polls event launchers around camera
|
// legacy method, updates sounds and polls event launchers around camera
|
||||||
@@ -500,6 +595,25 @@ basic_region::update() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// legacy method, finds and assigns traction piece(s) to pantographs of provided vehicle
|
||||||
|
void
|
||||||
|
basic_region::update_traction( TDynamicObject *Vehicle, int const Pantographindex ) {
|
||||||
|
// TODO: convert vectors to transformation matrix and pass them down the chain along with calculated position
|
||||||
|
auto const vFront = glm::make_vec3( Vehicle->VectorFront().getArray() ); // wektor normalny dla płaszczyzny ruchu pantografu
|
||||||
|
auto const vUp = glm::make_vec3( Vehicle->VectorUp().getArray() ); // wektor pionu pudła (pochylony od pionu na przechyłce)
|
||||||
|
auto const vLeft = glm::make_vec3( Vehicle->VectorLeft().getArray() ); // wektor odległości w bok (odchylony od poziomu na przechyłce)
|
||||||
|
auto const position = glm::dvec3 { Vehicle->GetPosition() }; // współrzędne środka pojazdu
|
||||||
|
|
||||||
|
auto p = Vehicle->pants[ Pantographindex ].fParamPants;
|
||||||
|
auto const pant0 = position + ( vLeft * p->vPos.z ) + ( vUp * p->vPos.y ) + ( vFront * p->vPos.x );
|
||||||
|
p->PantTraction = std::numeric_limits<double>::max(); // taka za duża wartość
|
||||||
|
|
||||||
|
auto const §ionlist = sections( pant0, 0.0 );
|
||||||
|
for( auto *section : sectionlist ) {
|
||||||
|
section->update_traction( Vehicle, Pantographindex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
basic_region::insert_shape( shape_node Shape, scratch_data &Scratchpad ) {
|
basic_region::insert_shape( shape_node Shape, scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
@@ -566,15 +680,15 @@ void
|
|||||||
basic_region::insert_path( TTrack *Path, scratch_data &Scratchpad ) {
|
basic_region::insert_path( TTrack *Path, scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
||||||
auto center = Path->location();
|
auto location = Path->location();
|
||||||
|
|
||||||
if( point_inside( center ) ) {
|
if( point_inside( location ) ) {
|
||||||
// NOTE: nodes placed outside of region boundaries are discarded
|
// NOTE: nodes placed outside of region boundaries are discarded
|
||||||
section( center ).insert( Path );
|
section( location ).insert( Path );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// tracks are guaranteed to hava a name so we can skip the check
|
// tracks are guaranteed to hava a name so we can skip the check
|
||||||
ErrorLog( "Bad scenario: track node \"" + Path->name() + "\" placed in location outside region bounds (" + to_string( center ) + ")" );
|
ErrorLog( "Bad scenario: track node \"" + Path->name() + "\" placed in location outside region bounds (" + to_string( location ) + ")" );
|
||||||
}
|
}
|
||||||
// also register path ends in appropriate sections, for path merging lookups
|
// also register path ends in appropriate sections, for path merging lookups
|
||||||
// TODO: clean this up during track refactoring
|
// TODO: clean this up during track refactoring
|
||||||
@@ -588,15 +702,15 @@ void
|
|||||||
basic_region::insert_traction( TTraction *Traction, scratch_data &Scratchpad ) {
|
basic_region::insert_traction( TTraction *Traction, scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
||||||
auto center = Traction->location();
|
auto location = Traction->location();
|
||||||
|
|
||||||
if( point_inside( center ) ) {
|
if( point_inside( location ) ) {
|
||||||
// NOTE: nodes placed outside of region boundaries are discarded
|
// NOTE: nodes placed outside of region boundaries are discarded
|
||||||
section( center ).insert( Traction );
|
section( location ).insert( Traction );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// tracks are guaranteed to hava a name so we can skip the check
|
// tracks are guaranteed to hava a name so we can skip the check
|
||||||
ErrorLog( "Bad scenario: traction node \"" + Traction->name() + "\" placed in location outside region bounds (" + to_string( center ) + ")" );
|
ErrorLog( "Bad scenario: traction node \"" + Traction->name() + "\" placed in location outside region bounds (" + to_string( location ) + ")" );
|
||||||
}
|
}
|
||||||
// also register traction ends in appropriate sections, for path merging lookups
|
// also register traction ends in appropriate sections, for path merging lookups
|
||||||
// TODO: clean this up during track refactoring
|
// TODO: clean this up during track refactoring
|
||||||
@@ -610,15 +724,15 @@ void
|
|||||||
basic_region::insert_instance( TAnimModel *Instance, scratch_data &Scratchpad ) {
|
basic_region::insert_instance( TAnimModel *Instance, scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
||||||
auto center = Instance->location();
|
auto location = Instance->location();
|
||||||
|
|
||||||
if( point_inside( center ) ) {
|
if( point_inside( location ) ) {
|
||||||
// NOTE: nodes placed outside of region boundaries are discarded
|
// NOTE: nodes placed outside of region boundaries are discarded
|
||||||
section( center ).insert( Instance );
|
section( location ).insert( Instance );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// tracks are guaranteed to hava a name so we can skip the check
|
// tracks are guaranteed to hava a name so we can skip the check
|
||||||
ErrorLog( "Bad scenario: model node \"" + Instance->name() + "\" placed in location outside region bounds (" + to_string( center ) + ")" );
|
ErrorLog( "Bad scenario: model node \"" + Instance->name() + "\" placed in location outside region bounds (" + to_string( location ) + ")" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,20 +740,34 @@ basic_region::insert_instance( TAnimModel *Instance, scratch_data &Scratchpad )
|
|||||||
void
|
void
|
||||||
basic_region::insert_sound( TTextSound *Sound, scratch_data &Scratchpad ) {
|
basic_region::insert_sound( TTextSound *Sound, scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
/*
|
|
||||||
// TODO: implement
|
|
||||||
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
||||||
auto center = Sound->location();
|
auto location = Sound->location();
|
||||||
|
|
||||||
if( point_inside( center ) ) {
|
if( point_inside( location ) ) {
|
||||||
// NOTE: nodes placed outside of region boundaries are discarded
|
// NOTE: nodes placed outside of region boundaries are discarded
|
||||||
section( center ).insert( Instance );
|
section( location ).insert( Sound );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// tracks are guaranteed to hava a name so we can skip the check
|
// tracks are guaranteed to hava a name so we can skip the check
|
||||||
ErrorLog( "Bad scenario: model node \"" + Instance->name() + "\" placed in location outside region bounds (" + to_string( center ) + ")" );
|
ErrorLog( "Bad scenario: sound node \"" + Sound->name() + "\" placed in location outside region bounds (" + to_string( location ) + ")" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// inserts provided event launcher in the region
|
||||||
|
void
|
||||||
|
basic_region::insert_launcher( TEventLauncher *Launcher, scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
|
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
||||||
|
auto location = Launcher->location();
|
||||||
|
|
||||||
|
if( point_inside( location ) ) {
|
||||||
|
// NOTE: nodes placed outside of region boundaries are discarded
|
||||||
|
section( location ).insert( Launcher );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// tracks are guaranteed to hava a name so we can skip the check
|
||||||
|
ErrorLog( "Bad scenario: event launcher \"" + Launcher->name() + "\" placed in location outside region bounds (" + to_string( location ) + ")" );
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
@@ -757,7 +885,7 @@ void
|
|||||||
basic_region::register_path( TTrack *Path, glm::dvec3 const &Point ) {
|
basic_region::register_path( TTrack *Path, glm::dvec3 const &Point ) {
|
||||||
|
|
||||||
if( point_inside( Point ) ) {
|
if( point_inside( Point ) ) {
|
||||||
section( Point ).register_end( Path, Point );
|
section( Point ).register_node( Path, Point );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,7 +894,7 @@ void
|
|||||||
basic_region::register_traction( TTraction *Traction, glm::dvec3 const &Point ) {
|
basic_region::register_traction( TTraction *Traction, glm::dvec3 const &Point ) {
|
||||||
|
|
||||||
if( point_inside( Point ) ) {
|
if( point_inside( Point ) ) {
|
||||||
section( Point ).register_end( Traction, Point );
|
section( Point ).register_node( Traction, Point );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
56
scene.h
56
scene.h
@@ -13,6 +13,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include <deque>
|
#include <deque>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "openglgeometrybank.h"
|
#include "openglgeometrybank.h"
|
||||||
@@ -24,7 +25,7 @@ namespace scene {
|
|||||||
|
|
||||||
int const EU07_CELLSIZE = 250;
|
int const EU07_CELLSIZE = 250;
|
||||||
int const EU07_SECTIONSIZE = 1000;
|
int const EU07_SECTIONSIZE = 1000;
|
||||||
int const EU07_REGIONSIDESECTIONCOUNT = 500; // number of 1km sections along a side of square region
|
int const EU07_REGIONSIDESECTIONCOUNT = 500; // number of sections along a side of square region
|
||||||
|
|
||||||
struct scratch_data {
|
struct scratch_data {
|
||||||
|
|
||||||
@@ -42,6 +43,8 @@ struct scratch_data {
|
|||||||
TDynamicObject * driver { nullptr };
|
TDynamicObject * driver { nullptr };
|
||||||
bool is_open { false };
|
bool is_open { false };
|
||||||
} trainset;
|
} trainset;
|
||||||
|
|
||||||
|
bool initialized { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
// basic element of rudimentary partitioning scheme for the section. fixed size, no further subdivision
|
// basic element of rudimentary partitioning scheme for the section. fixed size, no further subdivision
|
||||||
@@ -55,6 +58,9 @@ public:
|
|||||||
// legacy method, updates sounds and polls event launchers within radius around specified point
|
// legacy method, updates sounds and polls event launchers within radius around specified point
|
||||||
void
|
void
|
||||||
update();
|
update();
|
||||||
|
// legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
|
||||||
|
void
|
||||||
|
update_traction( TDynamicObject *Vehicle, int const Pantographindex );
|
||||||
// adds provided shape to the cell
|
// adds provided shape to the cell
|
||||||
void
|
void
|
||||||
insert( shape_node Shape );
|
insert( shape_node Shape );
|
||||||
@@ -67,6 +73,12 @@ public:
|
|||||||
// adds provided model instance to the cell
|
// adds provided model instance to the cell
|
||||||
void
|
void
|
||||||
insert( TAnimModel *Instance );
|
insert( TAnimModel *Instance );
|
||||||
|
// adds provided sound instance to the cell
|
||||||
|
void
|
||||||
|
insert( TTextSound *Sound );
|
||||||
|
// adds provided event launcher to the cell
|
||||||
|
void
|
||||||
|
insert( TEventLauncher *Launcher );
|
||||||
// registers provided path in the lookup directory of the cell
|
// registers provided path in the lookup directory of the cell
|
||||||
void
|
void
|
||||||
register_end( TTrack *Path );
|
register_end( TTrack *Path );
|
||||||
@@ -100,10 +112,12 @@ private:
|
|||||||
// types
|
// types
|
||||||
using shapenode_sequence = std::vector<shape_node>;
|
using shapenode_sequence = std::vector<shape_node>;
|
||||||
using path_sequence = std::vector<TTrack *>;
|
using path_sequence = std::vector<TTrack *>;
|
||||||
using path_set = std::set<TTrack *>;
|
// using path_set = std::unordered_set<TTrack *>;
|
||||||
using traction_sequence = std::vector<TTraction *>;
|
using traction_sequence = std::vector<TTraction *>;
|
||||||
using traction_set = std::set<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 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 + 0.25 * EU07_CELLSIZE ) };
|
||||||
bool m_active { false }; // whether the cell holds any actual data
|
bool m_active { false }; // whether the cell holds any actual data
|
||||||
@@ -114,10 +128,12 @@ private:
|
|||||||
instance_sequence m_instancesopaque;
|
instance_sequence m_instancesopaque;
|
||||||
instance_sequence m_instancetranslucent;
|
instance_sequence m_instancetranslucent;
|
||||||
traction_sequence m_traction;
|
traction_sequence m_traction;
|
||||||
|
sound_sequence m_sounds;
|
||||||
|
eventlauncher_sequence m_eventlaunchers;
|
||||||
// search helpers
|
// search helpers
|
||||||
struct lookup_data {
|
struct lookup_data {
|
||||||
path_set paths;
|
path_sequence paths;
|
||||||
traction_set traction;
|
traction_sequence traction;
|
||||||
} m_directories;
|
} m_directories;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -131,24 +147,22 @@ public:
|
|||||||
// legacy method, updates sounds and polls event launchers within radius around specified point
|
// legacy method, updates sounds and polls event launchers within radius around specified point
|
||||||
void
|
void
|
||||||
update( glm::dvec3 const &Location, float const Radius );
|
update( glm::dvec3 const &Location, float const Radius );
|
||||||
|
// legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
|
||||||
|
void
|
||||||
|
update_traction( TDynamicObject *Vehicle, int const Pantographindex );
|
||||||
// adds provided shape to the section
|
// adds provided shape to the section
|
||||||
void
|
void
|
||||||
insert( shape_node Shape );
|
insert( shape_node Shape );
|
||||||
// adds provided path to the section
|
// adds provided node to the section
|
||||||
|
template <class Type_>
|
||||||
void
|
void
|
||||||
insert( TTrack *Path );
|
insert( Type_ *Node ) {
|
||||||
// adds provided path to the section
|
cell( Node->location() ).insert( Node ); }
|
||||||
|
// registers provided node in the lookup directory of the section enclosing specified point
|
||||||
|
template <class Type_>
|
||||||
void
|
void
|
||||||
insert( TTraction *Traction );
|
register_node( Type_ *Node, glm::dvec3 const &Point ) {
|
||||||
// adds provided model instance to the section
|
cell( Point ).register_end( Node ); }
|
||||||
void
|
|
||||||
insert( TAnimModel *Instance );
|
|
||||||
// registers specified end point of the provided path in the lookup directory of the region
|
|
||||||
void
|
|
||||||
register_end( TTrack *Path, glm::dvec3 const &Point );
|
|
||||||
// registers specified end point of the provided traction piece in the lookup directory of the region
|
|
||||||
void
|
|
||||||
register_end( TTraction *Traction, glm::dvec3 const &Point );
|
|
||||||
// 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>
|
||||||
find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled );
|
find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled );
|
||||||
@@ -206,6 +220,9 @@ public:
|
|||||||
// legacy method, updates sounds and polls event launchers around camera
|
// legacy method, updates sounds and polls event launchers around camera
|
||||||
void
|
void
|
||||||
update();
|
update();
|
||||||
|
// legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
|
||||||
|
void
|
||||||
|
update_traction( TDynamicObject *Vehicle, int const Pantographindex );
|
||||||
// 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 );
|
||||||
@@ -221,6 +238,9 @@ public:
|
|||||||
// inserts provided sound in the region
|
// inserts provided sound in the region
|
||||||
void
|
void
|
||||||
insert_sound( TTextSound *Sound, scratch_data &Scratchpad );
|
insert_sound( TTextSound *Sound, scratch_data &Scratchpad );
|
||||||
|
// inserts provided event launcher in the region
|
||||||
|
void
|
||||||
|
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, optionally ignoring vehicles without drivers. 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 );
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ state_manager::deserialize( std::string const &Scenariofile ) {
|
|||||||
if( false == scenarioparser.ok() ) { return false; }
|
if( false == scenarioparser.ok() ) { return false; }
|
||||||
|
|
||||||
deserialize( scenarioparser );
|
deserialize( scenarioparser );
|
||||||
// TODO: initialize links between loaded nodes
|
|
||||||
|
|
||||||
|
Global::iPause &= ~0x10; // koniec pauzy wczytywania
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,6 +126,11 @@ state_manager::deserialize( cParser &Input ) {
|
|||||||
|
|
||||||
token = Input.getToken<std::string>();
|
token = Input.getToken<std::string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( false == importscratchpad.initialized ) {
|
||||||
|
// manually perform scenario initialization
|
||||||
|
deserialize_firstinit( Input, importscratchpad );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -247,11 +252,15 @@ state_manager::deserialize_event( cParser &Input, scene::scratch_data &Scratchpa
|
|||||||
void
|
void
|
||||||
state_manager::deserialize_firstinit( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_manager::deserialize_firstinit( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
// TODO: implement
|
if( true == Scratchpad.initialized ) { return; }
|
||||||
|
|
||||||
simulation::Paths.InitTracks();
|
simulation::Paths.InitTracks();
|
||||||
simulation::Traction.InitTraction();
|
simulation::Traction.InitTraction();
|
||||||
simulation::Events.InitEvents();
|
simulation::Events.InitEvents();
|
||||||
|
simulation::Events.InitLaunchers();
|
||||||
simulation::Memory.InitCells();
|
simulation::Memory.InitCells();
|
||||||
|
|
||||||
|
Scratchpad.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -283,7 +292,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
|
|
||||||
if( false == simulation::Vehicles.insert( vehicle ) ) {
|
if( false == simulation::Vehicles.insert( vehicle ) ) {
|
||||||
|
|
||||||
ErrorLog( "Bad scenario: vehicle with duplicate name, \"" + vehicle->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
ErrorLog( "Bad scenario: vehicle with duplicate name \"" + vehicle->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( vehicle->MoverParameters->CategoryFlag == 1 ) // trains only
|
if( ( vehicle->MoverParameters->CategoryFlag == 1 ) // trains only
|
||||||
@@ -303,7 +312,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
simulation::Region->insert_path( path, Scratchpad );
|
simulation::Region->insert_path( path, Scratchpad );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorLog( "Bad scenario: track with duplicate name, \"" + path->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
ErrorLog( "Bad scenario: track with duplicate name \"" + path->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
||||||
/*
|
/*
|
||||||
delete path;
|
delete path;
|
||||||
delete pathnode;
|
delete pathnode;
|
||||||
@@ -320,7 +329,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
simulation::Region->insert_traction( traction, Scratchpad );
|
simulation::Region->insert_traction( traction, Scratchpad );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorLog( "Bad scenario: traction piece with duplicate name, \"" + traction->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
ErrorLog( "Bad scenario: traction piece with duplicate name \"" + traction->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( nodedata.type == "tractionpowersource" ) {
|
else if( nodedata.type == "tractionpowersource" ) {
|
||||||
@@ -336,7 +345,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorLog( "Bad scenario: power grid source with duplicate name, \"" + powersource->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
ErrorLog( "Bad scenario: power grid source with duplicate name \"" + powersource->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( nodedata.type == "model" ) {
|
else if( nodedata.type == "model" ) {
|
||||||
@@ -355,7 +364,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
simulation::Region->insert_instance( instance, Scratchpad );
|
simulation::Region->insert_instance( instance, Scratchpad );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorLog( "Bad scenario: 3d model instance with duplicate name, \"" + instance->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
ErrorLog( "Bad scenario: 3d model instance with duplicate name \"" + instance->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -382,12 +391,25 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorLog( "Bad scenario: memory cell with duplicate name, \"" + memorycell->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
ErrorLog( "Bad scenario: memory cell with duplicate name \"" + memorycell->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( nodedata.type == "eventlauncher" ) {
|
else if( nodedata.type == "eventlauncher" ) {
|
||||||
// TODO: implement
|
|
||||||
skip_until( Input, "end" );
|
auto *eventlauncher{ deserialize_eventlauncher( Input, Scratchpad, nodedata ) };
|
||||||
|
if( simulation::Events.insert( eventlauncher ) ) {
|
||||||
|
// event launchers can be either global, or local with limited range of activation
|
||||||
|
// each gets assigned different caretaker
|
||||||
|
if( true == eventlauncher->IsGlobal() ) {
|
||||||
|
simulation::Events.queue( eventlauncher );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
simulation::Region->insert_launcher( eventlauncher, Scratchpad );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ErrorLog( "Bad scenario: event launcher with duplicate name \"" + eventlauncher->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( nodedata.type == "sound" ) {
|
else if( nodedata.type == "sound" ) {
|
||||||
|
|
||||||
@@ -396,7 +418,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
simulation::Region->insert_sound( sound, Scratchpad );
|
simulation::Region->insert_sound( sound, Scratchpad );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorLog( "Bad scenario: sound node with duplicate name, \"" + sound->m_name + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
ErrorLog( "Bad scenario: sound node with duplicate name \"" + sound->m_name + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,6 +626,23 @@ state_manager::deserialize_memorycell( cParser &Input, scene::scratch_data &Scra
|
|||||||
return memorycell;
|
return memorycell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEventLauncher *
|
||||||
|
state_manager::deserialize_eventlauncher( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
|
glm::dvec3 location;
|
||||||
|
Input.getTokens( 3 );
|
||||||
|
Input
|
||||||
|
>> location.x
|
||||||
|
>> location.y
|
||||||
|
>> location.z;
|
||||||
|
|
||||||
|
auto *eventlauncher = new TEventLauncher( Nodedata );
|
||||||
|
eventlauncher->Load( &Input );
|
||||||
|
eventlauncher->location( transform( location, Scratchpad ) );
|
||||||
|
|
||||||
|
return eventlauncher;
|
||||||
|
}
|
||||||
|
|
||||||
TAnimModel *
|
TAnimModel *
|
||||||
state_manager::deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
state_manager::deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata ) {
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "scene.h"
|
#include "scene.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "memcell.h"
|
#include "memcell.h"
|
||||||
|
#include "evlaunch.h"
|
||||||
#include "track.h"
|
#include "track.h"
|
||||||
#include "traction.h"
|
#include "traction.h"
|
||||||
#include "tractionpower.h"
|
#include "tractionpower.h"
|
||||||
@@ -60,6 +61,7 @@ private:
|
|||||||
TTraction * deserialize_traction( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TTraction * deserialize_traction( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
TTractionPowerSource * deserialize_tractionpowersource( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TTractionPowerSource * deserialize_tractionpowersource( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
TMemCell * deserialize_memorycell( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TMemCell * deserialize_memorycell( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
|
TEventLauncher * deserialize_eventlauncher( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
TAnimModel * deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TAnimModel * deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
TDynamicObject * deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TDynamicObject * deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
TTextSound * deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TTextSound * deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
|
|||||||
Reference in New Issue
Block a user