From aa24c55d2dae2de83a5c8a80ff74df6bbe90f2dd Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Sun, 26 Apr 2026 18:12:47 +0200 Subject: [PATCH 01/19] Change Math3D::vector3 to glm::dvec3 in TCamera class --- audio/audiorenderer.cpp | 2 +- rendering/openglrenderer.cpp | 4 ++-- utilities/dumb3d.cpp | 9 +++++++++ utilities/dumb3d.h | 2 ++ vehicle/Camera.cpp | 9 +++++---- vehicle/Camera.h | 15 +++++++-------- 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/audio/audiorenderer.cpp b/audio/audiorenderer.cpp index 0cd4b4e4..821a0161 100644 --- a/audio/audiorenderer.cpp +++ b/audio/audiorenderer.cpp @@ -378,7 +378,7 @@ openal_renderer::update( double const Deltatime ) { // orientation glm::dmat4 cameramatrix; Global.pCamera.SetMatrix( cameramatrix ); - auto cameraposition = Global.pCamera.Pos + (Global.viewport_move * glm::mat3(cameramatrix)); + auto cameraposition = Global.pCamera.Pos + glm::dvec3((Global.viewport_move * glm::mat3(cameramatrix))); cameramatrix = glm::dmat4(glm::inverse(Global.viewport_rotate)) * cameramatrix; auto rotationmatrix { glm::mat3{ cameramatrix } }; glm::vec3 const orientation[] = { diff --git a/rendering/openglrenderer.cpp b/rendering/openglrenderer.cpp index 386a725e..0f0b9bbf 100644 --- a/rendering/openglrenderer.cpp +++ b/rendering/openglrenderer.cpp @@ -2277,7 +2277,7 @@ opengl_renderer::Render( scene::shape_node const &Shape, bool const Ignorerange case rendermode::shadows: case rendermode::cabshadows: { // 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees - distancesquared = Math3D::SquareMagnitude( ( data.area.center - Global.pCamera.Pos ) / Global.ZoomFactor ) / Global.fDistanceFactor; + distancesquared = Math3D::SquareMagnitude( ( data.area.center - Global.pCamera.Pos ) / (double)Global.ZoomFactor ) / Global.fDistanceFactor; break; } case rendermode::reflections: { @@ -3505,7 +3505,7 @@ opengl_renderer::Render_Alpha( TAnimModel *Instance ) { 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 = Math3D::SquareMagnitude( ( Instance->location() - Global.pCamera.Pos ) / Global.ZoomFactor ) / Global.fDistanceFactor; + distancesquared = Math3D::SquareMagnitude( ( Instance->location() - Global.pCamera.Pos ) / (double)Global.ZoomFactor ) / Global.fDistanceFactor; break; } default: { diff --git a/utilities/dumb3d.cpp b/utilities/dumb3d.cpp index 7eb28abc..14dd9e17 100644 --- a/utilities/dumb3d.cpp +++ b/utilities/dumb3d.cpp @@ -26,6 +26,15 @@ void vector3::RotateY(double angle) x = (cos(angle) * x + z * sin(angle)); z = (z * cos(angle) - sin(angle) * tx); }; + +glm::vec3 RotateY(glm::vec3 v, float angle) +{ + float s = sin(angle); + float c = cos(angle); + + return glm::vec3(c * v.x + s * v.z, v.y, c * v.z - s * v.x); +} + void vector3::RotateZ(double angle) { double ty = y; diff --git a/utilities/dumb3d.h b/utilities/dumb3d.h index b2621b50..30560a4f 100644 --- a/utilities/dumb3d.h +++ b/utilities/dumb3d.h @@ -14,6 +14,8 @@ http://mozilla.org/MPL/2.0/. namespace Math3D { + glm::vec3 RotateY(glm::vec3 v, float angle); + // Define this to have Math3D.cp generate a main which tests these classes //#define TEST_MATH3D diff --git a/vehicle/Camera.cpp b/vehicle/Camera.cpp index cff526d3..248827bf 100644 --- a/vehicle/Camera.cpp +++ b/vehicle/Camera.cpp @@ -20,7 +20,8 @@ http://mozilla.org/MPL/2.0/. //--------------------------------------------------------------------------- -void TCamera::Init( Math3D::vector3 const &NPos, Math3D::vector3 const &NAngle/*, TCameraType const NType*/, TDynamicObject *Owner ) { +void TCamera::Init(glm::vec3 const &NPos, glm::vec3 const &NAngle /*, TCameraType const NType*/, TDynamicObject *Owner) +{ vUp = { 0, 1, 0 }; Velocity = { 0, 0, 0 }; @@ -170,7 +171,7 @@ void TCamera::Update() || ( true == DebugCameraFlag ) ) { // free movement position update auto movement { Velocity }; - movement.RotateY( Angle.y ); + movement = Math3D::RotateY(movement, Angle.y); Pos += movement * 5.0 * deltatime; } else { @@ -193,7 +194,7 @@ void TCamera::Update() movement.y = -movement.y; } */ - movement.RotateY( Angle.y ); + movement = Math3D::RotateY(movement, Angle.y); m_owneroffset += movement * deltatime; } @@ -221,7 +222,7 @@ bool TCamera::SetMatrix( glm::dmat4 &Matrix ) { void TCamera::RaLook() { // zmiana kierunku patrzenia - przelicza Yaw - Math3D::vector3 where = LookAt - Pos /*+ Math3D::vector3(0, 3, 0)*/; // trochę w górę od szyn + Math3D::vector3 where = glm::dvec3(LookAt )- Pos /*+ Math3D::vector3(0, 3, 0)*/; // trochę w górę od szyn if( ( where.x != 0.0 ) || ( where.z != 0.0 ) ) { Angle.y = atan2( -where.x, -where.z ); // kąt horyzontalny m_rotationoffsets.y = 0.0; diff --git a/vehicle/Camera.h b/vehicle/Camera.h index ee5a259c..f0c72f92 100644 --- a/vehicle/Camera.h +++ b/vehicle/Camera.h @@ -9,7 +9,6 @@ http://mozilla.org/MPL/2.0/. #pragma once -#include "utilities/dumb3d.h" #include "input/command.h" #include "vehicle/DynObj.h" @@ -18,7 +17,7 @@ http://mozilla.org/MPL/2.0/. class TCamera { public: // McZapkie: potrzebuje do kiwania na boki - void Init( Math3D::vector3 const &Location, Math3D::vector3 const &Angle, TDynamicObject *Owner ); + void Init(glm::vec3 const &Location, glm::vec3 const &Angle, TDynamicObject *Owner); void Reset(); void OnCursorMove(double const x, double const y); bool OnCommand( command_data const &Command ); @@ -26,14 +25,14 @@ class TCamera { bool SetMatrix(glm::dmat4 &Matrix); void RaLook(); - Math3D::vector3 Angle; // pitch, yaw, roll - Math3D::vector3 Pos; // współrzędne obserwatora - Math3D::vector3 LookAt; // współrzędne punktu, na który ma patrzeć - Math3D::vector3 vUp; - Math3D::vector3 Velocity; + glm::dvec3 Angle; // pitch, yaw, roll + glm::dvec3 Pos; // współrzędne obserwatora + glm::vec3 LookAt; // współrzędne punktu, na który ma patrzeć + glm::vec3 vUp; + glm::dvec3 Velocity; TDynamicObject *m_owner { nullptr }; // TODO: change to const when shake calculations are part of vehicles update - Math3D::vector3 m_owneroffset {}; + glm::vec3 m_owneroffset{}; private: glm::dvec3 m_moverate; From bdff45b58424f45f4eff4bd5e7e67e41fa15c876 Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Sun, 26 Apr 2026 22:40:02 +0200 Subject: [PATCH 02/19] use glm instead of Math3D in drivermode --- application/drivermode.cpp | 10 +++++----- application/drivermode.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/application/drivermode.cpp b/application/drivermode.cpp index 394aad1c..cd03e68c 100644 --- a/application/drivermode.cpp +++ b/application/drivermode.cpp @@ -719,11 +719,11 @@ void driver_mode::update_camera(double const Deltatime) Camera.Angle.y = simulation::Train->pMechViewAngle.y; } - auto const shakescale{FreeFlyModeFlag ? 5.0 : 1.0}; + float const shakescale{FreeFlyModeFlag ? 5.0f : 1.0f}; auto shakencamerapos{Camera.m_owneroffset + - shakescale * Math3D::vector3(1.5 * Camera.m_owner->ShakeState.offset.x, 2.0 * Camera.m_owner->ShakeState.offset.y, 1.5 * Camera.m_owner->ShakeState.offset.z)}; + shakescale * glm::vec3(1.5 * Camera.m_owner->ShakeState.offset.x, 2.0 * Camera.m_owner->ShakeState.offset.y, 1.5 * Camera.m_owner->ShakeState.offset.z)}; - Camera.Pos = (Camera.m_owner->GetWorldPosition(FreeFlyModeFlag ? shakencamerapos : // TODO: vehicle collision box for the external vehicle camera + Camera.Pos = (Camera.m_owner->GetWorldPosition(FreeFlyModeFlag ? Math3D::vector3(shakencamerapos) : // TODO: vehicle collision box for the external vehicle camera simulation::Train->clamp_inside(shakencamerapos))); if (!Global.iPause) @@ -1058,12 +1058,12 @@ void driver_mode::DistantView(bool const Near) if (true == Near) { - Camera.Pos = Math3D::vector3(Camera.Pos.x, vehicle->GetPosition().y, Camera.Pos.z) + left * vehicle->GetWidth() + Math3D::vector3(1.25 * left.x, 1.6, 1.25 * left.z); + Camera.Pos = glm::vec3(Camera.Pos.x, vehicle->GetPosition().y, Camera.Pos.z) + left * vehicle->GetWidth() + glm::vec3(1.25 * left.x, 1.6, 1.25 * left.z); } else { - Camera.Pos = vehicle->GetPosition() + vehicle->VectorFront() * vehicle->MoverParameters->CabOccupied * 50.0 + Math3D::vector3(-10.0 * left.x, 1.6, -10.0 * left.z); + Camera.Pos = vehicle->GetPosition() + vehicle->VectorFront() * vehicle->MoverParameters->CabOccupied * 50.0 + glm::vec3(-10.0 * left.x, 1.6, -10.0 * left.z); } Camera.m_owner = nullptr; diff --git a/application/drivermode.h b/application/drivermode.h index 85caecba..66ff6936 100644 --- a/application/drivermode.h +++ b/application/drivermode.h @@ -60,8 +60,8 @@ private: struct view_config { TDynamicObject const *owner { nullptr }; - Math3D::vector3 offset {}; - Math3D::vector3 angle {}; + glm::vec3 offset {}; + glm::vec3 angle {}; }; struct drivermode_input { From 2ed1e63416075a1b698f71d9a25f33fbeb19f22f Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Sun, 26 Apr 2026 22:41:54 +0200 Subject: [PATCH 03/19] use glm instead of Math3D in editormode --- application/editormode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/editormode.cpp b/application/editormode.cpp index 1e97e9de..bd5f987f 100644 --- a/application/editormode.cpp +++ b/application/editormode.cpp @@ -512,7 +512,7 @@ void editor_mode::enter() { auto const cab = (vehicle->MoverParameters->CabOccupied == 0 ? 1 : vehicle->MoverParameters->CabOccupied); auto const left = vehicle->VectorLeft() * cab; - Camera.Pos = Math3D::vector3(Camera.Pos.x, vehicle->GetPosition().y, Camera.Pos.z) + left * vehicle->GetWidth() + Math3D::vector3(1.25f * left.x, 1.6f, 1.25f * left.z); + Camera.Pos = glm::vec3(Camera.Pos.x, vehicle->GetPosition().y, Camera.Pos.z) + left * vehicle->GetWidth() + glm::vec3(1.25f * left.x, 1.6f, 1.25f * left.z); Camera.m_owner = nullptr; Camera.LookAt = vehicle->GetPosition(); Camera.RaLook(); // single camera reposition From 19d79a54e05e18619f342743e03ea8925053ede9 Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Sun, 26 Apr 2026 22:42:42 +0200 Subject: [PATCH 04/19] use glm instead of Math3D in skydome --- environment/skydome.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment/skydome.cpp b/environment/skydome.cpp index e0a1afe1..b268fdd4 100644 --- a/environment/skydome.cpp +++ b/environment/skydome.cpp @@ -47,7 +47,7 @@ float CSkyDome::m_zenithymatrix[ 3 ][ 4 ] = { CSkyDome::CSkyDome (int const Tesselation) : m_tesselation( Tesselation ) { -// SetSunPosition( Math3D::vector3(75.0f, 0.0f, 0.0f) ); +// SetSunPosition( glm::vec3(75.0f, 0.0f, 0.0f) ); SetTurbidity( Global.fTurbidity ); SetExposure( true, 10.0f ); SetOvercastFactor( 0.05f ); From 1553f82c49728507e7fe006de9005ff8a8c7d0fe Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Sun, 26 Apr 2026 22:54:12 +0200 Subject: [PATCH 05/19] use glm instead of Math3D in Model3d --- model/Model3d.cpp | 7 +++---- model/Model3d.h | 5 ++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/model/Model3d.cpp b/model/Model3d.cpp index d4132f9e..2cdb6501 100644 --- a/model/Model3d.cpp +++ b/model/Model3d.cpp @@ -1043,7 +1043,7 @@ void TSubModel::SetRotateXYZ(float3 vNewAngles) iAnimOwner = iInstance; // zapamiętanie czyja jest animacja } -void TSubModel::SetRotateXYZ(Math3D::vector3 vNewAngles) +void TSubModel::SetRotateXYZ(glm::vec3 vNewAngles) { // obrócenie submodelu o // podane kąty wokół osi // lokalnego układu @@ -1063,7 +1063,7 @@ void TSubModel::SetTranslate(float3 vNewTransVector) iAnimOwner = iInstance; // zapamiętanie czyja jest animacja } -void TSubModel::SetTranslate(Math3D::vector3 vNewTransVector) +void TSubModel::SetTranslate(glm::vec3 vNewTransVector) { // przesunięcie submodelu (np. w kabinie) v_TransVector.x = vNewTransVector.x; v_TransVector.y = vNewTransVector.y; @@ -1178,8 +1178,7 @@ void TSubModel::RaAnimation(glm::mat4 &m, TAnimType a) break; case TAnimType::at_Billboard: // obrót w pionie do kamery { - Math3D::matrix4x4 mat; - mat.OpenGL_Matrix(OpenGLMatrices.data_array(GL_MODELVIEW)); + glm::mat4 mat = glm::make_mat4(OpenGLMatrices.data_array(GL_MODELVIEW)); float3 gdzie = float3(mat[3][0], mat[3][1], mat[3][2]); // początek układu współrzędnych submodelu względem kamery m = glm::mat4(1.0f); m = glm::translate(m, glm::vec3(gdzie.x, gdzie.y, gdzie.z)); // początek układu zostaje bez zmian diff --git a/model/Model3d.h b/model/Model3d.h index f6ba3298..87304335 100644 --- a/model/Model3d.h +++ b/model/Model3d.h @@ -10,7 +10,6 @@ http://mozilla.org/MPL/2.0/. #pragma once #include "utilities/Classes.h" -#include "utilities/dumb3d.h" #include "utilities/Float3d.h" #include "rendering/geometrybank.h" #include "model/material.h" @@ -191,9 +190,9 @@ public: int TriangleAdd(TModel3d *m, material_handle tex, int tri); #endif void SetRotate(float3 vNewRotateAxis, float fNewAngle); - void SetRotateXYZ( Math3D::vector3 vNewAngles); + void SetRotateXYZ(glm::vec3 vNewAngles); void SetRotateXYZ(float3 vNewAngles); - void SetTranslate( Math3D::vector3 vNewTransVector); + void SetTranslate(glm::vec3 vNewTransVector); void SetTranslate(float3 vNewTransVector); void SetRotateIK1(float3 vNewAngles); TSubModel * GetFromName( std::string const &search, bool i = true ); From 9fef303ec0737841aad8d9a4ba81999ed111ab78 Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Sun, 26 Apr 2026 23:14:07 +0200 Subject: [PATCH 06/19] use glm instead of Math3D in AnimModel --- model/AnimModel.cpp | 20 ++++++++++---------- model/AnimModel.h | 17 ++++++++--------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/model/AnimModel.cpp b/model/AnimModel.cpp index 0e4ae9d3..ff7dbf91 100644 --- a/model/AnimModel.cpp +++ b/model/AnimModel.cpp @@ -29,11 +29,11 @@ std::list> TAnimModel::acAnimList; TAnimContainer::TAnimContainer() { - vRotateAngles = Math3D::vector3(0.0f, 0.0f, 0.0f); // aktualne kąty obrotu - vDesiredAngles = Math3D::vector3(0.0f, 0.0f, 0.0f); // docelowe kąty obrotu + vRotateAngles = glm::dvec3(0.0f, 0.0f, 0.0f); // aktualne kąty obrotu + vDesiredAngles = glm::dvec3(0.0f, 0.0f, 0.0f); // docelowe kąty obrotu fRotateSpeed = 0.0; - vTranslation = Math3D::vector3(0.0f, 0.0f, 0.0f); // aktualne przesunięcie - vTranslateTo = Math3D::vector3(0.0f, 0.0f, 0.0f); // docelowe przesunięcie + vTranslation = glm::dvec3(0.0f, 0.0f, 0.0f); // aktualne przesunięcie + vTranslateTo = glm::dvec3(0.0f, 0.0f, 0.0f); // docelowe przesunięcie fTranslateSpeed = 0.0; fAngleSpeed = 0.0; pSubModel = NULL; @@ -48,7 +48,7 @@ bool TAnimContainer::Init(TSubModel *pNewSubModel) return (pSubModel != NULL); } -void TAnimContainer::SetRotateAnim( Math3D::vector3 vNewRotateAngles, double fNewRotateSpeed) +void TAnimContainer::SetRotateAnim(glm::dvec3 vNewRotateAngles, double fNewRotateSpeed) { vDesiredAngles = vNewRotateAngles; fRotateSpeed = fNewRotateSpeed; @@ -68,7 +68,7 @@ void TAnimContainer::SetRotateAnim( Math3D::vector3 vNewRotateAngles, double fNe } } -void TAnimContainer::SetTranslateAnim( Math3D::vector3 vNewTranslate, double fNewSpeed) +void TAnimContainer::SetTranslateAnim(glm::dvec3 vNewTranslate, double fNewSpeed) { vTranslateTo = vNewTranslate; fTranslateSpeed = fNewSpeed; @@ -96,14 +96,14 @@ void TAnimContainer::UpdateModel() { if (fTranslateSpeed != 0.0) { auto dif = vTranslateTo - vTranslation; // wektor w kierunku docelowym - double l = LengthSquared3(dif); // długość wektora potrzebnego przemieszczenia + double l = glm::length(dif); // długość wektora potrzebnego przemieszczenia if (l >= 0.0001) { // jeśli do przemieszczenia jest ponad 1cm - auto s = Math3D::SafeNormalize(dif); // jednostkowy wektor kierunku + auto s = glm::normalize(dif); // jednostkowy wektor kierunku // Długość wektora nie jest równa 0, sprawdzane wcześniej więc wektor normalny będzie zawsze prawidłowy. s = s * (fTranslateSpeed * Timer::GetDeltaTime()); // przemieszczenie w podanym czasie z daną prędkością - if (LengthSquared3(s) < l) //żeby nie jechało na drugą stronę + if (glm::length(s) < l) //żeby nie jechało na drugą stronę vTranslation += s; else vTranslation = vTranslateTo; // koniec animacji, "koniec animowania" uruchomi @@ -113,7 +113,7 @@ void TAnimContainer::UpdateModel() { { // koniec animowania vTranslation = vTranslateTo; fTranslateSpeed = 0.0; // wyłączenie przeliczania wektora - if (LengthSquared3(vTranslation) <= 0.0001) // jeśli jest w punkcie początkowym + if (glm::length(vTranslation) <= 0.0001) // jeśli jest w punkcie początkowym iAnim &= ~2; // wyłączyć zmianę pozycji submodelu if( evDone ) { // wykonanie eventu informującego o zakończeniu diff --git a/model/AnimModel.h b/model/AnimModel.h index 802cb21c..e708daa0 100644 --- a/model/AnimModel.h +++ b/model/AnimModel.h @@ -15,7 +15,6 @@ http://mozilla.org/MPL/2.0/. #pragma once #include "utilities/Classes.h" -#include "utilities/dumb3d.h" #include "utilities/Float3d.h" #include "model/Model3d.h" #include "vehicle/DynObj.h" @@ -52,11 +51,11 @@ class TAnimContainer : std::enable_shared_from_this friend TAnimModel; private: - Math3D::vector3 vRotateAngles; // dla obrotów Eulera - Math3D::vector3 vDesiredAngles; + glm::dvec3 vRotateAngles; // dla obrotów Eulera + glm::dvec3 vDesiredAngles; double fRotateSpeed; - Math3D::vector3 vTranslation; - Math3D::vector3 vTranslateTo; + glm::dvec3 vTranslation; + glm::dvec3 vTranslateTo; double fTranslateSpeed; // może tu dać wektor? float4 qCurrent; // aktualny interpolowany float4 qStart; // pozycja początkowa (0 dla interpolacji) @@ -82,8 +81,8 @@ class TAnimContainer : std::enable_shared_from_this inline std::string NameGet() { return (pSubModel ? pSubModel->pName : ""); }; - void SetRotateAnim( Math3D::vector3 vNewRotateAngles, double fNewRotateSpeed); - void SetTranslateAnim( Math3D::vector3 vNewTranslate, double fNewSpeed); + void SetRotateAnim( glm::dvec3 vNewRotateAngles, double fNewRotateSpeed); + void SetTranslateAnim( glm::dvec3 vNewTranslate, double fNewSpeed); void AnimSetVMD(double fNewSpeed); void PrepareModel(); void UpdateModel(); @@ -93,8 +92,8 @@ class TAnimContainer : std::enable_shared_from_this double AngleGet() { return vRotateAngles.z; }; // jednak ostatnia, T3D ma inny układ inline - Math3D::vector3 TransGet() { - return Math3D::vector3(-vTranslation.x, vTranslation.z, vTranslation.y); }; // zmiana, bo T3D ma inny układ + glm::dvec3 TransGet() { + return glm::dvec3(-vTranslation.x, vTranslation.z, vTranslation.y); }; // zmiana, bo T3D ma inny układ inline void WillBeAnimated() { if (pSubModel) From 1cfcf47788ade38e3456d0728daf86cdf4bef75a Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Sun, 26 Apr 2026 23:27:10 +0200 Subject: [PATCH 07/19] use glm instead of Math3D in Globals --- simulation/simulationstateserializer.cpp | 2 +- utilities/Globals.h | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/simulation/simulationstateserializer.cpp b/simulation/simulationstateserializer.cpp index cbd7dd53..3c0a6dcd 100644 --- a/simulation/simulationstateserializer.cpp +++ b/simulation/simulationstateserializer.cpp @@ -278,7 +278,7 @@ state_serializer::deserialize_camera( cParser &Input, scene::scratch_data &Scrat if( into < 10 ) { // przepisanie do odpowiedniego miejsca w tabelce Global.FreeCameraInit[ into ] = xyz; Global.FreeCameraInitAngle[ into ] = - Math3D::vector3( + glm::dvec3( glm::radians( abc.x ), glm::radians( abc.y ), glm::radians( abc.z ) ); diff --git a/utilities/Globals.h b/utilities/Globals.h index efbdc29d..f9513b45 100644 --- a/utilities/Globals.h +++ b/utilities/Globals.h @@ -11,7 +11,6 @@ http://mozilla.org/MPL/2.0/. #include "utilities/Classes.h" #include "vehicle/Camera.h" -#include "utilities/dumb3d.h" #include "utilities/Float3d.h" #include "rendering/light.h" #include "utilities/utilities.h" @@ -46,8 +45,8 @@ struct global_settings { uint32_t random_seed = 0; TCamera pCamera; // parametry kamery TCamera pDebugCamera; - std::array FreeCameraInit; // pozycje kamery - std::array FreeCameraInitAngle; + std::array FreeCameraInit; // pozycje kamery + std::array FreeCameraInitAngle; int iCameraLast{ -1 }; int iSlowMotion{ 0 }; // info o malym FPS: 0-OK, 1-wyłączyć multisampling, 3-promień 1.5km, 7-1km basic_light DayLight; From ed28eff066edc11b4af32b6b281108842f6fa28d Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Mon, 27 Apr 2026 00:36:03 +0200 Subject: [PATCH 08/19] use glm instead of Math3D in world --- scene/scene.cpp | 2 +- vehicle/Driver.cpp | 6 ++-- world/Segment.cpp | 41 +++++++++++---------- world/Segment.h | 51 +++++++++++--------------- world/Spring.cpp | 9 +++-- world/Spring.h | 5 ++- world/Track.cpp | 90 +++++++++++++++++++++++----------------------- world/Track.h | 4 +-- world/TrkFoll.h | 6 ++-- 9 files changed, 101 insertions(+), 113 deletions(-) diff --git a/scene/scene.cpp b/scene/scene.cpp index d147f0d7..12971b73 100644 --- a/scene/scene.cpp +++ b/scene/scene.cpp @@ -517,7 +517,7 @@ basic_cell::find( glm::dvec3 const &Point, float const Radius, bool const Onlyco std::tuple basic_cell::find( glm::dvec3 const &Point, TTrack const *Exclude ) const { - Math3D::vector3 point { Point.x, Point.y, Point.z }; // sad workaround until math classes unification + glm::dvec3 point{Point.x, Point.y, Point.z}; // sad workaround until math classes unification // TODO: Is it needed? int endpointid; for( auto *path : m_directories.paths ) { diff --git a/vehicle/Driver.cpp b/vehicle/Driver.cpp index 9a1f5d84..765fdebe 100644 --- a/vehicle/Driver.cpp +++ b/vehicle/Driver.cpp @@ -59,12 +59,14 @@ double GetDistanceToEvent(TTrack const *track, basic_event const *event, double double seg_len = scan_dir > 0 ? 0.0 : 1.0; double const dzielnik = 1.0 / segment->GetLength();// rozdzielczosc mniej wiecej 1m int krok = 0; // krok obliczeniowy do sprawdzania czy odwracamy - len2 = (pos_event - segment->FastGetPoint(seg_len)).LengthSquared(); + auto temp = pos_event - segment->FastGetPoint(seg_len); + len2 = glm::dot(temp, temp); do { len1 = len2; seg_len += scan_dir > 0 ? dzielnik : -dzielnik; - len2 = (pos_event - segment->FastGetPoint(seg_len)).LengthSquared(); + temp = pos_event - segment->FastGetPoint(seg_len); + len2 = glm::dot(temp, temp); ++krok; } while ((len1 > len2) && (seg_len >= dzielnik && (seg_len <= (1.0 - dzielnik)))); //trzeba sprawdzić czy seg_len nie osiągnął skrajnych wartości, bo wtedy diff --git a/world/Segment.cpp b/world/Segment.cpp index 8e31ac8a..09d28be5 100644 --- a/world/Segment.cpp +++ b/world/Segment.cpp @@ -37,9 +37,9 @@ TSegment::TSegment(TTrack *owner) : pOwner( owner ) {} -bool TSegment::Init(Math3D::vector3 NewPoint1, Math3D::vector3 NewPoint2, double fNewStep, double fNewRoll1, double fNewRoll2) +bool TSegment::Init(glm::dvec3 NewPoint1, glm::dvec3 NewPoint2, double fNewStep, double fNewRoll1, double fNewRoll2) { // wersja dla prostego - wyliczanie punktów kontrolnych - Math3D::vector3 dir; + glm::dvec3 dir; // NOTE: we're enforcing division also for straight track, to ensure dense enough mesh for per-vertex lighting /* @@ -60,7 +60,7 @@ bool TSegment::Init(Math3D::vector3 NewPoint1, Math3D::vector3 NewPoint2, double } }; -bool TSegment::Init( Math3D::vector3 &NewPoint1, Math3D::vector3 NewCPointOut, Math3D::vector3 NewCPointIn, Math3D::vector3 &NewPoint2, double fNewStep, double fNewRoll1, double fNewRoll2, bool bIsCurve) +bool TSegment::Init(glm::dvec3 &NewPoint1, glm::dvec3 NewCPointOut, glm::dvec3 NewCPointIn, glm::dvec3 &NewPoint2, double fNewStep, double fNewRoll1, double fNewRoll2, bool bIsCurve) { // wersja uniwersalna (dla krzywej i prostego) Point1 = NewPoint1; CPointOut = NewCPointOut; @@ -107,7 +107,7 @@ bool TSegment::Init( Math3D::vector3 &NewPoint1, Math3D::vector3 NewCPointOut, M fLength = ComputeLength(); } else { - fLength = ( Point1 - Point2 ).Length(); + fLength = glm::length(Point1 - Point2); } if (fLength <= 0) { @@ -142,12 +142,12 @@ bool TSegment::Init( Math3D::vector3 &NewPoint1, Math3D::vector3 NewCPointOut, M return true; } -Math3D::vector3 TSegment::GetFirstDerivative(double const fTime) const +glm::dvec3 TSegment::GetFirstDerivative(double const fTime) const { double fOmTime = 1.0 - fTime; double fPowTime = fTime; - Math3D::vector3 kResult = fOmTime * (CPointOut - Point1); + glm::dvec3 kResult = fOmTime * (CPointOut - Point1); // int iDegreeM1 = 3 - 1; @@ -170,14 +170,14 @@ double TSegment::RombergIntegral(double const fA, double const fB) const double ms_apfRom[2][ms_iOrder]; ms_apfRom[0][0] = - 0.5 * fH * ((GetFirstDerivative(fA).Length()) + (GetFirstDerivative(fB).Length())); + 0.5 * fH * ((glm::length(GetFirstDerivative(fA))) + glm::length(GetFirstDerivative(fB))); for (int i0 = 2, iP0 = 1; i0 <= ms_iOrder; i0++, iP0 *= 2, fH *= 0.5) { // approximations via the trapezoid rule double fSum = 0.0; int i1; for (i1 = 1; i1 <= iP0; i1++) - fSum += (GetFirstDerivative(fA + fH * (i1 - 0.5)).Length()); + fSum += glm::length(GetFirstDerivative(fA + fH * (i1 - 0.5))); // Richardson extrapolation ms_apfRom[1][0] = 0.5 * (ms_apfRom[0][0] + fH * fSum); @@ -207,7 +207,7 @@ double TSegment::GetTFromS(double const s) const if( std::abs( fDifference ) < fTolerance ) { return fTime; } - fTime -= fDifference / GetFirstDerivative(fTime).Length(); + fTime -= fDifference / glm::length(GetFirstDerivative(fTime)); ++iteration; } while( iteration < 10 ); // arbitrary limit @@ -220,12 +220,12 @@ double TSegment::GetTFromS(double const s) const return fTime; }; -Math3D::vector3 TSegment::RaInterpolate(double const t) const +glm::dvec3 TSegment::RaInterpolate(double const t) const { // wyliczenie XYZ na krzywej Beziera z użyciem współczynników return t * (t * (t * vA + vB) + vC) + Point1; // 9 mnożeń, 9 dodawań }; -Math3D::vector3 TSegment::RaInterpolate0(double const t) const +glm::dvec3 TSegment::RaInterpolate0(double const t) const { // wyliczenie XYZ na krzywej Beziera, na użytek liczenia długości nie jest dodawane Point1 return t * (t * (t * vA + vB) + vC); // 9 mnożeń, 6 dodawań }; @@ -237,15 +237,15 @@ double TSegment::ComputeLength() const // McZapkie-150503: dlugosc miedzy punkta // poprzedniej // Ra: ewentualnie rozpoznać łuk okręgu płaskiego i liczyć ze wzoru na długość łuku double t, l = 0; - Math3D::vector3 last = Math3D::vector3(0, 0, 0); // długość liczona po przesunięciu odcinka do początku układu - Math3D::vector3 tmp = Point2 - Point1; - int m = 20.0 * tmp.Length(); // było zawsze do 10000, teraz jest liczone odcinkami po około 5cm + glm::dvec3 last{0, 0, 0}; // długość liczona po przesunięciu odcinka do początku układu + glm::dvec3 tmp = Point2 - Point1; + int m = 20.0 * glm::length(tmp); // było zawsze do 10000, teraz jest liczone odcinkami po około 5cm for (int i = 1; i <= m; i++) { t = double(i) / double(m); // wyznaczenie parametru na krzywej z przedziału (0,1> // tmp=Interpolate(t,p1,cp1,cp2,p2); tmp = RaInterpolate0(t); // obliczenie punktu dla tego parametru - t = Math3D::vector3(tmp - last).Length(); // obliczenie długości wektora + t = glm::length(tmp - last); // obliczenie długości wektora l += t; // zwiększenie wyliczanej długości last = tmp; } @@ -296,7 +296,7 @@ TSegment::find_nearest_point( glm::dvec3 const &Point ) const { const double fDirectionOffset = 0.1; // długość wektora do wyliczenia kierunku -Math3D::vector3 TSegment::GetDirection(double const fDistance) const +glm::dvec3 TSegment::GetDirection(double const fDistance) const { // takie toporne liczenie pochodnej dla podanego dystansu od Point1 double t1 = GetTFromS(fDistance - fDirectionOffset); if (t1 <= 0.0) @@ -307,7 +307,7 @@ Math3D::vector3 TSegment::GetDirection(double const fDistance) const return (FastGetPoint(t2) - FastGetPoint(t1)); } -Math3D::vector3 TSegment::FastGetDirection(double fDistance, double fOffset) +glm::dvec3 TSegment::FastGetDirection(double fDistance, double fOffset) { // takie toporne liczenie pochodnej dla parametru 0.0÷1.0 double t1 = fDistance - fOffset; if (t1 <= 0.0) @@ -338,8 +338,7 @@ Math3D::vector3 TSegment::GetPoint(double const fDistance) const }; */ // ustalenie pozycji osi na torze, przechyłki, pochylenia i kierunku jazdy -void TSegment::RaPositionGet(double const fDistance, Math3D::vector3 &p, Math3D::vector3 &a) const { - +void TSegment::RaPositionGet(double const fDistance, glm::dvec3 &p, glm::dvec3 &a) const { if (bCurve) { // można by wprowadzić uproszczony wzór dla okręgów płaskich auto const t = GetTFromS(fDistance); // aproksymacja dystansu na krzywej Beziera na parametr (t) @@ -364,7 +363,7 @@ void TSegment::RaPositionGet(double const fDistance, Math3D::vector3 &p, Math3D: } }; -Math3D::vector3 TSegment::FastGetPoint(double const t) const +glm::dvec3 TSegment::FastGetPoint(double const t) const { // return (bCurve?Interpolate(t,Point1,CPointOut,CPointIn,Point2):((1.0-t)*Point1+(t)*Point2)); return ( @@ -373,7 +372,7 @@ Math3D::vector3 TSegment::FastGetPoint(double const t) const interpolate( Point1, Point2, t ) ); } -bool TSegment::RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Origin, const gfx::vertex_array &ShapePoints, bool const Transition, double fTextureLength, double Texturescale, int iSkip, int iEnd, std::pair fOffsetX, glm::vec3 **p, bool bRender) +bool TSegment::RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin, const gfx::vertex_array &ShapePoints, bool const Transition, double fTextureLength, double Texturescale, int iSkip, int iEnd, std::pair fOffsetX, glm::vec3 **p, bool bRender) { // generowanie trójkątów dla odcinka trajektorii ruchu // standardowo tworzy triangle_strip dla prostego albo ich zestaw dla łuku // po modyfikacji - dla ujemnego (iNumShapePoints) w dodatkowych polach tabeli podany jest przekrój końcowy diff --git a/world/Segment.h b/world/Segment.h index 3e1b64c1..9da9fcc5 100644 --- a/world/Segment.h +++ b/world/Segment.h @@ -10,9 +10,9 @@ http://mozilla.org/MPL/2.0/. #pragma once #include "utilities/Classes.h" -#include "utilities/dumb3d.h" #include "rendering/geometrybank.h" #include "utilities/utilities.h" +#include struct map_colored_paths { std::vector switches; @@ -42,7 +42,7 @@ struct segment_data { class TSegment { // aproksymacja toru (zwrotnica ma dwa takie, jeden z nich jest aktywny) private: - Math3D::vector3 Point1, CPointOut, CPointIn, Point2; + glm::dvec3 Point1, CPointOut, CPointIn, Point2; float fRoll1 { 0.f }, fRoll2 { 0.f }; // przechyłka na końcach @@ -52,63 +52,54 @@ class TSegment int iSegCount = 0; // ilość odcinków do rysowania krzywej double fDirection = 0.0; // Ra: kąt prostego w planie; dla łuku kąt od Point1 double fStoop = 0.0; // Ra: kąt wzniesienia; dla łuku od Point1 - Math3D::vector3 vA, vB, vC; // współczynniki wielomianów trzeciego stopnia vD==Point1 + glm::dvec3 vA, vB, vC; // współczynniki wielomianów trzeciego stopnia vD==Point1 TTrack *pOwner = nullptr; // wskaźnik na właściciela - Math3D::vector3 - GetFirstDerivative(double const fTime) const; - double - RombergIntegral(double const fA, double const fB) const; - double - GetTFromS(double const s) const; - Math3D::vector3 - RaInterpolate(double const t) const; - Math3D::vector3 - RaInterpolate0(double const t) const; + glm::dvec3 GetFirstDerivative(double const fTime) const; + double RombergIntegral(double const fA, double const fB) const; + double GetTFromS(double const s) const; + glm::dvec3 RaInterpolate(double const t) const; + glm::dvec3 RaInterpolate0(double const t) const; public: bool bCurve = false; TSegment(TTrack *owner); - bool - Init( Math3D::vector3 NewPoint1, Math3D::vector3 NewPoint2, double fNewStep, double fNewRoll1 = 0, double fNewRoll2 = 0); - bool - Init( Math3D::vector3 &NewPoint1, Math3D::vector3 NewCPointOut, Math3D::vector3 NewCPointIn, Math3D::vector3 &NewPoint2, double fNewStep, double fNewRoll1 = 0, double fNewRoll2 = 0, bool bIsCurve = true); + bool Init(glm::dvec3 NewPoint1, glm::dvec3 NewPoint2, double fNewStep, double fNewRoll1 = 0, double fNewRoll2 = 0); + bool Init(glm::dvec3 &NewPoint1, glm::dvec3 NewCPointOut, glm::dvec3 NewCPointIn, glm::dvec3 &NewPoint2, double fNewStep, double fNewRoll1 = 0, double fNewRoll2 = 0, bool bIsCurve = true); double ComputeLength() const; // McZapkie-150503 // finds point on segment closest to specified point in 3d space. returns: point on segment as value in range 0-1 double find_nearest_point( glm::dvec3 const &Point ) const; - inline - Math3D::vector3 + inline + glm::dvec3 GetDirection1() const { return bCurve ? CPointOut - Point1 : CPointOut; }; inline - Math3D::vector3 + glm::dvec3 GetDirection2() const { return bCurve ? CPointIn - Point2 : CPointIn; }; - Math3D::vector3 + glm::dvec3 GetDirection(double const fDistance) const; inline - Math3D::vector3 + glm::dvec3 GetDirection() const { return CPointOut; }; - Math3D::vector3 + glm::dvec3 FastGetDirection(double const fDistance, double const fOffset); /* Math3D::vector3 GetPoint(double const fDistance) const; */ - void - RaPositionGet(double const fDistance, Math3D::vector3 &p, Math3D::vector3 &a) const; - Math3D::vector3 - FastGetPoint(double const t) const; + void RaPositionGet(double const fDistance, glm::dvec3 &p, glm::dvec3 &a) const; + glm::dvec3 FastGetPoint(double const t) const; inline - Math3D::vector3 + glm::dvec3 FastGetPoint_0() const { return Point1; }; inline - Math3D::vector3 + glm::dvec3 FastGetPoint_1() const { return Point2; }; inline @@ -123,7 +114,7 @@ public: r2 = fRoll2; } bool - RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Origin, gfx::vertex_array const &ShapePoints, bool const Transition, double fTextureLength, double Texturescale = 1.0, int iSkip = 0, int iEnd = 0, std::pair fOffsetX = {0.f, 0.f}, glm::vec3 **p = nullptr, bool bRender = true ); + RenderLoft( gfx::vertex_array &Output, glm::dvec3 const &Origin, gfx::vertex_array const &ShapePoints, bool const Transition, double fTextureLength, double Texturescale = 1.0, int iSkip = 0, int iEnd = 0, std::pair fOffsetX = {0.f, 0.f}, glm::vec3 **p = nullptr, bool bRender = true ); /* void Render(); diff --git a/world/Spring.cpp b/world/Spring.cpp index 05ec3a9b..49992411 100644 --- a/world/Spring.cpp +++ b/world/Spring.cpp @@ -17,15 +17,14 @@ void TSpring::Init(double nKs, double nKd) { kd = Kd; } -Math3D::vector3 TSpring::ComputateForces( Math3D::vector3 const &pPosition1, Math3D::vector3 const &pPosition2) { - - Math3D::vector3 springForce; +glm::dvec3 TSpring::ComputateForces(glm::dvec3 const &pPosition1, glm::dvec3 const &pPosition2) { + glm::vec3 springForce; // p1 = &system[spring->p1]; // p2 = &system[spring->p2]; // VectorDifference(&p1->pos,&p2->pos,&deltaP); // Vector distance auto deltaP = pPosition1 - pPosition2; // dist = VectorLength(&deltaP); // Magnitude of deltaP - auto dist = deltaP.Length(); + auto dist = glm::length(deltaP); if( dist > restLen ) { // Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest) @@ -35,7 +34,7 @@ Math3D::vector3 TSpring::ComputateForces( Math3D::vector3 const &pPosition1, Mat auto deltaV = pPosition1 - pPosition2; // Dterm = (DotProduct(&deltaV,&deltaP) * spring->Kd) / dist; // Damping Term - auto Dterm = (DotProduct(deltaV,deltaP) * Kd) / dist; + auto Dterm = (glm::dot(deltaV,deltaP) * Kd) / dist; //Dterm = 0; // ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector diff --git a/world/Spring.h b/world/Spring.h index d527041d..6800ba29 100644 --- a/world/Spring.h +++ b/world/Spring.h @@ -10,7 +10,6 @@ http://mozilla.org/MPL/2.0/. #ifndef ParticlesH #define ParticlesH -#include "utilities/dumb3d.h" /* #define STATIC_THRESHOLD 0.17f const double m_Kd = 0.02f; // DAMPING FACTOR @@ -28,8 +27,8 @@ public: // void Init(TParticnp1, TParticle *np2, double nKs= 0.5f, double nKd= 0.002f, // double nrestLen= -1.0f); void Init(double nKs = 0.5f, double nKd = 0.002f); - Math3D::vector3 ComputateForces( Math3D::vector3 const &pPosition1, Math3D::vector3 const &pPosition2); -//private: + glm::dvec3 ComputateForces(glm::dvec3 const &pPosition1, glm::dvec3 const &pPosition2); + //private: // members double restLen { 0.01 }; // LENGTH OF SPRING AT REST double Ks { 0.0 }; // SPRING CONSTANT diff --git a/world/Track.cpp b/world/Track.cpp index 22387323..60411db0 100644 --- a/world/Track.cpp +++ b/world/Track.cpp @@ -23,7 +23,6 @@ http://mozilla.org/MPL/2.0/. #include "vehicle/DynObj.h" #include "vehicle/Driver.h" #include "model/AnimModel.h" -#include "world/Track.h" #include "utilities/Timer.h" #include "utilities/Logs.h" #include "rendering/renderer.h" @@ -218,7 +217,7 @@ TTrack * TTrack::Create400m(int what, double dx) trk->m_visible = false; // nie potrzeba pokazywać, zresztą i tak nie ma tekstur trk->iCategoryFlag = what; // taki sam typ plus informacja, że dodatkowy trk->Init(); // utworzenie segmentu - trk->Segment->Init( Math3D::vector3( -dx, 0, 0 ), Math3D::vector3( -dx, 0, 400 ), 10.0, 0, 0 ); // prosty + trk->Segment->Init(glm::dvec3(-dx, 0, 0), glm::dvec3(-dx, 0, 400), 10.0, 0, 0); // prosty trk->location( glm::dvec3{ -dx, 0, 200 } ); //środek, aby się mogło wyświetlić simulation::Paths.insert( trk ); simulation::Region->insert( trk ); @@ -237,7 +236,7 @@ TTrack * TTrack::NullCreate(int dir) trk->iCategoryFlag = (iCategoryFlag & 15) | 0x80; // taki sam typ plus informacja, że dodatkowy float r1, r2; Segment->GetRolls(r1, r2); // pobranie przechyłek na początku toru - Math3D::vector3 p1, cv1, cv2, p2; // będziem tworzyć trajektorię lotu + glm::dvec3 p1, cv1, cv2, p2; // będziem tworzyć trajektorię lotu if (iCategoryFlag & 1) { // tylko dla kolei trk->iDamageFlag = 128; // wykolejenie @@ -247,21 +246,21 @@ TTrack * TTrack::NullCreate(int dir) { //łączenie z nowym torem case 0: p1 = Segment->FastGetPoint_0(); - p2 = p1 - 450.0 * Normalize(Segment->GetDirection1()); + p2 = p1 - 450.0 * glm::normalize(Segment->GetDirection1()); // bo prosty, kontrolne wyliczane przy zmiennej przechyłce trk->Segment->Init(p1, p2, 5, -RadToDeg(r1), 70.0); ConnectPrevPrev(trk, 0); break; case 1: p1 = Segment->FastGetPoint_1(); - p2 = p1 - 450.0 * Normalize(Segment->GetDirection2()); + p2 = p1 - 450.0 * glm::normalize(Segment->GetDirection2()); // bo prosty, kontrolne wyliczane przy zmiennej przechyłce trk->Segment->Init(p1, p2, 5, RadToDeg(r2), 70.0); ConnectNextPrev(trk, 0); break; case 3: // na razie nie możliwe p1 = SwitchExtension->Segments[1]->FastGetPoint_1(); // koniec toru drugiego zwrotnicy - p2 = p1 - 450.0 * Normalize( SwitchExtension->Segments[1]->GetDirection2()); // przedłużenie na wprost + p2 = p1 - 450.0 * glm::normalize(SwitchExtension->Segments[1]->GetDirection2()); // przedłużenie na wprost trk->Segment->Init(p1, p2, 5, RadToDeg(r2), 70.0); // bo prosty, kontrolne wyliczane przy zmiennej przechyłce ConnectNextPrev(trk, 0); // trk->ConnectPrevNext(trk,dir); @@ -288,24 +287,24 @@ TTrack * TTrack::NullCreate(int dir) { //łączenie z nowym torem case 0: p1 = Segment->FastGetPoint_0(); - cv1 = -20.0 * Normalize(Segment->GetDirection1()); // pierwszy wektor kontrolny + cv1 = -20.0 * glm::normalize(Segment->GetDirection1()); // pierwszy wektor kontrolny p2 = p1 + cv1 + cv1; // 40m // bo prosty, kontrolne wyliczane przy zmiennej przechyłce - trk->Segment->Init(p1, p1 + cv1, p2 + Math3D::vector3(-cv1.z, cv1.y, cv1.x), p2, 2, -RadToDeg(r1), 0.0); + trk->Segment->Init(p1, p1 + cv1, p2 + glm::dvec3(-cv1.z, cv1.y, cv1.x), p2, 2, -RadToDeg(r1), 0.0); ConnectPrevPrev(trk, 0); // bo prosty, kontrolne wyliczane przy zmiennej przechyłce - trk2->Segment->Init(p1, p1 + cv1, p2 + Math3D::vector3(cv1.z, cv1.y, -cv1.x), p2, 2, -RadToDeg(r1), 0.0); + trk2->Segment->Init(p1, p1 + cv1, p2 + glm::dvec3(cv1.z, cv1.y, -cv1.x), p2, 2, -RadToDeg(r1), 0.0); trk2->iPrevDirection = 0; // zwrotnie do tego samego odcinka break; case 1: p1 = Segment->FastGetPoint_1(); - cv1 = -20.0 * Normalize(Segment->GetDirection2()); // pierwszy wektor kontrolny + cv1 = -20.0 * glm::normalize(Segment->GetDirection2()); // pierwszy wektor kontrolny p2 = p1 + cv1 + cv1; // bo prosty, kontrolne wyliczane przy zmiennej przechyłce - trk->Segment->Init(p1, p1 + cv1, p2 + Math3D::vector3(-cv1.z, cv1.y, cv1.x), p2, 2, RadToDeg(r2), 0.0); + trk->Segment->Init(p1, p1 + cv1, p2 + glm::dvec3(-cv1.z, cv1.y, cv1.x), p2, 2, RadToDeg(r2), 0.0); ConnectNextPrev(trk, 0); // bo prosty, kontrolne wyliczane przy zmiennej przechyłce - trk2->Segment->Init(p1, p1 + cv1, p2 + Math3D::vector3(cv1.z, cv1.y, -cv1.x), p2, 2, RadToDeg(r2), 0.0); + trk2->Segment->Init(p1, p1 + cv1, p2 + glm::dvec3(cv1.z, cv1.y, -cv1.x), p2, 2, RadToDeg(r2), 0.0); trk2->iPrevDirection = 1; // zwrotnie do tego samego odcinka break; } @@ -387,7 +386,7 @@ void TTrack::ConnectNextNext(TTrack *pTrack, int typ) void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) { // pobranie obiektu trajektorii ruchu - Math3D::vector3 pt, vec, p1, p2, cp1, cp2, p3, p4, cp3, cp4; // dodatkowe punkty potrzebne do skrzyżowań + glm::dvec3 pt, vec, p1, p2, cp1, cp2, p3, p4, cp3, cp4; // dodatkowe punkty potrzebne do skrzyżowań double a1, a2, r1, r2, r3, r4; std::string str; size_t i; //,state; //Ra: teraz już nie ma początkowego stanu zwrotnicy we wpisie @@ -560,10 +559,10 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) // na przechyłce doliczyć jeszcze pół przechyłki } - if( ( ( ( p1 + p1 + p2 ) / 3.0 - p1 - cp1 ).Length() < 0.02 ) - || ( ( ( p1 + p2 + p2 ) / 3.0 - p2 + cp1 ).Length() < 0.02 ) ) { + if( (glm::length(( p1 + p1 + p2 ) / 3.0 - p1 - cp1) < 0.02 ) + || ( glm::length(( p1 + p2 + p2 ) / 3.0 - p2 + cp1) < 0.02 ) ) { // "prostowanie" prostych z kontrolnymi, dokładność 2cm - cp1 = cp2 = Math3D::vector3( 0, 0, 0 ); + cp1 = cp2 = glm::dvec3(0, 0, 0); } if( fRadius != 0 ) { @@ -576,22 +575,22 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) } else { // HACK: crude check whether claimed straight is an actual straight piece - if( ( cp1 == Math3D::vector3() ) - && ( cp2 == Math3D::vector3() ) ) { + if ((cp1 == glm::dvec3()) && (cp2 == glm::dvec3())) + { segsize = 10.0; // for straights, 10m per segment works good enough } else { // HACK: divide roughly in 10 segments. segsize = clamp( - ( p1 - p2 ).Length() * 0.1, + glm::length( p1 - p2 ) * 0.1, 2.0 / Global.SplineFidelity, 10.0 / Global.SplineFidelity ); } } - if( ( cp1 == Math3D::vector3( 0, 0, 0 ) ) - && ( cp2 == Math3D::vector3( 0, 0, 0 ) ) ) { + if ((cp1 == glm::dvec3()) && (cp2 == glm::dvec3())) + { // Ra: hm, czasem dla prostego są podane... // gdy prosty, kontrolne wyliczane przy zmiennej przechyłce Segment->Init( p1, p2, segsize, r1, r2 ); @@ -656,10 +655,10 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) if( eType != tt_Cross ) { // dla skrzyżowań muszą być podane kontrolne - if( ( ( ( p1 + p1 + p2 ) / 3.0 - p1 - cp1 ).Length() < 0.02 ) - || ( ( ( p1 + p2 + p2 ) / 3.0 - p2 + cp1 ).Length() < 0.02 ) ) { + if( ( glm::length(( p1 + p1 + p2 ) / 3.0 - p1 - cp1 ) < 0.02 ) + || ( glm::length(( p1 + p2 + p2 ) / 3.0 - p2 + cp1 ) < 0.02 ) ) { // "prostowanie" prostych z kontrolnymi, dokładność 2cm - cp1 = cp2 = Math3D::vector3( 0, 0, 0 ); + cp1 = cp2 = glm::dvec3(0, 0, 0); } } @@ -673,22 +672,22 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) } else { // HACK: crude check whether claimed straight is an actual straight piece - if( ( cp1 == Math3D::vector3() ) - && ( cp2 == Math3D::vector3() ) ) { + if ((cp1 == glm::dvec3()) && (cp2 == glm::dvec3())) + { segsize = 10.0; // for straights, 10m per segment works good enough } else { // HACK: divide roughly in 10 segments. segsize = clamp( - ( p1 - p2 ).Length() * 0.1, + glm::length( p1 - p2 ) * 0.1, 2.0 / Global.SplineFidelity, 10.0 / Global.SplineFidelity ); } } - if( ( cp1 == Math3D::vector3( 0, 0, 0 ) ) - && ( cp2 == Math3D::vector3( 0, 0, 0 ) ) ) { + if ((cp1 == glm::dvec3()) && (cp2 == glm::dvec3())) + { // Ra: hm, czasem dla prostego są podane... // gdy prosty, kontrolne wyliczane przy zmiennej przechyłce SwitchExtension->Segments[ 0 ]->Init( p1, p2, segsize, r1, r2 ); @@ -720,10 +719,10 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) if( eType != tt_Cross ) { // dla skrzyżowań muszą być podane kontrolne - if( ( ( ( p3 + p3 + p4 ) / 3.0 - p3 - cp3 ).Length() < 0.02 ) - || ( ( ( p3 + p4 + p4 ) / 3.0 - p4 + cp3 ).Length() < 0.02 ) ) { + if( ( glm::length(( p3 + p3 + p4 ) / 3.0 - p3 - cp3) < 0.02 ) + || ( glm::length(( p3 + p4 + p4 ) / 3.0 - p4 + cp3) < 0.02 ) ) { // "prostowanie" prostych z kontrolnymi, dokładność 2cm - cp3 = cp4 = Math3D::vector3( 0, 0, 0 ); + cp3 = cp4 = glm::dvec3(0, 0, 0); } } @@ -737,22 +736,22 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) } else { // HACK: crude check whether claimed straight is an actual straight piece - if( ( cp3 == Math3D::vector3() ) - && ( cp4 == Math3D::vector3() ) ) { + if ((cp3 == glm::dvec3()) && (cp4 == glm::dvec3())) + { segsize = 10.0; // for straights, 10m per segment works good enough } else { // HACK: divide roughly in 10 segments. segsize = clamp( - ( p3 - p4 ).Length() * 0.1, + glm::length( p3 - p4 ) * 0.1, 2.0 / Global.SplineFidelity, 10.0 / Global.SplineFidelity ); } } - if( ( cp3 == Math3D::vector3( 0, 0, 0 ) ) - && ( cp4 == Math3D::vector3( 0, 0, 0 ) ) ) { + if ((cp3 == glm::dvec3()) && (cp4 == glm::dvec3())) + { // Ra: hm, czasem dla prostego są podane... // gdy prosty, kontrolne wyliczane przy zmiennej przechyłce SwitchExtension->Segments[ 1 ]->Init( p3, p4, segsize, r3, r4 ); @@ -770,7 +769,8 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) if (eType == tt_Cross) { // Ra 2014-07: dla skrzyżowań będą dodatkowe segmenty SwitchExtension->Segments[2]->Init(p2, cp2 + p2, cp4 + p4, p4, segsize, r2, r4); // z punktu 2 do 4 - if (LengthSquared3(p3 - p1) < 0.01) // gdy mniej niż 10cm, to mamy skrzyżowanie trzech dróg + auto p1p3 = p3 - p1; + if (glm::dot(p1p3, p1p3) < 0.01) // gdy mniej niż 10cm, to mamy skrzyżowanie trzech dróg SwitchExtension->iRoads = 3; else // dla 4 dróg będą dodatkowe 3 segmenty { @@ -785,7 +785,7 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) if( eType == tt_Switch ) // Ra: zamienić później na iloczyn wektorowy { - Math3D::vector3 v1, v2; + glm::dvec3 v1, v2; double a1, a2; v1 = SwitchExtension->Segments[0]->FastGetPoint_1() - SwitchExtension->Segments[0]->FastGetPoint_0(); @@ -1517,14 +1517,14 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) { case tt_Cross: // skrzyżowanie dróg rysujemy inaczej { // ustalenie współrzędnych środka - przecięcie Point1-Point2 z CV4-Point4 double a[4]; // kąty osi ulic wchodzących - Math3D::vector3 p[4]; // punkty się przydadzą do obliczeń + glm::dvec3 p[4]; // punkty się przydadzą do obliczeń // na razie połowa odległości pomiędzy Point1 i Point2, potem się dopracuje a[0] = a[1] = 0.5; // parametr do poszukiwania przecięcia łuków // modyfikować a[0] i a[1] tak, aby trafić na przecięcie odcinka 34 p[0] = SwitchExtension->Segments[0]->FastGetPoint(a[0]); // współrzędne środka pierwszego odcinka p[1] = SwitchExtension->Segments[1]->FastGetPoint(a[1]); //-//- drugiego // p[2]=p[1]-p[0]; //jeśli różne od zera, przeliczyć a[0] i a[1] i wyznaczyć nowe punkty - Math3D::vector3 oxz = p[0]; // punkt mapowania środka tekstury skrzyżowania + glm::dvec3 oxz = p[0]; // punkt mapowania środka tekstury skrzyżowania p[0] = SwitchExtension->Segments[0]->GetDirection1(); // Point1 - pobranie wektorów kontrolnych p[1] = SwitchExtension->Segments[1]->GetDirection2(); // Point3 (bo zamienione) p[2] = SwitchExtension->Segments[0]->GetDirection2(); // Point2 @@ -2042,9 +2042,7 @@ TTrack * TTrack::RaAnimate() cosa = -hlen * std::cos( glm::radians( SwitchExtension->fOffset ) ); SwitchExtension->vTrans = ac->TransGet(); auto middle = location() + SwitchExtension->vTrans; // SwitchExtension->Segments[0]->FastGetPoint(0.5); - Segment->Init( - middle + Math3D::vector3( sina, 0.0, cosa ), - middle - Math3D::vector3( sina, 0.0, cosa ), + Segment->Init(middle + glm::dvec3(sina, 0.0, cosa), middle - glm::dvec3(sina, 0.0, cosa), 10.0 ); // nowy odcinek for( auto dynamic : Dynamics ) { // minimalny ruch, aby przeliczyć pozycję @@ -2086,7 +2084,7 @@ bool TTrack::IsGroupable() return true; }; -bool Equal( Math3D::vector3 v1, Math3D::vector3 *v2) +bool Equal(glm::dvec3 v1, glm::dvec3 *v2) { // sprawdzenie odległości punktów // Ra: powinno być do 100cm wzdłuż toru i ze 2cm w poprzek (na prostej może nie być długiego // kawałka) @@ -2101,7 +2099,7 @@ bool Equal( Math3D::vector3 v1, Math3D::vector3 *v2) // return (SquareMagnitude(v1-*v2)<0.00012); //0.011^2=0.00012 }; -int TTrack::TestPoint( Math3D::vector3 *Point) +int TTrack::TestPoint(glm::dvec3 *Point) { // sprawdzanie, czy tory można połączyć switch (eType) { diff --git a/world/Track.h b/world/Track.h index ffc622db..04d78496 100644 --- a/world/Track.h +++ b/world/Track.h @@ -92,7 +92,7 @@ class TSwitchExtension basic_event *evPlus = nullptr, *evMinus = nullptr; // zdarzenia sygnalizacji rozprucia float fVelocity = -1.0; // maksymalne ograniczenie prędkości (ustawianej eventem) - Math3D::vector3 vTrans; // docelowa translacja przesuwnicy + glm::dvec3 vTrans; // docelowa translacja przesuwnicy material_handle m_material3 = 0; // texture of auto generated switch trackbed gfx::geometry_handle Geometry3; // geometry of auto generated switch trackbed @@ -308,7 +308,7 @@ public: } double WidthTotal(); bool IsGroupable(); - int TestPoint( Math3D::vector3 *Point); + int TestPoint(glm::dvec3 *Point); void MovedUp1(float const dh); void VelocitySet(float v); double VelocityGet(); diff --git a/world/TrkFoll.h b/world/TrkFoll.h index 3bcea7ae..7276fcd4 100644 --- a/world/TrkFoll.h +++ b/world/TrkFoll.h @@ -44,9 +44,9 @@ public: void Render(float fNr); // members double fOffsetH = 0.0; // Ra: odległość środka osi od osi toru (dla samochodów) - użyć do wężykowania - Math3D::vector3 pPosition; // współrzędne XYZ w układzie scenerii - Math3D::vector3 vAngles; // x:przechyłka, y:pochylenie, z:kierunek w planie (w radianach) -private: + glm::dvec3 pPosition; // współrzędne XYZ w układzie scenerii + glm::dvec3 vAngles; // x:przechyłka, y:pochylenie, z:kierunek w planie (w radianach) + private: // methods bool ComputatePosition(); // przeliczenie pozycji na torze // members From b712ca4d68f8d91e82d15fbeaf793d28150e1449 Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Mon, 27 Apr 2026 00:41:45 +0200 Subject: [PATCH 09/19] lengthSquared should be changed to glm::dot, not glm::length --- model/AnimModel.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/model/AnimModel.cpp b/model/AnimModel.cpp index ff7dbf91..be872a6f 100644 --- a/model/AnimModel.cpp +++ b/model/AnimModel.cpp @@ -96,14 +96,14 @@ void TAnimContainer::UpdateModel() { if (fTranslateSpeed != 0.0) { auto dif = vTranslateTo - vTranslation; // wektor w kierunku docelowym - double l = glm::length(dif); // długość wektora potrzebnego przemieszczenia - if (l >= 0.0001) + double l2 = glm::dot(dif, dif); // długość wektora potrzebnego przemieszczenia + if (l2 >= 0.0001) { // jeśli do przemieszczenia jest ponad 1cm auto s = glm::normalize(dif); // jednostkowy wektor kierunku // Długość wektora nie jest równa 0, sprawdzane wcześniej więc wektor normalny będzie zawsze prawidłowy. s = s * (fTranslateSpeed * Timer::GetDeltaTime()); // przemieszczenie w podanym czasie z daną prędkością - if (glm::length(s) < l) //żeby nie jechało na drugą stronę + if (glm::dot(s, s) < l2) //żeby nie jechało na drugą stronę vTranslation += s; else vTranslation = vTranslateTo; // koniec animacji, "koniec animowania" uruchomi @@ -113,7 +113,7 @@ void TAnimContainer::UpdateModel() { { // koniec animowania vTranslation = vTranslateTo; fTranslateSpeed = 0.0; // wyłączenie przeliczania wektora - if (glm::length(vTranslation) <= 0.0001) // jeśli jest w punkcie początkowym + if (glm::dot(vTranslation, vTranslation) <= 0.0001) // jeśli jest w punkcie początkowym iAnim &= ~2; // wyłączyć zmianę pozycji submodelu if( evDone ) { // wykonanie eventu informującego o zakończeniu From fae68642bc48503e448a67534eb311bde5d68cba Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Mon, 27 Apr 2026 13:07:38 +0200 Subject: [PATCH 10/19] use glm instead of Math3D in vehicle WARNING: Model rotation is broken --- application/drivermode.cpp | 20 ++++----- application/editormode.cpp | 6 +-- audio/sound.cpp | 6 +-- rendering/lightarray.cpp | 4 +- rendering/opengl33renderer.cpp | 10 ++--- rendering/openglrenderer.cpp | 8 ++-- scene/scene.cpp | 22 +++++----- utilities/dumb3d.cpp | 7 ++++ utilities/dumb3d.h | 21 ++++++++++ vehicle/Camera.cpp | 4 +- vehicle/Driver.cpp | 13 +++--- vehicle/Driver.h | 4 +- vehicle/DynObj.cpp | 77 +++++++++++++++++----------------- vehicle/DynObj.h | 48 ++++++++++----------- vehicle/Train.cpp | 36 ++++++++-------- vehicle/Train.h | 22 +++++----- 16 files changed, 168 insertions(+), 140 deletions(-) diff --git a/application/drivermode.cpp b/application/drivermode.cpp index cd03e68c..51c31a7c 100644 --- a/application/drivermode.cpp +++ b/application/drivermode.cpp @@ -569,7 +569,7 @@ void driver_mode::update_camera(double const Deltatime) Camera.Reset(); // likwidacja obrotów - patrzy horyzontalnie na południe if (Camera.m_owner == nullptr) { - if (controlled && LengthSquared3(controlled->GetPosition() - Camera.Pos) < (1500 * 1500)) + if (controlled && glm::length(controlled->GetPosition() - Camera.Pos) < 1500) { // gdy bliżej niż 1.5km Camera.LookAt = controlled->GetPosition() + 0.4 * controlled->VectorUp() * controlled->MoverParameters->Dim.H; @@ -583,7 +583,7 @@ void driver_mode::update_camera(double const Deltatime) if (d && pDynamicNearest) { // jeśli jakiś jest znaleziony wcześniej - if (100.0 * LengthSquared3(d->GetPosition() - Camera.Pos) > LengthSquared3(pDynamicNearest->GetPosition() - Camera.Pos)) + if (100.0 * glm::length(d->GetPosition() - Camera.Pos) > glm::length(pDynamicNearest->GetPosition() - Camera.Pos)) { d = pDynamicNearest; // jeśli najbliższy nie jest 10 razy bliżej niż } @@ -692,12 +692,12 @@ void driver_mode::update_camera(double const Deltatime) else if (Global.shiftState) { // patrzenie w bok przez szybę - Camera.LookAt = Camera.Pos - (lr ? -1 : 1) * controlled->VectorLeft() * simulation::Train->Occupied()->CabOccupied; + Camera.LookAt = Camera.Pos - (lr ? -1.0 : 1.0) * controlled->VectorLeft() * (double)simulation::Train->Occupied()->CabOccupied; } else { // patrzenie w kierunku osi pojazdu, z uwzględnieniem kabiny - jakby z lusterka, // ale bez odbicia - Camera.LookAt = Camera.Pos - simulation::Train->GetDirection() * simulation::Train->Occupied()->CabOccupied; //-1 albo 1 + Camera.LookAt = Camera.Pos - simulation::Train->GetDirection() * (double)simulation::Train->Occupied()->CabOccupied; //-1 albo 1 } auto const shakeangles{simulation::Train->Dynamic()->shake_angles()}; Camera.Angle.x = 0.5 * shakeangles.second; // hustanie kamery przod tyl @@ -723,7 +723,7 @@ void driver_mode::update_camera(double const Deltatime) auto shakencamerapos{Camera.m_owneroffset + shakescale * glm::vec3(1.5 * Camera.m_owner->ShakeState.offset.x, 2.0 * Camera.m_owner->ShakeState.offset.y, 1.5 * Camera.m_owner->ShakeState.offset.z)}; - Camera.Pos = (Camera.m_owner->GetWorldPosition(FreeFlyModeFlag ? Math3D::vector3(shakencamerapos) : // TODO: vehicle collision box for the external vehicle camera + Camera.Pos = (Camera.m_owner->GetWorldPosition(FreeFlyModeFlag ? glm::dvec3(shakencamerapos) : // TODO: vehicle collision box for the external vehicle camera simulation::Train->clamp_inside(shakencamerapos))); if (!Global.iPause) @@ -758,7 +758,7 @@ void driver_mode::update_camera(double const Deltatime) else { // patrzenie w kierunku osi pojazdu, z uwzględnieniem kabiny - Camera.LookAt = Camera.m_owner->GetWorldPosition(Camera.m_owneroffset) + Camera.m_owner->VectorFront() * 5.0 * simulation::Train->Occupied()->CabOccupied; //-1 albo 1 + Camera.LookAt = Camera.m_owner->GetWorldPosition(Camera.m_owneroffset) + Camera.m_owner->VectorFront() * 5.0 * (double)simulation::Train->Occupied()->CabOccupied; //-1 albo 1 } Camera.vUp = simulation::Train->GetUp(); } @@ -1053,17 +1053,17 @@ void driver_mode::DistantView(bool const Near) } auto const cab = (vehicle->MoverParameters->CabOccupied == 0 ? 1 : vehicle->MoverParameters->CabOccupied); - auto const left = vehicle->VectorLeft() * cab; + auto const left = vehicle->VectorLeft() * (double)cab; if (true == Near) { - Camera.Pos = glm::vec3(Camera.Pos.x, vehicle->GetPosition().y, Camera.Pos.z) + left * vehicle->GetWidth() + glm::vec3(1.25 * left.x, 1.6, 1.25 * left.z); + Camera.Pos = glm::dvec3(Camera.Pos.x, vehicle->GetPosition().y, Camera.Pos.z) + left * vehicle->GetWidth() + glm::dvec3(1.25 * left.x, 1.6, 1.25 * left.z); } else { - Camera.Pos = vehicle->GetPosition() + vehicle->VectorFront() * vehicle->MoverParameters->CabOccupied * 50.0 + glm::vec3(-10.0 * left.x, 1.6, -10.0 * left.z); + Camera.Pos = vehicle->GetPosition() + vehicle->VectorFront() * (double)vehicle->MoverParameters->CabOccupied * 50.0 + glm::dvec3(-10.0 * left.x, 1.6, -10.0 * left.z); } Camera.m_owner = nullptr; @@ -1237,7 +1237,7 @@ void driver_mode::CabView() else { // patrz w strone wlasciwej kabiny - Camera.LookAt = Camera.m_owner->GetWorldPosition(Camera.m_owneroffset) + Camera.m_owner->VectorFront() * 5.0 * Camera.m_owner->MoverParameters->CabOccupied; + Camera.LookAt = Camera.m_owner->GetWorldPosition(Camera.m_owneroffset) + Camera.m_owner->VectorFront() * 5.0 * (double)Camera.m_owner->MoverParameters->CabOccupied; } train->pMechOffset = Camera.m_owneroffset; } diff --git a/application/editormode.cpp b/application/editormode.cpp index bd5f987f..14ace793 100644 --- a/application/editormode.cpp +++ b/application/editormode.cpp @@ -510,9 +510,9 @@ void editor_mode::enter() auto const *vehicle = Camera.m_owner; if (vehicle) { - auto const cab = (vehicle->MoverParameters->CabOccupied == 0 ? 1 : vehicle->MoverParameters->CabOccupied); - auto const left = vehicle->VectorLeft() * cab; - Camera.Pos = glm::vec3(Camera.Pos.x, vehicle->GetPosition().y, Camera.Pos.z) + left * vehicle->GetWidth() + glm::vec3(1.25f * left.x, 1.6f, 1.25f * left.z); + const int cab = (vehicle->MoverParameters->CabOccupied == 0 ? 1 : vehicle->MoverParameters->CabOccupied); + const glm::dvec3 left = vehicle->VectorLeft() * (double)cab; + Camera.Pos = glm::dvec3(Camera.Pos.x, vehicle->GetPosition().y, Camera.Pos.z) + left * vehicle->GetWidth() + glm::dvec3(1.25f * left.x, 1.6f, 1.25f * left.z); Camera.m_owner = nullptr; Camera.LookAt = vehicle->GetPosition(); Camera.RaLook(); // single camera reposition diff --git a/audio/sound.cpp b/audio/sound.cpp index 77e6c9c2..715da729 100644 --- a/audio/sound.cpp +++ b/audio/sound.cpp @@ -928,9 +928,9 @@ sound_source::location() const { // otherwise combine offset with the location of the carrier return { m_owner->GetPosition() - + m_owner->VectorLeft() * m_offset.x - + m_owner->VectorUp() * m_offset.y - + m_owner->VectorFront() * m_offset.z }; + + m_owner->VectorLeft() * (double)m_offset.x + + m_owner->VectorUp() * (double)m_offset.y + + m_owner->VectorFront() * (double)m_offset.z }; } void diff --git a/rendering/lightarray.cpp b/rendering/lightarray.cpp index db6097f8..41bff159 100644 --- a/rendering/lightarray.cpp +++ b/rendering/lightarray.cpp @@ -46,12 +46,12 @@ light_array::update() { if( light.index == end::front ) { // front light set light.position = light.owner->GetPosition() + ( light.owner->VectorFront() * ( std::max( 0.0, light.owner->GetLength() * 0.5 - 2.0 ) ) );// +( light.owner->VectorUp() * 0.25 ); - light.direction = glm::make_vec3( light.owner->VectorFront().getArray() ); + light.direction = glm::make_vec3( glm::value_ptr(light.owner->VectorFront()) ); // TODO: It is needed to get value_ptr and then make_vec3? } else { // rear light set light.position = light.owner->GetPosition() - ( light.owner->VectorFront() * ( std::max( 0.0, light.owner->GetLength() * 0.5 - 2.0 ) ) );// +( light.owner->VectorUp() * 0.25 ); - light.direction = glm::make_vec3( light.owner->VectorFront().getArray() ); + light.direction = glm::make_vec3( glm::value_ptr(light.owner->VectorFront()) ); // TODO: It is needed to get value_ptr and then make_vec3? light.direction.x = -light.direction.x; light.direction.z = -light.direction.z; } diff --git a/rendering/opengl33renderer.cpp b/rendering/opengl33renderer.cpp index 44a0c7a5..9b1de506 100644 --- a/rendering/opengl33renderer.cpp +++ b/rendering/opengl33renderer.cpp @@ -1203,7 +1203,7 @@ bool opengl33_renderer::Render_lowpoly( TDynamicObject *Dynamic, float const Squ ::glPushMatrix(); ::glTranslated( originoffset.x, originoffset.y, originoffset.z ); - ::glMultMatrixd( Dynamic->mMatrix.readArray() ); + ::glMultMatrixd( glm::value_ptr(Dynamic->mMatrix) ); } // HACK: reduce light level for vehicle interior if there's strong global lighting source if( false == Alpha ) { @@ -2890,7 +2890,7 @@ bool opengl33_renderer::Render(TDynamicObject *Dynamic) ::glPushMatrix(); ::glTranslated(originoffset.x, originoffset.y, originoffset.z); - ::glMultMatrixd(Dynamic->mMatrix.getArray()); + ::glMultMatrixd(glm::value_ptr(Dynamic->mMatrix)); switch (m_renderpass.draw_mode) { @@ -3012,7 +3012,7 @@ bool opengl33_renderer::Render_cab(TDynamicObject const *Dynamic, float const Li auto const originoffset = Dynamic->GetPosition() - m_renderpass.pass_camera.position(); ::glTranslated(originoffset.x, originoffset.y, originoffset.z); - ::glMultMatrixd(Dynamic->mMatrix.readArray()); + ::glMultMatrixd(glm::value_ptr(Dynamic->mMatrix)); switch (m_renderpass.draw_mode) { @@ -3908,7 +3908,7 @@ bool opengl33_renderer::Render_Alpha(TDynamicObject *Dynamic) ::glPushMatrix(); ::glTranslated(originoffset.x, originoffset.y, originoffset.z); - ::glMultMatrixd(Dynamic->mMatrix.getArray()); + ::glMultMatrixd(glm::value_ptr(Dynamic->mMatrix)); if (Dynamic->fShade > 0.0f) { @@ -4665,7 +4665,7 @@ void opengl33_renderer::Update_Lights(light_array &Lights) auto const offset{ 75.f * ( 5.f / cone ) }; headlights.position() = scenelight.owner->GetPosition() - - scenelight.direction * offset + - glm::dvec3(scenelight.direction * offset) + up * ( size * 0.5 ); /* headlights.projection() = ortho_projection( diff --git a/rendering/openglrenderer.cpp b/rendering/openglrenderer.cpp index 0f0b9bbf..2ad18574 100644 --- a/rendering/openglrenderer.cpp +++ b/rendering/openglrenderer.cpp @@ -806,7 +806,7 @@ bool opengl_renderer::Render_lowpoly( TDynamicObject *Dynamic, float const Squar ::glPushMatrix(); ::glTranslated( originoffset.x, originoffset.y, originoffset.z ); - ::glMultMatrixd( Dynamic->mMatrix.getArray() ); + ::glMultMatrixd( glm::value_ptr(Dynamic->mMatrix) ); m_renderspecular = true; // vehicles are rendered with specular component. static models without, at least for the time being } @@ -2480,7 +2480,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) { ::glPushMatrix(); ::glTranslated( originoffset.x, originoffset.y, originoffset.z ); - ::glMultMatrixd( Dynamic->mMatrix.getArray() ); + ::glMultMatrixd( glm::value_ptr(Dynamic->mMatrix) ); switch( m_renderpass.draw_mode ) { @@ -2593,7 +2593,7 @@ opengl_renderer::Render_cab( TDynamicObject const *Dynamic, float const Lightlev auto const originoffset = Dynamic->GetPosition() - m_renderpass.camera.position(); ::glTranslated( originoffset.x, originoffset.y, originoffset.z ); - ::glMultMatrixd( Dynamic->mMatrix.readArray() ); + ::glMultMatrixd( glm::value_ptr(Dynamic->mMatrix) ); switch( m_renderpass.draw_mode ) { case rendermode::color: { @@ -3675,7 +3675,7 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) { ::glPushMatrix(); ::glTranslated( originoffset.x, originoffset.y, originoffset.z ); - ::glMultMatrixd( Dynamic->mMatrix.getArray() ); + ::glMultMatrixd( glm::value_ptr(Dynamic->mMatrix) ); if( Dynamic->fShade > 0.0f ) { // change light level based on light level of the occupied track diff --git a/scene/scene.cpp b/scene/scene.cpp index 12971b73..99617a67 100644 --- a/scene/scene.cpp +++ b/scene/scene.cpp @@ -46,9 +46,10 @@ basic_cell::on_click( TAnimModel const *Instance ) { void basic_cell::update_traction( TDynamicObject *Vehicle, int const Pantographindex ) { // Winger 170204 - szukanie trakcji nad pantografami - auto const vFront = glm::make_vec3( Vehicle->VectorFront().getArray() ); // wektor normalny dla płaszczyzny ruchu pantografu - auto const vUp = glm::make_vec3( Vehicle->VectorUp().getArray() ); // wektor pionu pudła (pochylony od pionu na przechyłce) - auto const vLeft = glm::make_vec3( Vehicle->VectorLeft().getArray() ); // wektor odległości w bok (odchylony od poziomu na przechyłce) + // TODO: Why glm::make_vec3 and glm::value_ptr? + auto const vFront = glm::make_vec3( glm::value_ptr(Vehicle->VectorFront()) ); // wektor normalny dla płaszczyzny ruchu pantografu + auto const vUp = glm::make_vec3( glm::value_ptr(Vehicle->VectorUp()) ); // wektor pionu pudła (pochylony od pionu na przechyłce) + auto const vLeft = glm::make_vec3( glm::value_ptr(Vehicle->VectorLeft()) ); // wektor odległości w bok (odchylony od poziomu na przechyłce) auto const position = glm::dvec3 { Vehicle->GetPosition() }; // współrzędne środka pojazdu auto pantograph = Vehicle->pants[ Pantographindex ].fParamPants; @@ -689,10 +690,10 @@ basic_section::on_click( TAnimModel const *Instance ) { // legacy method, finds and assigns traction piece(s) to pantographs of provided vehicle void basic_section::update_traction( TDynamicObject *Vehicle, int const Pantographindex ) { - - auto const vFront = glm::make_vec3( Vehicle->VectorFront().getArray() ); // wektor normalny dla płaszczyzny ruchu pantografu - auto const vUp = glm::make_vec3( Vehicle->VectorUp().getArray() ); // wektor pionu pudła (pochylony od pionu na przechyłce) - auto const vLeft = glm::make_vec3( Vehicle->VectorLeft().getArray() ); // wektor odległości w bok (odchylony od poziomu na przechyłce) + // TODO: Why glm::make_vec3 and glm::value_ptr? + auto const vFront = glm::make_vec3( glm::value_ptr(Vehicle->VectorFront()) ); // wektor normalny dla płaszczyzny ruchu pantografu + auto const vUp = glm::make_vec3( glm::value_ptr(Vehicle->VectorUp()) ); // wektor pionu pudła (pochylony od pionu na przechyłce) + auto const vLeft = glm::make_vec3( glm::value_ptr(Vehicle->VectorLeft()) ); // wektor odległości w bok (odchylony od poziomu na przechyłce) auto const position = glm::dvec3{ Vehicle->GetPosition() }; // współrzędne środka pojazdu auto pantograph = Vehicle->pants[ Pantographindex ].fParamPants; @@ -1058,9 +1059,10 @@ basic_region::update_sounds() { void basic_region::update_traction( TDynamicObject *Vehicle, int const Pantographindex ) { // TODO: convert vectors to transformation matrix and pass them down the chain along with calculated position - auto const vFront = glm::make_vec3( Vehicle->VectorFront().getArray() ); // wektor normalny dla płaszczyzny ruchu pantografu - auto const vUp = glm::make_vec3( Vehicle->VectorUp().getArray() ); // wektor pionu pudła (pochylony od pionu na przechyłce) - auto const vLeft = glm::make_vec3( Vehicle->VectorLeft().getArray() ); // wektor odległości w bok (odchylony od poziomu na przechyłce) + // TODO: Why glm::make_vec3 and glm::value_ptr? + auto const vFront = glm::make_vec3( glm::value_ptr(Vehicle->VectorFront()) ); // wektor normalny dla płaszczyzny ruchu pantografu + auto const vUp = glm::make_vec3( glm::value_ptr(Vehicle->VectorUp()) ); // wektor pionu pudła (pochylony od pionu na przechyłce) + auto const vLeft = glm::make_vec3( glm::value_ptr(Vehicle->VectorLeft()) ); // wektor odległości w bok (odchylony od poziomu na przechyłce) auto const position = glm::dvec3 { Vehicle->GetPosition() }; // współrzędne środka pojazdu auto p = Vehicle->pants[ Pantographindex ].fParamPants; diff --git a/utilities/dumb3d.cpp b/utilities/dumb3d.cpp index 14dd9e17..0693d1a3 100644 --- a/utilities/dumb3d.cpp +++ b/utilities/dumb3d.cpp @@ -34,6 +34,13 @@ glm::vec3 RotateY(glm::vec3 v, float angle) return glm::vec3(c * v.x + s * v.z, v.y, c * v.z - s * v.x); } +glm::dvec3 RotateY(glm::dvec3 v, double angle) +{ + double s = sin(angle); + double c = cos(angle); + + return glm::vec3(c * v.x + s * v.z, v.y, c * v.z - s * v.x); +} void vector3::RotateZ(double angle) { diff --git a/utilities/dumb3d.h b/utilities/dumb3d.h index 30560a4f..19075cd4 100644 --- a/utilities/dumb3d.h +++ b/utilities/dumb3d.h @@ -15,6 +15,27 @@ namespace Math3D { glm::vec3 RotateY(glm::vec3 v, float angle); + glm::dvec3 RotateY(glm::dvec3 v, double angle); + + inline glm::dmat4 BasisChange(glm::dvec3 u, glm::dvec3 v, glm::dvec3 n) + { + glm::dmat4 M(1.0); + + M[0] = glm::dvec4(u, 0.0); // kolumna 0 + M[1] = glm::dvec4(v, 0.0); // kolumna 1 + M[2] = glm::dvec4(n, 0.0); // kolumna 2 + M[3] = glm::dvec4(0.0, 0.0, 0.0, 1.0); // kolumna 3 + + return M; + } + + inline glm::dmat4 BasisChange(glm::dvec3 v, glm::dvec3 n) + { + glm::dvec3 u = glm::cross(v, n); + return BasisChange(u, v, n); + } + + // Define this to have Math3D.cp generate a main which tests these classes //#define TEST_MATH3D diff --git a/vehicle/Camera.cpp b/vehicle/Camera.cpp index 248827bf..51f1ca46 100644 --- a/vehicle/Camera.cpp +++ b/vehicle/Camera.cpp @@ -222,12 +222,12 @@ bool TCamera::SetMatrix( glm::dmat4 &Matrix ) { void TCamera::RaLook() { // zmiana kierunku patrzenia - przelicza Yaw - Math3D::vector3 where = glm::dvec3(LookAt )- Pos /*+ Math3D::vector3(0, 3, 0)*/; // trochę w górę od szyn + auto where = glm::dvec3(LookAt )- Pos /*+ Math3D::vector3(0, 3, 0)*/; // trochę w górę od szyn if( ( where.x != 0.0 ) || ( where.z != 0.0 ) ) { Angle.y = atan2( -where.x, -where.z ); // kąt horyzontalny m_rotationoffsets.y = 0.0; } - double l = Math3D::Length3(where); + double l = glm::length(where); if( l > 0.0 ) { Angle.x = asin( where.y / l ); // kąt w pionie m_rotationoffsets.x = 0.0; diff --git a/vehicle/Driver.cpp b/vehicle/Driver.cpp index 765fdebe..d506d624 100644 --- a/vehicle/Driver.cpp +++ b/vehicle/Driver.cpp @@ -198,7 +198,7 @@ void TSpeedPos::Clear() fVelNext = -1.0; // prędkość bez ograniczeń fSectionVelocityDist = 0.0; //brak długości fDist = 0.0; - vPos = Math3D::vector3(0, 0, 0); + vPos = glm::dvec3(0, 0, 0); trTrack = NULL; // brak wskaźnika }; @@ -536,11 +536,10 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) } // account for the fact tracing begins from active axle, not the actual front of the vehicle // NOTE: position of the couplers is modified by track offset, but the axles ain't, so we need to account for this as well - fTrackLength -= ( + fTrackLength -= glm::length( pVehicle->AxlePositionGet() - pVehicle->RearPosition() - + pVehicle->VectorLeft() * pVehicle->MoverParameters->OffsetTrackH ) - .Length(); + + pVehicle->VectorLeft() * pVehicle->MoverParameters->OffsetTrackH ); // aktualna odległość ma być ujemna gdyż jesteśmy na końcu składu fCurrentDistance = -fLength - fTrackLength; fTrackLength = pTrack->Length(); //skasowanie zmian w zmiennej żeby poprawnie liczyło w dalszych krokach @@ -5371,7 +5370,7 @@ basic_event * TController::CheckTrackEventBackward(double fDirection, TTrack *Tr { // sprawdzanie eventu w torze, czy jest sygnałowym - skanowanie do tyłu // NOTE: this method returns only one event which meets the conditions, due to limitations in the caller // TBD, TODO: clean up the caller and return all suitable events, as in theory things will go awry if the track has more than one signal - auto const dir{ Vehicle->VectorFront() * Vehicle->DirectionGet() }; + auto const dir{ Vehicle->VectorFront() * (double)Vehicle->DirectionGet() }; auto const pos{ End == end::front ? Vehicle->RearPosition() : Vehicle->HeadPosition() }; auto const &eventsequence { ( fDirection * Eventdirection > 0 ? Track->m_events2 : Track->m_events1 ) }; for( auto const &event : eventsequence ) { @@ -5512,7 +5511,7 @@ TCommandType TController::BackwardScan( double const Range ) // opcjonalnie może być skanowanie od "wskaźnika" z przodu, np. W5, Tm=Ms1, koniec toru wg // drugiej osi w kierunku ruchu auto const *scantrack{BackwardTraceRoute(scandist, scandir, pVehicles[end::front], e)}; - auto const dir{startdir * + auto const dir{(double)startdir * pVehicles[end::front]->VectorFront()}; // wektor w kierunku jazdy/szukania // jeśli wstecz wykryto koniec toru to raczej nic się nie da w takiej sytuacji zrobić @@ -5548,7 +5547,7 @@ TCommandType TController::BackwardScan( double const Range ) } scanvel = e->input_value(1); // prędkość przy tym semaforze // przeliczamy odległość od semafora - potrzebne by były współrzędne początku składu - scandist = sem.Length() - 2; // 2m luzu przy manewrach wystarczy + scandist = glm::length(sem) - 2; // 2m luzu przy manewrach wystarczy if (scandist < 0) { // ujemnych nie ma po co wysyłać diff --git a/vehicle/Driver.h b/vehicle/Driver.h index e897ba91..40f05ba8 100644 --- a/vehicle/Driver.h +++ b/vehicle/Driver.h @@ -156,7 +156,7 @@ class TSpeedPos int iFlags{ spNone }; // flagi typu wpisu do tabelki bool bMoved{ false }; // czy przesunięty (dotyczy punktu zatrzymania w peronie) double fMoved{ 0.0 }; // ile przesunięty (dotyczy punktu zatrzymania w peronie) - Math3D::vector3 vPos; // współrzędne XYZ do liczenia odległości + glm::dvec3 vPos; // współrzędne XYZ do liczenia odległości struct { TTrack *trTrack{ nullptr }; // wskaźnik na tor o zmiennej prędkości (zwrotnica, obrotnica) @@ -490,7 +490,7 @@ private: std::string Order2Str( TOrders Order ) const; // members std::string m_assignment; - Math3D::vector3 vCommandLocation; // polozenie wskaznika, sygnalizatora lub innego obiektu do ktorego odnosi sie komenda // NOTE: not used + glm::dvec3 vCommandLocation; // polozenie wskaznika, sygnalizatora lub innego obiektu do ktorego odnosi sie komenda // NOTE: not used TOrders OrderList[ maxorders ]; // lista rozkazów int OrderPos = 0, OrderTop = 0; // rozkaz aktualny oraz wolne miejsce do wstawiania nowych diff --git a/vehicle/DynObj.cpp b/vehicle/DynObj.cpp index 8f4a3db5..24a87629 100644 --- a/vehicle/DynObj.cpp +++ b/vehicle/DynObj.cpp @@ -34,9 +34,9 @@ http://mozilla.org/MPL/2.0/. #include "vehicle/Driver.h" // Ra: taki zapis funkcjonuje lepiej, ale może nie jest optymalny -#define vWorldFront Math3D::vector3(0, 0, 1) -#define vWorldUp Math3D::vector3(0, 1, 0) -#define vWorldLeft CrossProduct(vWorldUp, vWorldFront) +#define vWorldFront glm::vec3(0, 0, 1) +#define vWorldUp glm::vec3(0, 1, 0) +#define vWorldLeft glm::cross(vWorldUp, vWorldFront) #define M_2PI 6.283185307179586476925286766559; const float maxrot = (float)(M_PI / 3.0); // 60° @@ -72,7 +72,7 @@ TextureTest( std::string const &Name ) { //--------------------------------------------------------------------------- void TAnimPant::AKP_4E() { // ustawienie wymiarów dla pantografu AKP-4E - vPos = Math3D::vector3(0, 0, 0); // przypisanie domyśnych współczynników do pantografów + vPos = glm::dvec3(0, 0, 0); // przypisanie domyśnych współczynników do pantografów fLenL1 = 1.22; // 1.176289 w modelach fLenU1 = 1.755; // 1.724482197 w modelach fHoriz = 0.535; // 0.54555075 przesunięcie ślizgu w długości pojazdu względem @@ -99,7 +99,7 @@ void TAnimPant::AKP_4E() }; void TAnimPant::WBL85() { // ustawienie wymiarów dla pantografu WBL88 - vPos = Math3D::vector3(0, 0, 0); // przypisanie domyśnych współczynników do pantografów + vPos = glm::dvec3(0, 0, 0); // przypisanie domyśnych współczynników do pantografów // mnozniki animacji ramion dla pantografu WBL88 rd1rf = 1.f; @@ -133,7 +133,7 @@ void TAnimPant::WBL85() }; void TAnimPant::EC160_200() { // ustawienie wymiarów dla pantografow EC160 lub EC200 - vPos = Math3D::vector3(0, 0, 0); // przypisanie domyśnych współczynników do pantografów + vPos = glm::dvec3(0, 0, 0); // przypisanie domyśnych współczynników do pantografów // mnozniki animacji ramion dla pantografow EC160 lub EC200 rd1rf = 1.f; @@ -167,7 +167,7 @@ void TAnimPant::EC160_200() }; void TAnimPant::DSAx() { // ustawienie wymiarów dla pantografow z rodziny DSA - vPos = Math3D::vector3(0, 0, 0); // przypisanie domyśnych współczynników do pantografów + vPos = glm::dvec3(0, 0, 0); // przypisanie domyśnych współczynników do pantografów // mnozniki animacji ramion dla pantografow z rodziny DSA rd1rf = 1.f; @@ -504,7 +504,7 @@ TDynamicObject * TDynamicObject::GetFirstDynamic(int cpl_type, int cf) return FirstFind(cpl_type, cf); // używa referencji }; -void TDynamicObject::ABuSetModelShake( Math3D::vector3 mShake ) +void TDynamicObject::ABuSetModelShake(glm::dvec3 mShake) { modelShake = mShake; }; @@ -619,7 +619,7 @@ void TDynamicObject::UpdateDoorTranslate(TAnim *pAnim) { side::left ) ] }; pAnim->smAnimated->SetTranslate( - Math3D::vector3{ + glm::vec3{ 0.0, 0.0, door.position } ); @@ -683,7 +683,7 @@ void TDynamicObject::UpdateDoorPlug(TAnim *pAnim) { side::left ) ] }; pAnim->smAnimated->SetTranslate( - Math3D::vector3 { + glm::vec3{ std::min( door.position * 2.f, MoverParameters->Doors.range_out ), @@ -722,7 +722,7 @@ void TDynamicObject::UpdatePlatformTranslate( TAnim *pAnim ) { side::left ) ] }; pAnim->smAnimated->SetTranslate( - Math3D::vector3{ + glm::vec3{ interpolate( 0.f, MoverParameters->Doors.step_range, door.step_position ), 0.0, 0.0 } ); @@ -1081,10 +1081,10 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist) if( dist >= 0.0 ) { continue; } if( smBuforLewy[ i ] ) { - smBuforLewy[ i ]->SetTranslate( Math3D::vector3( dist, 0, 0 ) ); + smBuforLewy[ i ]->SetTranslate( glm::vec3( dist, 0, 0 ) ); } if( smBuforPrawy[ i ] ) { - smBuforPrawy[ i ]->SetTranslate( Math3D::vector3( dist, 0, 0 ) ); + smBuforPrawy[ i ]->SetTranslate( glm::vec3( dist, 0, 0 ) ); } } } // vehicle within 50m @@ -1411,19 +1411,20 @@ TDynamicObject * TDynamicObject::ABuFindNearestObject(glm::vec3 pos, TTrack *Tra if( CouplNr == -2 ) { // wektor [kamera-obiekt] - poszukiwanie obiektu - if( Math3D::LengthSquared3( pos - dynamic->vPosition ) < 100.0 ) { + if (glm::length(glm::dvec3(pos) - dynamic->vPosition) < 10.0) + { // 10 metrów return dynamic; } } else { // jeśli (CouplNr) inne niz -2, szukamy sprzęgu - if( Math3D::LengthSquared3( pos - dynamic->vCoulpler[ 0 ] ) < 25.0 ) { + if (glm::length(glm::dvec3(pos) - dynamic->vCoulpler[0]) < 5.0) { // 5 metrów CouplNr = 0; return dynamic; } - if( Math3D::LengthSquared3( pos - dynamic->vCoulpler[ 1 ] ) < 25.0 ) { + if (glm::length(glm::dvec3(pos) - dynamic->vCoulpler[1]) < 5.0) { // 5 metrów CouplNr = 1; return dynamic; @@ -1860,7 +1861,7 @@ TDynamicObject::remove_coupler_adapter( int const Side ) { } TDynamicObject::TDynamicObject() { - modelShake = Math3D::vector3(0, 0, 0); + modelShake = glm::dvec3(0, 0, 0); // fTrackBlock = 10000.0; // brak przeszkody na drodze btnOn = false; vUp = vWorldUp; @@ -1897,8 +1898,8 @@ TDynamicObject::TDynamicObject() { smBuforLewy[0] = smBuforLewy[1] = NULL; smBuforPrawy[0] = smBuforPrawy[1] = NULL; smBogie[0] = smBogie[1] = NULL; - bogieRot[0] = bogieRot[1] = Math3D::vector3(0, 0, 0); - modelRot = Math3D::vector3(0, 0, 0); + bogieRot[0] = bogieRot[1] = glm::dvec3(0, 0, 0); + modelRot = glm::dvec3(0, 0, 0); cp1 = cp2 = sp1 = sp2 = 0; iDirection = 1; // stoi w kierunku tradycyjnym (0, gdy jest odwrócony) iAxleFirst = 0; // numer pierwszej osi w kierunku ruchu (przełączenie @@ -2545,7 +2546,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424" // potem juz liczona prawidlowa wartosc masy MoverParameters->ComputeConstans(); // wektor podłogi dla wagonów, przesuwa ładunek - vFloor = Math3D::vector3(0, 0, MoverParameters->Floor); + vFloor = glm::dvec3(0, 0, MoverParameters->Floor); // długość większa od zera oznacza OK; 2mm docisku? return MoverParameters->Dim.L; @@ -2669,7 +2670,7 @@ void TDynamicObject::Move(double fDistance) vFront = Axle0.pPosition - Axle1.pPosition; // wektor pomiędzy skrajnymi osiami // Ra 2F1J: to nie jest stabilne (powoduje rzucanie taborem) i wymaga // dopracowania - fAdjustment = vFront.Length() - fAxleDist; // na łuku będzie ujemny + fAdjustment = glm::length(vFront) - fAxleDist; // na łuku będzie ujemny // if (fabs(fAdjustment)>0.02) //jeśli jest zbyt dużo, to rozłożyć na kilka przeliczeń (wygasza drgania?) //{//parę centymetrów trzeba by już skorygować; te błędy mogą się też // generować na ostrych łukach @@ -2677,27 +2678,25 @@ void TDynamicObject::Move(double fDistance) //} // else // fAdjustment=0.0; - vFront = Normalize(vFront); // kierunek ustawienia pojazdu (wektor jednostkowy) - vLeft = Normalize(CrossProduct(vWorldUp, vFront)); // wektor poziomy w lewo, + vFront = glm::normalize(vFront); // kierunek ustawienia pojazdu (wektor jednostkowy) + vLeft = glm::normalize(glm::cross(glm::dvec3(vWorldUp), vFront)); // wektor poziomy w lewo, // normalizacja potrzebna z powodu pochylenia (vFront) - vUp = CrossProduct(vFront, vLeft); // wektor w górę, będzie jednostkowy + vUp = glm::cross(vFront, vLeft); // wektor w górę, będzie jednostkowy modelRot.z = atan2(-vFront.x, vFront.z); // kąt obrotu pojazdu [rad]; z ABuBogies() auto const roll { Roll() }; // suma przechyłek if (roll != 0.0) { // wyznaczanie przechylenia tylko jeśli jest przechyłka // można by pobrać wektory normalne z toru... - mMatrix.Identity(); // ta macierz jest potrzebna głównie do wyświetlania - mMatrix.Rotation(roll * 0.5, vFront); // obrót wzdłuż osi o przechyłkę - vUp = mMatrix * vUp; // wektor w górę pojazdu (przekręcenie na przechyłce) + mMatrix = glm::rotate(glm::dmat4(1.0), roll * 0.5, vFront); // ta macierz jest potrzebna głównie do wyświetlania // obrót wzdłuż osi o przechyłkę + vUp = glm::dvec3(mMatrix * glm::dvec4(vUp, 0.0)); // wektor w górę pojazdu (przekręcenie na przechyłce) // vLeft=mMatrix*DynamicObject->vLeft; // vUp=CrossProduct(vFront,vLeft); //wektor w górę // vLeft=Normalize(CrossProduct(vWorldUp,vFront)); //wektor w lewo - vLeft = Normalize(CrossProduct(vUp, vFront)); // wektor w lewo + vLeft = glm::normalize(glm::cross(vUp, vFront)); // wektor w lewo // vUp=CrossProduct(vFront,vLeft); //wektor w górę } - mMatrix.Identity(); // to też można by od razu policzyć, ale potrzebne jest do wyświetlania - mMatrix.BasisChange(vLeft, vUp, vFront); // przesuwanie jest jednak rzadziej niż renderowanie - mMatrix = Inverse(mMatrix); // wyliczenie macierzy dla pojazdu (potrzebna tylko do wyświetlania?) + mMatrix = Math3D::BasisChange(vLeft, vUp, vFront); // to też można by od razu policzyć, ale potrzebne jest do wyświetlania // przesuwanie jest jednak rzadziej niż renderowanie + mMatrix = glm::inverse(mMatrix); // wyliczenie macierzy dla pojazdu (potrzebna tylko do wyświetlania?) // if (MoverParameters->CategoryFlag&2) { // przesunięcia są używane po wyrzuceniu pociągu z toru vPosition.x += MoverParameters->OffsetTrackH * vLeft.x; // dodanie przesunięcia w bok @@ -8075,7 +8074,7 @@ TDynamicObject::update_shake( double const Timedelta ) { // Granice mozna ustalic doswiadczalnie. Ja proponuje 14:20 if( Global.iSlowMotion == 0 ) { // musi być pełna prędkość - Math3D::vector3 shakevector; + glm::dvec3 shakevector; if( ( MoverParameters->EngineType == TEngineType::DieselElectric ) || ( MoverParameters->EngineType == TEngineType::DieselEngine ) ) { if( std::abs( MoverParameters->enrot ) > 0.0 ) { @@ -8117,7 +8116,7 @@ TDynamicObject::update_shake( double const Timedelta ) { auto const iVel { std::min( GetVelocity(), 150.0 ) }; if( iVel > 0.5 ) { // acceleration-driven base shake - shakevector += Math3D::vector3( + shakevector += glm::dvec3( -MoverParameters->AccN * Timedelta * 5.0 * Global.ShakingMultiplierRL, // highlight side sway -MoverParameters->AccVert * Timedelta * Global.ShakingMultiplierUD, -MoverParameters->AccSVBased * Timedelta * 1.5 * Global.ShakingMultiplierBF); // accent acceleration/deceleration @@ -8128,7 +8127,7 @@ TDynamicObject::update_shake( double const Timedelta ) { if( LocalRandom( iVel ) > 25.0 ) { // extra shake at increased velocity shake += ShakeSpring.ComputateForces( - Math3D::vector3( + glm::dvec3( ( LocalRandom( iVel * 2 ) - iVel ) / ( ( iVel * 2 ) * 4 ) * BaseShake.jolt_scale.x, ( LocalRandom( iVel * 2 ) - iVel ) / ( ( iVel * 2 ) * 4 ) * BaseShake.jolt_scale.y, ( LocalRandom( iVel * 2 ) - iVel ) / ( ( iVel * 2 ) * 4 ) * BaseShake.jolt_scale.z ) @@ -8138,7 +8137,7 @@ TDynamicObject::update_shake( double const Timedelta ) { } shake *= 0.85; - ShakeState.velocity -= ( shake + ShakeState.velocity * 100 ) * ( BaseShake.jolt_scale.x + BaseShake.jolt_scale.y + BaseShake.jolt_scale.z ) / ( 200 ); + ShakeState.velocity -= ( shake + ShakeState.velocity * 100.0 ) * ( BaseShake.jolt_scale.x + BaseShake.jolt_scale.y + BaseShake.jolt_scale.z ) / ( 200.0 ); // McZapkie: ShakeState.offset += ShakeState.velocity * Timedelta; @@ -8741,10 +8740,10 @@ vehicle_table::update( double Deltatime, int Iterationcount ) { // legacy method, checks for presence and height of traction wire for specified vehicle void vehicle_table::update_traction( TDynamicObject *Vehicle ) { - - auto const vFront = glm::make_vec3( Vehicle->VectorFront().getArray() ); // wektor normalny dla płaszczyzny ruchu pantografu - auto const vUp = glm::make_vec3( Vehicle->VectorUp().getArray() ); // wektor pionu pudła (pochylony od pionu na przechyłce) - auto const vLeft = glm::make_vec3( Vehicle->VectorLeft().getArray() ); // wektor odległości w bok (odchylony od poziomu na przechyłce) + // TODO: Why glm::make_vec3 and glm::value_ptr? + auto const vFront = glm::make_vec3( glm::value_ptr(Vehicle->VectorFront()) ); // wektor normalny dla płaszczyzny ruchu pantografu + auto const vUp = glm::make_vec3( glm::value_ptr(Vehicle->VectorUp()) ); // wektor pionu pudła (pochylony od pionu na przechyłce) + auto const vLeft = glm::make_vec3( glm::value_ptr(Vehicle->VectorLeft()) ); // wektor odległości w bok (odchylony od poziomu na przechyłce) auto const position = glm::dvec3 { Vehicle->GetPosition() }; // współrzędne środka pojazdu for( int pantographindex = 0; pantographindex < Vehicle->iAnimType[ ANIM_PANTS ]; ++pantographindex ) { diff --git a/vehicle/DynObj.h b/vehicle/DynObj.h index 70748d69..04e2e6c8 100644 --- a/vehicle/DynObj.h +++ b/vehicle/DynObj.h @@ -87,7 +87,7 @@ class TAnimValveGear class TAnimPant { // współczynniki do animacji pantografu public: - Math3D::vector3 vPos; // Ra: współrzędne punktu zerowego pantografu (X dodatnie dla przedniego) + glm::dvec3 vPos; // Ra: współrzędne punktu zerowego pantografu (X dodatnie dla przedniego) double fLenL1; // długość dolnego ramienia 1, odczytana z modelu double fLenU1; // długość górnego ramienia 1, odczytana z modelu double fLenL2; // długość dolnego ramienia 2, odczytana z modelu @@ -194,9 +194,9 @@ public: static bool bDynamicRemove; // moved from ground //private: // położenie pojazdu w świecie oraz parametry ruchu - Math3D::vector3 vPosition; // Ra: pozycja pojazdu liczona zaraz po przesunięciu - Math3D::vector3 vCoulpler[ 2 ]; // współrzędne sprzęgów do liczenia zderzeń czołowych - Math3D::vector3 vUp, vFront, vLeft; // wektory jednostkowe ustawienia pojazdu + glm::dvec3 vPosition; // Ra: pozycja pojazdu liczona zaraz po przesunięciu + glm::dvec3 vCoulpler[2]; // współrzędne sprzęgów do liczenia zderzeń czołowych + glm::dvec3 vUp, vFront, vLeft; // wektory jednostkowe ustawienia pojazdu int iDirection; // kierunek pojazdu względem czoła składu (1=zgodny,0=przeciwny) TTrackShape ts; // parametry toru przekazywane do fizyki TTrackParam tp; // parametry toru przekazywane do fizyki @@ -204,7 +204,7 @@ public: TTrackFollower Axle1; // oś z tyłu (od sprzęgu 1) int iAxleFirst; // numer pierwszej osi w kierunku ruchu (oś wiążąca pojazd z torem i wyzwalająca eventy) float fAxleDist; // rozstaw wózków albo osi do liczenia proporcji zacienienia - Math3D::vector3 modelRot; // obrot pudła względem świata - do przeanalizowania, czy potrzebne!!! + glm::dvec3 modelRot; // obrot pudła względem świata - do przeanalizowania, czy potrzebne!!! TDynamicObject * ABuFindNearestObject(glm::vec3 pos, TTrack *Track, TDynamicObject *MyPointer, int &CouplNr ); glm::dvec3 m_future_movement; @@ -214,7 +214,7 @@ public: // parametry położenia pojazdu dostępne publicznie std::string asTrack; // nazwa toru początkowego; wywalić? std::string asDestination; // dokąd pojazd ma być kierowany "(stacja):(tor)" - Math3D::matrix4x4 mMatrix; // macierz przekształcenia do renderowania modeli + glm::dmat4 mMatrix; // macierz przekształcenia do renderowania modeli TMoverParameters *MoverParameters; // parametry fizyki ruchu oraz przeliczanie inline TDynamicObject *NextConnected() { return MoverParameters->Neighbours[ end::rear ].vehicle; }; // pojazd podłączony od strony sprzęgu 1 (kabina -1) inline TDynamicObject *PrevConnected() { return MoverParameters->Neighbours[ end::front ].vehicle; }; // pojazd podłączony od strony sprzęgu 0 (kabina 1) @@ -304,7 +304,7 @@ private: void toggle_lights(); // switch light levels for registered interior sections private: // Ra: ciąg dalszy animacji, dopiero do ogarnięcia // ABuWozki 060504 - Math3D::vector3 bogieRot[2]; // Obroty wozkow w/m korpusu + glm::dvec3 bogieRot[2]; // Obroty wozkow w/m korpusu TSubModel *smBogie[2]; // Wyszukiwanie max 2 wozkow TSubModel *smWahacze[4]; // wahacze (np. nogi, dźwignia w drezynie) TSubModel *smBrakeMode; // Ra 15-01: nastawa hamulca też @@ -316,7 +316,7 @@ private: TSubModel *smBuforLewy[2]; TSubModel *smBuforPrawy[2]; TAnimValveGear *pValveGear; - Math3D::vector3 vFloor; // podłoga dla ładunku + glm::dvec3 vFloor; // podłoga dla ładunku public: TAnim *pants; // indeks obiektu animującego dla pantografu 0 TAnim *wipers; // wycieraczki @@ -644,7 +644,7 @@ private: TDynamicObject * ABuScanNearestObject(glm::vec3 pos, TTrack *Track, double ScanDir, double ScanDist, int &CouplNr); TDynamicObject * GetFirstDynamic(int cpl_type, int cf = 1); - void ABuSetModelShake( Math3D::vector3 mShake); + void ABuSetModelShake(glm::dvec3 mShake); // McZapkie-010302 TController *Mechanik; @@ -693,20 +693,20 @@ private: void Move(double fDistance); void FastMove(double fDistance); void RenderSounds(); - inline Math3D::vector3 GetPosition() const { + inline glm::dvec3 GetPosition() const { return vPosition; }; // converts location from vehicle coordinates frame to world frame - inline Math3D::vector3 GetWorldPosition( Math3D::vector3 const &Location ) const { - return vPosition + mMatrix * Location; } + inline glm::dvec3 GetWorldPosition( glm::dvec3 const &Location ) const { + return vPosition + glm::dvec3(mMatrix * glm::dvec4(Location, 1.0)); } // pobranie współrzędnych czoła - inline Math3D::vector3 HeadPosition() const { + inline glm::dvec3 HeadPosition() const { return vCoulpler[iDirection ^ 1]; }; // pobranie współrzędnych tyłu - inline Math3D::vector3 RearPosition() const { + inline glm::dvec3 RearPosition() const { return vCoulpler[iDirection]; }; - inline Math3D::vector3 CouplerPosition( end const End ) const { + inline glm::dvec3 CouplerPosition( end const End ) const { return vCoulpler[ End ]; } - inline Math3D::vector3 AxlePositionGet() { + inline glm::dvec3 AxlePositionGet() { return iAxleFirst ? Axle1.pPosition : Axle0.pPosition; }; @@ -722,16 +722,16 @@ private: ( iAxleFirst ? Axle1.pPosition : Axle0.pPosition ) : ( iAxleFirst ? Axle0.pPosition : Axle1.pPosition ) ); } */ - inline Math3D::vector3 VectorFront() const { + inline glm::dvec3 VectorFront() const { return vFront; }; - inline Math3D::vector3 VectorUp() const { + inline glm::dvec3 VectorUp() const { return vUp; }; - inline Math3D::vector3 VectorLeft() const { + inline glm::dvec3 VectorLeft() const { return vLeft; }; inline double const * Matrix() const { - return mMatrix.readArray(); }; + return glm::value_ptr(mMatrix); }; inline double * Matrix() { - return mMatrix.getArray(); }; + return glm::value_ptr(mMatrix); }; inline double GetVelocity() const { return MoverParameters->Vel; }; inline double GetLength() const { @@ -855,11 +855,11 @@ public: bool IsHunting { false }; TSpring ShakeSpring; struct shake_state { - Math3D::vector3 velocity {}; // current shaking vector - Math3D::vector3 offset {}; // overall shake-driven offset from base position + glm::dvec3 velocity{}; // current shaking vector + glm::dvec3 offset{}; // overall shake-driven offset from base position } ShakeState; - Math3D::vector3 modelShake; + glm::dvec3 modelShake; }; diff --git a/vehicle/Train.cpp b/vehicle/Train.cpp index de2e8e5e..4470ff1e 100644 --- a/vehicle/Train.cpp +++ b/vehicle/Train.cpp @@ -568,7 +568,7 @@ TTrain::TTrain() { fHaslerTimer = 0; DynamicSet(NULL); // ustawia wszystkie mv* //----- - pMechSittingPosition = Math3D::vector3(0, 0, 0); // ABu: 180404 + pMechSittingPosition = glm::dvec3(0, 0, 0); // ABu: 180404 fTachoTimer = 0.0; // włączenie skoków wskazań prędkościomierza // @@ -5122,10 +5122,10 @@ void TTrain::OnCommand_redmarkerstoggle( TTrain *Train, command_data const &Comm if( vehicle == nullptr ) { return; } + auto locationHead = vehicle->HeadPosition() - glm::dvec3(Command.location); // TODO: Maybe command_data should be dvec3? + auto locationRear = vehicle->RearPosition() - glm::dvec3(Command.location); int const CouplNr { - clamp( - vehicle->DirectionGet() - * ( Math3D::LengthSquared3( vehicle->HeadPosition() - Command.location ) > Math3D::LengthSquared3( vehicle->RearPosition() - Command.location ) ? + clamp(vehicle->DirectionGet() * (glm::dot(locationHead, locationHead) > glm::dot(locationRear, locationRear) ? 1 : -1 ), 0, 1 ) }; // z [-1,1] zrobić [0,1] @@ -5147,11 +5147,11 @@ void TTrain::OnCommand_endsignalstoggle( TTrain *Train, command_data const &Comm auto *vehicle { std::get( simulation::Region->find_vehicle( Command.location, 10, false, true ) ) }; if( vehicle == nullptr ) { return; } - + // TODO: Maybe command_data should be dvec3? int const CouplNr { clamp( vehicle->DirectionGet() - * ( Math3D::LengthSquared3( vehicle->HeadPosition() - Command.location ) > Math3D::LengthSquared3( vehicle->RearPosition() - Command.location ) ? + * ( Math3D::LengthSquared3( vehicle->HeadPosition() - glm::dvec3(Command.location) ) > Math3D::LengthSquared3( vehicle->RearPosition() - glm::dvec3(Command.location) ) ? 1 : -1 ), 0, 1 ) }; // z [-1,1] zrobić [0,1] @@ -9449,7 +9449,7 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) { */ // configure placement of sound emitters which aren't bound with any device model, and weren't placed manually - auto const caboffset { glm::dvec3 { ( Cabine[ cabindex ].CabPos1 + Cabine[ cabindex ].CabPos2 ) * 0.5 } +glm::dvec3 { 0, 1, 0 } }; + auto const caboffset { glm::dvec3 { ( Cabine[ cabindex ].CabPos1 + Cabine[ cabindex ].CabPos2 ) * 0.5f } +glm::dvec3 { 0, 1, 0 } }; // NOTE: since radiosound is an incomplete template not using std::optional it gets a special treatment if( m_radiosound.offset() == nullvector ) { m_radiosound.offset( btLampkaRadio.model_offset() ); @@ -9517,15 +9517,15 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) return true; } -Math3D::vector3 TTrain::MirrorPosition(bool lewe) +glm::dvec3 TTrain::MirrorPosition(bool lewe) { // zwraca współrzędne widoku kamery z lusterka auto const shiftdirection { ( lewe ? -1 : 1 ) * ( iCabn == 2 ? 1 : -1 ) }; - return DynamicObject->mMatrix - * Math3D::vector3( + return DynamicObject->mMatrix * + glm::dvec4( mvOccupied->Dim.W * ( 0.5 * shiftdirection ) + ( 0.2 * shiftdirection ), 1.5 + Cabine[iCabn].CabPos1.y, - interpolate( Cabine[ iCabn ].CabPos1.z , Cabine[ iCabn ].CabPos2.z, 0.5 ) ); + interpolate( Cabine[ iCabn ].CabPos1.z , Cabine[ iCabn ].CabPos2.z, 0.5 ), 0.0 ); }; void TTrain::DynamicSet(TDynamicObject *d) @@ -9697,23 +9697,23 @@ TTrain::MoveToVehicle(TDynamicObject *target) { } // checks whether specified point is within boundaries of the active cab -bool -TTrain::point_inside( Math3D::vector3 const Point ) const { +bool TTrain::point_inside(glm::dvec3 const Point) const +{ return ( Point.x >= Cabine[ iCabn ].CabPos1.x ) && ( Point.x <= Cabine[ iCabn ].CabPos2.x ) && ( Point.y >= Cabine[ iCabn ].CabPos1.y + 0.5 ) && ( Point.y <= Cabine[ iCabn ].CabPos2.y + 1.8 ) && ( Point.z >= Cabine[ iCabn ].CabPos1.z ) && ( Point.z <= Cabine[ iCabn ].CabPos2.z ); } -Math3D::vector3 -TTrain::clamp_inside( Math3D::vector3 const &Point ) const { +glm::dvec3 TTrain::clamp_inside(glm::dvec3 const &Point) const +{ if( DebugModeFlag ) { return Point; } return { - clamp( Point.x, Cabine[ iCabn ].CabPos1.x, Cabine[ iCabn ].CabPos2.x ), - clamp( Point.y, Cabine[ iCabn ].CabPos1.y + 0.5, Cabine[ iCabn ].CabPos2.y + 1.8 ), - clamp( Point.z, Cabine[ iCabn ].CabPos1.z, Cabine[ iCabn ].CabPos2.z ) }; + clamp( Point.x, (double)Cabine[ iCabn ].CabPos1.x, (double)Cabine[ iCabn ].CabPos2.x ), + clamp( Point.y, (double)Cabine[ iCabn ].CabPos1.y + 0.5, (double)Cabine[ iCabn ].CabPos2.y + 1.8 ), + clamp( Point.z, (double)Cabine[ iCabn ].CabPos1.z, (double)Cabine[ iCabn ].CabPos2.z ) }; } const TTrain::screenentry_sequence& TTrain::get_screens() { diff --git a/vehicle/Train.h b/vehicle/Train.h index 96a41463..b226ee13 100644 --- a/vehicle/Train.h +++ b/vehicle/Train.h @@ -39,8 +39,8 @@ public: TGauge &Gauge( int n = -1 ); // pobranie adresu obiektu TButton &Button( int n = -1 ); // pobranie adresu obiektu // members - Math3D::vector3 CabPos1 { 0, 1, 1 }; - Math3D::vector3 CabPos2 { 0, 1, -1 }; + glm::vec3 CabPos1{0, 1, 1}; + glm::vec3 CabPos2{0, 1, -1}; bool bEnabled { false }; bool bOccupied { true }; /* @@ -153,11 +153,11 @@ class TTrain { // McZapkie-010302 bool Init(TDynamicObject *NewDynamicObject, bool e3d = false); - inline - Math3D::vector3 GetDirection() const { + inline glm::dvec3 GetDirection() const + { return DynamicObject->VectorFront(); }; - inline - Math3D::vector3 GetUp() const { + inline glm::dvec3 GetUp() const + { return DynamicObject->VectorUp(); }; inline std::string GetLabel( TSubModel const *Control ) const { @@ -847,9 +847,9 @@ public: // reszta może by?publiczna int iCabn { 0 }; // 0: mid, 1: front, 2: rear bool is_cab_initialized { false }; // McZapkie: do poruszania sie po kabinie - Math3D::vector3 pMechSittingPosition; // ABu 180404 - Math3D::vector3 MirrorPosition( bool lewe ); - Math3D::vector3 pMechOffset; // base position of the driver in the cab + glm::dvec3 pMechSittingPosition; // ABu 180404 + glm::dvec3 MirrorPosition(bool lewe); + glm::dvec3 pMechOffset; // base position of the driver in the cab glm::vec2 pMechViewAngle { 0.0, 0.0 }; // camera pitch and yaw values, preserved while in external view private: @@ -927,8 +927,8 @@ private: void DynamicSet(TDynamicObject *d); void MoveToVehicle( TDynamicObject *target ); // checks whether specified point is within boundaries of the active cab - bool point_inside( Math3D::vector3 const Point ) const; - Math3D::vector3 clamp_inside( Math3D::vector3 const &Point ) const; + bool point_inside(glm::dvec3 const Point) const; + glm::dvec3 clamp_inside(glm::dvec3 const &Point) const; const screenentry_sequence & get_screens(); uint16_t id(); From ef852b430749bce5f301a2ca0339be378f7840e4 Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Mon, 27 Apr 2026 21:28:06 +0200 Subject: [PATCH 11/19] Fix model rotation by changing glm::dmat4 BasisChange definition --- utilities/dumb3d.h | 9 +-------- vehicle/Train.cpp | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/utilities/dumb3d.h b/utilities/dumb3d.h index 19075cd4..33ea4bde 100644 --- a/utilities/dumb3d.h +++ b/utilities/dumb3d.h @@ -19,14 +19,7 @@ namespace Math3D inline glm::dmat4 BasisChange(glm::dvec3 u, glm::dvec3 v, glm::dvec3 n) { - glm::dmat4 M(1.0); - - M[0] = glm::dvec4(u, 0.0); // kolumna 0 - M[1] = glm::dvec4(v, 0.0); // kolumna 1 - M[2] = glm::dvec4(n, 0.0); // kolumna 2 - M[3] = glm::dvec4(0.0, 0.0, 0.0, 1.0); // kolumna 3 - - return M; + return glm::dmat4{glm::dvec4(u.x, v.x, n.x, 0.0), glm::dvec4(u.y, v.y, n.y, 0.0), glm::dvec4(u.z, v.z, n.z, 0.0), glm::dvec4(0.0, 0.0, 0.0, 1.0)}; // 4 columns; first rows: u, v, n } inline glm::dmat4 BasisChange(glm::dvec3 v, glm::dvec3 n) diff --git a/vehicle/Train.cpp b/vehicle/Train.cpp index 4470ff1e..ee2cd6ec 100644 --- a/vehicle/Train.cpp +++ b/vehicle/Train.cpp @@ -9525,7 +9525,7 @@ glm::dvec3 TTrain::MirrorPosition(bool lewe) glm::dvec4( mvOccupied->Dim.W * ( 0.5 * shiftdirection ) + ( 0.2 * shiftdirection ), 1.5 + Cabine[iCabn].CabPos1.y, - interpolate( Cabine[ iCabn ].CabPos1.z , Cabine[ iCabn ].CabPos2.z, 0.5 ), 0.0 ); + interpolate( Cabine[ iCabn ].CabPos1.z , Cabine[ iCabn ].CabPos2.z, 0.5 ), 1.0); }; void TTrain::DynamicSet(TDynamicObject *d) From 438cc563d93fb82d5535fe81d145ec74929f3cdf Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Mon, 27 Apr 2026 21:41:00 +0200 Subject: [PATCH 12/19] use glm instead of Math3D in rendering --- rendering/frustum.h | 9 --------- rendering/opengl33renderer.cpp | 12 ++++++------ rendering/opengl33renderer.h | 4 ++-- rendering/openglrenderer.cpp | 14 +++++++------- rendering/openglrenderer.h | 4 ++-- 5 files changed, 17 insertions(+), 26 deletions(-) diff --git a/rendering/frustum.h b/rendering/frustum.h index eb1f8df6..111a2d9b 100644 --- a/rendering/frustum.h +++ b/rendering/frustum.h @@ -47,9 +47,6 @@ public: inline bool point_inside( float3 const &Point ) const { return point_inside( Point.x, Point.y, Point.z ); } - inline - bool - point_inside( Math3D::vector3 const &Point ) const { return point_inside( static_cast( Point.x ), static_cast( Point.y ), static_cast( Point.z ) ); } bool point_inside( float const X, float const Y, float const Z ) const; // tests if the sphere is in frustum, returns the distance between origin and sphere centre @@ -62,9 +59,6 @@ public: inline float sphere_inside( float3 const &Center, float const Radius ) const { return sphere_inside( Center.x, Center.y, Center.z, Radius ); } - inline - float - sphere_inside( Math3D::vector3 const &Center, float const Radius ) const { return sphere_inside( static_cast( Center.x ), static_cast( Center.y ), static_cast( Center.z ), Radius ); } float sphere_inside( float const X, float const Y, float const Z, float const Radius ) const; // returns true if specified cube is inside of the frustum. Size = half of the length @@ -74,9 +68,6 @@ public: inline bool cube_inside( float3 const &Center, float const Size ) const { return cube_inside( Center.x, Center.y, Center.z, Size ); } - inline - bool - cube_inside( Math3D::vector3 const &Center, float const Size ) const { return cube_inside( static_cast( Center.x ), static_cast( Center.y ), static_cast( Center.z ), Size ); } bool cube_inside( float const X, float const Y, float const Z, float const Size ) const; diff --git a/rendering/opengl33renderer.cpp b/rendering/opengl33renderer.cpp index 9b1de506..88181cef 100644 --- a/rendering/opengl33renderer.cpp +++ b/rendering/opengl33renderer.cpp @@ -1266,7 +1266,7 @@ bool opengl33_renderer::Render_coupler_adapter( TDynamicObject *Dynamic, float c if( Dynamic->m_coupleradapters[ End ] == nullptr ) { return false; } - auto const position { Math3D::vector3 { + auto const position { glm::dvec3 { 0.f, Dynamic->MoverParameters->Couplers[ End ].adapter_height, ( Dynamic->MoverParameters->Couplers[ End ].adapter_length + Dynamic->MoverParameters->Dim.L * 0.5 ) * ( End == end::front ? 1 : -1 ) } }; @@ -2681,7 +2681,7 @@ void opengl33_renderer::Render(scene::shape_node const &Shape, bool const Ignore case rendermode::shadows: { // 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees - distancesquared = Math3D::SquareMagnitude((data.area.center - m_renderpass.viewport_camera.position()) / (double)Global.ZoomFactor) / Global.fDistanceFactor; + distancesquared = glm::length2((data.area.center - m_renderpass.viewport_camera.position()) / (double)Global.ZoomFactor) / Global.fDistanceFactor; break; } case rendermode::reflections: @@ -3105,9 +3105,9 @@ bool opengl33_renderer::Render(TModel3d *Model, material_data const *Material, f return true; } -bool opengl33_renderer::Render(TModel3d *Model, material_data const *Material, float const Squaredistance, Math3D::vector3 const &Position, glm::vec3 const &A) +bool opengl33_renderer::Render(TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &A) { - Math3D::vector3 Angle(A); + glm::dvec3 Angle(A); // TODO: Why copy? ::glPushMatrix(); ::glTranslated(Position.x, Position.y, Position.z); if (Angle.y != 0.0) @@ -3980,9 +3980,9 @@ bool opengl33_renderer::Render_Alpha(TModel3d *Model, material_data const *Mater return true; } -bool opengl33_renderer::Render_Alpha(TModel3d *Model, material_data const *Material, float const Squaredistance, Math3D::vector3 const &Position, glm::vec3 const &A) +bool opengl33_renderer::Render_Alpha(TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &A) { - Math3D::vector3 Angle(A); + glm::dvec3 Angle(A); // TODO: Why copy? ::glPushMatrix(); ::glTranslated(Position.x, Position.y, Position.z); if (Angle.y != 0.0) diff --git a/rendering/opengl33renderer.h b/rendering/opengl33renderer.h index 04ead7f0..2efdd272 100644 --- a/rendering/opengl33renderer.h +++ b/rendering/opengl33renderer.h @@ -261,7 +261,7 @@ class opengl33_renderer : public gfx_renderer { void Render(scene::shape_node const &Shape, bool const Ignorerange); void Render(TAnimModel *Instance); bool Render(TDynamicObject *Dynamic); - bool Render(TModel3d *Model, material_data const *Material, float const Squaredistance, Math3D::vector3 const &Position, glm::vec3 const &Angle); + bool Render(TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &Angle); bool Render(TModel3d *Model, material_data const *Material, float const Squaredistance); void Render(TSubModel *Submodel); void Render(TTrack *Track); @@ -280,7 +280,7 @@ class opengl33_renderer : public gfx_renderer { void Render_Alpha(TTraction *Traction); void Render_Alpha(scene::lines_node const &Lines); bool Render_Alpha(TDynamicObject *Dynamic); - bool Render_Alpha(TModel3d *Model, material_data const *Material, float const Squaredistance, Math3D::vector3 const &Position, glm::vec3 const &Angle); + bool Render_Alpha(TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &Angle); bool Render_Alpha(TModel3d *Model, material_data const *Material, float const Squaredistance); void Render_Alpha(TSubModel *Submodel); void Update_Lights(light_array &Lights); diff --git a/rendering/openglrenderer.cpp b/rendering/openglrenderer.cpp index 2ad18574..b1db5312 100644 --- a/rendering/openglrenderer.cpp +++ b/rendering/openglrenderer.cpp @@ -867,7 +867,7 @@ bool opengl_renderer::Render_coupler_adapter( TDynamicObject *Dynamic, float con if( Dynamic->m_coupleradapters[ End ] == nullptr ) { return false; } - auto const position { Math3D::vector3 { + auto const position { glm::dvec3 { 0.f, Dynamic->MoverParameters->Couplers[ End ].adapter_height, ( Dynamic->MoverParameters->Couplers[ End ].adapter_length + Dynamic->MoverParameters->Dim.L * 0.5 ) * ( End == end::front ? 1 : -1 ) } }; @@ -2277,7 +2277,7 @@ opengl_renderer::Render( scene::shape_node const &Shape, bool const Ignorerange case rendermode::shadows: case rendermode::cabshadows: { // 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees - distancesquared = Math3D::SquareMagnitude( ( data.area.center - Global.pCamera.Pos ) / (double)Global.ZoomFactor ) / Global.fDistanceFactor; + distancesquared = glm::length2( ( data.area.center - Global.pCamera.Pos ) / (double)Global.ZoomFactor ) / Global.fDistanceFactor; break; } case rendermode::reflections: { @@ -2696,7 +2696,7 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, float c } bool -opengl_renderer::Render( TModel3d *Model, material_data const *Material, float const Squaredistance, Math3D::vector3 const &Position, glm::vec3 const &Angle ) { +opengl_renderer::Render( TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &Angle ) { ::glPushMatrix(); ::glTranslated( Position.x, Position.y, Position.z ); @@ -3505,7 +3505,7 @@ opengl_renderer::Render_Alpha( TAnimModel *Instance ) { 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 = Math3D::SquareMagnitude( ( Instance->location() - Global.pCamera.Pos ) / (double)Global.ZoomFactor ) / Global.fDistanceFactor; + distancesquared = glm::length2( ( Instance->location() - Global.pCamera.Pos ) / (double)Global.ZoomFactor ) / Global.fDistanceFactor; break; } default: { @@ -3549,7 +3549,7 @@ opengl_renderer::Render_Alpha( TTraction *Traction ) { 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 = Math3D::SquareMagnitude( ( Traction->location() - Global.pCamera.Pos ) / Global.ZoomFactor ) / Global.fDistanceFactor; + distancesquared = glm::length2( ( Traction->location() - Global.pCamera.Pos ) / Global.ZoomFactor ) / Global.fDistanceFactor; break; } default: { @@ -3613,7 +3613,7 @@ opengl_renderer::Render_Alpha( scene::lines_node const &Lines ) { 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 = Math3D::SquareMagnitude( ( data.area.center - Global.pCamera.Pos ) / Global.ZoomFactor ) / Global.fDistanceFactor; + distancesquared = glm::length2( ( data.area.center - Global.pCamera.Pos ) / Global.ZoomFactor ) / Global.fDistanceFactor; break; } default: { @@ -3769,7 +3769,7 @@ opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, f } bool -opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, float const Squaredistance, Math3D::vector3 const &Position, glm::vec3 const &Angle ) { +opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &Angle ) { ::glPushMatrix(); ::glTranslated( Position.x, Position.y, Position.z ); diff --git a/rendering/openglrenderer.h b/rendering/openglrenderer.h index aa01a805..ded24877 100644 --- a/rendering/openglrenderer.h +++ b/rendering/openglrenderer.h @@ -223,7 +223,7 @@ private: bool Render( TDynamicObject *Dynamic ); bool - Render( TModel3d *Model, material_data const *Material, float const Squaredistance, Math3D::vector3 const &Position, glm::vec3 const &Angle ); + Render( TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &Angle ); bool Render( TModel3d *Model, material_data const *Material, float const Squaredistance ); void @@ -259,7 +259,7 @@ private: bool Render_Alpha( TDynamicObject *Dynamic ); bool - Render_Alpha( TModel3d *Model, material_data const *Material, float const Squaredistance, Math3D::vector3 const &Position, glm::vec3 const &Angle ); + Render_Alpha( TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &Angle ); bool Render_Alpha( TModel3d *Model, material_data const *Material, float const Squaredistance ); void From 0fcdf983921a1be7042447556853c4c14d0b02c0 Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Mon, 27 Apr 2026 21:57:13 +0200 Subject: [PATCH 13/19] more glm instead of Math3D in vehicle --- vehicle/DynObj.h | 6 +++--- vehicle/Train.cpp | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/vehicle/DynObj.h b/vehicle/DynObj.h index 04e2e6c8..c495f578 100644 --- a/vehicle/DynObj.h +++ b/vehicle/DynObj.h @@ -716,7 +716,7 @@ private: // TODO: check if scanning takes into account direction when selecting axle // if it does, replace the version above // if it doesn't, fix it so it does - inline Math3D::vector3 AxlePositionGet() { + inline glm::dvec3 AxlePositionGet() { return ( iDirection ? ( iAxleFirst ? Axle1.pPosition : Axle0.pPosition ) : @@ -834,8 +834,8 @@ public: std::pair shake_angles() const; // members struct baseshake_config { - Math3D::vector3 angle_scale { 0.05, 0.0, 0.1 }; // roll, yaw, pitch - Math3D::vector3 jolt_scale { 0.2, 0.2, 0.1 }; + glm::dvec3 angle_scale { 0.05, 0.0, 0.1 }; // roll, yaw, pitch + glm::dvec3 jolt_scale{0.2, 0.2, 0.1}; double jolt_limit { 2.0f }; } BaseShake; struct engineshake_config { diff --git a/vehicle/Train.cpp b/vehicle/Train.cpp index ee2cd6ec..9e062133 100644 --- a/vehicle/Train.cpp +++ b/vehicle/Train.cpp @@ -563,7 +563,7 @@ TTrain::TTrain() { fPPress = fNPress = 0; // asMessage=""; - pMechOffset = Math3D::vector3(0, 0, 0); + pMechOffset = glm::dvec3(0, 0, 0); fBlinkTimer = 0; fHaslerTimer = 0; DynamicSet(NULL); // ustawia wszystkie mv* @@ -5147,11 +5147,10 @@ void TTrain::OnCommand_endsignalstoggle( TTrain *Train, command_data const &Comm auto *vehicle { std::get( simulation::Region->find_vehicle( Command.location, 10, false, true ) ) }; if( vehicle == nullptr ) { return; } - // TODO: Maybe command_data should be dvec3? int const CouplNr { clamp( vehicle->DirectionGet() - * ( Math3D::LengthSquared3( vehicle->HeadPosition() - glm::dvec3(Command.location) ) > Math3D::LengthSquared3( vehicle->RearPosition() - glm::dvec3(Command.location) ) ? + * ( glm::length2( vehicle->HeadPosition() - glm::dvec3(Command.location) ) > glm::length2( vehicle->RearPosition() - glm::dvec3(Command.location) ) ? 1 : -1 ), 0, 1 ) }; // z [-1,1] zrobić [0,1] From d5d1825e38d8966d8518667604c7af919fe3c2ce Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Mon, 27 Apr 2026 23:03:47 +0200 Subject: [PATCH 14/19] Remove dumb3d --- CMakeLists.txt | 1 - McZapkie/MOVER.h | 1 - rendering/frustum.h | 1 - utilities/dumb3d.cpp | 430 -------------------------- utilities/dumb3d.h | 671 ----------------------------------------- utilities/glmHelpers.h | 21 ++ vehicle/Camera.cpp | 5 +- vehicle/DynObj.cpp | 3 +- vehicle/Train.cpp | 1 - 9 files changed, 26 insertions(+), 1108 deletions(-) delete mode 100644 utilities/dumb3d.cpp delete mode 100644 utilities/dumb3d.h create mode 100644 utilities/glmHelpers.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 593f2238..8806a7dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,7 +104,6 @@ set(SOURCES "vehicle/Camera.cpp" "vehicle/Driver.cpp" "application/driverhints.cpp" -"utilities/dumb3d.cpp" "vehicle/DynObj.cpp" "EU07.cpp" "export_e3d_standalone.cpp" diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 78062821..939a5e50 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -78,7 +78,6 @@ zwiekszenie nacisku przy duzych predkosciach w hamulcach Oerlikona ... */ -#include "utilities/dumb3d.h" #include "utilities/utilities.h" extern int ConversionError; diff --git a/rendering/frustum.h b/rendering/frustum.h index 111a2d9b..4afe02f0 100644 --- a/rendering/frustum.h +++ b/rendering/frustum.h @@ -10,7 +10,6 @@ http://mozilla.org/MPL/2.0/. #pragma once #include "utilities/Float3d.h" -#include "utilities/dumb3d.h" inline std::vector const ndcfrustumshapepoints // { diff --git a/utilities/dumb3d.cpp b/utilities/dumb3d.cpp deleted file mode 100644 index 0693d1a3..00000000 --- a/utilities/dumb3d.cpp +++ /dev/null @@ -1,430 +0,0 @@ -/* -This Source Code Form is subject to the -terms of the Mozilla Public License, v. -2.0. If a copy of the MPL was not -distributed with this file, You can -obtain one at -http://mozilla.org/MPL/2.0/. -*/ - -#include "stdafx.h" -#include "utilities/dumb3d.h" -#include - -namespace Math3D -{ - -void vector3::RotateX(double angle) -{ - double ty = y; - y = (cos(angle) * y - z * sin(angle)); - z = (z * cos(angle) + sin(angle) * ty); -}; -void vector3::RotateY(double angle) -{ - double tx = x; - x = (cos(angle) * x + z * sin(angle)); - z = (z * cos(angle) - sin(angle) * tx); -}; - -glm::vec3 RotateY(glm::vec3 v, float angle) -{ - float s = sin(angle); - float c = cos(angle); - - return glm::vec3(c * v.x + s * v.z, v.y, c * v.z - s * v.x); -} -glm::dvec3 RotateY(glm::dvec3 v, double angle) -{ - double s = sin(angle); - double c = cos(angle); - - return glm::vec3(c * v.x + s * v.z, v.y, c * v.z - s * v.x); -} - -void vector3::RotateZ(double angle) -{ - double ty = y; - y = (cos(angle) * y + x * sin(angle)); - x = (x * cos(angle) - sin(angle) * ty); -}; - -void inline vector3::SafeNormalize() -{ - double l = Length(); - if (l == 0) - { - x = y = z = 0; - } - else - { - x /= l; - y /= l; - z /= l; - } -} - -// From code in Graphics Gems; p. 766 -inline scalar_t det2x2(scalar_t a, scalar_t b, scalar_t c, scalar_t d) -{ - return a * d - b * c; -} - -inline scalar_t det3x3(scalar_t a1, scalar_t a2, scalar_t a3, scalar_t b1, scalar_t b2, scalar_t b3, - scalar_t c1, scalar_t c2, scalar_t c3) -{ - return a1 * det2x2(b2, b3, c2, c3) - b1 * det2x2(a2, a3, c2, c3) + c1 * det2x2(a2, a3, b2, b3); -} - -scalar_t Determinant(const matrix4x4 &m) -{ - scalar_t a1 = m[0][0]; - scalar_t a2 = m[1][0]; - scalar_t a3 = m[2][0]; - scalar_t a4 = m[3][0]; - scalar_t b1 = m[0][1]; - scalar_t b2 = m[1][1]; - scalar_t b3 = m[2][1]; - scalar_t b4 = m[3][1]; - scalar_t c1 = m[0][2]; - scalar_t c2 = m[1][2]; - scalar_t c3 = m[2][2]; - scalar_t c4 = m[3][2]; - scalar_t d1 = m[0][3]; - scalar_t d2 = m[1][3]; - scalar_t d3 = m[2][3]; - scalar_t d4 = m[3][3]; - - return a1 * det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4) - - b1 * det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4) + - c1 * det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4) - - d1 * det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4); -} - -matrix4x4 Adjoint(const matrix4x4 &m) -{ - scalar_t a1 = m[0][0]; - scalar_t a2 = m[0][1]; - scalar_t a3 = m[0][2]; - scalar_t a4 = m[0][3]; - scalar_t b1 = m[1][0]; - scalar_t b2 = m[1][1]; - scalar_t b3 = m[1][2]; - scalar_t b4 = m[1][3]; - scalar_t c1 = m[2][0]; - scalar_t c2 = m[2][1]; - scalar_t c3 = m[2][2]; - scalar_t c4 = m[2][3]; - scalar_t d1 = m[3][0]; - scalar_t d2 = m[3][1]; - scalar_t d3 = m[3][2]; - scalar_t d4 = m[3][3]; - - // Adjoint(x,y) = -1^(x+y) * a(y,x) - // Where a(i,j) is the 3x3 determinant of m with row i and col j removed - matrix4x4 retVal; - retVal(0)[0] = det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4); - retVal(0)[1] = -det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4); - retVal(0)[2] = det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4); - retVal(0)[3] = -det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4); - - retVal(1)[0] = -det3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4); - retVal(1)[1] = det3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4); - retVal(1)[2] = -det3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4); - retVal(1)[3] = det3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4); - - retVal(2)[0] = det3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4); - retVal(2)[1] = -det3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4); - retVal(2)[2] = det3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4); - retVal(2)[3] = -det3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4); - - retVal(3)[0] = -det3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3); - retVal(3)[1] = det3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3); - retVal(3)[2] = -det3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3); - retVal(3)[3] = det3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3); - - return retVal; -} - -matrix4x4 Inverse(const matrix4x4 &m) -{ - matrix4x4 retVal = Adjoint(m); - scalar_t det = Determinant(m); - assert(det); - - for (int i = 0; i < 4; ++i) - { - for (int j = 0; j < 4; ++j) - { - retVal(i)[j] /= det; - } - } - - return retVal; -} -} - -//************************************** -// Testing from here on. -//************************************** -#ifdef TEST_MATH3D -#include - -using namespace Math3D; -using namespace std; - -static int failures = 0; - -void ReportFailure(const char *className, const char *testName, bool passed) -{ - cout << className; - if (passed) - cout << " passed test "; - else - { - cout << " FAILED test "; - ++failures; - } - cout << testName << "." << endl; -} - -const char *vector3Name = "vector3"; -const char *matrix4x4Name = "matrix4x4"; - -void Testvector3Constructors(void) -{ - // Default ctor... just make sure it compiles - vector3 defaultCtorTest; - - // Initializer ctor test (3 param) - vector3 initCtorTest(1, 2, 3); - ReportFailure(vector3Name, "initialized ctor (3 parameter version)", - (initCtorTest[0] == 1 && initCtorTest[1] == 2 && initCtorTest[2] == 3 && - initCtorTest[3] == 1)); - - // Initializer ctor test (4 param) - vector3 initCtorTest2(1, 2, 3, 4); - ReportFailure(vector3Name, "initialized ctor (4 parameter version)", - (initCtorTest2[0] == 1 && initCtorTest2[1] == 2 && initCtorTest2[2] == 3 && - initCtorTest2[3] == 4)); - - scalar_t initArray[] = {1, 2, 3, 4}; - vector3 initCtorArrayTest3(initArray); - ReportFailure(vector3Name, "array initialized ctor (3 parameter version)", - (initCtorArrayTest3[0] == 1 && initCtorArrayTest3[1] == 2 && - initCtorArrayTest3[2] == 3 && initCtorArrayTest3[3] == 1)); - - vector3 initCtorArrayTest4(initArray, 4); - ReportFailure(vector3Name, "array initialized ctor (4 parameter version)", - (initCtorArrayTest4[0] == 1 && initCtorArrayTest4[1] == 2 && - initCtorArrayTest4[2] == 3 && initCtorArrayTest4[3] == 4)); - - // Copy ctor test - vector3 copyCtorTest(initCtorTest2); - ReportFailure(vector3Name, "copy ctor", (copyCtorTest[0] == 1 && copyCtorTest[1] == 2 && - copyCtorTest[2] == 3 && copyCtorTest[3] == 4)); -} - -void Testvector3Comparison(void) -{ - vector3 alpha(1, 1, 1); - vector3 beta(alpha); - vector3 gamma(2, 3, 4); - - ReportFailure(vector3Name, "equivalence operator test 1", (alpha == beta)); - ReportFailure(vector3Name, "equivalence operator test 2", (!(alpha == gamma))); - ReportFailure(vector3Name, "comparison operator test 1", !(alpha < beta)); - ReportFailure(vector3Name, "comparison operator test 2", (alpha < gamma)); - ReportFailure(vector3Name, "comparison operator test 3", !(gamma < beta)); -} - -void Testvector3Assignment(void) -{ - vector3 alpha(1, 1, 1, 1); - vector3 beta(10, 10, 10, 10); - alpha = beta; - ReportFailure(vector3Name, "assignment operator", (alpha == beta)); -} - -void Testvector3UnaryOps(void) -{ - vector3 alpha(10, 10, 10, 10); - vector3 beta(-10, -10, -10, -10); - alpha = -alpha; - ReportFailure(vector3Name, "negation operator", (alpha == beta)); - - ReportFailure(vector3Name, "length squared 3 element version", LengthSquared3(alpha) == 300); - ReportFailure(vector3Name, "length 3 element version", Length3(alpha) == SQRT_FUNCTION(300)); - ReportFailure(vector3Name, "length squared 4 element version", LengthSquared4(alpha) == 400); - ReportFailure(vector3Name, "length 4 element version", Length4(alpha) == SQRT_FUNCTION(400)); - - // Manually normalize beta - // Done without /= on vector3, as we want to be independant of failure of /= - // Earlier failures should be resolved before later ones (just like C++) - beta = alpha; - for (int i = 0; i < 3; ++i) - beta(i) /= SQRT_FUNCTION(300); - beta(3) = 1; - ReportFailure(vector3Name, "normalize 3 element version", Normalize3(alpha) == beta); - - beta = alpha; - for (int i = 0; i < 4; ++i) - beta(i) /= SQRT_FUNCTION(400); - ReportFailure(vector3Name, "normalize 4 element version", Normalize4(alpha) == beta); -} - -void Testvector3BinaryOps(void) -{ - // Vector * Matrix is tested in Testmatrix4x4BinaryOps - vector3 testVec(1, 1, 1, 1); - vector3 deltaVec(1, 2, 3, 4); - vector3 crossVec(1, -2, 1, 1); // testVec x deltaVec - - vector3 factorVec(10, 10, 10, 10); - vector3 sumVec(2, 3, 4, 5); - vector3 difVec(0, -1, -2, -3); - vector3 testVec2; - - ReportFailure(vector3Name, "scalar multiply 1", (testVec * 10) == factorVec); - ReportFailure(vector3Name, "scalar multiply 2", (10 * testVec) == factorVec); - testVec2 = testVec; - ReportFailure(vector3Name, "scalar multiply and store", (testVec2 *= 10) == factorVec); - - ReportFailure(vector3Name, "scalar divide", (factorVec / 10) == testVec); - testVec2 = factorVec; - ReportFailure(vector3Name, "scalar divide and store", (testVec2 /= 10) == testVec); - - ReportFailure(vector3Name, "vector addition", (testVec + deltaVec) == sumVec); - testVec2 = testVec; - ReportFailure(vector3Name, "vector addition and store", (testVec2 += deltaVec) == sumVec); - - ReportFailure(vector3Name, "vector subtraction", (testVec - deltaVec) == difVec); - testVec2 = testVec; - ReportFailure(vector3Name, "vector subtraction and store", (testVec2 -= deltaVec) == difVec); - - ReportFailure(vector3Name, "3 element dot product", 6 == DotProduct3(testVec, deltaVec)); - ReportFailure(vector3Name, "4 element dot product", 10 == DotProduct4(testVec, deltaVec)); - - ReportFailure(vector3Name, "cross product", crossVec == CrossProduct(testVec, deltaVec)); -} - -void Testvector3(void) -{ - // Accessors cannot be tested effectively... - // They are really trivial, and so don't really need testing, - // but more importantly, how do you test the ctors without assuming - // the accessors work? Conversely, how do you test the acccessors - // without assuming the ctors work? Chicken and egg problem, and I - // decided on testing the ctors, not the accessors. - Testvector3Constructors(); - Testvector3Comparison(); - Testvector3Assignment(); - Testvector3UnaryOps(); - Testvector3BinaryOps(); -} - -void Testmatrix4x4Constructors(void) -{ - // Check if default ctor compiles - matrix4x4 defaultTest; - - scalar_t initArray[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - matrix4x4 arrayTest; - arrayTest.C_Matrix(initArray); - bool passedTest = true; - for (int x = 0; x < 4; ++x) - for (int y = 0; y < 4; ++y) - if (arrayTest[x][y] != initArray[(y << 2) + x]) - passedTest = false; - ReportFailure(matrix4x4Name, "array constructor", passedTest); - - matrix4x4 copyTest(arrayTest); - passedTest = true; - for (int x = 0; x < 4; ++x) - for (int y = 0; y < 4; ++y) - if (arrayTest[x][y] != copyTest[x][y]) - passedTest = false; - ReportFailure(matrix4x4Name, "copy constructor", passedTest); -} - -void Testmatrix4x4Comparison(void) -{ - scalar_t initArray[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - scalar_t initArray2[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; - matrix4x4 alpha, beta, gamma; - alpha.C_Matrix(initArray); - beta.C_Matrix(initArray); - gamma.C_Matrix(initArray2); - - ReportFailure(matrix4x4Name, "equality test 1", alpha == beta); - ReportFailure(matrix4x4Name, "equality test 2", !(alpha == gamma)); - ReportFailure(matrix4x4Name, "comparison test 1", alpha < gamma); - ReportFailure(matrix4x4Name, "comparison test 2", !(gamma < alpha)); - ReportFailure(matrix4x4Name, "comparison test 3", !(alpha < beta)); -} - -void Testmatrix4x4BinaryOps(void) -{ - scalar_t initVector[] = {0, 1, 2, 3}; - scalar_t initMatrix[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - scalar_t resultVector[] = {0 * 0 + 1 * 1 + 2 * 2 + 3 * 3, 0 * 4 + 1 * 5 + 2 * 6 + 3 * 7, - 0 * 8 + 1 * 9 + 2 * 10 + 3 * 11, 0 * 12 + 1 * 13 + 2 * 14 + 3 * 15}; - - vector3 vector1(initVector, 4); - matrix4x4 matrix1; - matrix1.C_Matrix(initMatrix); - vector3 vectorTest(resultVector, 4); - ReportFailure(matrix4x4Name, "matrix * vector", vectorTest == matrix1 * vector1); - - scalar_t initMatrix2[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; - - matrix4x4 matrix2; - matrix2.C_Matrix(initMatrix2); - matrix4x4 resultMatrix; - for (int x = 0; x < 4; ++x) - for (int y = 0; y < 4; ++y) - { - resultMatrix(x)[y] = 0; - for (int i = 0; i < 4; ++i) - resultMatrix(x)[y] += matrix1[i][y] * matrix2[x][i]; - } - ReportFailure(matrix4x4Name, "matrix * matrix", resultMatrix == matrix1 * matrix2); -} - -void Testmatrix4x4(void) -{ - Testmatrix4x4Constructors(); - Testmatrix4x4Comparison(); - Testmatrix4x4BinaryOps(); -} - -int main(int, char *[]) -{ - int vectorFailures = 0; - int matrixFailures = 0; - Testvector3(); - vectorFailures = failures; - failures = 0; - - Testmatrix4x4(); - matrixFailures = failures; - - cout << endl - << "****************************************" << endl; - cout << "* *" << endl; - if (vectorFailures + matrixFailures == 0) - cout << "* No failures detected in Math3D *" << endl; - else - { - cout << "* FAILURES DETECTED IN MATH3D! *" << endl; - cout << "* Total vector3 failures: " << vectorFailures << " *" << endl; - cout << "* Total matrix4x4 failures: " << matrixFailures << " *" << endl; - cout << "* Total Failures in Math3D: " << vectorFailures + matrixFailures << " *" - << endl; - } - cout << "* *" << endl; - cout << "****************************************" << endl; - - return 0; -} -#endif diff --git a/utilities/dumb3d.h b/utilities/dumb3d.h deleted file mode 100644 index 33ea4bde..00000000 --- a/utilities/dumb3d.h +++ /dev/null @@ -1,671 +0,0 @@ -/* -This Source Code Form is subject to the -terms of the Mozilla Public License, v. -2.0. If a copy of the MPL was not -distributed with this file, You can -obtain one at -http://mozilla.org/MPL/2.0/. -*/ - -#pragma once - -#include - -namespace Math3D -{ - - glm::vec3 RotateY(glm::vec3 v, float angle); - glm::dvec3 RotateY(glm::dvec3 v, double angle); - - inline glm::dmat4 BasisChange(glm::dvec3 u, glm::dvec3 v, glm::dvec3 n) - { - return glm::dmat4{glm::dvec4(u.x, v.x, n.x, 0.0), glm::dvec4(u.y, v.y, n.y, 0.0), glm::dvec4(u.z, v.z, n.z, 0.0), glm::dvec4(0.0, 0.0, 0.0, 1.0)}; // 4 columns; first rows: u, v, n - } - - inline glm::dmat4 BasisChange(glm::dvec3 v, glm::dvec3 n) - { - glm::dvec3 u = glm::cross(v, n); - return BasisChange(u, v, n); - } - - - -// Define this to have Math3D.cp generate a main which tests these classes -//#define TEST_MATH3D - -// Define this to allow streaming output of vectors and matrices -// Automatically enabled by TEST_MATH3D -//#define OSTREAM_MATH3D - -// definition of the scalar type -typedef double scalar_t; -// inline pass-throughs to various basic math functions -// written in this style to allow for easy substitution with more efficient versions -inline scalar_t SINE_FUNCTION(scalar_t x) -{ - return std::sin(x); -} -inline scalar_t COSINE_FUNCTION(scalar_t x) -{ - return std::cos(x); -} -inline scalar_t SQRT_FUNCTION(scalar_t x) -{ - return std::sqrt(x); -} - -// 2 element vector -class vector2 -{ - public: - vector2(void) : - x(0.0), y(0.0) - { - } - vector2(scalar_t a, scalar_t b) - { - x = a; - y = b; - } - double x; - union - { - double y; - double z; - }; -}; -// 3 element vector -class vector3 -{ - public: - vector3(void) : - x(0.0), y(0.0), z(0.0) - {} - vector3( scalar_t X, scalar_t Y, scalar_t Z ) : - x( X ), y( Y ), z( Z ) - {} - template - vector3( glm::tvec3 const &Vector ) : - x( Vector.x ), y( Vector.y ), z( Vector.z ) - {} - template - operator glm::tvec3() const { - return glm::tvec3{ x, y, z }; } - // The int parameter is the number of elements to copy from initArray (3 or 4) - // explicit vector3(scalar_t* initArray, int arraySize = 3) - // { for (int i = 0;ix) > 0.02) - return false; // sześcian zamiast kuli - if (std::fabs(z - v->z) > 0.02) - return false; - if (std::fabs(y - v->y) > 0.02) - return false; - return true; - }; - - operator glm::dvec3() const - { - return glm::dvec3(x, y, z); - } - private: -}; - -// 4 element matrix -class matrix4x4 -{ - public: - matrix4x4(void) - { - memset( e, 0, sizeof( e ) ); - } - - // When defining matrices in C arrays, it is easiest to define them with - // the column increasing fastest. However, some APIs (OpenGL in particular) do this - // backwards, hence the "constructor" from C matrices, or from OpenGL matrices. - // Note that matrices are stored internally in OpenGL format. - void C_Matrix(scalar_t const *initArray) - { - int i = 0; - for (int y = 0; y < 4; ++y) - for (int x = 0; x < 4; ++x) - (*this)(x)[y] = initArray[i++]; - } - template - void OpenGL_Matrix(Type_ const *initArray) - { - int i = 0; - for (int x = 0; x < 4; ++x) - for (int y = 0; y < 4; ++y) - (*this)(x)[y] = initArray[i++]; - } - - // [] is to read, () is to write (const correctness) - // m[x][y] or m(x)[y] is the correct form - const scalar_t *operator[](int i) const - { - return &e[i << 2]; - } - scalar_t *operator()(int i) - { - return &e[i << 2]; - } - - // Low-level access to the array. - const scalar_t *readArray(void) const - { - return e; - } - scalar_t *getArray(void) - { - return e; - } - - // Construct various matrices; REPLACES CURRENT CONTENTS OF THE MATRIX! - // Written this way to work in-place and hence be somewhat more efficient - void Identity(void) - { - for (int i = 0; i < 16; ++i) - e[i] = 0; - e[0] = 1; - e[5] = 1; - e[10] = 1; - e[15] = 1; - } - inline matrix4x4 &Rotation(scalar_t angle, vector3 axis); - inline matrix4x4 &Translation(const vector3 &translation); - inline matrix4x4 &Scale(scalar_t x, scalar_t y, scalar_t z); - inline matrix4x4 &BasisChange(const vector3 &v, const vector3 &n); - inline matrix4x4 &BasisChange(const vector3 &u, const vector3 &v, const vector3 &n); - inline matrix4x4 &ProjectionMatrix(bool perspective, scalar_t l, scalar_t r, scalar_t t, - scalar_t b, scalar_t n, scalar_t f); - void InitialRotate() - { // taka specjalna rotacja, nie ma co ciągać trygonometrii - double f; - for (int i = 0; i < 16; i += 4) - { - e[i] = -e[i]; // zmiana znaku X - f = e[i + 1]; - e[i + 1] = e[i + 2]; - e[i + 2] = f; // zamiana Y i Z - } - }; - inline bool IdentityIs() - { // sprawdzenie jednostkowości - for (int i = 0; i < 16; ++i) - if (e[i] != ((i % 5) ? 0.0 : 1.0)) // jedynki tylko na 0, 5, 10 i 15 - return false; - return true; - } - - operator glm::dmat4() const - { - return glm::make_mat4(e); - } - - private: - scalar_t e[16]; -}; - -// Scalar operations - -// Returns false if there are 0 solutions -inline bool SolveQuadratic(scalar_t a, scalar_t b, scalar_t c, scalar_t *x1, scalar_t *x2); - -// Vector operations -inline bool operator==(const vector3 &, const vector3 &); -inline bool operator<(const vector3 &, const vector3 &); - -inline vector3 operator-(const vector3 &); -inline vector3 operator*(const vector3 &, scalar_t); -inline vector3 operator*(scalar_t, const vector3 &); -inline vector3 &operator*=(vector3 &, scalar_t); -inline vector3 operator/(const vector3 &, scalar_t); -inline vector3 &operator/=(vector3 &, scalar_t); - -inline vector3 operator+(const vector3 &, const vector3 &); -inline vector3 &operator+=(vector3 &, const vector3 &); -inline vector3 operator-(const vector3 &, const vector3 &); -inline vector3 &operator-=(vector3 &, const vector3 &); - -// X3 is the 3 element version of a function, X4 is four element -inline scalar_t LengthSquared3(const vector3 &); -inline scalar_t LengthSquared4(const vector3 &); -inline scalar_t Length3(const vector3 &); -inline scalar_t Length4(const vector3 &); -inline vector3 Normalize(const vector3 &); -inline vector3 Normalize4(const vector3 &); -inline scalar_t DotProduct(const vector3 &, const vector3 &); -inline scalar_t DotProduct4(const vector3 &, const vector3 &); -// Cross product is only defined for 3 elements -inline vector3 CrossProduct(const vector3 &, const vector3 &); - -inline vector3 operator*(const matrix4x4 &, const vector3 &); - -// Matrix operations -inline bool operator==(const matrix4x4 &, const matrix4x4 &); -inline bool operator<(const matrix4x4 &, const matrix4x4 &); - -inline matrix4x4 operator*(const matrix4x4 &, const matrix4x4 &); - -inline matrix4x4 Transpose(const matrix4x4 &); -scalar_t Determinant(const matrix4x4 &); -matrix4x4 Adjoint(const matrix4x4 &); -matrix4x4 Inverse(const matrix4x4 &); - -// Inline implementations follow -inline bool SolveQuadratic(scalar_t a, scalar_t b, scalar_t c, scalar_t *x1, scalar_t *x2) -{ - // If a == 0, solve a linear equation - if (a == 0) - { - if (b == 0) - return false; - *x1 = c / b; - *x2 = *x1; - return true; - } - else - { - scalar_t det = b * b - 4 * a * c; - if (det < 0) - return false; - det = SQRT_FUNCTION(det) / (2 * a); - scalar_t prefix = -b / (2 * a); - *x1 = prefix + det; - *x2 = prefix - det; - return true; - } -} - -inline bool operator==(const vector3 &v1, const vector3 &v2) -{ - return (v1.x == v2.x && v1.y == v2.y && v1.z == v2.z); -} - -inline bool operator<(const vector3 &v1, const vector3 &v2) -{ - // for (int i=0;i<4;++i) - // if (v1[i] < v2[i]) return true; - // else if (v1[i] > v2[i]) return false; - - return false; -} - -inline vector3 operator-(const vector3 &v) -{ - return vector3(-v.x, -v.y, -v.z); -} - -inline vector3 operator*(const vector3 &v, scalar_t k) -{ - return vector3(k * v.x, k * v.y, k * v.z); -} - -inline vector3 operator*(scalar_t k, const vector3 &v) -{ - return v * k; -} - -inline vector3 &operator*=(vector3 &v, scalar_t k) -{ - v.x *= k; - v.y *= k; - v.z *= k; - return v; -}; - -inline vector3 operator/(const vector3 &v, scalar_t k) -{ - return vector3(v.x / k, v.y / k, v.z / k); -} - -inline vector3 &operator/=(vector3 &v, scalar_t k) -{ - v.x /= k; - v.y /= k; - v.z /= k; - return v; -} - -inline scalar_t LengthSquared3(const vector3 &v) -{ - return DotProduct(v, v); -} -inline scalar_t LengthSquared4(const vector3 &v) -{ - return DotProduct4(v, v); -} - -inline scalar_t Length3(const vector3 &v) -{ - return SQRT_FUNCTION(LengthSquared3(v)); -} -inline scalar_t Length4(const vector3 &v) -{ - return SQRT_FUNCTION(LengthSquared4(v)); -} - -inline vector3 Normalize(const vector3 &v) -{ - vector3 retVal = v / Length3(v); - return retVal; -} -inline vector3 SafeNormalize(const vector3 &v) -{ - double l = Length3(v); - vector3 retVal; - if (l == 0) - retVal.x = retVal.y = retVal.z = 0; - else - retVal = v / l; - return retVal; -} -inline vector3 Normalize4(const vector3 &v) -{ - return v / Length4(v); -} - -inline vector3 operator+(const vector3 &v1, const vector3 &v2) -{ - return vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z); -} - -inline vector3 &operator+=(vector3 &v1, const vector3 &v2) -{ - v1.x += v2.x; - v1.y += v2.y; - v1.z += v2.z; - return v1; -} - -inline vector3 operator-(const vector3 &v1, const vector3 &v2) -{ - return vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); -} - -inline vector3 &operator-=(vector3 &v1, const vector3 &v2) -{ - v1.x -= v2.x; - v1.y -= v2.y; - v1.z -= v2.z; - return v1; -} - -inline scalar_t DotProduct(const vector3 &v1, const vector3 &v2) -{ - return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; -} - -inline scalar_t DotProduct4(const vector3 &v1, const vector3 &v2) -{ - return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; -} - -inline vector3 CrossProduct(const vector3 &v1, const vector3 &v2) -{ - return vector3(v1.y * v2.z - v1.z * v2.y, v2.x * v1.z - v2.z * v1.x, v1.x * v2.y - v1.y * v2.x); -} - -inline vector3 Interpolate( vector3 const &First, vector3 const &Second, float const Factor ) { - - return ( First * ( 1.0f - Factor ) ) + ( Second * Factor ); -} - -inline vector3 operator*(const matrix4x4 &m, const vector3 &v) -{ - return vector3(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0], - v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1], - v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]); -} - -void inline vector3::Normalize() -{ - double il = 1 / Length(); - x *= il; - y *= il; - z *= il; -} - -double inline vector3::Length() const -{ - return SQRT_FUNCTION(x * x + y * y + z * z); -} - -double inline vector3::LengthSquared() const { - - return ( x * x + y * y + z * z ); -} - -inline bool operator==(const matrix4x4 &m1, const matrix4x4 &m2) -{ - for (int x = 0; x < 4; ++x) - for (int y = 0; y < 4; ++y) - if (m1[x][y] != m2[x][y]) - return false; - return true; -} - -inline bool operator<(const matrix4x4 &m1, const matrix4x4 &m2) -{ - for (int x = 0; x < 4; ++x) - for (int y = 0; y < 4; ++y) - if (m1[x][y] < m2[x][y]) - return true; - else if (m1[x][y] > m2[x][y]) - return false; - return false; -} - -inline matrix4x4 operator*(const matrix4x4 &m1, const matrix4x4 &m2) -{ - matrix4x4 retVal; - for (int x = 0; x < 4; ++x) - for (int y = 0; y < 4; ++y) - { - retVal(x)[y] = 0; - for (int i = 0; i < 4; ++i) - retVal(x)[y] += m1[i][y] * m2[x][i]; - } - return retVal; -} - -inline matrix4x4 Transpose(const matrix4x4 &m) -{ - matrix4x4 retVal; - for (int x = 0; x < 4; ++x) - for (int y = 0; y < 4; ++y) - retVal(x)[y] = m[y][x]; - return retVal; -} - -inline matrix4x4 &matrix4x4::Rotation(scalar_t angle, vector3 axis) -{ - scalar_t c = COSINE_FUNCTION(angle); - scalar_t s = SINE_FUNCTION(angle); - // One minus c (short name for legibility of formulai) - scalar_t omc = (1 - c); - - if (LengthSquared3(axis) != 1) - axis = Normalize(axis); - - scalar_t x = axis.x; - scalar_t y = axis.y; - scalar_t z = axis.z; - scalar_t xs = x * s; - scalar_t ys = y * s; - scalar_t zs = z * s; - scalar_t xyomc = x * y * omc; - scalar_t xzomc = x * z * omc; - scalar_t yzomc = y * z * omc; - - e[0] = x * x * omc + c; - e[1] = xyomc + zs; - e[2] = xzomc - ys; - e[3] = 0; - - e[4] = xyomc - zs; - e[5] = y * y * omc + c; - e[6] = yzomc + xs; - e[7] = 0; - - e[8] = xzomc + ys; - e[9] = yzomc - xs; - e[10] = z * z * omc + c; - e[11] = 0; - - e[12] = 0; - e[13] = 0; - e[14] = 0; - e[15] = 1; - - return *this; -} - -inline matrix4x4 &matrix4x4::Translation(const vector3 &translation) -{ - Identity(); - e[12] = translation.x; - e[13] = translation.y; - e[14] = translation.z; - return *this; -} - -inline matrix4x4 &matrix4x4::Scale(scalar_t x, scalar_t y, scalar_t z) -{ - Identity(); - e[0] = x; - e[5] = y; - e[10] = z; - return *this; -} - -inline matrix4x4 &matrix4x4::BasisChange(const vector3 &u, const vector3 &v, const vector3 &n) -{ - e[0] = u.x; - e[1] = v.x; - e[2] = n.x; - e[3] = 0; - - e[4] = u.y; - e[5] = v.y; - e[6] = n.y; - e[7] = 0; - - e[8] = u.z; - e[9] = v.z; - e[10] = n.z; - e[11] = 0; - - e[12] = 0; - e[13] = 0; - e[14] = 0; - e[15] = 1; - - return *this; -} - -inline matrix4x4 &matrix4x4::BasisChange(const vector3 &v, const vector3 &n) -{ - vector3 u = CrossProduct(v, n); - return BasisChange(u, v, n); -} - -inline matrix4x4 &matrix4x4::ProjectionMatrix(bool perspective, scalar_t left_plane, - scalar_t right_plane, scalar_t top_plane, - scalar_t bottom_plane, scalar_t near_plane, - scalar_t far_plane) -{ - scalar_t A = (right_plane + left_plane) / (right_plane - left_plane); - scalar_t B = (top_plane + bottom_plane) / (top_plane - bottom_plane); - scalar_t C = (far_plane + near_plane) / (far_plane - near_plane); - - Identity(); - if (perspective) - { - e[0] = 2 * near_plane / (right_plane - left_plane); - e[5] = 2 * near_plane / (top_plane - bottom_plane); - e[8] = A; - e[9] = B; - e[10] = C; - e[11] = -1; - e[14] = 2 * far_plane * near_plane / (far_plane - near_plane); - } - else - { - e[0] = 2 / (right_plane - left_plane); - e[5] = 2 / (top_plane - bottom_plane); - e[10] = -2 / (far_plane - near_plane); - e[12] = A; - e[13] = B; - e[14] = C; - } - return *this; -} - -double inline SquareMagnitude(const vector3 &v) -{ - return v.x * v.x + v.y * v.y + v.z * v.z; -} - -} // close namespace - -// If we're testing, then we need OSTREAM support -#ifdef TEST_MATH3D -#define OSTREAM_MATH3D -#endif - -#ifdef OSTREAM_MATH3D -#include -// Streaming support -std::ostream &operator<<(std::ostream &os, const Math3D::vector3 &v) -{ - os << '['; - for (int i = 0; i < 4; ++i) - os << ' ' << v[i]; - return os << ']'; -} - -std::ostream &operator<<(std::ostream &os, const Math3D::matrix4x4 &m) -{ - for (int y = 0; y < 4; ++y) - { - os << '['; - for (int x = 0; x < 4; ++x) - os << ' ' << m[x][y]; - os << " ]" << std::endl; - } - return os; -} -#endif // OSTREAM_MATH3D diff --git a/utilities/glmHelpers.h b/utilities/glmHelpers.h new file mode 100644 index 00000000..b784f2d3 --- /dev/null +++ b/utilities/glmHelpers.h @@ -0,0 +1,21 @@ +#pragma once +#include + +inline glm::dmat4 BasisChange(glm::dvec3 u, glm::dvec3 v, glm::dvec3 n) +{ + return glm::dmat4{glm::dvec4(u.x, v.x, n.x, 0.0), glm::dvec4(u.y, v.y, n.y, 0.0), glm::dvec4(u.z, v.z, n.z, 0.0), glm::dvec4(0.0, 0.0, 0.0, 1.0)}; // 4 columns; first rows: u, v, n +} + +inline glm::dmat4 BasisChange(glm::dvec3 v, glm::dvec3 n) +{ + glm::dvec3 u = glm::cross(v, n); + return BasisChange(u, v, n); +} + +template inline glm::vec<3, T> RotateY(const glm::vec<3, T> &v, T angle) +{ + T s = std::sin(angle); + T c = std::cos(angle); + + return glm::vec<3, T>(c * v.x + s * v.z, v.y, c * v.z - s * v.x); +} diff --git a/vehicle/Camera.cpp b/vehicle/Camera.cpp index 51f1ca46..4d2d630f 100644 --- a/vehicle/Camera.cpp +++ b/vehicle/Camera.cpp @@ -12,6 +12,7 @@ http://mozilla.org/MPL/2.0/. #include "utilities/Globals.h" #include "utilities/utilities.h" +#include "utilities/glmHelpers.h" #include "Console.h" #include "utilities/Timer.h" #include "vehicle/Driver.h" @@ -171,7 +172,7 @@ void TCamera::Update() || ( true == DebugCameraFlag ) ) { // free movement position update auto movement { Velocity }; - movement = Math3D::RotateY(movement, Angle.y); + movement = RotateY(movement, Angle.y); Pos += movement * 5.0 * deltatime; } else { @@ -194,7 +195,7 @@ void TCamera::Update() movement.y = -movement.y; } */ - movement = Math3D::RotateY(movement, Angle.y); + movement = RotateY(movement, Angle.y); m_owneroffset += movement * deltatime; } diff --git a/vehicle/DynObj.cpp b/vehicle/DynObj.cpp index 24a87629..d8b764cb 100644 --- a/vehicle/DynObj.cpp +++ b/vehicle/DynObj.cpp @@ -23,6 +23,7 @@ http://mozilla.org/MPL/2.0/. #include "utilities/Globals.h" #include "utilities/Timer.h" #include "utilities/Logs.h" +#include "utilities/glmHelpers.h" #include "Console.h" #include "world/Traction.h" #include "audio/sound.h" @@ -2695,7 +2696,7 @@ void TDynamicObject::Move(double fDistance) vLeft = glm::normalize(glm::cross(vUp, vFront)); // wektor w lewo // vUp=CrossProduct(vFront,vLeft); //wektor w górę } - mMatrix = Math3D::BasisChange(vLeft, vUp, vFront); // to też można by od razu policzyć, ale potrzebne jest do wyświetlania // przesuwanie jest jednak rzadziej niż renderowanie + mMatrix = BasisChange(vLeft, vUp, vFront); // to też można by od razu policzyć, ale potrzebne jest do wyświetlania // przesuwanie jest jednak rzadziej niż renderowanie mMatrix = glm::inverse(mMatrix); // wyliczenie macierzy dla pojazdu (potrzebna tylko do wyświetlania?) // if (MoverParameters->CategoryFlag&2) { // przesunięcia są używane po wyrzuceniu pociągu z toru diff --git a/vehicle/Train.cpp b/vehicle/Train.cpp index 9e062133..d79e1023 100644 --- a/vehicle/Train.cpp +++ b/vehicle/Train.cpp @@ -23,7 +23,6 @@ http://mozilla.org/MPL/2.0/. #include "utilities/Logs.h" #include "model/MdlMngr.h" #include "model/Model3d.h" -#include "utilities/dumb3d.h" #include "utilities/Timer.h" #include "vehicle/Driver.h" #include "vehicle/DynObj.h" From 7d561f8443b7af3e8ea3dc88a96f9633229d5e2f Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Mon, 27 Apr 2026 23:13:12 +0200 Subject: [PATCH 15/19] use glm::length2 instead of glm::dot for squared length --- betterRenderer/renderer/source/track_batching.cpp | 8 ++++---- model/AnimModel.cpp | 6 +++--- vehicle/Driver.cpp | 6 ++---- world/Track.cpp | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/betterRenderer/renderer/source/track_batching.cpp b/betterRenderer/renderer/source/track_batching.cpp index 4223ae31..cebb8669 100644 --- a/betterRenderer/renderer/source/track_batching.cpp +++ b/betterRenderer/renderer/source/track_batching.cpp @@ -583,7 +583,7 @@ void NvRenderer::RenderBatches(const RenderPass& pass) { glm::clamp(pass.m_origin, batch.m_origin - batch.m_extent, batch.m_origin + batch.m_extent) - pass.m_origin; - if (glm::dot(closest_point, closest_point) >= batch.m_sqr_distance_max) + if (glm::length2(closest_point) >= batch.m_sqr_distance_max) return; if (batch.m_transforms.size() > 0) { double min_dist = std::numeric_limits::max(); @@ -594,9 +594,9 @@ void NvRenderer::RenderBatches(const RenderPass& pass) { batch.m_instance_radius)) continue; glm::dvec3 offset = instance_transform[3].xyz - pass.m_origin; - double dist = glm::dot(offset, offset); - min_dist = glm::min(min_dist, dist); - max_dist = glm::max(max_dist, dist); + double dist2 = glm::length2(offset); + min_dist = glm::min(min_dist, dist2); + max_dist = glm::max(max_dist, dist2); } if (min_dist > max_dist) return; if (min_dist >= batch.m_sqr_distance_max || diff --git a/model/AnimModel.cpp b/model/AnimModel.cpp index be872a6f..78e2eda5 100644 --- a/model/AnimModel.cpp +++ b/model/AnimModel.cpp @@ -96,14 +96,14 @@ void TAnimContainer::UpdateModel() { if (fTranslateSpeed != 0.0) { auto dif = vTranslateTo - vTranslation; // wektor w kierunku docelowym - double l2 = glm::dot(dif, dif); // długość wektora potrzebnego przemieszczenia + double l2 = glm::length2(dif); // długość wektora potrzebnego przemieszczenia if (l2 >= 0.0001) { // jeśli do przemieszczenia jest ponad 1cm auto s = glm::normalize(dif); // jednostkowy wektor kierunku // Długość wektora nie jest równa 0, sprawdzane wcześniej więc wektor normalny będzie zawsze prawidłowy. s = s * (fTranslateSpeed * Timer::GetDeltaTime()); // przemieszczenie w podanym czasie z daną prędkością - if (glm::dot(s, s) < l2) //żeby nie jechało na drugą stronę + if (glm::length2(s) < l2) //żeby nie jechało na drugą stronę vTranslation += s; else vTranslation = vTranslateTo; // koniec animacji, "koniec animowania" uruchomi @@ -113,7 +113,7 @@ void TAnimContainer::UpdateModel() { { // koniec animowania vTranslation = vTranslateTo; fTranslateSpeed = 0.0; // wyłączenie przeliczania wektora - if (glm::dot(vTranslation, vTranslation) <= 0.0001) // jeśli jest w punkcie początkowym + if (glm::length2(vTranslation) <= 0.0001) // jeśli jest w punkcie początkowym iAnim &= ~2; // wyłączyć zmianę pozycji submodelu if( evDone ) { // wykonanie eventu informującego o zakończeniu diff --git a/vehicle/Driver.cpp b/vehicle/Driver.cpp index d506d624..0a3f6265 100644 --- a/vehicle/Driver.cpp +++ b/vehicle/Driver.cpp @@ -59,14 +59,12 @@ double GetDistanceToEvent(TTrack const *track, basic_event const *event, double double seg_len = scan_dir > 0 ? 0.0 : 1.0; double const dzielnik = 1.0 / segment->GetLength();// rozdzielczosc mniej wiecej 1m int krok = 0; // krok obliczeniowy do sprawdzania czy odwracamy - auto temp = pos_event - segment->FastGetPoint(seg_len); - len2 = glm::dot(temp, temp); + len2 = glm::length2(pos_event - segment->FastGetPoint(seg_len)); do { len1 = len2; seg_len += scan_dir > 0 ? dzielnik : -dzielnik; - temp = pos_event - segment->FastGetPoint(seg_len); - len2 = glm::dot(temp, temp); + len2 = glm::length2(pos_event - segment->FastGetPoint(seg_len)); ++krok; } while ((len1 > len2) && (seg_len >= dzielnik && (seg_len <= (1.0 - dzielnik)))); //trzeba sprawdzić czy seg_len nie osiągnął skrajnych wartości, bo wtedy diff --git a/world/Track.cpp b/world/Track.cpp index 60411db0..e688c79b 100644 --- a/world/Track.cpp +++ b/world/Track.cpp @@ -770,7 +770,7 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) { // Ra 2014-07: dla skrzyżowań będą dodatkowe segmenty SwitchExtension->Segments[2]->Init(p2, cp2 + p2, cp4 + p4, p4, segsize, r2, r4); // z punktu 2 do 4 auto p1p3 = p3 - p1; - if (glm::dot(p1p3, p1p3) < 0.01) // gdy mniej niż 10cm, to mamy skrzyżowanie trzech dróg + if (glm::length2(p1p3) < 0.01) // gdy mniej niż 10cm, to mamy skrzyżowanie trzech dróg SwitchExtension->iRoads = 3; else // dla 4 dróg będą dodatkowe 3 segmenty { From cba106e22e26ad20e996231e88d7149ab43a68b3 Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Mon, 27 Apr 2026 23:27:08 +0200 Subject: [PATCH 16/19] Use glm::length2 instead of glm::length where possible --- application/drivermode.cpp | 4 ++-- audio/audiorenderer.cpp | 2 +- model/Model3d.cpp | 5 +++-- rendering/opengl33renderer.cpp | 5 +++-- rendering/openglrenderer.cpp | 5 +++-- rendering/precipitation.cpp | 4 +++- scene/scene.cpp | 6 ++++-- vehicle/DynObj.cpp | 9 ++++++--- world/Track.cpp | 15 +++++++++------ 9 files changed, 34 insertions(+), 21 deletions(-) diff --git a/application/drivermode.cpp b/application/drivermode.cpp index 51c31a7c..33f1bcd5 100644 --- a/application/drivermode.cpp +++ b/application/drivermode.cpp @@ -569,7 +569,7 @@ void driver_mode::update_camera(double const Deltatime) Camera.Reset(); // likwidacja obrotów - patrzy horyzontalnie na południe if (Camera.m_owner == nullptr) { - if (controlled && glm::length(controlled->GetPosition() - Camera.Pos) < 1500) + if (controlled && glm::length2(controlled->GetPosition() - Camera.Pos) < 1500 * 1500) // length2 is better than length for comparing because it does not require sqrt function { // gdy bliżej niż 1.5km Camera.LookAt = controlled->GetPosition() + 0.4 * controlled->VectorUp() * controlled->MoverParameters->Dim.H; @@ -583,7 +583,7 @@ void driver_mode::update_camera(double const Deltatime) if (d && pDynamicNearest) { // jeśli jakiś jest znaleziony wcześniej - if (100.0 * glm::length(d->GetPosition() - Camera.Pos) > glm::length(pDynamicNearest->GetPosition() - Camera.Pos)) + if (100.0 * glm::length2(d->GetPosition() - Camera.Pos) > glm::length2(pDynamicNearest->GetPosition() - Camera.Pos)) // length2 is better than length for comparing because it does not require sqrt function { d = pDynamicNearest; // jeśli najbliższy nie jest 10 razy bliżej niż } diff --git a/audio/audiorenderer.cpp b/audio/audiorenderer.cpp index 821a0161..6c60ebff 100644 --- a/audio/audiorenderer.cpp +++ b/audio/audiorenderer.cpp @@ -406,7 +406,7 @@ openal_renderer::update( double const Deltatime ) { cameramove = glm::dvec3{ 0.0 }; } // ... from camera jump to another location - if( glm::length( cameramove ) > 100.0 ) { + if( glm::length2( cameramove ) > 100.0 * 100.0) { // length2 is better than length for comparing because it does not require sqrt function cameramove = glm::dvec3{ 0.0 }; } m_listenervelocity = limit_velocity( cameramove / Deltatime ); diff --git a/model/Model3d.cpp b/model/Model3d.cpp index 2cdb6501..9b867bb4 100644 --- a/model/Model3d.cpp +++ b/model/Model3d.cpp @@ -630,8 +630,9 @@ std::pair TSubModel::Load(cParser &parser, bool dynamic) if (idx > 0) { // jeśli pierwszy trójkąt będzie zdegenerowany, to zostanie usunięty i nie ma co sprawdzać - if ((glm::length((vertex)->position - (vertex - 1)->position) > 1000.0) || (glm::length((vertex - 1)->position - (vertex - 2)->position) > 1000.0) || - (glm::length((vertex - 2)->position - (vertex)->position) > 1000.0)) + // length2 is better than length for comparing because it does not require sqrt function + if ((glm::length2((vertex)->position - (vertex - 1)->position) > 1000.0 * 1000.0) || (glm::length2((vertex - 1)->position - (vertex - 2)->position) > 1000.0 * 1000.0) || + (glm::length2((vertex - 2)->position - (vertex)->position) > 1000.0 * 1000.0)) { // jeżeli są dalej niż 2km od siebie //Ra 15-01: // obiekt wstawiany nie powinien być większy niż 300m (trójkąty terenu w E3D mogą mieć 1.5km) diff --git a/rendering/opengl33renderer.cpp b/rendering/opengl33renderer.cpp index 88181cef..be59d298 100644 --- a/rendering/opengl33renderer.cpp +++ b/rendering/opengl33renderer.cpp @@ -1293,7 +1293,8 @@ bool opengl33_renderer::Render_reflections(viewport_config &vp) auto const timestamp{ Timer::GetRenderTime() }; if( ( timestamp - m_environmentupdatetime < Global.reflectiontune.update_interval ) - && ( glm::length( m_renderpass.pass_camera.position() - m_environmentupdatelocation ) < 1000.0 ) ) { + && ( glm::length2( m_renderpass.pass_camera.position() - m_environmentupdatelocation ) < 1000.0 * 1000.0 ) ) // length2 is better than length for comparing because it does not require sqrt function + { // run update every 5+ mins of simulation time, or at least 1km from the last location return false; } @@ -4620,7 +4621,7 @@ void opengl33_renderer::Update_Lights(light_array &Lights) break; } auto const lightoffset = glm::vec3{scenelight.position - camera}; - if (glm::length(lightoffset) > 1000.f) { + if (glm::length2(lightoffset) > 1000.f * 1000.f) { // we don't care about lights past arbitrary limit of 1 km. // but there could still be weaker lights which are closer, so keep looking continue; diff --git a/rendering/openglrenderer.cpp b/rendering/openglrenderer.cpp index b1db5312..1919219a 100644 --- a/rendering/openglrenderer.cpp +++ b/rendering/openglrenderer.cpp @@ -892,7 +892,7 @@ opengl_renderer::Render_reflections() { auto const timestamp { Timer::GetRenderTime() }; if( ( timestamp - m_environmentupdatetime < Global.reflectiontune.update_interval ) - && ( glm::length( m_renderpass.camera.position() - m_environmentupdatelocation ) < 1000.0 ) ) { + && ( glm::length2( m_renderpass.camera.position() - m_environmentupdatelocation ) < 1000.0 * 1000.0 ) ) { // run update every 5+ mins of simulation time, or at least 1km from the last location return false; } @@ -4341,7 +4341,8 @@ opengl_renderer::Update_Lights( light_array &Lights ) { break; } auto const lightoffset = glm::vec3{ scenelight.position - camera }; - if( glm::length( lightoffset ) > 1000.f ) { + // length2 is better than length for comparing because it does not require sqrt function + if( glm::length2( lightoffset ) > 1000.f * 1000.f ) { // we don't care about lights past arbitrary limit of 1 km. // but there could still be weaker lights which are closer, so keep looking continue; diff --git a/rendering/precipitation.cpp b/rendering/precipitation.cpp index fdb4d3d1..cafc472e 100644 --- a/rendering/precipitation.cpp +++ b/rendering/precipitation.cpp @@ -70,7 +70,9 @@ basic_precipitation::update() { cameramove = glm::dvec3{ 0.0 }; } // ... from camera jump to another location - if( glm::length( cameramove ) > 100.0 ) { + // length2 is better than length for comparing because it does not require sqrt function + if( glm::length2( cameramove ) > 100.0 * 100.0 ) + { cameramove = glm::dvec3{ 0.0 }; } diff --git a/scene/scene.cpp b/scene/scene.cpp index 99617a67..57df3293 100644 --- a/scene/scene.cpp +++ b/scene/scene.cpp @@ -285,7 +285,8 @@ basic_cell::insert( shape_node Shape ) { if( ( shapedata.rangesquared_min == targetshapedata.rangesquared_min ) && ( shapedata.rangesquared_max == targetshapedata.rangesquared_max ) // ...and located close to each other (within arbitrary limit of 25m) - && ( glm::length( shapedata.area.center - targetshapedata.area.center ) < 25.0 ) ) { + // length2 is better than length for comparing because it does not require sqrt function + && ( glm::length2( shapedata.area.center - targetshapedata.area.center ) < 25.0 * 25.0 ) ) { if( true == targetshape.merge( Shape ) ) { // if the shape was merged there's nothing left to do @@ -311,7 +312,8 @@ basic_cell::insert( lines_node Lines ) { if( ( linesdata.rangesquared_min == targetlinesdata.rangesquared_min ) && ( linesdata.rangesquared_max == targetlinesdata.rangesquared_max ) // ...and located close to each other (within arbitrary limit of 10m) - && ( glm::length( linesdata.area.center - targetlinesdata.area.center ) < 10.0 ) ) { + // length2 is better than length for comparing because it does not require sqrt function + && ( glm::length2( linesdata.area.center - targetlinesdata.area.center ) < 10.0 * 10.0) ) { if( true == targetlines.merge( Lines ) ) { // if the shape was merged there's nothing left to do diff --git a/vehicle/DynObj.cpp b/vehicle/DynObj.cpp index d8b764cb..0d27ebed 100644 --- a/vehicle/DynObj.cpp +++ b/vehicle/DynObj.cpp @@ -1412,7 +1412,8 @@ TDynamicObject * TDynamicObject::ABuFindNearestObject(glm::vec3 pos, TTrack *Tra if( CouplNr == -2 ) { // wektor [kamera-obiekt] - poszukiwanie obiektu - if (glm::length(glm::dvec3(pos) - dynamic->vPosition) < 10.0) + // length2 is better than length for comparing because it does not require sqrt function + if (glm::length2(glm::dvec3(pos) - dynamic->vPosition) < 10.0 * 10.0) { // 10 metrów return dynamic; @@ -1420,12 +1421,14 @@ TDynamicObject * TDynamicObject::ABuFindNearestObject(glm::vec3 pos, TTrack *Tra } else { // jeśli (CouplNr) inne niz -2, szukamy sprzęgu - if (glm::length(glm::dvec3(pos) - dynamic->vCoulpler[0]) < 5.0) { + // length2 is better than length for comparing because it does not require sqrt function + if (glm::length2(glm::dvec3(pos) - dynamic->vCoulpler[0]) < 5.0 * 5.0) { // 5 metrów CouplNr = 0; return dynamic; } - if (glm::length(glm::dvec3(pos) - dynamic->vCoulpler[1]) < 5.0) { + // length2 is better than length for comparing because it does not require sqrt function + if (glm::length2(glm::dvec3(pos) - dynamic->vCoulpler[1]) < 5.0 * 5.0) { // 5 metrów CouplNr = 1; return dynamic; diff --git a/world/Track.cpp b/world/Track.cpp index e688c79b..eab3cb74 100644 --- a/world/Track.cpp +++ b/world/Track.cpp @@ -559,8 +559,9 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) // na przechyłce doliczyć jeszcze pół przechyłki } - if( (glm::length(( p1 + p1 + p2 ) / 3.0 - p1 - cp1) < 0.02 ) - || ( glm::length(( p1 + p2 + p2 ) / 3.0 - p2 + cp1) < 0.02 ) ) { + // length2 is better than length for comparing because it does not require sqrt function + if( (glm::length2(( p1 + p1 + p2 ) / 3.0 - p1 - cp1) < 0.02 * 0.02) + || (glm::length2(( p1 + p2 + p2 ) / 3.0 - p2 + cp1) < 0.02 * 0.02) ) { // "prostowanie" prostych z kontrolnymi, dokładność 2cm cp1 = cp2 = glm::dvec3(0, 0, 0); } @@ -655,8 +656,9 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) if( eType != tt_Cross ) { // dla skrzyżowań muszą być podane kontrolne - if( ( glm::length(( p1 + p1 + p2 ) / 3.0 - p1 - cp1 ) < 0.02 ) - || ( glm::length(( p1 + p2 + p2 ) / 3.0 - p2 + cp1 ) < 0.02 ) ) { + // length2 is better than length for comparing because it does not require sqrt function + if( (glm::length2(( p1 + p1 + p2 ) / 3.0 - p1 - cp1 ) < 0.02 * 0.02) + || (glm::length2(( p1 + p2 + p2 ) / 3.0 - p2 + cp1 ) < 0.02 * 0.02) ) { // "prostowanie" prostych z kontrolnymi, dokładność 2cm cp1 = cp2 = glm::dvec3(0, 0, 0); } @@ -719,8 +721,9 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) if( eType != tt_Cross ) { // dla skrzyżowań muszą być podane kontrolne - if( ( glm::length(( p3 + p3 + p4 ) / 3.0 - p3 - cp3) < 0.02 ) - || ( glm::length(( p3 + p4 + p4 ) / 3.0 - p4 + cp3) < 0.02 ) ) { + // length2 is better than length for comparing because it does not require sqrt function + if( (glm::length2(( p3 + p3 + p4 ) / 3.0 - p3 - cp3) < 0.02 * 0.02) + || (glm::length2(( p3 + p4 + p4 ) / 3.0 - p4 + cp3) < 0.02 * 0.02) ) { // "prostowanie" prostych z kontrolnymi, dokładność 2cm cp3 = cp4 = glm::dvec3(0, 0, 0); } From 623c4f827e670f1a5b916cefaf326c22bc4efc29 Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Tue, 28 Apr 2026 00:51:17 +0200 Subject: [PATCH 17/19] Remove not needed casts, variables and switch from double precission to float precission for some angle vectors --- audio/audiorenderer.cpp | 2 +- audio/sound.cpp | 2 +- model/AnimModel.cpp | 10 +++++----- model/AnimModel.h | 6 +++--- rendering/opengl33renderer.cpp | 18 ++++++++---------- rendering/openglrenderer.cpp | 4 ++-- rendering/particles.cpp | 2 +- utilities/Globals.h | 2 +- vehicle/Camera.cpp | 17 +++++++---------- vehicle/Camera.h | 4 ++-- vehicle/DynObj.cpp | 12 ++++++------ vehicle/DynObj.h | 8 ++++---- world/Segment.cpp | 2 +- world/Segment.h | 2 +- world/TrkFoll.h | 2 +- 15 files changed, 44 insertions(+), 49 deletions(-) diff --git a/audio/audiorenderer.cpp b/audio/audiorenderer.cpp index 6c60ebff..19ced6bb 100644 --- a/audio/audiorenderer.cpp +++ b/audio/audiorenderer.cpp @@ -387,7 +387,7 @@ openal_renderer::update( double const Deltatime ) { ::alListenerfv( AL_ORIENTATION, reinterpret_cast( orientation ) ); // velocity if( Deltatime > 0 ) { - auto cameramove { glm::dvec3{ cameraposition - cached_camerapos} }; + auto cameramove { cameraposition - cached_camerapos }; cached_camerapos = cameraposition; // intercept sudden user-induced camera jumps... // ...from free fly mode change diff --git a/audio/sound.cpp b/audio/sound.cpp index 715da729..98e25a20 100644 --- a/audio/sound.cpp +++ b/audio/sound.cpp @@ -363,7 +363,7 @@ sound_source::play( int const Flags ) { if( m_range != -1 ) { auto const cutoffrange { std::abs( m_range * 5 ) }; - if( glm::length2( location() - glm::dvec3 { Global.pCamera.Pos } ) > std::min( 2750.f * 2750.f, cutoffrange * cutoffrange ) ) { + if( glm::length2( location() - Global.pCamera.Pos ) > std::min( 2750.f * 2750.f, cutoffrange * cutoffrange ) ) { // while we drop sounds from beyond sensible and/or audible range // we act as if it was activated normally, meaning no need to include the opening bookend in subsequent calls m_playbeginning = false; diff --git a/model/AnimModel.cpp b/model/AnimModel.cpp index 78e2eda5..28f81ca9 100644 --- a/model/AnimModel.cpp +++ b/model/AnimModel.cpp @@ -29,11 +29,11 @@ std::list> TAnimModel::acAnimList; TAnimContainer::TAnimContainer() { - vRotateAngles = glm::dvec3(0.0f, 0.0f, 0.0f); // aktualne kąty obrotu - vDesiredAngles = glm::dvec3(0.0f, 0.0f, 0.0f); // docelowe kąty obrotu + vRotateAngles = glm::vec3(0.0f, 0.0f, 0.0f); // aktualne kąty obrotu + vDesiredAngles = glm::vec3(0.0f, 0.0f, 0.0f); // docelowe kąty obrotu fRotateSpeed = 0.0; - vTranslation = glm::dvec3(0.0f, 0.0f, 0.0f); // aktualne przesunięcie - vTranslateTo = glm::dvec3(0.0f, 0.0f, 0.0f); // docelowe przesunięcie + vTranslation = glm::dvec3(0.0, 0.0, 0.0); // aktualne przesunięcie + vTranslateTo = glm::dvec3(0.0, 0.0, 0.0); // docelowe przesunięcie fTranslateSpeed = 0.0; fAngleSpeed = 0.0; pSubModel = NULL; @@ -48,7 +48,7 @@ bool TAnimContainer::Init(TSubModel *pNewSubModel) return (pSubModel != NULL); } -void TAnimContainer::SetRotateAnim(glm::dvec3 vNewRotateAngles, double fNewRotateSpeed) +void TAnimContainer::SetRotateAnim(glm::vec3 vNewRotateAngles, double fNewRotateSpeed) { vDesiredAngles = vNewRotateAngles; fRotateSpeed = fNewRotateSpeed; diff --git a/model/AnimModel.h b/model/AnimModel.h index e708daa0..2d470e67 100644 --- a/model/AnimModel.h +++ b/model/AnimModel.h @@ -51,8 +51,8 @@ class TAnimContainer : std::enable_shared_from_this friend TAnimModel; private: - glm::dvec3 vRotateAngles; // dla obrotów Eulera - glm::dvec3 vDesiredAngles; + glm::vec3 vRotateAngles; // dla obrotów Eulera + glm::vec3 vDesiredAngles; double fRotateSpeed; glm::dvec3 vTranslation; glm::dvec3 vTranslateTo; @@ -81,7 +81,7 @@ class TAnimContainer : std::enable_shared_from_this inline std::string NameGet() { return (pSubModel ? pSubModel->pName : ""); }; - void SetRotateAnim( glm::dvec3 vNewRotateAngles, double fNewRotateSpeed); + void SetRotateAnim( glm::vec3 vNewRotateAngles, double fNewRotateSpeed); void SetTranslateAnim( glm::dvec3 vNewTranslate, double fNewSpeed); void AnimSetVMD(double fNewSpeed); void PrepareModel(); diff --git a/rendering/opengl33renderer.cpp b/rendering/opengl33renderer.cpp index be59d298..3ec1770d 100644 --- a/rendering/opengl33renderer.cpp +++ b/rendering/opengl33renderer.cpp @@ -3106,17 +3106,16 @@ bool opengl33_renderer::Render(TModel3d *Model, material_data const *Material, f return true; } -bool opengl33_renderer::Render(TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &A) +bool opengl33_renderer::Render(TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &Angle) { - glm::dvec3 Angle(A); // TODO: Why copy? ::glPushMatrix(); ::glTranslated(Position.x, Position.y, Position.z); if (Angle.y != 0.0) - ::glRotated(Angle.y, 0.0, 1.0, 0.0); + ::glRotated(Angle.y, 0.f, 1.f, 0.f); if (Angle.x != 0.0) - ::glRotated(Angle.x, 1.0, 0.0, 0.0); + ::glRotated(Angle.x, 1.f, 0.f, 0.f); if (Angle.z != 0.0) - ::glRotated(Angle.z, 0.0, 0.0, 1.0); + ::glRotated(Angle.z, 0.f, 0.f, 1.f); auto const result = Render(Model, Material, Squaredistance); @@ -3981,17 +3980,16 @@ bool opengl33_renderer::Render_Alpha(TModel3d *Model, material_data const *Mater return true; } -bool opengl33_renderer::Render_Alpha(TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &A) +bool opengl33_renderer::Render_Alpha(TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &Angle) { - glm::dvec3 Angle(A); // TODO: Why copy? ::glPushMatrix(); ::glTranslated(Position.x, Position.y, Position.z); if (Angle.y != 0.0) - ::glRotated(Angle.y, 0.0, 1.0, 0.0); + ::glRotated(Angle.y, 0.f, 1.f, 0.f); if (Angle.x != 0.0) - ::glRotated(Angle.x, 1.0, 0.0, 0.0); + ::glRotated(Angle.x, 1.f, 0.f, 0.f); if (Angle.z != 0.0) - ::glRotated(Angle.z, 0.0, 0.0, 1.0); + ::glRotated(Angle.z, 0.f, 0.f, 1.f); auto const result = Render_Alpha(Model, Material, Squaredistance); // position is effectively camera offset diff --git a/rendering/openglrenderer.cpp b/rendering/openglrenderer.cpp index 1919219a..b3c196e3 100644 --- a/rendering/openglrenderer.cpp +++ b/rendering/openglrenderer.cpp @@ -1041,8 +1041,8 @@ opengl_renderer::setup_pass( renderpass_config &Config, rendermode const Mode, f camera.position() = Global.pCamera.Pos - glm::dvec3 { lightvector }; viewmatrix *= glm::lookAt( camera.position(), - glm::dvec3 { Global.pCamera.Pos }, - glm::dvec3 { 0.f, 1.f, 0.f } ); + Global.pCamera.Pos, + glm::dvec3 { 0, 1, 0 } ); // projection auto const maphalfsize { std::min( 10.f, Config.draw_range * 0.5f ) }; camera.projection() *= diff --git a/rendering/particles.cpp b/rendering/particles.cpp index 9ec3839f..7155eab0 100644 --- a/rendering/particles.cpp +++ b/rendering/particles.cpp @@ -302,7 +302,7 @@ smoke_source::location() const { m_offset.x * m_owner.vehicle->VectorLeft() + m_offset.y * m_owner.vehicle->VectorUp() + m_offset.z * m_owner.vehicle->VectorFront() }; - location += glm::dvec3{ m_owner.vehicle->GetPosition() }; + location += m_owner.vehicle->GetPosition(); break; } case owner_type::node: { diff --git a/utilities/Globals.h b/utilities/Globals.h index f9513b45..6cef875a 100644 --- a/utilities/Globals.h +++ b/utilities/Globals.h @@ -46,7 +46,7 @@ struct global_settings { TCamera pCamera; // parametry kamery TCamera pDebugCamera; std::array FreeCameraInit; // pozycje kamery - std::array FreeCameraInitAngle; + std::array FreeCameraInitAngle; int iCameraLast{ -1 }; int iSlowMotion{ 0 }; // info o malym FPS: 0-OK, 1-wyłączyć multisampling, 3-promień 1.5km, 7-1km basic_light DayLight; diff --git a/vehicle/Camera.cpp b/vehicle/Camera.cpp index 4d2d630f..d5216930 100644 --- a/vehicle/Camera.cpp +++ b/vehicle/Camera.cpp @@ -172,7 +172,7 @@ void TCamera::Update() || ( true == DebugCameraFlag ) ) { // free movement position update auto movement { Velocity }; - movement = RotateY(movement, Angle.y); + movement = RotateY(movement, (double)Angle.y); Pos += movement * 5.0 * deltatime; } else { @@ -195,7 +195,7 @@ void TCamera::Update() movement.y = -movement.y; } */ - movement = RotateY(movement, Angle.y); + movement = RotateY(movement, (double)Angle.y); m_owneroffset += movement * deltatime; } @@ -203,19 +203,16 @@ void TCamera::Update() bool TCamera::SetMatrix( glm::dmat4 &Matrix ) { - Matrix = glm::rotate( Matrix, -Angle.z, glm::dvec3( 0.0, 0.0, 1.0 ) ); // po wyłączeniu tego kręci się pojazd, a sceneria nie - Matrix = glm::rotate( Matrix, -Angle.x, glm::dvec3( 1.0, 0.0, 0.0 ) ); - Matrix = glm::rotate( Matrix, -Angle.y, glm::dvec3( 0.0, 1.0, 0.0 ) ); // w zewnętrznym widoku: kierunek patrzenia + Matrix = glm::rotate(Matrix, -(double)Angle.x, glm::dvec3(1, 0, 0)); + Matrix = glm::rotate(Matrix, -(double)Angle.y, glm::dvec3(0, 1, 0)); // w zewnętrznym widoku: kierunek patrzenia + Matrix = glm::rotate(Matrix, -(double)Angle.z, glm::dvec3(0, 0, 1)); // po wyłączeniu tego kręci się pojazd, a sceneria nie if( ( m_owner != nullptr ) && ( false == DebugCameraFlag ) ) { - Matrix *= glm::lookAt( - glm::dvec3{ Pos }, - glm::dvec3{ LookAt }, - glm::dvec3{ vUp } ); + Matrix *= glm::lookAt(Pos, glm::dvec3{ LookAt }, glm::dvec3{ vUp } ); } else { - Matrix = glm::translate( Matrix, glm::dvec3{ -Pos } ); // nie zmienia kierunku patrzenia + Matrix = glm::translate( Matrix, -Pos ); // nie zmienia kierunku patrzenia } return true; diff --git a/vehicle/Camera.h b/vehicle/Camera.h index f0c72f92..9498c349 100644 --- a/vehicle/Camera.h +++ b/vehicle/Camera.h @@ -25,7 +25,7 @@ class TCamera { bool SetMatrix(glm::dmat4 &Matrix); void RaLook(); - glm::dvec3 Angle; // pitch, yaw, roll + glm::vec3 Angle; // pitch, yaw, roll glm::dvec3 Pos; // współrzędne obserwatora glm::vec3 LookAt; // współrzędne punktu, na który ma patrzeć glm::vec3 vUp; @@ -36,7 +36,7 @@ class TCamera { private: glm::dvec3 m_moverate; - glm::dvec3 m_rotationoffsets; // requested changes to pitch, yaw and roll + glm::vec3 m_rotationoffsets; // requested changes to pitch, yaw and roll }; diff --git a/vehicle/DynObj.cpp b/vehicle/DynObj.cpp index 0d27ebed..cca459d0 100644 --- a/vehicle/DynObj.cpp +++ b/vehicle/DynObj.cpp @@ -1511,11 +1511,11 @@ void TDynamicObject::ABuBogies() // [rad] // bogieRot[0].z=ABuAcos(Axle0.pPosition-Axle3.pPosition); bogieRot[0].z = Axle0.vAngles.z; - bogieRot[0] = RadToDeg(modelRot - bogieRot[0]); // mnożenie wektora przez stałą + bogieRot[0] = glm::degrees(modelRot - bogieRot[0]); // mnożenie wektora przez stałą smBogie[0]->SetRotateXYZ(bogieRot[0]); // bogieRot[1].z=ABuAcos(Axle2.pPosition-Axle1.pPosition); bogieRot[1].z = Axle1.vAngles.z; - bogieRot[1] = RadToDeg(modelRot - bogieRot[1]); + bogieRot[1] = glm::degrees(modelRot - bogieRot[1]); smBogie[1]->SetRotateXYZ(bogieRot[1]); } }; @@ -3220,7 +3220,7 @@ bool TDynamicObject::Update(double dt, double dt1) ErrorLog( "Bad traction: " + MoverParameters->Name + " lost power for " + to_string( NoVoltTime, 2 ) + " sec. at " - + to_string( glm::dvec3{ vPosition } ) ); + + to_string(vPosition) ); } } } @@ -3658,7 +3658,7 @@ bool TDynamicObject::Update(double dt, double dt1) glm::dvec3 old_pos = vPosition; Move(dDOMoveLen); - m_future_movement = (glm::dvec3(vPosition) - old_pos) / dt1 * Timer::GetDeltaRenderTime(); + m_future_movement = (vPosition - old_pos) / dt1 * Timer::GetDeltaRenderTime(); if (!bEnabled) // usuwane pojazdy nie mają toru { // pojazd do usunięcia @@ -8141,7 +8141,7 @@ TDynamicObject::update_shake( double const Timedelta ) { } shake *= 0.85; - ShakeState.velocity -= ( shake + ShakeState.velocity * 100.0 ) * ( BaseShake.jolt_scale.x + BaseShake.jolt_scale.y + BaseShake.jolt_scale.z ) / ( 200.0 ); + ShakeState.velocity -= ( shake + ShakeState.velocity * 100.0 ) * (double)( BaseShake.jolt_scale.x + BaseShake.jolt_scale.y + BaseShake.jolt_scale.z ) / ( 200.0 ); // McZapkie: ShakeState.offset += ShakeState.velocity * Timedelta; @@ -8748,7 +8748,7 @@ vehicle_table::update_traction( TDynamicObject *Vehicle ) { auto const vFront = glm::make_vec3( glm::value_ptr(Vehicle->VectorFront()) ); // wektor normalny dla płaszczyzny ruchu pantografu auto const vUp = glm::make_vec3( glm::value_ptr(Vehicle->VectorUp()) ); // wektor pionu pudła (pochylony od pionu na przechyłce) auto const vLeft = glm::make_vec3( glm::value_ptr(Vehicle->VectorLeft()) ); // wektor odległości w bok (odchylony od poziomu na przechyłce) - auto const position = glm::dvec3 { Vehicle->GetPosition() }; // współrzędne środka pojazdu + auto const position = Vehicle->GetPosition(); // współrzędne środka pojazdu for( int pantographindex = 0; pantographindex < Vehicle->iAnimType[ ANIM_PANTS ]; ++pantographindex ) { // pętla po pantografach diff --git a/vehicle/DynObj.h b/vehicle/DynObj.h index c495f578..aa509f1b 100644 --- a/vehicle/DynObj.h +++ b/vehicle/DynObj.h @@ -204,7 +204,7 @@ public: TTrackFollower Axle1; // oś z tyłu (od sprzęgu 1) int iAxleFirst; // numer pierwszej osi w kierunku ruchu (oś wiążąca pojazd z torem i wyzwalająca eventy) float fAxleDist; // rozstaw wózków albo osi do liczenia proporcji zacienienia - glm::dvec3 modelRot; // obrot pudła względem świata - do przeanalizowania, czy potrzebne!!! + glm::vec3 modelRot; // obrot pudła względem świata - do przeanalizowania, czy potrzebne!!! TDynamicObject * ABuFindNearestObject(glm::vec3 pos, TTrack *Track, TDynamicObject *MyPointer, int &CouplNr ); glm::dvec3 m_future_movement; @@ -304,7 +304,7 @@ private: void toggle_lights(); // switch light levels for registered interior sections private: // Ra: ciąg dalszy animacji, dopiero do ogarnięcia // ABuWozki 060504 - glm::dvec3 bogieRot[2]; // Obroty wozkow w/m korpusu + glm::vec3 bogieRot[2]; // Obroty wozkow w/m korpusu TSubModel *smBogie[2]; // Wyszukiwanie max 2 wozkow TSubModel *smWahacze[4]; // wahacze (np. nogi, dźwignia w drezynie) TSubModel *smBrakeMode; // Ra 15-01: nastawa hamulca też @@ -834,8 +834,8 @@ public: std::pair shake_angles() const; // members struct baseshake_config { - glm::dvec3 angle_scale { 0.05, 0.0, 0.1 }; // roll, yaw, pitch - glm::dvec3 jolt_scale{0.2, 0.2, 0.1}; + glm::vec3 angle_scale { 0.05, 0.0, 0.1 }; // roll, yaw, pitch + glm::vec3 jolt_scale{0.2, 0.2, 0.1}; double jolt_limit { 2.0f }; } BaseShake; struct engineshake_config { diff --git a/world/Segment.cpp b/world/Segment.cpp index 09d28be5..9ddccae4 100644 --- a/world/Segment.cpp +++ b/world/Segment.cpp @@ -338,7 +338,7 @@ Math3D::vector3 TSegment::GetPoint(double const fDistance) const }; */ // ustalenie pozycji osi na torze, przechyłki, pochylenia i kierunku jazdy -void TSegment::RaPositionGet(double const fDistance, glm::dvec3 &p, glm::dvec3 &a) const { +void TSegment::RaPositionGet(double const fDistance, glm::dvec3 &p, glm::vec3 &a) const { if (bCurve) { // można by wprowadzić uproszczony wzór dla okręgów płaskich auto const t = GetTFromS(fDistance); // aproksymacja dystansu na krzywej Beziera na parametr (t) diff --git a/world/Segment.h b/world/Segment.h index 9da9fcc5..24725d78 100644 --- a/world/Segment.h +++ b/world/Segment.h @@ -92,7 +92,7 @@ public: Math3D::vector3 GetPoint(double const fDistance) const; */ - void RaPositionGet(double const fDistance, glm::dvec3 &p, glm::dvec3 &a) const; + void RaPositionGet(double const fDistance, glm::dvec3 &p, glm::vec3 &a) const; glm::dvec3 FastGetPoint(double const t) const; inline glm::dvec3 diff --git a/world/TrkFoll.h b/world/TrkFoll.h index 7276fcd4..bba97681 100644 --- a/world/TrkFoll.h +++ b/world/TrkFoll.h @@ -45,7 +45,7 @@ public: // members double fOffsetH = 0.0; // Ra: odległość środka osi od osi toru (dla samochodów) - użyć do wężykowania glm::dvec3 pPosition; // współrzędne XYZ w układzie scenerii - glm::dvec3 vAngles; // x:przechyłka, y:pochylenie, z:kierunek w planie (w radianach) + glm::vec3 vAngles; // x:przechyłka, y:pochylenie, z:kierunek w planie (w radianach) private: // methods bool ComputatePosition(); // przeliczenie pozycji na torze From 6be1b0886dcf35e453a1c3908b8e5f37c14163ed Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Tue, 28 Apr 2026 01:23:53 +0200 Subject: [PATCH 18/19] Remove sad workaround --- scene/scene.cpp | 31 +++++++++++++------------------ vehicle/DynObj.cpp | 7 +++---- world/Track.cpp | 4 ++-- world/Track.h | 2 +- 4 files changed, 19 insertions(+), 25 deletions(-) diff --git a/scene/scene.cpp b/scene/scene.cpp index 57df3293..21365bd7 100644 --- a/scene/scene.cpp +++ b/scene/scene.cpp @@ -46,11 +46,10 @@ basic_cell::on_click( TAnimModel const *Instance ) { void basic_cell::update_traction( TDynamicObject *Vehicle, int const Pantographindex ) { // Winger 170204 - szukanie trakcji nad pantografami - // TODO: Why glm::make_vec3 and glm::value_ptr? - auto const vFront = glm::make_vec3( glm::value_ptr(Vehicle->VectorFront()) ); // wektor normalny dla płaszczyzny ruchu pantografu - auto const vUp = glm::make_vec3( glm::value_ptr(Vehicle->VectorUp()) ); // wektor pionu pudła (pochylony od pionu na przechyłce) - auto const vLeft = glm::make_vec3( glm::value_ptr(Vehicle->VectorLeft()) ); // wektor odległości w bok (odchylony od poziomu na przechyłce) - auto const position = glm::dvec3 { Vehicle->GetPosition() }; // współrzędne środka pojazdu + auto const vFront = Vehicle->VectorFront(); // wektor normalny dla płaszczyzny ruchu pantografu + auto const vUp = Vehicle->VectorUp(); // wektor pionu pudła (pochylony od pionu na przechyłce) + auto const vLeft = Vehicle->VectorLeft(); // wektor odległości w bok (odchylony od poziomu na przechyłce) + auto const position = Vehicle->GetPosition(); // współrzędne środka pojazdu auto pantograph = Vehicle->pants[ Pantographindex ].fParamPants; auto const pantographposition = position + ( vLeft * pantograph->vPos.z ) + ( vUp * pantograph->vPos.y ) + ( vFront * pantograph->vPos.x ); @@ -519,15 +518,13 @@ basic_cell::find( glm::dvec3 const &Point, float const Radius, bool const Onlyco // finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint std::tuple basic_cell::find( glm::dvec3 const &Point, TTrack const *Exclude ) const { - - glm::dvec3 point{Point.x, Point.y, Point.z}; // sad workaround until math classes unification // TODO: Is it needed? int endpointid; for( auto *path : m_directories.paths ) { if( path == Exclude ) { continue; } - endpointid = path->TestPoint( &point ); + endpointid = path->TestPoint( &Point ); if( endpointid >= 0 ) { return { path, endpointid }; @@ -692,11 +689,10 @@ basic_section::on_click( TAnimModel const *Instance ) { // legacy method, finds and assigns traction piece(s) to pantographs of provided vehicle void basic_section::update_traction( TDynamicObject *Vehicle, int const Pantographindex ) { - // TODO: Why glm::make_vec3 and glm::value_ptr? - auto const vFront = glm::make_vec3( glm::value_ptr(Vehicle->VectorFront()) ); // wektor normalny dla płaszczyzny ruchu pantografu - auto const vUp = glm::make_vec3( glm::value_ptr(Vehicle->VectorUp()) ); // wektor pionu pudła (pochylony od pionu na przechyłce) - auto const vLeft = glm::make_vec3( glm::value_ptr(Vehicle->VectorLeft()) ); // wektor odległości w bok (odchylony od poziomu na przechyłce) - auto const position = glm::dvec3{ Vehicle->GetPosition() }; // współrzędne środka pojazdu + auto const vFront = Vehicle->VectorFront(); // wektor normalny dla płaszczyzny ruchu pantografu + auto const vUp = Vehicle->VectorUp(); // wektor pionu pudła (pochylony od pionu na przechyłce) + auto const vLeft = Vehicle->VectorLeft(); // wektor odległości w bok (odchylony od poziomu na przechyłce) + auto const position = Vehicle->GetPosition(); // współrzędne środka pojazdu auto pantograph = Vehicle->pants[ Pantographindex ].fParamPants; auto const pantographposition = position + ( vLeft * pantograph->vPos.z ) + ( vUp * pantograph->vPos.y ) + ( vFront * pantograph->vPos.x ); @@ -1061,11 +1057,10 @@ basic_region::update_sounds() { void basic_region::update_traction( TDynamicObject *Vehicle, int const Pantographindex ) { // TODO: convert vectors to transformation matrix and pass them down the chain along with calculated position - // TODO: Why glm::make_vec3 and glm::value_ptr? - auto const vFront = glm::make_vec3( glm::value_ptr(Vehicle->VectorFront()) ); // wektor normalny dla płaszczyzny ruchu pantografu - auto const vUp = glm::make_vec3( glm::value_ptr(Vehicle->VectorUp()) ); // wektor pionu pudła (pochylony od pionu na przechyłce) - auto const vLeft = glm::make_vec3( glm::value_ptr(Vehicle->VectorLeft()) ); // wektor odległości w bok (odchylony od poziomu na przechyłce) - auto const position = glm::dvec3 { Vehicle->GetPosition() }; // współrzędne środka pojazdu + auto const vFront = Vehicle->VectorFront(); // wektor normalny dla płaszczyzny ruchu pantografu + auto const vUp = Vehicle->VectorUp(); // wektor pionu pudła (pochylony od pionu na przechyłce) + auto const vLeft = Vehicle->VectorLeft(); // wektor odległości w bok (odchylony od poziomu na przechyłce) + auto const position = Vehicle->GetPosition(); // współrzędne środka pojazdu auto p = Vehicle->pants[ Pantographindex ].fParamPants; auto const pant0 = position + ( vLeft * p->vPos.z ) + ( vUp * p->vPos.y ) + ( vFront * p->vPos.x ); diff --git a/vehicle/DynObj.cpp b/vehicle/DynObj.cpp index cca459d0..fe4a9933 100644 --- a/vehicle/DynObj.cpp +++ b/vehicle/DynObj.cpp @@ -8744,10 +8744,9 @@ vehicle_table::update( double Deltatime, int Iterationcount ) { // legacy method, checks for presence and height of traction wire for specified vehicle void vehicle_table::update_traction( TDynamicObject *Vehicle ) { - // TODO: Why glm::make_vec3 and glm::value_ptr? - auto const vFront = glm::make_vec3( glm::value_ptr(Vehicle->VectorFront()) ); // wektor normalny dla płaszczyzny ruchu pantografu - auto const vUp = glm::make_vec3( glm::value_ptr(Vehicle->VectorUp()) ); // wektor pionu pudła (pochylony od pionu na przechyłce) - auto const vLeft = glm::make_vec3( glm::value_ptr(Vehicle->VectorLeft()) ); // wektor odległości w bok (odchylony od poziomu na przechyłce) + auto const vFront = Vehicle->VectorFront(); // wektor normalny dla płaszczyzny ruchu pantografu + auto const vUp = Vehicle->VectorUp(); // wektor pionu pudła (pochylony od pionu na przechyłce) + auto const vLeft = Vehicle->VectorLeft(); // wektor odległości w bok (odchylony od poziomu na przechyłce) auto const position = Vehicle->GetPosition(); // współrzędne środka pojazdu for( int pantographindex = 0; pantographindex < Vehicle->iAnimType[ ANIM_PANTS ]; ++pantographindex ) { diff --git a/world/Track.cpp b/world/Track.cpp index eab3cb74..37375b35 100644 --- a/world/Track.cpp +++ b/world/Track.cpp @@ -2087,7 +2087,7 @@ bool TTrack::IsGroupable() return true; }; -bool Equal(glm::dvec3 v1, glm::dvec3 *v2) +bool Equal(const glm::dvec3 v1, const glm::dvec3 *v2) { // sprawdzenie odległości punktów // Ra: powinno być do 100cm wzdłuż toru i ze 2cm w poprzek (na prostej może nie być długiego // kawałka) @@ -2102,7 +2102,7 @@ bool Equal(glm::dvec3 v1, glm::dvec3 *v2) // return (SquareMagnitude(v1-*v2)<0.00012); //0.011^2=0.00012 }; -int TTrack::TestPoint(glm::dvec3 *Point) +int TTrack::TestPoint(const glm::dvec3 *Point) { // sprawdzanie, czy tory można połączyć switch (eType) { diff --git a/world/Track.h b/world/Track.h index 04d78496..26298344 100644 --- a/world/Track.h +++ b/world/Track.h @@ -308,7 +308,7 @@ public: } double WidthTotal(); bool IsGroupable(); - int TestPoint(glm::dvec3 *Point); + int TestPoint(const glm::dvec3 *Point); void MovedUp1(float const dh); void VelocitySet(float v); double VelocityGet(); From ca839652bf85bfd77c2bc3db4ea54a6f4516d43a Mon Sep 17 00:00:00 2001 From: docentYT <63965954+docentYT@users.noreply.github.com> Date: Tue, 28 Apr 2026 13:23:14 +0200 Subject: [PATCH 19/19] Use the sq function to force constexpr expressions for numeric literals and enhance readability --- application/drivermode.cpp | 4 ++-- audio/audiorenderer.cpp | 4 ++-- audio/sound.cpp | 2 +- environment/moon.cpp | 4 ++-- model/AnimModel.cpp | 4 ++-- model/Model3d.cpp | 4 ++-- rendering/opengl33renderer.cpp | 20 ++++++++++---------- rendering/openglrenderer.cpp | 28 ++++++++++++++-------------- rendering/precipitation.cpp | 2 +- scene/scene.cpp | 18 +++++++++--------- scene/scene.h | 8 ++++---- utilities/utilities.h | 5 +++++ vehicle/DynObj.cpp | 6 +++--- vehicle/Train.cpp | 2 +- world/Track.cpp | 12 ++++++------ 15 files changed, 64 insertions(+), 59 deletions(-) diff --git a/application/drivermode.cpp b/application/drivermode.cpp index 33f1bcd5..1aec7a7a 100644 --- a/application/drivermode.cpp +++ b/application/drivermode.cpp @@ -569,7 +569,7 @@ void driver_mode::update_camera(double const Deltatime) Camera.Reset(); // likwidacja obrotów - patrzy horyzontalnie na południe if (Camera.m_owner == nullptr) { - if (controlled && glm::length2(controlled->GetPosition() - Camera.Pos) < 1500 * 1500) // length2 is better than length for comparing because it does not require sqrt function + if (controlled && glm::length2(controlled->GetPosition() - Camera.Pos) < sq(1500)) // length2 is better than length for comparing because it does not require sqrt function { // gdy bliżej niż 1.5km Camera.LookAt = controlled->GetPosition() + 0.4 * controlled->VectorUp() * controlled->MoverParameters->Dim.H; @@ -583,7 +583,7 @@ void driver_mode::update_camera(double const Deltatime) if (d && pDynamicNearest) { // jeśli jakiś jest znaleziony wcześniej - if (100.0 * glm::length2(d->GetPosition() - Camera.Pos) > glm::length2(pDynamicNearest->GetPosition() - Camera.Pos)) // length2 is better than length for comparing because it does not require sqrt function + if (sq(10.0) * glm::length2(d->GetPosition() - Camera.Pos) > glm::length2(pDynamicNearest->GetPosition() - Camera.Pos)) // length2 is better than length for comparing because it does not require sqrt function { d = pDynamicNearest; // jeśli najbliższy nie jest 10 razy bliżej niż } diff --git a/audio/audiorenderer.cpp b/audio/audiorenderer.cpp index 19ced6bb..88fd74e8 100644 --- a/audio/audiorenderer.cpp +++ b/audio/audiorenderer.cpp @@ -150,7 +150,7 @@ openal_source::sync_with( sound_properties const &State ) { is_multipart ? EU07_SOUND_CUTOFFRANGE : // we keep multi-part sounds around longer, to minimize restarts as the sounds get out and back in range sound_range * 7.5f ); - if( glm::length2( sound_distance ) > std::min( ( cutoffrange * cutoffrange ), ( EU07_SOUND_CUTOFFRANGE * EU07_SOUND_CUTOFFRANGE ) ) ) { + if( glm::length2( sound_distance ) > std::min( sq(cutoffrange), sq(EU07_SOUND_CUTOFFRANGE) ) ) { stop(); sync = sync_state::bad_distance; // flag sync failure for the controller return; @@ -406,7 +406,7 @@ openal_renderer::update( double const Deltatime ) { cameramove = glm::dvec3{ 0.0 }; } // ... from camera jump to another location - if( glm::length2( cameramove ) > 100.0 * 100.0) { // length2 is better than length for comparing because it does not require sqrt function + if( glm::length2( cameramove ) > sq(100.0)) { // length2 is better than length for comparing because it does not require sqrt function cameramove = glm::dvec3{ 0.0 }; } m_listenervelocity = limit_velocity( cameramove / Deltatime ); diff --git a/audio/sound.cpp b/audio/sound.cpp index 98e25a20..fafcd53b 100644 --- a/audio/sound.cpp +++ b/audio/sound.cpp @@ -363,7 +363,7 @@ sound_source::play( int const Flags ) { if( m_range != -1 ) { auto const cutoffrange { std::abs( m_range * 5 ) }; - if( glm::length2( location() - Global.pCamera.Pos ) > std::min( 2750.f * 2750.f, cutoffrange * cutoffrange ) ) { + if( glm::length2( location() - Global.pCamera.Pos ) > std::min( sq(2750.f), sq(cutoffrange) ) ) { // while we drop sounds from beyond sensible and/or audible range // we act as if it was activated normally, meaning no need to include the opening bookend in subsequent calls m_playbeginning = false; diff --git a/environment/moon.cpp b/environment/moon.cpp index d7b4ab58..31d4b493 100644 --- a/environment/moon.cpp +++ b/environment/moon.cpp @@ -136,7 +136,7 @@ void cMoon::move() { // mean anomaly m_body.mnanom = clamp_circular( 115.3654 + 13.0649929509 * daynumber ); // M, degrees // eccentricity - double const e = 0.054900; + double constexpr e = 0.054900; // eccentric anomaly double E0 = m_body.mnanom + radtodeg * e * std::sin( degtorad * m_body.mnanom ) * ( 1.0 + e * std::cos( degtorad * m_body.mnanom ) ); double E1 = E0 - ( E0 - radtodeg * e * std::sin( degtorad * E0 ) - m_body.mnanom ) / ( 1.0 - e * std::cos( degtorad * E0 ) ); @@ -147,7 +147,7 @@ void cMoon::move() { double const E = E1; // lunar orbit plane rectangular coordinates double const xv = mndistance * ( std::cos( degtorad * E ) - e ); - double const yv = mndistance * std::sin( degtorad * E ) * std::sqrt( 1.0 - e*e ); + double const yv = mndistance * std::sin( degtorad * E ) * std::sqrt( 1.0 - sq(e) ); // distance m_body.distance = std::sqrt( xv*xv + yv*yv ); // r // true anomaly diff --git a/model/AnimModel.cpp b/model/AnimModel.cpp index 28f81ca9..96543401 100644 --- a/model/AnimModel.cpp +++ b/model/AnimModel.cpp @@ -97,7 +97,7 @@ void TAnimContainer::UpdateModel() { { auto dif = vTranslateTo - vTranslation; // wektor w kierunku docelowym double l2 = glm::length2(dif); // długość wektora potrzebnego przemieszczenia - if (l2 >= 0.0001) + if (l2 >= sq(0.01)) { // jeśli do przemieszczenia jest ponad 1cm auto s = glm::normalize(dif); // jednostkowy wektor kierunku // Długość wektora nie jest równa 0, sprawdzane wcześniej więc wektor normalny będzie zawsze prawidłowy. s = s * @@ -113,7 +113,7 @@ void TAnimContainer::UpdateModel() { { // koniec animowania vTranslation = vTranslateTo; fTranslateSpeed = 0.0; // wyłączenie przeliczania wektora - if (glm::length2(vTranslation) <= 0.0001) // jeśli jest w punkcie początkowym + if (glm::length2(vTranslation) <= sq(0.01)) // jeśli jest w punkcie początkowym iAnim &= ~2; // wyłączyć zmianę pozycji submodelu if( evDone ) { // wykonanie eventu informującego o zakończeniu diff --git a/model/Model3d.cpp b/model/Model3d.cpp index 9b867bb4..0e5a12d8 100644 --- a/model/Model3d.cpp +++ b/model/Model3d.cpp @@ -631,8 +631,8 @@ std::pair TSubModel::Load(cParser &parser, bool dynamic) { // jeśli pierwszy trójkąt będzie zdegenerowany, to zostanie usunięty i nie ma co sprawdzać // length2 is better than length for comparing because it does not require sqrt function - if ((glm::length2((vertex)->position - (vertex - 1)->position) > 1000.0 * 1000.0) || (glm::length2((vertex - 1)->position - (vertex - 2)->position) > 1000.0 * 1000.0) || - (glm::length2((vertex - 2)->position - (vertex)->position) > 1000.0 * 1000.0)) + if ((glm::length2((vertex)->position - (vertex - 1)->position) > sq(1000.0)) || (glm::length2((vertex - 1)->position - (vertex - 2)->position) > sq(1000.0)) || + (glm::length2((vertex - 2)->position - (vertex)->position) > sq(1000.0))) { // jeżeli są dalej niż 2km od siebie //Ra 15-01: // obiekt wstawiany nie powinien być większy niż 300m (trójkąty terenu w E3D mogą mieć 1.5km) diff --git a/rendering/opengl33renderer.cpp b/rendering/opengl33renderer.cpp index 3ec1770d..b3cd2cd2 100644 --- a/rendering/opengl33renderer.cpp +++ b/rendering/opengl33renderer.cpp @@ -26,8 +26,8 @@ http://mozilla.org/MPL/2.0/. //#define EU07_DEBUG_OPENGL -int const EU07_PICKBUFFERSIZE{ 1024 }; // size of (square) textures bound with the pick framebuffer -int const EU07_REFLECTIONFIDELITYOFFSET { 250 }; // artificial increase of range for reflection pass detail reduction +int constexpr EU07_PICKBUFFERSIZE{ 1024 }; // size of (square) textures bound with the pick framebuffer +int constexpr EU07_REFLECTIONFIDELITYOFFSET { 250 }; // artificial increase of range for reflection pass detail reduction void GLAPIENTRY ErrorCallback( GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam ) { @@ -1293,7 +1293,7 @@ bool opengl33_renderer::Render_reflections(viewport_config &vp) auto const timestamp{ Timer::GetRenderTime() }; if( ( timestamp - m_environmentupdatetime < Global.reflectiontune.update_interval ) - && ( glm::length2( m_renderpass.pass_camera.position() - m_environmentupdatelocation ) < 1000.0 * 1000.0 ) ) // length2 is better than length for comparing because it does not require sqrt function + && ( glm::length2( m_renderpass.pass_camera.position() - m_environmentupdatelocation ) < sq(1000.0)) ) // length2 is better than length for comparing because it does not require sqrt function { // run update every 5+ mins of simulation time, or at least 1km from the last location return false; @@ -2690,7 +2690,7 @@ void opengl33_renderer::Render(scene::shape_node const &Shape, bool const Ignore // reflection mode draws simplified version of the shapes, by artificially increasing view range distancesquared = // TBD, TODO: bind offset value with setting variable? - ( EU07_REFLECTIONFIDELITYOFFSET * EU07_REFLECTIONFIDELITYOFFSET ) + sq(EU07_REFLECTIONFIDELITYOFFSET) + glm::length2( ( data.area.center - m_renderpass.pass_camera.position() ) ); /* // TBD: take into account distance multipliers? @@ -2764,7 +2764,7 @@ void opengl33_renderer::Render(TAnimModel *Instance) return; } // TBD, TODO: bind offset value with setting variable? - distancesquared += ( EU07_REFLECTIONFIDELITYOFFSET * EU07_REFLECTIONFIDELITYOFFSET ); + distancesquared += sq(EU07_REFLECTIONFIDELITYOFFSET); break; } default: @@ -2779,7 +2779,7 @@ void opengl33_renderer::Render(TAnimModel *Instance) } // crude way to reject early items too far to affect the output (mostly relevant for shadow passes) auto const drawdistancethreshold{ m_renderpass.draw_range + 250 }; - if( distancesquared > drawdistancethreshold * drawdistancethreshold ) { + if( distancesquared > sq(drawdistancethreshold) ) { return; } // second stage visibility cull, reject modelstoo far away to be noticeable @@ -2857,7 +2857,7 @@ bool opengl33_renderer::Render(TDynamicObject *Dynamic) } // TBD, TODO: bind offset value with setting variable? // NOTE: combined 'squared' distance doesn't equal actual squared (distance + offset) but, eh - squaredistance += ( EU07_REFLECTIONFIDELITYOFFSET * EU07_REFLECTIONFIDELITYOFFSET ); + squaredistance += sq(EU07_REFLECTIONFIDELITYOFFSET); break; } default: @@ -2869,7 +2869,7 @@ bool opengl33_renderer::Render(TDynamicObject *Dynamic) } // crude way to reject early items too far to affect the output (mostly relevant for shadow and reflection passes) auto const drawdistancethreshold{ m_renderpass.draw_range + 250 }; - if( squaredistance > drawdistancethreshold * drawdistancethreshold ) { + if( squaredistance > sq(drawdistancethreshold) ) { return false; } // second stage visibility cull, reject vehicles too far away to be noticeable @@ -3779,7 +3779,7 @@ void opengl33_renderer::Render_Alpha(TAnimModel *Instance) } // crude way to reject early items too far to affect the output (mostly relevant for shadow passes) auto const drawdistancethreshold{ m_renderpass.draw_range + 250 }; - if( distancesquared > drawdistancethreshold * drawdistancethreshold ) { + if( distancesquared > sq(drawdistancethreshold) ) { return; } // second stage visibility cull, reject modelstoo far away to be noticeable @@ -4619,7 +4619,7 @@ void opengl33_renderer::Update_Lights(light_array &Lights) break; } auto const lightoffset = glm::vec3{scenelight.position - camera}; - if (glm::length2(lightoffset) > 1000.f * 1000.f) { + if (glm::length2(lightoffset) > sq(1000.f)) { // we don't care about lights past arbitrary limit of 1 km. // but there could still be weaker lights which are closer, so keep looking continue; diff --git a/rendering/openglrenderer.cpp b/rendering/openglrenderer.cpp index b3c196e3..75af6723 100644 --- a/rendering/openglrenderer.cpp +++ b/rendering/openglrenderer.cpp @@ -28,9 +28,9 @@ http://mozilla.org/MPL/2.0/. #include "rendering/screenshot.h" #include -int const EU07_PICKBUFFERSIZE { 1024 }; // size of (square) textures bound with the pick framebuffer -int const EU07_ENVIRONMENTBUFFERSIZE { 256 }; // size of (square) environmental cube map texture -int const EU07_REFLECTIONFIDELITYOFFSET { 250 }; // artificial increase of range for reflection pass detail reduction +int constexpr EU07_PICKBUFFERSIZE { 1024 }; // size of (square) textures bound with the pick framebuffer +int constexpr EU07_ENVIRONMENTBUFFERSIZE { 256 }; // size of (square) environmental cube map texture +int constexpr EU07_REFLECTIONFIDELITYOFFSET { 250 }; // artificial increase of range for reflection pass detail reduction float const EU07_OPACITYDEFAULT { 0.5f }; @@ -892,7 +892,7 @@ opengl_renderer::Render_reflections() { auto const timestamp { Timer::GetRenderTime() }; if( ( timestamp - m_environmentupdatetime < Global.reflectiontune.update_interval ) - && ( glm::length2( m_renderpass.camera.position() - m_environmentupdatelocation ) < 1000.0 * 1000.0 ) ) { + && ( glm::length2( m_renderpass.camera.position() - m_environmentupdatelocation ) < sq(1000.0)) ) { // run update every 5+ mins of simulation time, or at least 1km from the last location return false; } @@ -2284,7 +2284,7 @@ opengl_renderer::Render( scene::shape_node const &Shape, bool const Ignorerange // reflection mode draws simplified version of the shapes, by artificially increasing view range distancesquared = // TBD, TODO: bind offset value with setting variable? - ( EU07_REFLECTIONFIDELITYOFFSET * EU07_REFLECTIONFIDELITYOFFSET ) + sq(EU07_REFLECTIONFIDELITYOFFSET) // TBD: take into account distance multipliers? + glm::length2( ( data.area.center - m_renderpass.camera.position() ) ) /* / Global.fDistanceFactor */; break; @@ -2360,7 +2360,7 @@ opengl_renderer::Render( TAnimModel *Instance ) { return; } // TBD, TODO: bind offset value with setting variable? - distancesquared += ( EU07_REFLECTIONFIDELITYOFFSET * EU07_REFLECTIONFIDELITYOFFSET ); + distancesquared += sq(EU07_REFLECTIONFIDELITYOFFSET); break; } default: { @@ -2374,7 +2374,7 @@ opengl_renderer::Render( TAnimModel *Instance ) { } // crude way to reject early items too far to affect the output (mostly relevant for shadow passes) auto const drawdistancethreshold{ m_renderpass.draw_range + 250 }; - if( distancesquared > drawdistancethreshold * drawdistancethreshold ) { + if( distancesquared > sq(drawdistancethreshold) ) { return; } // second stage visibility cull, reject modelstoo far away to be noticeable @@ -2426,14 +2426,14 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) { 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 ); + squaredistance = std::max( sq(100.f), squaredistance ); } break; } case rendermode::cabshadows: { 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 ); + squaredistance = std::max( sq(100.f), squaredistance ); break; } case rendermode::reflections: { @@ -2441,7 +2441,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) { // it also ignores zoom settings and distance multipliers squaredistance = std::max( - 100.f * 100.f, + sq(100.f), // TBD: take into account distance multipliers? glm::length2( glm::vec3{ originoffset } ) /* / Global.fDistanceFactor */ ); // NOTE: arbitrary draw range limit @@ -2450,7 +2450,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) { } // TBD, TODO: bind offset value with setting variable? // NOTE: combined 'squared' distance doesn't equal actual squared (distance + offset) but, eh - squaredistance += ( EU07_REFLECTIONFIDELITYOFFSET * EU07_REFLECTIONFIDELITYOFFSET ); + squaredistance += sq(EU07_REFLECTIONFIDELITYOFFSET); break; } default: { @@ -2461,7 +2461,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) { } // crude way to reject early items too far to affect the output (mostly relevant for shadow and reflection passes) auto const drawdistancethreshold{ m_renderpass.draw_range + 250 }; - if( squaredistance > drawdistancethreshold * drawdistancethreshold ) { + if( squaredistance > sq(drawdistancethreshold) ) { return false; } // second stage visibility cull, reject vehicles too far away to be noticeable @@ -3519,7 +3519,7 @@ opengl_renderer::Render_Alpha( TAnimModel *Instance ) { } // crude way to reject early items too far to affect the output (mostly relevant for shadow passes) auto const drawdistancethreshold{ m_renderpass.draw_range + 250 }; - if( distancesquared > drawdistancethreshold * drawdistancethreshold ) { + if( distancesquared > sq(drawdistancethreshold) ) { return; } // second stage visibility cull, reject modelstoo far away to be noticeable @@ -4342,7 +4342,7 @@ opengl_renderer::Update_Lights( light_array &Lights ) { } auto const lightoffset = glm::vec3{ scenelight.position - camera }; // length2 is better than length for comparing because it does not require sqrt function - if( glm::length2( lightoffset ) > 1000.f * 1000.f ) { + if( glm::length2( lightoffset ) > sq(1000.f)) { // we don't care about lights past arbitrary limit of 1 km. // but there could still be weaker lights which are closer, so keep looking continue; diff --git a/rendering/precipitation.cpp b/rendering/precipitation.cpp index cafc472e..3f9ecaec 100644 --- a/rendering/precipitation.cpp +++ b/rendering/precipitation.cpp @@ -71,7 +71,7 @@ basic_precipitation::update() { } // ... from camera jump to another location // length2 is better than length for comparing because it does not require sqrt function - if( glm::length2( cameramove ) > 100.0 * 100.0 ) + if( glm::length2( cameramove ) > sq(100.0) ) { cameramove = glm::dvec3{ 0.0 }; } diff --git a/scene/scene.cpp b/scene/scene.cpp index 21365bd7..9780b593 100644 --- a/scene/scene.cpp +++ b/scene/scene.cpp @@ -285,7 +285,7 @@ basic_cell::insert( shape_node Shape ) { && ( shapedata.rangesquared_max == targetshapedata.rangesquared_max ) // ...and located close to each other (within arbitrary limit of 25m) // length2 is better than length for comparing because it does not require sqrt function - && ( glm::length2( shapedata.area.center - targetshapedata.area.center ) < 25.0 * 25.0 ) ) { + && ( glm::length2( shapedata.area.center - targetshapedata.area.center ) < sq(25.0) ) ) { if( true == targetshape.merge( Shape ) ) { // if the shape was merged there's nothing left to do @@ -312,7 +312,7 @@ basic_cell::insert( lines_node Lines ) { && ( linesdata.rangesquared_max == targetlinesdata.rangesquared_max ) // ...and located close to each other (within arbitrary limit of 10m) // length2 is better than length for comparing because it does not require sqrt function - && ( glm::length2( linesdata.area.center - targetlinesdata.area.center ) < 10.0 * 10.0) ) { + && ( glm::length2( linesdata.area.center - targetlinesdata.area.center ) < sq(10.0) ) ) { if( true == targetlines.merge( Lines ) ) { // if the shape was merged there's nothing left to do @@ -701,7 +701,7 @@ basic_section::update_traction( TDynamicObject *Vehicle, int const Pantographind for( auto &cell : m_cells ) { // we reject early cells which aren't within our area of interest - if( glm::length2( cell.area().center - pantographposition ) < ( ( cell.area().radius + radius ) * ( cell.area().radius + radius ) ) ) { + if( glm::length2( cell.area().center - pantographposition ) < sq(cell.area().radius + radius) ) { cell.update_traction( Vehicle, Pantographindex ); } } @@ -713,7 +713,7 @@ basic_section::update_events( glm::dvec3 const &Location, float const Radius ) { for( auto &cell : m_cells ) { - if( glm::length2( cell.area().center - Location ) < ( ( cell.area().radius + Radius ) * ( cell.area().radius + Radius ) ) ) { + if( glm::length2( cell.area().center - Location ) < sq(cell.area().radius + Radius) ) { // we reject cells which aren't within our area of interest cell.update_events(); } @@ -726,7 +726,7 @@ basic_section::update_sounds( glm::dvec3 const &Location, float const Radius ) { for( auto &cell : m_cells ) { - if( glm::length2( cell.area().center - Location ) < ( ( cell.area().radius + Radius ) * ( cell.area().radius + Radius ) ) ) { + if( glm::length2( cell.area().center - Location ) < sq(cell.area().radius + Radius) ) { // we reject cells which aren't within our area of interest cell.update_sounds(); } @@ -739,7 +739,7 @@ basic_section::radio_stop( glm::dvec3 const &Location, float const Radius ) { for( auto &cell : m_cells ) { - if( glm::length2( cell.area().center - Location ) < ( ( cell.area().radius + Radius ) * ( cell.area().radius + Radius ) ) ) { + if( glm::length2( cell.area().center - Location ) < sq(cell.area().radius + Radius) ) { // we reject cells which aren't within our area of interest cell.radio_stop(); } @@ -854,7 +854,7 @@ basic_section::find( glm::dvec3 const &Point, float const Radius, bool const Onl for( auto &cell : m_cells ) { // we reject early cells which aren't within our area of interest - if( glm::length2( cell.area().center - Point ) > ( ( cell.area().radius + Radius ) * ( cell.area().radius + Radius ) ) ) { + if( glm::length2( cell.area().center - Point ) > sq(cell.area().radius + Radius) ) { continue; } std::tie( vehiclefound, distancefound ) = cell.find( Point, Radius, Onlycontrolled, Findbycoupler ); @@ -900,7 +900,7 @@ basic_section::find( glm::dvec3 const &Point, TTraction const *Other, int const for( auto &cell : m_cells ) { // we reject early cells which aren't within our area of interest - if( glm::length2( cell.area().center - Point ) > ( ( cell.area().radius + radius ) * ( cell.area().radius + radius ) ) ) { + if( glm::length2( cell.area().center - Point ) > sq(cell.area().radius + radius) ) { continue; } std::tie( tractionfound, endpointfound, distancefound ) = cell.find( Point, Other, Currentdirection ); @@ -1477,7 +1477,7 @@ basic_region::sections( glm::dvec3 const &Point, float const Radius ) { auto *section { m_sections[ row * EU07_REGIONSIDESECTIONCOUNT + column ] }; if( ( section != nullptr ) - && ( glm::length2( section->area().center - Point ) <= ( ( section->area().radius + padding + Radius ) * ( section->area().radius + padding + Radius ) ) ) ) { + && ( glm::length2( section->area().center - Point ) <= sq( section->area().radius + padding + Radius ) ) ) { m_scratchpad.sections.emplace_back( section ); } diff --git a/scene/scene.h b/scene/scene.h index df641d02..31ae66e2 100644 --- a/scene/scene.h +++ b/scene/scene.h @@ -29,9 +29,9 @@ class opengl33_renderer; namespace scene { -int const EU07_CELLSIZE = 250; -int const EU07_SECTIONSIZE = 1000; -int const EU07_REGIONSIDESECTIONCOUNT = 500; // number of sections along a side of square region +int constexpr EU07_CELLSIZE = 250; +int constexpr EU07_SECTIONSIZE = 1000; +int constexpr EU07_REGIONSIDESECTIONCOUNT = 500; // number of sections along a side of square region struct scratch_data { @@ -428,7 +428,7 @@ public: //private: // types - using section_array = std::array; + using section_array = std::array; struct region_scratchpad { diff --git a/utilities/utilities.h b/utilities/utilities.h index 058220ca..4738b62f 100644 --- a/utilities/utilities.h +++ b/utilities/utilities.h @@ -29,6 +29,11 @@ template T sign(T x) #define DegToRad(a) ((M_PI / 180.0) * (a)) //(a) w nawiasie, bo może być dodawaniem #define RadToDeg(r) ((180.0 / M_PI) * (r)) +template constexpr T sq(T v) +{ + return v * v; +} + namespace paths { inline constexpr const char *scenery = "scenery/"; diff --git a/vehicle/DynObj.cpp b/vehicle/DynObj.cpp index fe4a9933..7952712c 100644 --- a/vehicle/DynObj.cpp +++ b/vehicle/DynObj.cpp @@ -1413,7 +1413,7 @@ TDynamicObject * TDynamicObject::ABuFindNearestObject(glm::vec3 pos, TTrack *Tra if( CouplNr == -2 ) { // wektor [kamera-obiekt] - poszukiwanie obiektu // length2 is better than length for comparing because it does not require sqrt function - if (glm::length2(glm::dvec3(pos) - dynamic->vPosition) < 10.0 * 10.0) + if (glm::length2(glm::dvec3(pos) - dynamic->vPosition) < sq(10.0)) { // 10 metrów return dynamic; @@ -1422,13 +1422,13 @@ TDynamicObject * TDynamicObject::ABuFindNearestObject(glm::vec3 pos, TTrack *Tra else { // jeśli (CouplNr) inne niz -2, szukamy sprzęgu // length2 is better than length for comparing because it does not require sqrt function - if (glm::length2(glm::dvec3(pos) - dynamic->vCoulpler[0]) < 5.0 * 5.0) { + if (glm::length2(glm::dvec3(pos) - dynamic->vCoulpler[0]) < sq(5.0)) { // 5 metrów CouplNr = 0; return dynamic; } // length2 is better than length for comparing because it does not require sqrt function - if (glm::length2(glm::dvec3(pos) - dynamic->vCoulpler[1]) < 5.0 * 5.0) { + if (glm::length2(glm::dvec3(pos) - dynamic->vCoulpler[1]) < sq(5.0)) { // 5 metrów CouplNr = 1; return dynamic; diff --git a/vehicle/Train.cpp b/vehicle/Train.cpp index d79e1023..c2b96713 100644 --- a/vehicle/Train.cpp +++ b/vehicle/Train.cpp @@ -9724,7 +9724,7 @@ TTrain::radio_message( sound_source *Message, int const Channel ) { auto const soundrange { Message->range() }; if( ( soundrange > 0 ) - && ( glm::length2( Message->location() - glm::dvec3 { DynamicObject->GetPosition() } ) > ( soundrange * soundrange ) ) ) { + && ( glm::length2( Message->location() - glm::dvec3 { DynamicObject->GetPosition() } ) > sq(soundrange) ) ) { // skip message playback if the receiver is outside of the emitter's range return; } diff --git a/world/Track.cpp b/world/Track.cpp index 37375b35..2f40a723 100644 --- a/world/Track.cpp +++ b/world/Track.cpp @@ -560,8 +560,8 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) } // length2 is better than length for comparing because it does not require sqrt function - if( (glm::length2(( p1 + p1 + p2 ) / 3.0 - p1 - cp1) < 0.02 * 0.02) - || (glm::length2(( p1 + p2 + p2 ) / 3.0 - p2 + cp1) < 0.02 * 0.02) ) { + if( (glm::length2(( p1 + p1 + p2 ) / 3.0 - p1 - cp1) < sq(0.02)) + || (glm::length2(( p1 + p2 + p2 ) / 3.0 - p2 + cp1) < sq(0.02)) ) { // "prostowanie" prostych z kontrolnymi, dokładność 2cm cp1 = cp2 = glm::dvec3(0, 0, 0); } @@ -657,8 +657,8 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) if( eType != tt_Cross ) { // dla skrzyżowań muszą być podane kontrolne // length2 is better than length for comparing because it does not require sqrt function - if( (glm::length2(( p1 + p1 + p2 ) / 3.0 - p1 - cp1 ) < 0.02 * 0.02) - || (glm::length2(( p1 + p2 + p2 ) / 3.0 - p2 + cp1 ) < 0.02 * 0.02) ) { + if( glm::length2(( p1 + p1 + p2 ) / 3.0 - p1 - cp1 ) < sq(0.02) + || glm::length2(( p1 + p2 + p2 ) / 3.0 - p2 + cp1 ) < sq(0.02) ) { // "prostowanie" prostych z kontrolnymi, dokładność 2cm cp1 = cp2 = glm::dvec3(0, 0, 0); } @@ -722,8 +722,8 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin) if( eType != tt_Cross ) { // dla skrzyżowań muszą być podane kontrolne // length2 is better than length for comparing because it does not require sqrt function - if( (glm::length2(( p3 + p3 + p4 ) / 3.0 - p3 - cp3) < 0.02 * 0.02) - || (glm::length2(( p3 + p4 + p4 ) / 3.0 - p4 + cp3) < 0.02 * 0.02) ) { + if( (glm::length2(( p3 + p3 + p4 ) / 3.0 - p3 - cp3) < sq(0.02)) + || (glm::length2(( p3 + p4 + p4 ) / 3.0 - p4 + cp3) < sq(0.02)) ) { // "prostowanie" prostych z kontrolnymi, dokładność 2cm cp3 = cp4 = glm::dvec3(0, 0, 0); }