diff --git a/AnimModel.cpp b/AnimModel.cpp index e0f108a6..d364815b 100644 --- a/AnimModel.cpp +++ b/AnimModel.cpp @@ -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ść 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 pCurrent->UpdateModel(); // przeliczenie animacji każdego submodelu // if () //tylko dla modeli z IK !!!! diff --git a/AnimModel.h b/AnimModel.h index de4124ae..b6ec7055 100644 --- a/AnimModel.h +++ b/AnimModel.h @@ -125,6 +125,7 @@ class TAnimAdvanced class TAnimModel : public scene::basic_node { friend class opengl_renderer; + friend class ui_layer; public: // constructors @@ -151,7 +152,7 @@ public: return &m_materialdata; } inline TModel3d * - Model() { + Model() const { return pModel; } // members static TAnimContainer *acAnimList; // lista animacji z eventem, które muszą być przeliczane również bez wyświetlania diff --git a/Driver.cpp b/Driver.cpp index ebecd129..81199126 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -872,7 +872,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN auto L = 0.0; auto Par1 = sSpeedTable[i].evEvent->ValueGet(1); 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) { L = -Par1; } @@ -2732,65 +2732,69 @@ bool TController::IncSpeed() if (!mvControlling->FuseFlag) //&&mvControlling->StLinFlag) //yBARC if ((mvControlling->MainCtrlPos == 0) || (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 - // (zgaśnie DelayCtrlFlag) - if (Ready || (iDrivigFlags & movePress)) - { - bool scndctrl = ((mvOccupied->Vel <= 30) || - (mvControlling->Imax > mvControlling->ImaxLo) || - (fVoltage + fVoltage < - mvControlling->EnginePowerSource.CollectorParameters.MinV + - 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); + // na pozycji 0 przejdzie, a na pozostałych będzie czekać, aż się załączą liniowe (zgaśnie DelayCtrlFlag) + 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 }; + auto const useseriesmode = ( + ( mvOccupied->Vel <= ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ? 35 : 25 ) + ( mvControlling->ScndCtrlPos == 0 ? 0 : 5 ) ) + || ( mvControlling->Imax > mvControlling->ImaxLo ) + || ( fVoltage < useseriesmodevoltage ) ); - if ((fabs(mvControlling->Im) < - (fReady < 0.4 ? mvControlling->Imin : mvControlling->IminLo))||(mvControlling->Vel>Vs)) - { // Ra: wywalał nadmiarowy, bo Im może być ujemne; jak nie odhamowany, to nie - // przesadzać z prądem - if ((mvOccupied->Vel <= 30) || - (mvControlling->Imax > mvControlling->ImaxLo) || - (fVoltage + fVoltage < - mvControlling->EnginePowerSource.CollectorParameters.MinV + - mvControlling->EnginePowerSource.CollectorParameters.MaxV)) - { // bocznik na szeregowej przy ciezkich bruttach albo przy wysokim rozruchu - // pod górę albo przy niskim napięciu - if (mvControlling->MainCtrlPos ? - mvControlling->RList[mvControlling->MainCtrlPos].R > 0.0 : - true) // oporowa - { - OK = (mvControlling->DelayCtrlFlag ? - true : - mvControlling->IncMainCtrl(1)); // kręcimy nastawnik jazdy - if ((OK) && - (mvControlling->MainCtrlPos == - 1)) // czekaj na 1 pozycji, zanim się nie włączą liniowe - iDrivigFlags |= moveIncSpeed; - else - iDrivigFlags &= ~moveIncSpeed; // usunięcie flagi czekania - } - else // jeśli bezoporowa (z wyjątekiem 0) - OK = false; // to dać bocznik - } - else - { // przekroczone 30km/h, można wejść na jazdę równoległą - if (mvControlling->ScndCtrlPos) // jeśli ustawiony bocznik - if (mvControlling->MainCtrlPos < - mvControlling->MainCtrlPosNo - 1) // a nie jest ostatnia pozycja - mvControlling->DecScndCtrl(2); // to bocznik na zero po chamsku - // (ktoś miał to poprawić...) - OK = mvControlling->IncMainCtrl(1); - } - if ((mvControlling->MainCtrlPos > 2) && - (mvControlling->Im == 0)) // brak prądu na dalszych pozycjach - Need_TryAgain = true; // nie załączona lokomotywa albo wywalił - // nadmiarowy - else if (!OK) // nie da się wrzucić kolejnej pozycji - OK = mvControlling->IncScndCtrl(1); // to dać bocznik + auto const scndctrl = ( + ( mvControlling->StLinFlag ) + && ( mvControlling->RList[ mvControlling->MainCtrlActualPos ].R < 0.01 ) + && ( useseriesmode ? + mvControlling->RList[ mvControlling->MainCtrlActualPos ].Bn == 1 : + mvControlling->RList[ mvControlling->MainCtrlActualPos ].Bn > 1 ) ); + + double Vs = 99999; + if( scndctrl ? + ( mvControlling->ScndCtrlPos < mvControlling->ScndCtrlPosNo ) : + ( mvControlling->MainCtrlPos < mvControlling->MainCtrlPosNo ) ) { + Vs = ESMVelocity( !scndctrl ); + } + + if( ( std::abs( mvControlling->Im ) < ( fReady < 0.4 ? mvControlling->Imin : mvControlling->IminLo ) ) + || ( mvControlling->Vel > Vs ) ) { + // Ra: wywalał nadmiarowy, bo Im może być ujemne; jak nie odhamowany, to nie przesadzać z prądem + if( scndctrl ) { + // to dać bocznik + // engage the shuntfield only if there's sufficient power margin to draw from + OK = ( + fVoltage > useseriesmodevoltage + 0.0125 * mvControlling->EnginePowerSource.CollectorParameters.MaxV ? + mvControlling->IncScndCtrl( 1 ) : + false ); + } + else { + // jeśli ustawiony bocznik to bocznik na zero po chamsku + if( mvControlling->ScndCtrlPos ) { + mvControlling->DecScndCtrl( 2 ); + } + // kręcimy nastawnik jazdy + OK = ( + mvControlling->DelayCtrlFlag ? + true : + mvControlling->IncMainCtrl( 1 ) ); + // czekaj na 1 pozycji, zanim się nie włączą liniowe + if( true == mvControlling->StLinFlag ) { + iDrivigFlags |= moveIncSpeed; + } + else { + iDrivigFlags &= ~moveIncSpeed; + } + + 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 break; @@ -2976,11 +2980,8 @@ void TController::SpeedSet() break; case ElectricSeriesMotor: if( ( false == mvControlling->StLinFlag ) - && ( false == mvControlling->DelayCtrlFlag ) - && ( 0 == ( iDrivigFlags & moveIncSpeed ) ) ) // styczniki liniowe rozłączone yBARC - { - // if (iDrivigFlags&moveIncSpeed) {} //jeśli czeka na załączenie liniowych - // else + && ( false == mvControlling->DelayCtrlFlag ) ) { + // styczniki liniowe rozłączone yBARC while( DecSpeed() ) ; // 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 { if( ( IdleTime > 45.0 ) diff --git a/Track.h b/Track.h index 97f30815..4348d210 100644 --- a/Track.h +++ b/Track.h @@ -127,6 +127,8 @@ private: class TTrack : public scene::basic_node { friend class opengl_renderer; + // NOTE: temporary arrangement + friend class ui_layer; private: TIsolated * pIsolated = nullptr; // obwód izolowany obsługujący zajęcia/zwolnienia grupy torów diff --git a/Train.cpp b/Train.cpp index 878fe33f..c9fd1e74 100644 --- a/Train.cpp +++ b/Train.cpp @@ -6355,6 +6355,7 @@ void TTrain::clear_cab_controls() ggRadioTest.Clear(); ggDoorLeftButton.Clear(); ggDoorRightButton.Clear(); + ggTrainHeatingButton.Clear(); ggDepartureSignalButton.Clear(); ggCompressorButton.Clear(); ggConverterButton.Clear(); diff --git a/World.cpp b/World.cpp index 20f235b4..dc1b6b5a 100644 --- a/World.cpp +++ b/World.cpp @@ -237,15 +237,14 @@ void TWorld::TrainDelete(TDynamicObject *d) if (Train) if (Train->Dynamic() != d) return; // nie tego usuwać -#ifdef EU07_SCENERY_EDITOR - if( ( Train->DynamicObject ) - && ( Train->DynamicObject->Mechanik ) ) { +/* + if( ( Train->Dynamic() ) + && ( Train->Dynamic()->Mechanik ) ) { // 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ć - Train = NULL; +*/ + SafeDelete( Train ); // i nie ma czym sterować Controlled = NULL; // tego też już nie ma mvControlled = NULL; }; diff --git a/renderer.cpp b/renderer.cpp index 98ac8b80..63720686 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -1806,15 +1806,6 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator // tracks // TODO: update after path node refactoring 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 // debug ::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 ) ) ); 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 ::glPopMatrix(); @@ -1924,6 +1906,17 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator 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; } 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 ) ) ); 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 break; } @@ -2754,25 +2755,22 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First, } void -opengl_renderer::Render( TMemCell *Memcell ) { +opengl_renderer::Render( TMemCell const *Memcell ) { ::glPushMatrix(); auto const position = Memcell->location() - m_renderpass.camera.position(); ::glTranslated( position.x, position.y + 0.5, position.z ); switch( m_renderpass.draw_mode ) { - case rendermode::color: { - ::glPushAttrib( GL_ENABLE_BIT ); - ::glDisable( GL_TEXTURE_2D ); - ::glColor3f( 0.36f, 0.75f, 0.35f ); - + case rendermode::color: + case rendermode::shadows: { ::gluSphere( m_quadric, 0.35, 4, 2 ); - - ::glPopAttrib(); break; } - case rendermode::shadows: case rendermode::pickscenery: { + // add the node to the pick list + m_picksceneryitems.emplace_back( Memcell ); + ::gluSphere( m_quadric, 0.35, 4, 2 ); break; } diff --git a/renderer.h b/renderer.h index c0f4ef5f..88405377 100644 --- a/renderer.h +++ b/renderer.h @@ -289,7 +289,7 @@ private: bool Render_cab( TDynamicObject const *Dynamic, bool const Alpha = false ); void - Render( TMemCell *Memcell ); + Render( TMemCell const *Memcell ); void Render_Alpha( scene::basic_region *Region ); void diff --git a/scene.cpp b/scene.cpp index 46bcd022..9b6312ec 100644 --- a/scene.cpp +++ b/scene.cpp @@ -360,6 +360,7 @@ basic_cell::insert( sound_source *Sound ) { m_active = true; 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 @@ -373,6 +374,16 @@ basic_cell::insert( TEventLauncher *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 void 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 void basic_region::insert_path( TTrack *Path, scratch_data &Scratchpad ) { - // NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done auto location = Path->location(); @@ -1154,7 +1164,6 @@ basic_region::insert_path( TTrack *Path, scratch_data &Scratchpad ) { // inserts provided track in the region void basic_region::insert_traction( TTraction *Traction, scratch_data &Scratchpad ) { - // NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done 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 void basic_region::insert_instance( TAnimModel *Instance, scratch_data &Scratchpad ) { - // NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done 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 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(); @@ -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 std::tuple basic_region::find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler ) { diff --git a/scene.h b/scene.h index 9ec4a714..1e0ab86d 100644 --- a/scene.h +++ b/scene.h @@ -114,6 +114,9 @@ public: // adds provided event launcher to the cell void insert( TEventLauncher *Launcher ); + // adds provided memory cell to the cell + void + insert( TMemCell *Memorycell ); // registers provided path in the lookup directory of the cell void register_end( TTrack *Path ); @@ -152,6 +155,7 @@ private: using instance_sequence = std::vector; using sound_sequence = std::vector; using eventlauncher_sequence = std::vector; + using memorycell_sequence = std::vector; // methods void enclose_area( scene::basic_node *Node ); @@ -168,6 +172,7 @@ private: traction_sequence m_traction; sound_sequence m_sounds; eventlauncher_sequence m_eventlaunchers; + memorycell_sequence m_memorycells; // search helpers struct lookup_data { path_sequence paths; @@ -329,6 +334,9 @@ public: // inserts provided event launcher in the region void 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 std::tuple find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler ); diff --git a/simulation.cpp b/simulation.cpp index ec2da2f8..39d06723 100644 --- a/simulation.cpp +++ b/simulation.cpp @@ -440,10 +440,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad 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 ) + ")" ); } -/* - // TODO: implement this - simulation::Region.insert_memorycell( memorycell, Scratchpad ); -*/ + simulation::Region->insert_memorycell( memorycell, Scratchpad ); } else if( nodedata.type == "eventlauncher" ) { diff --git a/uilayer.cpp b/uilayer.cpp index 7eccd73d..f54ca2c3 100644 --- a/uilayer.cpp +++ b/uilayer.cpp @@ -246,6 +246,8 @@ ui_layer::update() { "" ) ); } + EditorModeFlag = ( Global.iTextMode == GLFW_KEY_F11 ); + switch( Global.iTextMode ) { case( GLFW_KEY_F1 ) : { @@ -714,7 +716,120 @@ ui_layer::update() { uitextline1 = "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( 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( 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( node ); + + uitextline2 = + "data: [" + subnode->Text() + "]" + + " [" + to_string( subnode->Value1(), 2 ) + "]" + + " [" + to_string( subnode->Value2(), 2 ) + "]"; + uitextline3 = "track: " + ( subnode->asTrackName.empty() ? "none" : subnode->asTrackName ); + } break; } diff --git a/version.h b/version.h index be52643b..de5c235e 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 18 -#define VERSION_MINOR 622 +#define VERSION_MINOR 626 #define VERSION_REVISION 0