From 3a63d1d346f2d961b35dbf51bbf19515b979e1c9 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Tue, 22 Aug 2017 20:07:27 +0200 Subject: [PATCH] better AI handling of emergency stop procedure, simplified lod visibility calculations, adjustable track geometry fidelity --- Driver.cpp | 96 +++++++++++++++++++++++-------------------- Globals.cpp | 17 ++++---- Globals.h | 4 +- Model3d.cpp | 2 +- Model3d.h | 2 +- Track.cpp | 2 +- renderer.cpp | 114 +++++++++++++++++++-------------------------------- renderer.h | 8 ++-- 8 files changed, 109 insertions(+), 136 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index dd7a5004..cb0aa49c 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -3614,11 +3614,11 @@ bool TController::UpdateSituation(double dt) } // basic emergency stop handling, while at it if( ( true == mvOccupied->EmergencyBrakeFlag ) // radio-stop - && ( mvOccupied->Vel < 0.01 ) // and actual stop + && ( mvOccupied->Vel == 0.0 ) // and actual stop && ( true == mvOccupied->Radio ) ) { // and we didn't touch the radio yet // turning off the radio should reset the flag, during security system check - if( m_radiocontroltime > 2.5 ) { - // arbitrary 2.5 sec delay between stop and disabling the radio + if( m_radiocontroltime > 5.0 ) { + // arbitrary delay between stop and disabling the radio mvOccupied->Radio = false; m_radiocontroltime = 0.0; } @@ -3629,7 +3629,7 @@ bool TController::UpdateSituation(double dt) if( ( false == mvOccupied->Radio ) && ( false == mvOccupied->EmergencyBrakeFlag ) ) { // otherwise if it's safe to do so, turn the radio back on - if( m_radiocontroltime > 5.0 ) { + if( m_radiocontroltime > 10.0 ) { // arbitrary 5 sec delay before switching radio back on mvOccupied->Radio = true; m_radiocontroltime = 0.0; @@ -4200,8 +4200,8 @@ bool TController::UpdateSituation(double dt) } ReactionTime = ( vel != 0.0 ? - 0.1 : // orientuj się, bo jest goraco - 2.0 ); // we're already standing still, so take it easy + 0.1 : // orientuj się, bo jest goraco + 2.0 ); // we're already standing still, so take it easy } else { if( OrderCurrentGet() & Connect ) { @@ -4498,13 +4498,47 @@ bool TController::UpdateSituation(double dt) // last step sanity check, until the whole calculation is straightened out AccDesired = std::min( AccDesired, AccPreferred ); - if (AIControllFlag) - { // część wykonawcza tylko dla AI, dla człowieka jedynie napisy + + + if (AIControllFlag) { + // część wykonawcza tylko dla AI, dla człowieka jedynie napisy + + // zapobieganie poslizgowi u nas + if (mvControlling->SlippingWheels) { + + if (!mvControlling->DecScndCtrl(2)) // bocznik na zero + mvControlling->DecMainCtrl(1); +/* + if (mvOccupied->BrakeCtrlPos == + mvOccupied->BrakeCtrlPosNo) // jeśli ostatnia pozycja hamowania + //yB: ten warunek wyżej nie ma sensu + mvOccupied->DecBrakeLevel(); // to cofnij hamulec + DecBrake(); // to cofnij hamulec + else + mvControlling->AntiSlippingButton(); +*/ + DecBrake(); // to cofnij hamulec + mvControlling->AntiSlippingButton(); + ++iDriverFailCount; + mvControlling->SlippingWheels = false; // flaga już wykorzystana + } + if (iDriverFailCount > maxdriverfails) + { + Psyche = Easyman; + if (iDriverFailCount > maxdriverfails * 2) + SetDriverPsyche(); + } + + if( ( true == mvOccupied->EmergencyBrakeFlag ) // radio-stop + && ( mvOccupied->Vel > 0.0 ) ) { // and still moving + // if the radio-stop was issued don't waste effort trying to fight it + while( true == DecSpeed() ) { ; } // just throttle down... + goto maintenance; // ...and don't touch any other controls + } + if (mvControlling->ConvOvldFlag || !mvControlling->Mains) // WS może wywalić z powodu błędu w drutach { // wywalił bezpiecznik nadmiarowy przetwornicy - // while (DecSpeed()); //zerowanie napędu - // Controlling->ConvOvldFlag=false; //reset nadmiarowego PrepareEngine(); // próba ponownego załączenia } // włączanie bezpiecznika @@ -4513,14 +4547,10 @@ bool TController::UpdateSituation(double dt) (mvControlling->EngineType == DieselElectric)) if (mvControlling->FuseFlag || Need_TryAgain) { - Need_TryAgain = - false; // true, jeśli druga pozycja w elektryku nie załapała - // if (!Controlling->DecScndCtrl(1)) //kręcenie po mału - // if (!Controlling->DecMainCtrl(1)) //nastawnik jazdy na 0 + Need_TryAgain = false; // true, jeśli druga pozycja w elektryku nie załapała mvControlling->DecScndCtrl(2); // nastawnik bocznikowania na 0 mvControlling->DecMainCtrl(2); // nastawnik jazdy na 0 - mvControlling->MainSwitch( - true); // Ra: dodałem, bo EN57 stawały po wywaleniu + mvControlling->MainSwitch(true); // Ra: dodałem, bo EN57 stawały po wywaleniu if (!mvControlling->FuseOn()) HelpMeFlag = true; else @@ -4532,7 +4562,7 @@ bool TController::UpdateSituation(double dt) SetDriverPsyche(); } } - // NOTE: stop-gap measure, effect limited to trains only while car calculations seem off + // NOTE: as a stop-gap measure the routine is limited to trains only while car calculations seem off if( mvControlling->CategoryFlag == 1 ) { if( -AccDesired * BrakeAccFactor() < ( ( fReady > 0.4 ) || ( VelNext > vel - 40.0 ) ? fBrake_a0[ 0 ] * 0.8 : -fAccThreshold ) ) AccDesired = std::max( -0.06, AccDesired ); @@ -4744,31 +4774,6 @@ bool TController::UpdateSituation(double dt) WriteLog("BrakePos=" + AnsiString(mvOccupied->BrakeCtrlPos) + ", MainCtrl=" + AnsiString(mvControlling->MainCtrlPos)); #endif - // zapobieganie poslizgowi u nas - if (mvControlling->SlippingWheels) - { - if (!mvControlling->DecScndCtrl(2)) // bocznik na zero - mvControlling->DecMainCtrl(1); -/* - if (mvOccupied->BrakeCtrlPos == - mvOccupied->BrakeCtrlPosNo) // jeśli ostatnia pozycja hamowania - //yB: ten warunek wyżej nie ma sensu - mvOccupied->DecBrakeLevel(); // to cofnij hamulec - DecBrake(); // to cofnij hamulec - else - mvControlling->AntiSlippingButton(); -*/ - DecBrake(); // to cofnij hamulec - mvControlling->AntiSlippingButton(); - ++iDriverFailCount; - mvControlling->SlippingWheels = false; // flaga już wykorzystana - } - if (iDriverFailCount > maxdriverfails) - { - Psyche = Easyman; - if (iDriverFailCount > maxdriverfails * 2) - SetDriverPsyche(); - } } // if (AIControllFlag) } // kierunek różny od zera else @@ -4801,6 +4806,8 @@ bool TController::UpdateSituation(double dt) else LastReactionTime += dt; +maintenance: + if ((fLastStopExpDist > 0.0) && (mvOccupied->DistCounter > fLastStopExpDist)) { iStationStart = TrainParams->StationIndex; // zaktualizować wyświetlanie rozkładu @@ -4817,9 +4824,8 @@ bool TController::UpdateSituation(double dt) ReactionTime = fWarningDuration; // wcześniejszy przebłysk świadomości, by zakończyć trąbienie } - if (mvOccupied->Vel >= - 3.0) // jesli jedzie, można odblokować trąbienie, bo się wtedy nie włączy - { + if (mvOccupied->Vel >= 3.0) { + // jesli jedzie, można odblokować trąbienie, bo się wtedy nie włączy iDrivigFlags &= ~moveStartHornDone; // zatrąbi dopiero jak następnym razem stanie iDrivigFlags |= moveStartHorn; // i trąbić przed następnym ruszeniem } diff --git a/Globals.cpp b/Globals.cpp index 6bc61dc2..323c849d 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -51,7 +51,6 @@ bool Global::ControlPicking = false; // indicates controls pick mode is enabled bool Global::InputMouse = true; // whether control pick mode can be activated int Global::iTextMode = 0; // tryb pracy wyświetlacza tekstowego int Global::iScreenMode[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // numer ekranu wyświetlacza tekstowego -double Global::fSunDeclination = 0.0; // deklinacja Słońca double Global::fTimeAngleDeg = 0.0; // godzina w postaci kąta float Global::fClockAngleDeg[6]; // kąty obrotu cylindrów dla zegara cyfrowego std::string Global::szTexturesTGA = ".tga"; // lista tekstur od TGA @@ -63,7 +62,6 @@ int Global::iErorrCounter = 0; // licznik sprawdzań do śledzenia błędów Ope int Global::iTextures = 0; // licznik użytych tekstur TWorld *Global::pWorld = NULL; cParser *Global::pParser = NULL; -int Global::iSegmentsRendered = 90; // ilość segmentów do regulacji wydajności TCamera *Global::pCamera = NULL; // parametry kamery TDynamicObject *Global::pUserDynamic = NULL; // pojazd użytkownika, renderowany bez trzęsienia TTranscripts Global::tranTexts; // obiekt obsługujący stenogramy dźwięków na ekranie @@ -132,6 +130,7 @@ bool Global::bUseVBO = false; // czy jest VBO w karcie graficznej (czy użyć) std::string Global::LastGLError; GLint Global::iMaxTextureSize = 4096; // maksymalny rozmiar tekstury bool Global::bSmoothTraction = false; // wygładzanie drutów starym sposobem +float Global::SplineFidelity { 1.f }; // determines segment size during conversion of splines to geometry std::string Global::szDefaultExt = Global::szTexturesDDS; // domyślnie od DDS int Global::iMultisampling = 2; // tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px bool Global::DLFont{ false }; // switch indicating presence of basic font @@ -150,7 +149,6 @@ double Global::fFpsMax = 65.0; // górna granica FPS, przy której promień scen double Global::fFpsRadiusMax = 3000.0; // maksymalny promień renderowania int Global::iFpsRadiusMax = 225; // maksymalny promień renderowania double Global::fRadiusFactor = 1.1; // współczynnik jednorazowej zmiany promienia scenerii -bool Global::bOldSmudge = false; // Używanie starej smugi // parametry testowe (do testowania scenerii i obiektów) bool Global::bWireFrame = false; @@ -572,6 +570,13 @@ void Global::ConfigParse(cParser &Parser) Parser.getTokens(); Parser >> Global::bSmoothTraction; } + else if( token == "splinefidelity" ) { + // segment size during spline->geometry conversion + float splinefidelity; + Parser.getTokens(); + Parser >> splinefidelity; + Global::SplineFidelity = clamp( splinefidelity, 1.f, 4.f ); + } else if (token == "timespeed") { // przyspieszenie czasu, zmienna do testów @@ -631,12 +636,6 @@ void Global::ConfigParse(cParser &Parser) Parser.getTokens(); Parser >> Global::bHideConsole; } - else if (token == "oldsmudge") - { - - Parser.getTokens(); - Parser >> Global::bOldSmudge; - } else if (token == "rollfix") { // Ra: poprawianie przechyłki, aby wewnętrzna szyna była "pozioma" diff --git a/Globals.h b/Globals.h index 73f52cb2..db70de30 100644 --- a/Globals.h +++ b/Globals.h @@ -274,7 +274,7 @@ class Global static double fMoveLight; // numer dnia w roku albo -1 static bool FakeLight; // toggle between fixed and dynamic daylight static bool bSmoothTraction; // wygładzanie drutów - static double fSunDeclination; // deklinacja Słońca + static float SplineFidelity; // determines segment size during conversion of splines to geometry static double fTimeSpeed; // przyspieszenie czasu, zmienna do testów static double fTimeAngleDeg; // godzina w postaci kąta static float fClockAngleDeg[6]; // kąty obrotu cylindrów dla zegara cyfrowego @@ -294,14 +294,12 @@ class Global static int iSlowMotionMask; // maska wyłączanych właściwości static int iModifyTGA; // czy korygować pliki TGA dla szybszego wczytywania static bool bHideConsole; // hunter-271211: ukrywanie konsoli - static bool bOldSmudge; // Używanie starej smugi static TWorld *pWorld; // wskaźnik na świat do usuwania pojazdów static TAnimModel *pTerrainCompact; // obiekt terenu do ewentualnego zapisania w pliku static std::string asTerrainModel; // nazwa obiektu terenu do zapisania w pliku static bool bRollFix; // czy wykonać przeliczanie przechyłki static cParser *pParser; - static int iSegmentsRendered; // ilość segmentów do regulacji wydajności static double fFpsAverage; // oczekiwana wartosć FPS static double fFpsDeviation; // odchylenie standardowe FPS static double fFpsMin; // dolna granica FPS, przy której promień scenerii będzie zmniejszany diff --git a/Model3d.cpp b/Model3d.cpp index 12862a9d..802e918e 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -28,7 +28,7 @@ Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others using namespace Mtable; -double TSubModel::fSquareDist = 0; +float TSubModel::fSquareDist = 0.f; size_t TSubModel::iInstance; // numer renderowanego egzemplarza obiektu texture_handle const *TSubModel::ReplacableSkinId = NULL; int TSubModel::iAlpha = 0x30300030; // maska do testowania flag tekstur wymiennych diff --git a/Model3d.h b/Model3d.h index a1072228..395bf40a 100644 --- a/Model3d.h +++ b/Model3d.h @@ -153,7 +153,7 @@ public: static size_t iInstance; // identyfikator egzemplarza, który aktualnie renderuje model static material_handle const *ReplacableSkinId; static int iAlpha; // maska bitowa dla danego przebiegu - static double fSquareDist; + static float fSquareDist; static TModel3d *pRoot; static std::string *pasText; // tekst dla wyświetlacza (!!!! do przemyślenia) ~TSubModel(); diff --git a/Track.cpp b/Track.cpp index 7dbb6be7..528b955c 100644 --- a/Track.cpp +++ b/Track.cpp @@ -527,7 +527,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name) // na przechyłce doliczyć jeszcze pół przechyłki } if( fRadius != 0 ) // gdy podany promień - segsize = clamp( 0.2 + std::fabs( fRadius ) * 0.02, 2.0, 10.0 ); + segsize = clamp( std::fabs( fRadius ) * ( 0.02 / Global::SplineFidelity ), 2.0 / Global::SplineFidelity, 10.0 ); else segsize = 10.0; // for straights, 10m per segment works good enough diff --git a/renderer.cpp b/renderer.cpp index 39e4cd5c..4359b3f4 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -1616,16 +1616,16 @@ opengl_renderer::Render( TGroundNode *Node ) { switch( m_renderpass.draw_mode ) { case rendermode::shadows: { // 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees - distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor ); + distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor ) / Global::fDistanceFactor; break; } default: { - distancesquared = SquareMagnitude( ( Node->pCenter - m_renderpass.camera.position() ) / Global::ZoomFactor ); + distancesquared = SquareMagnitude( ( Node->pCenter - m_renderpass.camera.position() ) / Global::ZoomFactor ) / Global::fDistanceFactor; break; } } - if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) ) - || ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) { + if( ( distancesquared > Node->fSquareRadius ) + || ( distancesquared < Node->fSquareMinRadius ) ) { return false; } @@ -1671,28 +1671,12 @@ opengl_renderer::Render( TGroundNode *Node ) { Node->Model->RaPrepare(); if( Node->Model->pModel ) { // renderowanie rekurencyjne submodeli - switch( m_renderpass.draw_mode ) { - case rendermode::shadows: { - Render( - Node->Model->pModel, - Node->Model->Material(), - // 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees - SquareMagnitude( Node->pCenter - Global::pCameraPosition ), - Node->pCenter - m_renderpass.camera.position(), - Node->Model->vAngle ); - break; - } - default: { - auto const position = Node->pCenter - m_renderpass.camera.position(); - Render( - Node->Model->pModel, - Node->Model->Material(), - SquareMagnitude( position ), - position, - Node->Model->vAngle ); - break; - } - } + Render( + Node->Model->pModel, + Node->Model->Material(), + distancesquared, + Node->pCenter - m_renderpass.camera.position(), + Node->Model->vAngle ); } return true; } @@ -1726,7 +1710,7 @@ opengl_renderer::Render( TGroundNode *Node ) { break; } } - auto const linewidth = clamp( 0.5 * linealpha + Node->fLineThickness * Node->m_radius / 1000.0, 1.0, 32.0 ); + auto const linewidth = clamp( 0.5 * linealpha + Node->fLineThickness * Node->m_radius / 1000.0, 1.0, 8.0 ); if( linewidth > 1.0 ) { ::glLineWidth( static_cast( linewidth ) ); } @@ -1832,15 +1816,16 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) { } // setup TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji - auto const originoffset = Dynamic->vPosition - m_renderpass.camera.position(); - double squaredistance; + glm::dvec3 const originoffset = Dynamic->vPosition - m_renderpass.camera.position(); + // lod visibility ranges are defined for base (x 1.0) viewing distance. for render we adjust them for actual range multiplier and zoom + float squaredistance; switch( m_renderpass.draw_mode ) { case rendermode::shadows: { - squaredistance = SquareMagnitude( ( Dynamic->vPosition - Global::pCameraPosition ) / Global::ZoomFactor ); + squaredistance = glm::length2( glm::vec3{ glm::dvec3{ Dynamic->vPosition - Global::pCameraPosition } } / Global::ZoomFactor ) / Global::fDistanceFactor; break; } default: { - squaredistance = SquareMagnitude( originoffset / Global::ZoomFactor ); + squaredistance = glm::length2( glm::vec3{ originoffset } / Global::ZoomFactor ) / Global::fDistanceFactor; break; } } @@ -1995,7 +1980,7 @@ opengl_renderer::Render_cab( TDynamicObject *Dynamic ) { } bool -opengl_renderer::Render( TModel3d *Model, material_data const *Material, double const Squaredistance ) { +opengl_renderer::Render( TModel3d *Model, material_data const *Material, float const Squaredistance ) { auto alpha = ( Material != nullptr ? @@ -2027,7 +2012,7 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, double } bool -opengl_renderer::Render( TModel3d *Model, material_data const *Material, double const Squaredistance, Math3D::vector3 const &Position, Math3D::vector3 const &Angle ) { +opengl_renderer::Render( TModel3d *Model, material_data const *Material, float const Squaredistance, Math3D::vector3 const &Position, Math3D::vector3 const &Angle ) { ::glPushMatrix(); ::glTranslated( Position.x, Position.y, Position.z ); @@ -2049,8 +2034,8 @@ void opengl_renderer::Render( TSubModel *Submodel ) { if( ( Submodel->iVisible ) - && ( TSubModel::fSquareDist >= ( Submodel->fSquareMinDist / std::max( 1.f, Global::fDistanceFactor ) ) ) - && ( TSubModel::fSquareDist <= ( Submodel->fSquareMaxDist * std::max( 1.f, Global::fDistanceFactor ) ) ) ) { + && ( TSubModel::fSquareDist >= Submodel->fSquareMinDist ) + && ( TSubModel::fSquareDist <= Submodel->fSquareMaxDist ) ) { if( Submodel->iFlags & 0xC000 ) { ::glPushMatrix(); @@ -2205,7 +2190,7 @@ opengl_renderer::Render( TSubModel *Submodel ) { float const anglefactor = ( Submodel->fCosViewAngle - Submodel->fCosFalloffAngle ) / ( 1.0f - Submodel->fCosFalloffAngle ); // distance attenuation. NOTE: since it's fixed pipeline with built-in gamma correction we're using linear attenuation // we're capping how much effect the distance attenuation can have, otherwise the lights get too tiny at regular distances - float const distancefactor = static_cast( std::max( 0.5, ( Submodel->fSquareMaxDist - TSubModel::fSquareDist ) / ( Submodel->fSquareMaxDist * Global::fDistanceFactor ) ) ); + float const distancefactor = std::max( 0.5f, ( Submodel->fSquareMaxDist - TSubModel::fSquareDist ) / Submodel->fSquareMaxDist ); if( lightlevel > 0.f ) { // material configuration: @@ -2424,16 +2409,16 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) { switch( m_renderpass.draw_mode ) { case rendermode::shadows: { // 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees - distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor ); + distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor ) / Global::fDistanceFactor; break; } default: { - distancesquared = SquareMagnitude( ( Node->pCenter - m_renderpass.camera.position() ) / Global::ZoomFactor ); + distancesquared = SquareMagnitude( ( Node->pCenter - m_renderpass.camera.position() ) / Global::ZoomFactor ) / Global::fDistanceFactor; break; } } - if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) ) - || ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) { + if( ( distancesquared > Node->fSquareRadius ) + || ( distancesquared < Node->fSquareMinRadius ) ) { return false; } @@ -2488,28 +2473,12 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) { Node->Model->RaPrepare(); if( Node->Model->pModel ) { // renderowanie rekurencyjne submodeli - switch( m_renderpass.draw_mode ) { - case rendermode::shadows: { - Render_Alpha( - Node->Model->pModel, - Node->Model->Material(), - // 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees - SquareMagnitude( Node->pCenter - Global::pCameraPosition ), - Node->pCenter - m_renderpass.camera.position(), - Node->Model->vAngle ); - break; - } - default: { - auto const position = Node->pCenter - m_renderpass.camera.position(); - Render_Alpha( - Node->Model->pModel, - Node->Model->Material(), - SquareMagnitude( position ), - position, - Node->Model->vAngle ); - break; - } - } + Render_Alpha( + Node->Model->pModel, + Node->Model->Material(), + distancesquared, + Node->pCenter - m_renderpass.camera.position(), + Node->Model->vAngle ); } return true; } @@ -2531,7 +2500,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) { glm::vec4( Node->Diffuse * glm::vec3( Global::DayLight.ambient ), // w zaleznosci od koloru swiatla std::min( 1.0, linealpha ) ) ) ); - auto const linewidth = clamp( 0.5 * linealpha + Node->fLineThickness * Node->m_radius / 1000.0, 1.0, 32.0 ); + auto const linewidth = clamp( 0.5 * linealpha + Node->fLineThickness * Node->m_radius / 1000.0, 1.0, 8.0 ); if( linewidth > 1.0 ) { ::glLineWidth( static_cast(linewidth) ); } @@ -2589,15 +2558,16 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) { // setup TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji - auto const originoffset = Dynamic->vPosition - m_renderpass.camera.position(); - double squaredistance; + glm::dvec3 const originoffset = Dynamic->vPosition - m_renderpass.camera.position(); + // lod visibility ranges are defined for base (x 1.0) viewing distance. for render we adjust them for actual range multiplier and zoom + float squaredistance; switch( m_renderpass.draw_mode ) { case rendermode::shadows: { - squaredistance = SquareMagnitude( ( Dynamic->vPosition - Global::pCameraPosition ) / Global::ZoomFactor ); + squaredistance = glm::length2( glm::vec3{ glm::dvec3{ Dynamic->vPosition - Global::pCameraPosition } } / Global::ZoomFactor ) / Global::fDistanceFactor; break; } default: { - squaredistance = SquareMagnitude( originoffset / Global::ZoomFactor ); + squaredistance = glm::length2( glm::vec3{ originoffset } / Global::ZoomFactor ) / Global::fDistanceFactor; break; } } @@ -2656,7 +2626,7 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) { } bool -opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, double const Squaredistance ) { +opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, float const Squaredistance ) { auto alpha = ( Material != nullptr ? @@ -2688,7 +2658,7 @@ opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, d } bool -opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, double const Squaredistance, Math3D::vector3 const &Position, Math3D::vector3 const &Angle ) { +opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, float const Squaredistance, Math3D::vector3 const &Position, Math3D::vector3 const &Angle ) { ::glPushMatrix(); ::glTranslated( Position.x, Position.y, Position.z ); @@ -2710,8 +2680,8 @@ void opengl_renderer::Render_Alpha( TSubModel *Submodel ) { // renderowanie przezroczystych przez DL if( ( Submodel->iVisible ) - && ( TSubModel::fSquareDist >= ( Submodel->fSquareMinDist / std::max( 1.f, Global::fDistanceFactor ) ) ) - && ( TSubModel::fSquareDist <= ( Submodel->fSquareMaxDist * std::max( 1.f, Global::fDistanceFactor ) ) ) ) { + && ( TSubModel::fSquareDist >= Submodel->fSquareMinDist ) + && ( TSubModel::fSquareDist <= Submodel->fSquareMaxDist ) ) { if( Submodel->iFlags & 0xC000 ) { ::glPushMatrix(); @@ -3009,7 +2979,7 @@ opengl_renderer::Update( double const Deltatime ) { m_framerate = 1000.f / ( m_drawtime / 20.f ); // adjust draw ranges etc, based on recent performance - auto const framerate = 1000.0f / (m_drawtimecolorpass / 20.0f); + auto const framerate = 1000.f / (m_drawtimecolorpass / 20.f); float targetfactor; if( framerate > 90.0 ) { targetfactor = 3.0f; } diff --git a/renderer.h b/renderer.h index 81d991a7..51b3b374 100644 --- a/renderer.h +++ b/renderer.h @@ -277,9 +277,9 @@ private: bool Render( TDynamicObject *Dynamic ); bool - Render( TModel3d *Model, material_data const *Material, double const Squaredistance, Math3D::vector3 const &Position, Math3D::vector3 const &Angle ); + Render( TModel3d *Model, material_data const *Material, float const Squaredistance, Math3D::vector3 const &Position, Math3D::vector3 const &Angle ); bool - Render( TModel3d *Model, material_data const *Material, double const Squaredistance ); + Render( TModel3d *Model, material_data const *Material, float const Squaredistance ); void Render( TSubModel *Submodel ); void @@ -297,9 +297,9 @@ private: bool Render_Alpha( TDynamicObject *Dynamic ); bool - Render_Alpha( TModel3d *Model, material_data const *Material, double const Squaredistance, Math3D::vector3 const &Position, Math3D::vector3 const &Angle ); + Render_Alpha( TModel3d *Model, material_data const *Material, float const Squaredistance, Math3D::vector3 const &Position, Math3D::vector3 const &Angle ); bool - Render_Alpha( TModel3d *Model, material_data const *Material, double const Squaredistance ); + Render_Alpha( TModel3d *Model, material_data const *Material, float const Squaredistance ); void Render_Alpha( TSubModel *Submodel ); void