mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 00:29:19 +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:
@@ -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 !!!!
|
||||
|
||||
@@ -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
|
||||
|
||||
139
Driver.cpp
139
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,64 +2732,68 @@ 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 ?
|
||||
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)); // kręcimy nastawnik jazdy
|
||||
if ((OK) &&
|
||||
(mvControlling->MainCtrlPos ==
|
||||
1)) // czekaj na 1 pozycji, zanim się nie włączą liniowe
|
||||
mvControlling->IncMainCtrl( 1 ) );
|
||||
// czekaj na 1 pozycji, zanim się nie włączą liniowe
|
||||
if( true == mvControlling->StLinFlag ) {
|
||||
iDrivigFlags |= moveIncSpeed;
|
||||
else
|
||||
iDrivigFlags &= ~moveIncSpeed; // usunięcie flagi czekania
|
||||
}
|
||||
else // jeśli bezoporowa (z wyjątekiem 0)
|
||||
OK = false; // to dać bocznik
|
||||
else {
|
||||
iDrivigFlags &= ~moveIncSpeed;
|
||||
}
|
||||
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->Im == 0 )
|
||||
&& ( mvControlling->MainCtrlPos > 2 ) ) {
|
||||
// brak prądu na dalszych pozycjach
|
||||
// nie załączona lokomotywa albo wywalił nadmiarowy
|
||||
Need_TryAgain = true;
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
else {
|
||||
OK = false;
|
||||
}
|
||||
}
|
||||
mvControlling->AutoRelayCheck(); // sprawdzenie logiki sterowania
|
||||
@@ -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 )
|
||||
|
||||
2
Track.h
2
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
|
||||
|
||||
@@ -6355,6 +6355,7 @@ void TTrain::clear_cab_controls()
|
||||
ggRadioTest.Clear();
|
||||
ggDoorLeftButton.Clear();
|
||||
ggDoorRightButton.Clear();
|
||||
ggTrainHeatingButton.Clear();
|
||||
ggDepartureSignalButton.Clear();
|
||||
ggCompressorButton.Clear();
|
||||
ggConverterButton.Clear();
|
||||
|
||||
13
World.cpp
13
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;
|
||||
};
|
||||
|
||||
54
renderer.cpp
54
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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
31
scene.cpp
31
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<TDynamicObject *, float>
|
||||
basic_region::find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler ) {
|
||||
|
||||
8
scene.h
8
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<TAnimModel *>;
|
||||
using sound_sequence = std::vector<sound_source *>;
|
||||
using eventlauncher_sequence = std::vector<TEventLauncher *>;
|
||||
using memorycell_sequence = std::vector<TMemCell *>;
|
||||
// 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<TDynamicObject *, float>
|
||||
find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler );
|
||||
|
||||
@@ -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" ) {
|
||||
|
||||
|
||||
117
uilayer.cpp
117
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<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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user