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

build 180626. ai power use logic tweaks, basic selected node attributes display in scenery editor, memory cell visualization in scenery editor debug mode, minor bug fixes

This commit is contained in:
tmj-fstate
2018-06-27 03:22:50 +02:00
parent c6d2f1271d
commit 30e31cdfd0
13 changed files with 278 additions and 111 deletions

View File

@@ -550,7 +550,7 @@ void TAnimModel::RaAnimate( unsigned int const Framestamp ) {
// Ra 2F1I: to by można pomijać dla modeli bez animacji, których jest większość // Ra 2F1I: to by można pomijać dla modeli bez animacji, których jest większość
TAnimContainer *pCurrent; TAnimContainer *pCurrent;
for (pCurrent = pRoot; pCurrent != NULL; pCurrent = pCurrent->pNext) for (pCurrent = pRoot; pCurrent != nullptr; pCurrent = pCurrent->pNext)
if (!pCurrent->evDone) // jeśli jest bez eventu if (!pCurrent->evDone) // jeśli jest bez eventu
pCurrent->UpdateModel(); // przeliczenie animacji każdego submodelu pCurrent->UpdateModel(); // przeliczenie animacji każdego submodelu
// if () //tylko dla modeli z IK !!!! // if () //tylko dla modeli z IK !!!!

View File

@@ -125,6 +125,7 @@ class TAnimAdvanced
class TAnimModel : public scene::basic_node { class TAnimModel : public scene::basic_node {
friend class opengl_renderer; friend class opengl_renderer;
friend class ui_layer;
public: public:
// constructors // constructors
@@ -151,7 +152,7 @@ public:
return &m_materialdata; } return &m_materialdata; }
inline inline
TModel3d * TModel3d *
Model() { Model() const {
return pModel; } return pModel; }
// members // members
static TAnimContainer *acAnimList; // lista animacji z eventem, które muszą być przeliczane również bez wyświetlania static TAnimContainer *acAnimList; // lista animacji z eventem, które muszą być przeliczane również bez wyświetlania

View File

@@ -872,7 +872,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
auto L = 0.0; auto L = 0.0;
auto Par1 = sSpeedTable[i].evEvent->ValueGet(1); auto Par1 = sSpeedTable[i].evEvent->ValueGet(1);
auto Par2 = sSpeedTable[i].evEvent->ValueGet(2); auto Par2 = sSpeedTable[i].evEvent->ValueGet(2);
if ((Par2 > 0) || (fLength < -Par2)) { //użyj tego W4 if ((Par2 >= 0) || (fLength < -Par2)) { //użyj tego W4
if (Par1 < 0) { if (Par1 < 0) {
L = -Par1; L = -Par1;
} }
@@ -2732,65 +2732,69 @@ bool TController::IncSpeed()
if (!mvControlling->FuseFlag) //&&mvControlling->StLinFlag) //yBARC if (!mvControlling->FuseFlag) //&&mvControlling->StLinFlag) //yBARC
if ((mvControlling->MainCtrlPos == 0) || if ((mvControlling->MainCtrlPos == 0) ||
(mvControlling->StLinFlag)) // youBy polecił dodać 2012-09-08 v367 (mvControlling->StLinFlag)) // youBy polecił dodać 2012-09-08 v367
// na pozycji 0 przejdzie, a na pozostałych będzie czekać, aż się załączą liniowe // na pozycji 0 przejdzie, a na pozostałych będzie czekać, aż się załączą liniowe (zgaśnie DelayCtrlFlag)
// (zgaśnie DelayCtrlFlag) if (Ready || (iDrivigFlags & movePress)) {
if (Ready || (iDrivigFlags & movePress)) // use series mode to build up speed, when high threshold is set for motor overload relay or if the power station is heavily burdened
{ auto const useseriesmodevoltage { 0.85 * mvControlling->EnginePowerSource.CollectorParameters.MaxV };
bool scndctrl = ((mvOccupied->Vel <= 30) || auto const useseriesmode = (
(mvControlling->Imax > mvControlling->ImaxLo) || ( mvOccupied->Vel <= ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ? 35 : 25 ) + ( mvControlling->ScndCtrlPos == 0 ? 0 : 5 ) )
(fVoltage + fVoltage < || ( mvControlling->Imax > mvControlling->ImaxLo )
mvControlling->EnginePowerSource.CollectorParameters.MinV + || ( fVoltage < useseriesmodevoltage ) );
mvControlling->EnginePowerSource.CollectorParameters.MaxV) ||
(mvControlling->MainCtrlPos == mvControlling->MainCtrlPosNo));
scndctrl = ((scndctrl) && (mvControlling->MainCtrlPos > 1) && (mvControlling->RList[mvControlling->MainCtrlActualPos].R < 0.01)&& (mvControlling->ScndCtrlPos != mvControlling->ScndCtrlPosNo));
double Vs = 99999;
if((mvControlling->MainCtrlPos != mvControlling->MainCtrlPosNo)||(mvControlling->ScndCtrlPos!=mvControlling->ScndCtrlPosNo))
Vs = ESMVelocity(!scndctrl);
if ((fabs(mvControlling->Im) < auto const scndctrl = (
(fReady < 0.4 ? mvControlling->Imin : mvControlling->IminLo))||(mvControlling->Vel>Vs)) ( mvControlling->StLinFlag )
{ // Ra: wywalał nadmiarowy, bo Im może być ujemne; jak nie odhamowany, to nie && ( mvControlling->RList[ mvControlling->MainCtrlActualPos ].R < 0.01 )
// przesadzać z prądem && ( useseriesmode ?
if ((mvOccupied->Vel <= 30) || mvControlling->RList[ mvControlling->MainCtrlActualPos ].Bn == 1 :
(mvControlling->Imax > mvControlling->ImaxLo) || mvControlling->RList[ mvControlling->MainCtrlActualPos ].Bn > 1 ) );
(fVoltage + fVoltage <
mvControlling->EnginePowerSource.CollectorParameters.MinV + double Vs = 99999;
mvControlling->EnginePowerSource.CollectorParameters.MaxV)) if( scndctrl ?
{ // bocznik na szeregowej przy ciezkich bruttach albo przy wysokim rozruchu ( mvControlling->ScndCtrlPos < mvControlling->ScndCtrlPosNo ) :
// pod górę albo przy niskim napięciu ( mvControlling->MainCtrlPos < mvControlling->MainCtrlPosNo ) ) {
if (mvControlling->MainCtrlPos ? Vs = ESMVelocity( !scndctrl );
mvControlling->RList[mvControlling->MainCtrlPos].R > 0.0 : }
true) // oporowa
{ if( ( std::abs( mvControlling->Im ) < ( fReady < 0.4 ? mvControlling->Imin : mvControlling->IminLo ) )
OK = (mvControlling->DelayCtrlFlag ? || ( mvControlling->Vel > Vs ) ) {
true : // Ra: wywalał nadmiarowy, bo Im może być ujemne; jak nie odhamowany, to nie przesadzać z prądem
mvControlling->IncMainCtrl(1)); // kręcimy nastawnik jazdy if( scndctrl ) {
if ((OK) && // to dać bocznik
(mvControlling->MainCtrlPos == // engage the shuntfield only if there's sufficient power margin to draw from
1)) // czekaj na 1 pozycji, zanim się nie włączą liniowe OK = (
iDrivigFlags |= moveIncSpeed; fVoltage > useseriesmodevoltage + 0.0125 * mvControlling->EnginePowerSource.CollectorParameters.MaxV ?
else mvControlling->IncScndCtrl( 1 ) :
iDrivigFlags &= ~moveIncSpeed; // usunięcie flagi czekania false );
} }
else // jeśli bezoporowa (z wyjątekiem 0) else {
OK = false; // to dać bocznik // jeśli ustawiony bocznik to bocznik na zero po chamsku
} if( mvControlling->ScndCtrlPos ) {
else mvControlling->DecScndCtrl( 2 );
{ // przekroczone 30km/h, można wejść na jazdę równoległą }
if (mvControlling->ScndCtrlPos) // jeśli ustawiony bocznik // kręcimy nastawnik jazdy
if (mvControlling->MainCtrlPos < OK = (
mvControlling->MainCtrlPosNo - 1) // a nie jest ostatnia pozycja mvControlling->DelayCtrlFlag ?
mvControlling->DecScndCtrl(2); // to bocznik na zero po chamsku true :
// (ktoś miał to poprawić...) mvControlling->IncMainCtrl( 1 ) );
OK = mvControlling->IncMainCtrl(1); // czekaj na 1 pozycji, zanim się nie włączą liniowe
} if( true == mvControlling->StLinFlag ) {
if ((mvControlling->MainCtrlPos > 2) && iDrivigFlags |= moveIncSpeed;
(mvControlling->Im == 0)) // brak prądu na dalszych pozycjach }
Need_TryAgain = true; // nie załączona lokomotywa albo wywalił else {
// nadmiarowy iDrivigFlags &= ~moveIncSpeed;
else if (!OK) // nie da się wrzucić kolejnej pozycji }
OK = mvControlling->IncScndCtrl(1); // to dać bocznik
if( ( mvControlling->Im == 0 )
&& ( mvControlling->MainCtrlPos > 2 ) ) {
// brak prądu na dalszych pozycjach
// nie załączona lokomotywa albo wywalił nadmiarowy
Need_TryAgain = true;
}
}
} }
else {
OK = false;
}
} }
mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania
break; break;
@@ -2976,11 +2980,8 @@ void TController::SpeedSet()
break; break;
case ElectricSeriesMotor: case ElectricSeriesMotor:
if( ( false == mvControlling->StLinFlag ) if( ( false == mvControlling->StLinFlag )
&& ( false == mvControlling->DelayCtrlFlag ) && ( false == mvControlling->DelayCtrlFlag ) ) {
&& ( 0 == ( iDrivigFlags & moveIncSpeed ) ) ) // styczniki liniowe rozłączone yBARC // styczniki liniowe rozłączone yBARC
{
// if (iDrivigFlags&moveIncSpeed) {} //jeśli czeka na załączenie liniowych
// else
while( DecSpeed() ) while( DecSpeed() )
; // zerowanie napędu ; // zerowanie napędu
} }
@@ -3853,6 +3854,28 @@ TController::UpdateSituation(double dt) {
} }
} }
} }
if( fVoltage < 0.8 * mvControlling->EnginePowerSource.CollectorParameters.MaxV ) {
// if the power station is heavily burdened try to reduce the load
switch( mvControlling->EngineType ) {
case ElectricSeriesMotor: {
if( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 ) {
// limit yourself to series mode
if( mvControlling->ScndCtrlPos ) {
mvControlling->DecScndCtrl( 2 );
}
while( ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 )
&& ( mvControlling->DecMainCtrl( 1 ) ) ) {
; // all work is performed in the header
}
}
break;
}
default: {
break;
}
}
}
} }
else { else {
if( ( IdleTime > 45.0 ) if( ( IdleTime > 45.0 )

View File

@@ -127,6 +127,8 @@ private:
class TTrack : public scene::basic_node { class TTrack : public scene::basic_node {
friend class opengl_renderer; friend class opengl_renderer;
// NOTE: temporary arrangement
friend class ui_layer;
private: private:
TIsolated * pIsolated = nullptr; // obwód izolowany obsługujący zajęcia/zwolnienia grupy torów TIsolated * pIsolated = nullptr; // obwód izolowany obsługujący zajęcia/zwolnienia grupy torów

View File

@@ -6355,6 +6355,7 @@ void TTrain::clear_cab_controls()
ggRadioTest.Clear(); ggRadioTest.Clear();
ggDoorLeftButton.Clear(); ggDoorLeftButton.Clear();
ggDoorRightButton.Clear(); ggDoorRightButton.Clear();
ggTrainHeatingButton.Clear();
ggDepartureSignalButton.Clear(); ggDepartureSignalButton.Clear();
ggCompressorButton.Clear(); ggCompressorButton.Clear();
ggConverterButton.Clear(); ggConverterButton.Clear();

View File

@@ -237,15 +237,14 @@ void TWorld::TrainDelete(TDynamicObject *d)
if (Train) if (Train)
if (Train->Dynamic() != d) if (Train->Dynamic() != d)
return; // nie tego usuwać return; // nie tego usuwać
#ifdef EU07_SCENERY_EDITOR /*
if( ( Train->DynamicObject ) if( ( Train->Dynamic() )
&& ( Train->DynamicObject->Mechanik ) ) { && ( Train->Dynamic()->Mechanik ) ) {
// likwidacja kabiny wymaga przejęcia przez AI // likwidacja kabiny wymaga przejęcia przez AI
Train->DynamicObject->Mechanik->TakeControl( true ); Train->Dynamic()->Mechanik->TakeControl( true );
} }
#endif */
delete Train; // i nie ma czym sterować SafeDelete( Train ); // i nie ma czym sterować
Train = NULL;
Controlled = NULL; // tego też już nie ma Controlled = NULL; // tego też już nie ma
mvControlled = NULL; mvControlled = NULL;
}; };

View File

@@ -1806,15 +1806,6 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
// tracks // tracks
// TODO: update after path node refactoring // TODO: update after path node refactoring
Render( std::begin( cell->m_paths ), std::end( cell->m_paths ) ); Render( std::begin( cell->m_paths ), std::end( cell->m_paths ) );
#ifdef EU07_SCENERY_EDITOR
// TODO: re-implement
// memcells
if( EditorModeFlag ) {
for( auto const memcell : Groundsubcell->m_memcells ) {
Render( memcell );
}
}
#endif
#ifdef EU07_USE_DEBUG_CULLING #ifdef EU07_USE_DEBUG_CULLING
// debug // debug
::glLineWidth( 2.f ); ::glLineWidth( 2.f );
@@ -1884,16 +1875,7 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
::glColor3fv( glm::value_ptr( pick_color( m_picksceneryitems.size() + 1 ) ) ); ::glColor3fv( glm::value_ptr( pick_color( m_picksceneryitems.size() + 1 ) ) );
Render( path ); Render( path );
} }
#ifdef EU07_SCENERY_EDITOR
// memcells
// TODO: re-implement
if( EditorModeFlag ) {
for( auto const memcell : Groundsubcell->m_memcells ) {
::glColor3fv( glm::value_ptr( pick_color( m_picksceneryitems.size() + 1 ) ) );
Render( memcell );
}
}
#endif
// post-render cleanup // post-render cleanup
::glPopMatrix(); ::glPopMatrix();
@@ -1924,6 +1906,17 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
Render( dynamic ); Render( dynamic );
} }
} }
// memcells
if( ( EditorModeFlag )
&& ( DebugModeFlag ) ) {
::glPushAttrib( GL_ENABLE_BIT );
::glDisable( GL_TEXTURE_2D );
::glColor3f( 0.36f, 0.75f, 0.35f );
for( auto const *memorycell : cell->m_memorycells ) {
Render( memorycell );
}
::glPopAttrib();
}
break; break;
} }
case rendermode::pickscenery: { case rendermode::pickscenery: {
@@ -1933,6 +1926,14 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
::glColor3fv( glm::value_ptr( pick_color( m_picksceneryitems.size() + 1 ) ) ); ::glColor3fv( glm::value_ptr( pick_color( m_picksceneryitems.size() + 1 ) ) );
Render( instance ); Render( instance );
} }
// memcells
if( ( EditorModeFlag )
&& ( DebugModeFlag ) ) {
for( auto const *memorycell : cell->m_memorycells ) {
::glColor3fv( glm::value_ptr( pick_color( m_picksceneryitems.size() + 1 ) ) );
Render( memorycell );
}
}
// vehicles aren't included in scenery picking for the time being // vehicles aren't included in scenery picking for the time being
break; break;
} }
@@ -2754,25 +2755,22 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
} }
void void
opengl_renderer::Render( TMemCell *Memcell ) { opengl_renderer::Render( TMemCell const *Memcell ) {
::glPushMatrix(); ::glPushMatrix();
auto const position = Memcell->location() - m_renderpass.camera.position(); auto const position = Memcell->location() - m_renderpass.camera.position();
::glTranslated( position.x, position.y + 0.5, position.z ); ::glTranslated( position.x, position.y + 0.5, position.z );
switch( m_renderpass.draw_mode ) { switch( m_renderpass.draw_mode ) {
case rendermode::color: { case rendermode::color:
::glPushAttrib( GL_ENABLE_BIT ); case rendermode::shadows: {
::glDisable( GL_TEXTURE_2D );
::glColor3f( 0.36f, 0.75f, 0.35f );
::gluSphere( m_quadric, 0.35, 4, 2 ); ::gluSphere( m_quadric, 0.35, 4, 2 );
::glPopAttrib();
break; break;
} }
case rendermode::shadows:
case rendermode::pickscenery: { case rendermode::pickscenery: {
// add the node to the pick list
m_picksceneryitems.emplace_back( Memcell );
::gluSphere( m_quadric, 0.35, 4, 2 ); ::gluSphere( m_quadric, 0.35, 4, 2 );
break; break;
} }

View File

@@ -289,7 +289,7 @@ private:
bool bool
Render_cab( TDynamicObject const *Dynamic, bool const Alpha = false ); Render_cab( TDynamicObject const *Dynamic, bool const Alpha = false );
void void
Render( TMemCell *Memcell ); Render( TMemCell const *Memcell );
void void
Render_Alpha( scene::basic_region *Region ); Render_Alpha( scene::basic_region *Region );
void void

View File

@@ -360,6 +360,7 @@ basic_cell::insert( sound_source *Sound ) {
m_active = true; m_active = true;
m_sounds.emplace_back( Sound ); m_sounds.emplace_back( Sound );
// NOTE: sound sources are virtual 'points' hence they don't ever expand cell range
} }
// adds provided sound instance to the cell // adds provided sound instance to the cell
@@ -373,6 +374,16 @@ basic_cell::insert( TEventLauncher *Launcher ) {
enclose_area( Launcher ); enclose_area( Launcher );
} }
// adds provided memory cell to the cell
void
basic_cell::insert( TMemCell *Memorycell ) {
m_active = true;
m_memorycells.emplace_back( Memorycell );
// NOTE: memory cells are virtual 'points' hence they don't ever expand cell range
}
// 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 ) {
@@ -1132,7 +1143,6 @@ basic_region::insert_lines( lines_node Lines, scratch_data &Scratchpad ) {
// inserts provided track in the region // inserts provided track in the region
void void
basic_region::insert_path( TTrack *Path, scratch_data &Scratchpad ) { basic_region::insert_path( TTrack *Path, scratch_data &Scratchpad ) {
// 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 location = Path->location(); auto location = Path->location();
@@ -1154,7 +1164,6 @@ basic_region::insert_path( TTrack *Path, scratch_data &Scratchpad ) {
// inserts provided track in the region // inserts provided track in the region
void 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 location = Traction->location(); auto location = Traction->location();
@@ -1176,7 +1185,6 @@ basic_region::insert_traction( TTraction *Traction, scratch_data &Scratchpad ) {
// inserts provided instance of 3d model in the region // inserts provided instance of 3d model in the region
void 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 location = Instance->location(); auto location = Instance->location();
@@ -1209,7 +1217,6 @@ basic_region::insert_sound( sound_source *Sound, scratch_data &Scratchpad ) {
// inserts provided event launcher in the region // inserts provided event launcher in the region
void void
basic_region::insert_launcher( TEventLauncher *Launcher, scratch_data &Scratchpad ) { basic_region::insert_launcher( TEventLauncher *Launcher, 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 location = Launcher->location(); auto location = Launcher->location();
@@ -1223,6 +1230,22 @@ basic_region::insert_launcher( TEventLauncher *Launcher, scratch_data &Scratchpa
} }
} }
// inserts provided memory cell in the region
void
basic_region::insert_memorycell( TMemCell *Memorycell, scratch_data &Scratchpad ) {
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
auto location = Memorycell->location();
if( point_inside( location ) ) {
// NOTE: nodes placed outside of region boundaries are discarded
section( location ).insert( Memorycell );
}
else {
// tracks are guaranteed to hava a name so we can skip the check
ErrorLog( "Bad scenario: memory cell \"" + Memorycell->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
std::tuple<TDynamicObject *, float> std::tuple<TDynamicObject *, float>
basic_region::find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler ) { basic_region::find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler ) {

View File

@@ -114,6 +114,9 @@ public:
// adds provided event launcher to the cell // adds provided event launcher to the cell
void void
insert( TEventLauncher *Launcher ); insert( TEventLauncher *Launcher );
// adds provided memory cell to the cell
void
insert( TMemCell *Memorycell );
// 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 );
@@ -152,6 +155,7 @@ private:
using instance_sequence = std::vector<TAnimModel *>; using instance_sequence = std::vector<TAnimModel *>;
using sound_sequence = std::vector<sound_source *>; using sound_sequence = std::vector<sound_source *>;
using eventlauncher_sequence = std::vector<TEventLauncher *>; using eventlauncher_sequence = std::vector<TEventLauncher *>;
using memorycell_sequence = std::vector<TMemCell *>;
// methods // methods
void void
enclose_area( scene::basic_node *Node ); enclose_area( scene::basic_node *Node );
@@ -168,6 +172,7 @@ private:
traction_sequence m_traction; traction_sequence m_traction;
sound_sequence m_sounds; sound_sequence m_sounds;
eventlauncher_sequence m_eventlaunchers; eventlauncher_sequence m_eventlaunchers;
memorycell_sequence m_memorycells;
// search helpers // search helpers
struct lookup_data { struct lookup_data {
path_sequence paths; path_sequence paths;
@@ -329,6 +334,9 @@ public:
// inserts provided event launcher in the region // inserts provided event launcher in the region
void void
insert_launcher( TEventLauncher *Launcher, scratch_data &Scratchpad ); insert_launcher( TEventLauncher *Launcher, scratch_data &Scratchpad );
// inserts provided memory cell in the region
void
insert_memorycell( TMemCell *Memorycell, scratch_data &Scratchpad );
// find a vehicle located nearest to specified point, within specified radius. reurns: located vehicle and distance // find a vehicle located nearest to specified point, within specified radius. reurns: located vehicle and distance
std::tuple<TDynamicObject *, float> std::tuple<TDynamicObject *, float>
find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler ); find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler );

View File

@@ -440,10 +440,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
if( false == simulation::Memory.insert( memorycell ) ) { if( false == simulation::Memory.insert( memorycell ) ) {
ErrorLog( "Bad scenario: memory memorycell with duplicate name \"" + memorycell->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" ); ErrorLog( "Bad scenario: memory memorycell with duplicate name \"" + memorycell->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
} }
/* simulation::Region->insert_memorycell( memorycell, Scratchpad );
// TODO: implement this
simulation::Region.insert_memorycell( memorycell, Scratchpad );
*/
} }
else if( nodedata.type == "eventlauncher" ) { else if( nodedata.type == "eventlauncher" ) {

View File

@@ -246,6 +246,8 @@ ui_layer::update() {
"" ) ); "" ) );
} }
EditorModeFlag = ( Global.iTextMode == GLFW_KEY_F11 );
switch( Global.iTextMode ) { switch( Global.iTextMode ) {
case( GLFW_KEY_F1 ) : { case( GLFW_KEY_F1 ) : {
@@ -714,7 +716,120 @@ ui_layer::update() {
uitextline1 = uitextline1 =
"Node name: " + node->name() "Node name: " + node->name()
+ "; location: [" + to_string( node->location().x, 2 ) + ", " + to_string( node->location().y, 2 ) + ", " + to_string( node->location().z, 2 ) + "]"; + "; location: [" + to_string( node->location().x, 2 ) + ", " + to_string( node->location().y, 2 ) + ", " + to_string( node->location().z, 2 ) + "]"
+ " (distance: " + to_string( glm::length( glm::dvec3{ node->location().x, 0.0, node->location().z } -glm::dvec3{ Global.pCameraPosition.x, 0.0, Global.pCameraPosition.z } ), 1 ) + " m)";
// subclass-specific data
// TBD, TODO: specialized data dump method in each node subclass, or data imports in the panel for provided subclass pointer?
if( typeid( *node ) == typeid( TAnimModel ) ) {
auto const *subnode = static_cast<TAnimModel const *>( node );
uitextline2 = "angle: " + to_string( clamp_circular( subnode->vAngle.y, 360.0 ), 2 ) + " deg";
uitextline2 += "; lights: ";
if( subnode->iNumLights > 0 ) {
uitextline2 += '[';
for( int lightidx = 0; lightidx < subnode->iNumLights; ++lightidx ) {
uitextline2 += to_string( subnode->lsLights[ lightidx ] );
if( lightidx < subnode->iNumLights - 1 ) {
uitextline2 += ", ";
}
}
uitextline2 += ']';
}
else {
uitextline2 += "none";
}
// 3d shape
auto modelfile { (
subnode->pModel ?
subnode->pModel->NameGet() :
"none" ) };
if( modelfile.find( szModelPath ) == 0 ) {
// don't include 'models/' in the path
modelfile.erase( 0, std::string{ szModelPath }.size() );
}
// texture
auto texturefile { (
subnode->Material()->replacable_skins[ 1 ] != null_handle ?
GfxRenderer.Material( subnode->Material()->replacable_skins[ 1 ] ).name :
"none" ) };
if( texturefile.find( szTexturePath ) == 0 ) {
// don't include 'textures/' in the path
texturefile.erase( 0, std::string{ szTexturePath }.size() );
}
uitextline3 = "mesh: " + modelfile;
uitextline4 = "skin: " + texturefile;
}
else if( typeid( *node ) == typeid( TTrack ) ) {
auto const *subnode = static_cast<TTrack const *>( node );
// basic attributes
uitextline2 =
"isolated: " + ( subnode->pIsolated ? subnode->pIsolated->asName : "none" )
+ "; velocity: " + to_string( subnode->SwitchExtension ? subnode->SwitchExtension->fVelocity : subnode->fVelocity )
+ "; width: " + to_string( subnode->fTrackWidth ) + " m"
+ "; friction: " + to_string( subnode->fFriction, 2 )
+ "; quality: " + to_string( subnode->iQualityFlag );
// textures
auto texturefile { (
subnode->m_material1 != null_handle ?
GfxRenderer.Material( subnode->m_material1 ).name :
"none" ) };
if( texturefile.find( szTexturePath ) == 0 ) {
texturefile.erase( 0, std::string{ szTexturePath }.size() );
}
auto texturefile2{ (
subnode->m_material2 != null_handle ?
GfxRenderer.Material( subnode->m_material2 ).name :
"none" ) };
if( texturefile2.find( szTexturePath ) == 0 ) {
texturefile2.erase( 0, std::string{ szTexturePath }.size() );
}
uitextline2 += "; skins: [" + texturefile + ", " + texturefile2 + "]";
// paths
uitextline3 = "paths: ";
for( auto const &path : subnode->m_paths ) {
uitextline3 +=
"["
+ to_string( path.points[ segment_data::point::start ].x, 3 ) + ", "
+ to_string( path.points[ segment_data::point::start ].y, 3 ) + ", "
+ to_string( path.points[ segment_data::point::start ].z, 3 ) + "]->"
+ "["
+ to_string( path.points[ segment_data::point::end ].x, 3 ) + ", "
+ to_string( path.points[ segment_data::point::end ].y, 3 ) + ", "
+ to_string( path.points[ segment_data::point::end ].z, 3 ) + "] ";
}
// events
std::vector< std::pair< std::string, TTrack::event_sequence const * > > const eventsequences {
{ "ev0", &subnode->m_events0 }, { "ev0all", &subnode->m_events0all },
{ "ev1", &subnode->m_events1 }, { "ev1all", &subnode->m_events1all },
{ "ev2", &subnode->m_events2 }, { "ev2all", &subnode->m_events2all } };
for( auto const &eventsequence : eventsequences ) {
if( eventsequence.second->empty() ) { continue; }
uitextline4 += eventsequence.first + ": [";
for( auto const &event : *( eventsequence.second ) ) {
if( uitextline4.back() != '[' ) {
uitextline4 += ", ";
}
if( event.second ) {
uitextline4 += event.second->asName;
}
}
uitextline4 += "] ";
}
}
else if( typeid( *node ) == typeid( TMemCell ) ) {
auto const *subnode = static_cast<TMemCell const *>( node );
uitextline2 =
"data: [" + subnode->Text() + "]"
+ " [" + to_string( subnode->Value1(), 2 ) + "]"
+ " [" + to_string( subnode->Value2(), 2 ) + "]";
uitextline3 = "track: " + ( subnode->asTrackName.empty() ? "none" : subnode->asTrackName );
}
break; break;
} }

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define VERSION_MAJOR 18 #define VERSION_MAJOR 18
#define VERSION_MINOR 622 #define VERSION_MINOR 626
#define VERSION_REVISION 0 #define VERSION_REVISION 0