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

build 200112. vehicle level of detail selection tweak, track end detection logic tweak, minor bug fixes

This commit is contained in:
tmj-fstate
2020-01-13 15:59:13 +01:00
parent 70fba7df69
commit eb9304495a
11 changed files with 73 additions and 48 deletions

View File

@@ -746,8 +746,11 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
else if( sSpeedTable[ iLast ].trTrack == tLast ) {
// otherwise just mark the last added track as the final one
// TODO: investigate exactly how we can wind up not marking the last existing track as actual end
if( false == TestFlag( sSpeedTable[ iLast ].trTrack->iCategoryFlag, 0x100 ) ) {
// don't mark portals, as these aren't exactly track ends, but teleport devices
sSpeedTable[ iLast ].iFlags |= ( spEnabled | spEnd );
}
}
// to ostatnia pozycja, bo NULL nic nie da, a może się podpiąć obrotnica, czy jakieś transportery
return;
}

View File

@@ -1642,7 +1642,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
else if (DriverType == "reardriver")
DriverType = "2"; // sterujący kabiną -1
else if (DriverType == "passenger")
DriverType = "p"; // to do przemyślenia
DriverType = ""; // legacy type, no longer needed
else if (DriverType == "nobody")
DriverType = ""; // nikt nie siedzi
@@ -3341,8 +3341,7 @@ bool TDynamicObject::Update(double dt, double dt1)
( MoverParameters->DynamicBrakeFlag && MoverParameters->ResistorsFlag ) ?
0 :
std::abs( MoverParameters->Itot ) )
+ MoverParameters->TotalCurrent; // prąd pobierany przez pojazd - bez
// sensu z tym (TotalCurrent)
+ MoverParameters->TotalCurrent; // prąd pobierany przez pojazd - bez sensu z tym (TotalCurrent)
// TotalCurrent to bedzie prad nietrakcyjny (niezwiazany z napedem)
// fCurrent+=fabs(MoverParameters->Voltage)*1e-6; //prąd płynący przez woltomierz, rozładowuje kondensator orgromowy 4µF
double fPantCurrent = fCurrent; // normalnie cały prąd przez jeden pantograf
@@ -3387,8 +3386,16 @@ bool TDynamicObject::Update(double dt, double dt1)
if (p->hvPowerWire) {
auto const lastvoltage { MoverParameters->PantFrontVolt };
// TODO: wyliczyć trzeba prąd przypadający na pantograf i wstawić do GetVoltage()
if( lastvoltage == 0.0 ) {
// HACK: retrieve the wire voltage for calculations down the road without blowing up the supply
MoverParameters->PantFrontVolt = p->hvPowerWire->VoltageGet( MoverParameters->PantographVoltage, 0.0 );
}
else {
MoverParameters->PantFrontVolt = p->hvPowerWire->VoltageGet( MoverParameters->PantographVoltage, fPantCurrent );
fCurrent -= fPantCurrent; // taki prąd płynie przez powyższy pantograf
if( MoverParameters->PantFrontVolt > 0.0 ) {
fCurrent -= fPantCurrent; // taki prąd płynie przez powyższy pantograf (unless it doesn't)
}
}
// TODO: refactor reaction to voltage change to mover as sound event for specific pantograph
if( ( lastvoltage == 0.0 )
&& ( MoverParameters->PantFrontVolt > 0.0 ) ) {
@@ -3421,8 +3428,16 @@ bool TDynamicObject::Update(double dt, double dt1)
if (p->hvPowerWire) {
auto const lastvoltage { MoverParameters->PantRearVolt };
// TODO: wyliczyć trzeba prąd przypadający na pantograf i wstawić do GetVoltage()
if( lastvoltage == 0.0 ) {
// HACK: retrieve the wire voltage for calculations down the road without blowing up the supply
MoverParameters->PantRearVolt = p->hvPowerWire->VoltageGet( MoverParameters->PantographVoltage, 0.0 );
}
else {
MoverParameters->PantRearVolt = p->hvPowerWire->VoltageGet( MoverParameters->PantographVoltage, fPantCurrent );
fCurrent -= fPantCurrent; // taki prąd płynie przez powyższy pantograf
if( MoverParameters->PantRearVolt > 0.0 ) {
fCurrent -= fPantCurrent; // taki prąd płynie przez powyższy pantograf (unless it doesn't)
}
}
// TODO: refactor reaction to voltage change to mover as sound event for specific pantograph
if( ( lastvoltage == 0.0 )
&& ( MoverParameters->PantRearVolt > 0.0 ) ) {

View File

@@ -1651,8 +1651,8 @@ void TMoverParameters::ConverterCheck( double const Timestep ) {
if( ( ConverterAllow )
&& ( ConverterAllowLocal )
&& ( false == PantPressLockActive )
&& ( ( Mains )
|| ( GetAnyTrainsetVoltage() > 0.0 ) ) ) {
// HACK: allow carriages to operate converter without (missing) fuse prerequisite
&& ( ( Power > 1.0 ? Mains : GetAnyTrainsetVoltage() > 0.0 ) ) ) {
// delay timer can be optionally configured, and is set anew whenever converter goes off
if( ConverterStartDelayTimer <= 0.0 ) {
ConverterFlag = true;

View File

@@ -486,18 +486,21 @@ double TTraction::VoltageGet(double u, double i)
psPowered->CurrentGet( res ) * res :
0.0 );
}
if( ( psPower[0] && psPower[0]->Fuse() )
|| ( psPower[1] && psPower[1]->Fuse() ) ) {
// if either power source is out, so are we
return 0.0;
}
double r0t, r1t, r0g, r1g;
double i0, i1;
r0t = fResistance[0]; //średni pomysł, ale lepsze niż nic
r1t = fResistance[1]; // bo nie uwzględnia spadków z innych pojazdów
if (psPower[0] && psPower[1])
{ // gdy przęsło jest zasilane z obu stron - mamy trójkąt: res, r0t, r1t
// yB: Gdy wywali podstacja, to zaczyna się robić nieciekawie - napięcie w sekcji na jednym
// końcu jest równe zasilaniu,
// yB: a na drugim końcu jest równe 0. Kolejna sprawa to rozróżnienie uszynienia sieci na
// podstacji/odłączniku (czyli
// yB: potencjał masy na sieci) od braku zasilania (czyli odłączenie źródła od sieci i brak
// jego wpływu na napięcie).
// yB: Gdy wywali podstacja, to zaczyna się robić nieciekawie - napięcie w sekcji na jednym końcu jest równe zasilaniu,
// yB: a na drugim końcu jest równe 0. Kolejna sprawa to rozróżnienie uszynienia sieci na podstacji/odłączniku (czyli
// yB: potencjał masy na sieci) od braku zasilania (czyli odłączenie źródła od sieci i brak jego wpływu na napięcie).
if ((r0t > 0.0) && (r1t > 0.0))
{ // rezystancje w mianowniku nie mogą być zerowe
r0g = res + r0t + (res * r0t) / r1t; // przeliczenie z trójkąta na gwiazdę

View File

@@ -121,8 +121,7 @@ double TTractionPowerSource::CurrentGet(double res)
return 0;
}
if ((res > 0) || ((res < 0) && (Recuperation || true)))
TotalAdmitance +=
1.0 / res; // połączenie równoległe rezystancji jest równoważne sumie admitancji
TotalAdmitance += 1.0 / res; // połączenie równoległe rezystancji jest równoważne sumie admitancji
float NomVolt = (TotalPreviousAdmitance < 0 ? NominalVoltage * 1.083 : NominalVoltage);
TotalCurrent = (TotalPreviousAdmitance != 0.0) ?
NomVolt / (InternalRes + 1.0 / TotalPreviousAdmitance) :

View File

@@ -28,6 +28,8 @@ public:
void VoltageSet(double const v) {
NominalVoltage = v; };
void PowerSet(TTractionPowerSource *ps);
bool Fuse() const {
return ( FastFuse || SlowFuse ); }
// members
TTractionPowerSource *psNode[ 2 ] = { nullptr, nullptr }; // zasilanie na końcach dla sekcji
bool bSection = false; // czy jest sekcją

View File

@@ -6061,7 +6061,7 @@ bool TTrain::Update( double const Deltatime )
(std::abs(mvControlled->Im) > 0))
{
ggEngineVoltage.UpdateValue(
(x * (mvControlled->PantographVoltage -
(x * (std::abs(mvControlled->EngineVoltage) -
mvControlled->RList[mvControlled->MainCtrlActualPos].R *
std::abs(mvControlled->Im)) /
mvControlled->RList[mvControlled->MainCtrlActualPos].Mn));

View File

@@ -420,7 +420,7 @@ driver_mode::update_camera( double const Deltatime ) {
if( Camera.m_owner == nullptr ) {
if( controlled && LengthSquared3( controlled->GetPosition() - Camera.Pos ) < ( 1500 * 1500 ) ) {
// gdy bliżej niż 1.5km
Camera.LookAt = controlled->GetPosition();
Camera.LookAt = controlled->GetPosition() + 0.4 * controlled->VectorUp() * controlled->MoverParameters->Dim.H;
}
else {
TDynamicObject *d = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global.pCamera.Pos, 300, false, false ) );
@@ -437,7 +437,7 @@ driver_mode::update_camera( double const Deltatime ) {
if( d )
pDynamicNearest = d; // zmiana na nowy, jeśli coś znaleziony niepusty
if( pDynamicNearest )
Camera.LookAt = pDynamicNearest->GetPosition() + 0.5 * pDynamicNearest->VectorUp() * pDynamicNearest->MoverParameters->Dim.H;
Camera.LookAt = pDynamicNearest->GetPosition() + 0.4 * pDynamicNearest->VectorUp() * pDynamicNearest->MoverParameters->Dim.H;
}
Camera.RaLook(); // jednorazowe przestawienie kamery
}

View File

@@ -580,7 +580,7 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
scene_ubs.time = Timer::GetTime();
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
scene_ubs.inv_view = glm::inverse( glm::mat4{ glm::mat3{ m_renderpass.pass_camera.modelview() } } );
scene_ubs.inv_view = glm::inverse( glm::mat4{ glm::mat3{ m_colorpass.pass_camera.modelview() } } );
scene_ubo->update(scene_ubs);
scene_ubo->bind_uniform();
@@ -657,6 +657,7 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
setup_drawing(true);
m_renderpass.draw_stats = {};
model_ubs.future = glm::mat4();
glm::mat4 future;
if (Global.pCamera.m_owner != nullptr)
{
@@ -665,7 +666,7 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
future = glm::translate(mv, -glm::vec3(vehicle->get_future_movement())) * glm::inverse(mv);
}
model_ubs.future = glm::mat4();
Update_Lights( simulation::Lights );
glDebug("render environment");
@@ -683,8 +684,8 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
// precipitation happens when overcast is in 1-2 range
if (!FreeFlyModeFlag && Global.Overcast <= 1.0f && Global.render_cab)
{
glDebug("render cab opaque");
// cache shadow colour in case we need to account for cab light
glDebug("render opaque cab");
model_ubs.future = glm::mat4();
auto const *vehicle{ simulation::Train->Dynamic() };
if( vehicle->InteriorLightLevel > 0.f ) {
setup_shadow_color( glm::min( colors::white, m_shadowcolor + glm::vec4( vehicle->InteriorLight * vehicle->InteriorLightLevel, 1.f ) ) );
@@ -715,9 +716,7 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
// cab render
if (false == FreeFlyModeFlag && Global.render_cab)
{
glDebug("render translucent cab");
model_ubs.future = glm::mat4();
// cache shadow colour in case we need to account for cab light
auto *vehicle { simulation::Train->Dynamic() };
if( vehicle->InteriorLightLevel > 0.f ) {
setup_shadow_color( glm::min( colors::white, m_shadowcolor + glm::vec4( vehicle->InteriorLight * vehicle->InteriorLightLevel, 1.f ) ) );
@@ -725,16 +724,22 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode)
if (Global.Overcast > 1.0f)
{
// with active precipitation draw the opaque cab parts here to mask rain/snow placed 'inside' the cab
glDebug( "render opaque cab" );
setup_drawing(false);
Render_cab(vehicle, vehicle->InteriorLightLevel, false);
Render_interior( false );
Render_interior(false);
setup_drawing(true);
Render_interior( true );
Render_interior(true);
}
glDebug( "render translucent cab" );
Render_cab(vehicle, vehicle->InteriorLightLevel, true);
if( vehicle->InteriorLightLevel > 0.f ) {
setup_shadow_color( m_shadowcolor );
}
if( Global.Overcast > 1.0f ) {
// with the cab in place we can (finally) safely draw translucent part of the occupied vehicle
Render_Alpha( vehicle );
}
}
Timer::subsystem.gfx_color.stop();
@@ -950,7 +955,7 @@ bool opengl33_renderer::Render_interior( bool const Alpha ) {
while( dynamic != nullptr ) {
glm::dvec3 const originoffset { dynamic->vPosition - m_renderpass.pass_camera.position() };
float const squaredistance{ glm::length2( glm::vec3{ originoffset } / Global.ZoomFactor ) / Global.fDistanceFactor };
float const squaredistance{ glm::length2( glm::vec3{ originoffset } / Global.ZoomFactor ) };
dynamics.emplace_back( squaredistance, dynamic );
dynamic = dynamic->NextC( coupling::permanent );
}
@@ -959,7 +964,7 @@ bool opengl33_renderer::Render_interior( bool const Alpha ) {
while( dynamic != nullptr ) {
glm::dvec3 const originoffset { dynamic->vPosition - m_renderpass.pass_camera.position() };
float const squaredistance{ glm::length2( glm::vec3{ originoffset } / Global.ZoomFactor ) / Global.fDistanceFactor };
float const squaredistance{ glm::length2( glm::vec3{ originoffset } / Global.ZoomFactor ) };
dynamics.emplace_back( squaredistance, dynamic );
dynamic = dynamic->PrevC( coupling::permanent );
}
@@ -1909,8 +1914,6 @@ void opengl33_renderer::Render(scene::basic_region *Region)
{
case rendermode::color:
{
Update_Lights(simulation::Lights);
Render(std::begin(m_sectionqueue), std::end(m_sectionqueue));
// draw queue is filled while rendering sections
if (EditorModeFlag && m_current_viewport->main)
@@ -2343,7 +2346,7 @@ bool opengl33_renderer::Render(TDynamicObject *Dynamic)
{
case rendermode::shadows:
{
squaredistance = glm::length2(glm::vec3{glm::dvec3{Dynamic->vPosition - m_renderpass.viewport_camera.position()}} / Global.ZoomFactor) / Global.fDistanceFactor;
squaredistance = glm::length2(glm::vec3{glm::dvec3{Dynamic->vPosition - m_renderpass.viewport_camera.position()}} / Global.ZoomFactor);
if( false == FreeFlyModeFlag ) {
// filter out small details if we're in vehicle cab
squaredistance = std::max( 100.f * 100.f, squaredistance );
@@ -2352,7 +2355,7 @@ bool opengl33_renderer::Render(TDynamicObject *Dynamic)
}
default:
{
squaredistance = glm::length2(glm::vec3{originoffset} / Global.ZoomFactor) / Global.fDistanceFactor;
squaredistance = glm::length2(glm::vec3{originoffset} / Global.ZoomFactor);
// TODO: filter out small details based on fidelity setting
break;
}
@@ -3332,7 +3335,7 @@ bool opengl33_renderer::Render_Alpha(TDynamicObject *Dynamic)
case rendermode::shadows:
default:
{
squaredistance = glm::length2(glm::vec3{originoffset} / Global.ZoomFactor) / Global.fDistanceFactor;
squaredistance = glm::length2(glm::vec3{originoffset} / Global.ZoomFactor);
break;
}
}
@@ -3971,7 +3974,7 @@ void opengl33_renderer::Update_Lights(light_array &Lights)
Bind_Texture( gl::HEADLIGHT_TEX, m_headlightstexture );
// arrange the light array from closest to farthest from current position of the camera
auto const camera = m_renderpass.pass_camera.position();
auto const camera = m_colorpass.pass_camera.position();
std::sort(
std::begin(Lights.data), std::end(Lights.data),
[&camera](light_array::light_record const &Left, light_array::light_record const &Right) {

View File

@@ -751,7 +751,7 @@ bool opengl_renderer::Render_interior( bool const Alpha ) {
while( dynamic != nullptr ) {
glm::dvec3 const originoffset { dynamic->vPosition - m_renderpass.camera.position() };
float const squaredistance{ glm::length2( glm::vec3{ originoffset } / Global.ZoomFactor ) / Global.fDistanceFactor };
float const squaredistance{ glm::length2( glm::vec3{ originoffset } / Global.ZoomFactor ) };
dynamics.emplace_back( squaredistance, dynamic );
dynamic = dynamic->NextC( coupling::permanent );
}
@@ -760,7 +760,7 @@ bool opengl_renderer::Render_interior( bool const Alpha ) {
while( dynamic != nullptr ) {
glm::dvec3 const originoffset { dynamic->vPosition - m_renderpass.camera.position() };
float const squaredistance{ glm::length2( glm::vec3{ originoffset } / Global.ZoomFactor ) / Global.fDistanceFactor };
float const squaredistance{ glm::length2( glm::vec3{ originoffset } / Global.ZoomFactor ) };
dynamics.emplace_back( squaredistance, dynamic );
dynamic = dynamic->PrevC( coupling::permanent );
}
@@ -2249,7 +2249,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
glm::dvec3 const originoffset = Dynamic->vPosition - m_renderpass.camera.position();
switch( m_renderpass.draw_mode ) {
case rendermode::shadows: {
squaredistance = glm::length2( glm::vec3{ glm::dvec3{ Dynamic->vPosition - Global.pCamera.Pos } } / Global.ZoomFactor ) / Global.fDistanceFactor;
squaredistance = glm::length2( glm::vec3{ glm::dvec3{ Dynamic->vPosition - Global.pCamera.Pos } } / Global.ZoomFactor );
if( false == FreeFlyModeFlag ) {
// filter out small details if we're in vehicle cab
squaredistance = std::max( 100.f * 100.f, squaredistance );
@@ -2257,13 +2257,13 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
break;
}
case rendermode::cabshadows: {
squaredistance = glm::length2( glm::vec3{ glm::dvec3{ Dynamic->vPosition - Global.pCamera.Pos } } / Global.ZoomFactor ) / Global.fDistanceFactor;
squaredistance = glm::length2( glm::vec3{ glm::dvec3{ Dynamic->vPosition - Global.pCamera.Pos } } / Global.ZoomFactor );
// filter out small details
squaredistance = std::max( 100.f * 100.f, squaredistance );
break;
}
default: {
squaredistance = glm::length2( glm::vec3{ originoffset } / Global.ZoomFactor ) / Global.fDistanceFactor;
squaredistance = glm::length2( glm::vec3{ originoffset } / Global.ZoomFactor );
// TODO: filter out small details based on fidelity setting
break;
}
@@ -3432,11 +3432,11 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
float squaredistance;
switch( m_renderpass.draw_mode ) {
case rendermode::shadows: {
squaredistance = glm::length2( glm::vec3{ glm::dvec3{ Dynamic->vPosition - Global.pCamera.Pos } } / Global.ZoomFactor ) / Global.fDistanceFactor;
squaredistance = glm::length2( glm::vec3{ glm::dvec3{ Dynamic->vPosition - Global.pCamera.Pos } } / Global.ZoomFactor );
break;
}
default: {
squaredistance = glm::length2( glm::vec3{ originoffset } / Global.ZoomFactor ) / Global.fDistanceFactor;
squaredistance = glm::length2( glm::vec3{ originoffset } / Global.ZoomFactor );
break;
}
}

View File

@@ -1,5 +1,5 @@
#pragma once
#define VERSION_MAJOR 20
#define VERSION_MINOR 108
#define VERSION_MINOR 112
#define VERSION_REVISION 0