From f9a8c1fbb382436cf3f746f5e00986335446f55c Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Tue, 20 Oct 2020 17:23:58 +0200 Subject: [PATCH 1/5] indexed geometry tangent calculation, explicit optional material parameters, uint8 serialization fix --- Model3d.cpp | 12 +++++++----- geometrybank.cpp | 18 +++++++++++++----- geometrybank.h | 2 +- material.cpp | 6 +++--- material.h | 4 ++-- opengl33renderer.cpp | 14 +++++++------- sn_utils.cpp | 4 ++-- 7 files changed, 35 insertions(+), 25 deletions(-) diff --git a/Model3d.cpp b/Model3d.cpp index 257d0397..f0ba3e02 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -457,8 +457,9 @@ std::pair TSubModel::Load( cParser &parser, bool dynamic ) 0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta } // and same thing with selfillum - if (!std::isnan(mat.selfillum)) - fLight = mat.selfillum; + if( mat.selfillum ) { + fLight = mat.selfillum.value(); + } } // visibility range @@ -677,8 +678,8 @@ std::pair TSubModel::Load( cParser &parser, bool dynamic ) } } Vertices.resize( m_geometry.vertex_count ); // in case we had some degenerate triangles along the way - gfx::calculate_tangents( Vertices, GL_TRIANGLES ); gfx::calculate_indices( Indices, Vertices ); + gfx::calculate_tangents( Vertices, Indices, GL_TRIANGLES ); // update values potentially changed by indexing m_geometry.index_count = Indices.size(); m_geometry.vertex_count = Vertices.size(); @@ -2040,8 +2041,9 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector *t, opengl_material const &mat = GfxRenderer->Material(m_material); // replace submodel selfillum with material one - if (!std::isnan(mat.selfillum)) - fLight = mat.selfillum; + if( mat.selfillum ) { + fLight = mat.selfillum.value(); + } } } else { diff --git a/geometrybank.cpp b/geometrybank.cpp index 6a860150..07c61fb6 100644 --- a/geometrybank.cpp +++ b/geometrybank.cpp @@ -69,7 +69,7 @@ basic_vertex::deserialize_packed( std::istream &s, bool const Tangent ) { // based on // Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”. // Terathon Software, 2001. http://terathon.com/code/tangent.html -void calculate_tangents(vertex_array &vertices, int type) +void calculate_tangents(vertex_array &vertices, index_array const &indices, int const type) { size_t vertex_count = vertices.size(); @@ -77,12 +77,14 @@ void calculate_tangents(vertex_array &vertices, int type) return; size_t triangle_count; + size_t tri_count_base = indices.empty() ? vertex_count : indices.size(); + if (type == GL_TRIANGLES) - triangle_count = vertex_count / 3; + triangle_count = tri_count_base / 3; else if (type == GL_TRIANGLE_STRIP) - triangle_count = vertex_count - 2; + triangle_count = tri_count_base - 2; else if (type == GL_TRIANGLE_FAN) - triangle_count = vertex_count - 2; + triangle_count = tri_count_base - 2; else return; @@ -118,6 +120,12 @@ void calculate_tangents(vertex_array &vertices, int type) i3 = a + 2; } + if (!indices.empty()) { + i1 = indices[i1]; + i2 = indices[i2]; + i3 = indices[i3]; + } + const glm::vec3 &v1 = vertices[i1].position; const glm::vec3 &v2 = vertices[i2].position; const glm::vec3 &v3 = vertices[i3].position; @@ -181,7 +189,7 @@ void calculate_indices( index_array &Indices, vertex_array &Vertices ) { Indices.resize( Vertices.size() ); std::iota( std::begin( Indices ), std::end( Indices ), 0 ); - // gather instances of used verices, replace the original vertex bank with it after you're done + // gather instances of used vertices, replace the original vertex bank with it after you're done vertex_array indexedvertices; indexedvertices.reserve( std::max( 100, Vertices.size() / 3 ) ); // optimistic guesstimate, but should reduce re-allocation somewhat auto const matchtolerance { 1e-5f }; diff --git a/geometrybank.h b/geometrybank.h index 1740e88a..0d2a9b08 100644 --- a/geometrybank.h +++ b/geometrybank.h @@ -52,7 +52,7 @@ using basic_index = std::uint32_t; using vertex_array = std::vector; using index_array = std::vector; -void calculate_tangents( vertex_array &vertices, int type ); +void calculate_tangents( vertex_array &vertices, index_array const &indices, int const type ); void calculate_indices( index_array &Indices, vertex_array &Vertices ); // generic geometry bank class, allows storage, update and drawing of geometry chunks diff --git a/material.cpp b/material.cpp index 50052bb5..f4ef9120 100644 --- a/material.cpp +++ b/material.cpp @@ -425,9 +425,9 @@ opengl_material::deserialize_mapping( cParser &Input, int const Priority, bool c float opengl_material::get_or_guess_opacity() const { - if (!std::isnan(opacity)) - return opacity; - + if( opacity ) { + return opacity.value(); + } if (textures[0] != null_handle) { auto const &tex = GfxRenderer->Texture(textures[0]); diff --git a/material.h b/material.h index f5744e38..7b77d26f 100644 --- a/material.h +++ b/material.h @@ -24,8 +24,8 @@ struct opengl_material { std::vector params_state; std::shared_ptr shader; - float opacity = std::numeric_limits::quiet_NaN(); - float selfillum = std::numeric_limits::quiet_NaN(); + std::optional opacity; + std::optional selfillum; float glossiness { 10.f }; std::string name; diff --git a/opengl33renderer.cpp b/opengl33renderer.cpp index 4491fc03..e41a6fb4 100644 --- a/opengl33renderer.cpp +++ b/opengl33renderer.cpp @@ -1736,7 +1736,7 @@ gfx::geometry_handle opengl33_renderer::Insert( gfx::index_array &Indices, gfx:: // creates a new geometry chunk of specified type from supplied data, in specified bank. returns: handle to the chunk or NULL gfx::geometry_handle opengl33_renderer::Insert(gfx::vertex_array &Vertices, gfx::geometrybank_handle const &Geometry, int const Type) { - gfx::calculate_tangents(Vertices, Type); + gfx::calculate_tangents(Vertices, gfx::index_array(), Type); return m_geometry.create_chunk(Vertices, Geometry, Type); } @@ -1744,7 +1744,7 @@ gfx::geometry_handle opengl33_renderer::Insert(gfx::vertex_array &Vertices, gfx: // replaces data of specified chunk with the supplied vertex data, starting from specified offset bool opengl33_renderer::Replace(gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry, int const Type, std::size_t const Offset) { - gfx::calculate_tangents(Vertices, Type); + gfx::calculate_tangents(Vertices, gfx::index_array(), Type); return m_geometry.replace(Vertices, Geometry, Offset); } @@ -1752,7 +1752,7 @@ bool opengl33_renderer::Replace(gfx::vertex_array &Vertices, gfx::geometry_handl // adds supplied vertex data at the end of specified chunk bool opengl33_renderer::Append(gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry, int const Type) { - gfx::calculate_tangents(Vertices, Type); + gfx::calculate_tangents(Vertices, gfx::index_array(), Type); return m_geometry.append(Vertices, Geometry); } @@ -1863,17 +1863,17 @@ void opengl33_renderer::Bind_Material( material_handle const Material, TSubModel if( entry.size == 1 ) { // HACK: convert color to luminosity, if it's passed as single value - src == glm::vec4 { colors::RGBtoHSV( glm::vec3 { src } ).z }; + src = glm::vec4 { colors::RGBtoHSV( glm::vec3 { src } ).z }; } for (size_t j = 0; j < entry.size; j++) model_ubs.param[entry.location][entry.offset + j] = src[j]; } - if( !std::isnan( material.opacity ) ) { + if( material.opacity ) { model_ubs.opacity = ( m_blendingenabled ? - -material.opacity : - material.opacity ); + -material.opacity.value() : + material.opacity.value() ); } else { model_ubs.opacity = ( diff --git a/sn_utils.cpp b/sn_utils.cpp index 6b6ec740..56b18ff9 100644 --- a/sn_utils.cpp +++ b/sn_utils.cpp @@ -132,7 +132,7 @@ glm::vec4 sn_utils::d_vec4( std::istream& s ) uint8_t sn_utils::d_uint8( std::istream& s ) { uint8_t buf; - s.read((char*)buf, 1); + s.read((char*)&buf, 1); return buf; } @@ -221,7 +221,7 @@ void sn_utils::ls_float64(std::ostream &s, double t) void sn_utils::s_uint8(std::ostream &s, uint8_t v) { - s.write((char*)v, 1); + s.write((char*)&v, 1); } void sn_utils::s_str(std::ostream &s, std::string v) From b0d46b9ddcff45e3ab3810151979e0da49b9a0f1 Mon Sep 17 00:00:00 2001 From: milek7 Date: Mon, 19 Oct 2020 16:47:25 +0200 Subject: [PATCH 2/5] scale matchtolerance, add VNT2 chunk type --- Model3d.cpp | 32 ++++++++++++++++++++++++-------- geometrybank.cpp | 4 ++-- geometrybank.h | 2 +- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/Model3d.cpp b/Model3d.cpp index f0ba3e02..7aa88410 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -480,6 +480,7 @@ std::pair TSubModel::Load( cParser &parser, bool dynamic ) // transformation matrix fMatrix = new float4x4(); readMatrix(parser, *fMatrix); // wczytanie transform + float transformscale = 1.0f; if( !fMatrix->IdentityIs() ) { iFlags |= 0x8000; // transform niejedynkowy - trzeba go przechować // check the scaling @@ -497,6 +498,7 @@ std::pair TSubModel::Load( cParser &parser, bool dynamic ) rescale : normalize ); } + transformscale = (scale.x + scale.y + scale.z) / 3.0f; } if (eType < TP_ROTATOR) { // wczytywanie wierzchołków @@ -678,7 +680,7 @@ std::pair TSubModel::Load( cParser &parser, bool dynamic ) } } Vertices.resize( m_geometry.vertex_count ); // in case we had some degenerate triangles along the way - gfx::calculate_indices( Indices, Vertices ); + gfx::calculate_indices( Indices, Vertices, transformscale ); gfx::calculate_tangents( Vertices, Indices, GL_TRIANGLES ); // update values potentially changed by indexing m_geometry.index_count = Indices.size(); @@ -1689,9 +1691,17 @@ void TModel3d::SaveToBinFile(std::string const &FileName) sn_utils::ls_uint32( s, MAKE_ID4( 'I', 'D', 'X', '0' + indexsize ) ); sn_utils::ls_uint32( s, 8 + m_indexcount * indexsize ); Root->serialize_indices( s, indexsize ); - sn_utils::ls_uint32( s, MAKE_ID4( 'V', 'N', 'T', '1' ) ); - sn_utils::ls_uint32( s, 8 + m_vertexcount * 20 ); - Root->serialize_geometry( s, true, true ); + + if (!(Global.iConvertModels & 8)) { + sn_utils::ls_uint32( s, MAKE_ID4( 'V', 'N', 'T', '1' ) ); + sn_utils::ls_uint32( s, 8 + m_vertexcount * 20 ); + Root->serialize_geometry( s, true, true ); + } + else { + sn_utils::ls_uint32( s, MAKE_ID4( 'V', 'N', 'T', '2' ) ); + sn_utils::ls_uint32( s, 8 + m_vertexcount * 48 ); + Root->serialize_geometry( s, false, true ); + } } else { sn_utils::ls_uint32( s, MAKE_ID4( 'V', 'N', 'T', '0' ) ); @@ -1833,16 +1843,22 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic) auto const &submodelgeometry { submodel.m_geometry }; submodel.Vertices.resize( submodelgeometry.vertex_count ); m_vertexcount += submodelgeometry.vertex_count; - if( vertextype > 0 ) { + if (vertextype == 1) { // expanded chunk formats for( auto &vertex : submodel.Vertices ) { - vertex.deserialize_packed( s, vertextype > 0 ); + vertex.deserialize_packed( s, true ); } } - else { + else if (vertextype == 2) { + // expanded chunk formats + for( auto &vertex : submodel.Vertices ) { + vertex.deserialize( s, true ); + } + } + else if (vertextype == 0) { // legacy vnt0 format for( auto &vertex : submodel.Vertices ) { - vertex.deserialize( s, vertextype > 0 ); + vertex.deserialize( s, false ); if( submodel.eType < TP_ROTATOR ) { // normal vectors debug routine if( ( false == submodel.m_normalizenormals ) diff --git a/geometrybank.cpp b/geometrybank.cpp index 07c61fb6..2ed930d9 100644 --- a/geometrybank.cpp +++ b/geometrybank.cpp @@ -185,14 +185,14 @@ void calculate_tangents(vertex_array &vertices, index_array const &indices, int } } -void calculate_indices( index_array &Indices, vertex_array &Vertices ) { +void calculate_indices( index_array &Indices, vertex_array &Vertices, float tolerancescale ) { Indices.resize( Vertices.size() ); std::iota( std::begin( Indices ), std::end( Indices ), 0 ); // gather instances of used vertices, replace the original vertex bank with it after you're done vertex_array indexedvertices; indexedvertices.reserve( std::max( 100, Vertices.size() / 3 ) ); // optimistic guesstimate, but should reduce re-allocation somewhat - auto const matchtolerance { 1e-5f }; + auto const matchtolerance { 1e-5f * tolerancescale }; for( auto idx = 0; idx < Indices.size(); ++idx ) { if( Indices[ idx ] < idx ) { // this index is pointing to a vertex out of linear order, i.e. it's an already processed duplicate we can skip diff --git a/geometrybank.h b/geometrybank.h index 0d2a9b08..0c0ec075 100644 --- a/geometrybank.h +++ b/geometrybank.h @@ -53,7 +53,7 @@ using vertex_array = std::vector; using index_array = std::vector; void calculate_tangents( vertex_array &vertices, index_array const &indices, int const type ); -void calculate_indices( index_array &Indices, vertex_array &Vertices ); +void calculate_indices( index_array &Indices, vertex_array &Vertices, float tolerancescale = 1.0f ); // generic geometry bank class, allows storage, update and drawing of geometry chunks From 3d5bc7ab0571a6f7036c18c63933bafa43425a6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Sun, 18 Oct 2020 17:18:16 +0200 Subject: [PATCH 3/5] Small fix for parking brake --- DynObj.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DynObj.cpp b/DynObj.cpp index e7ca5c55..99d07a17 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -3157,7 +3157,7 @@ bool TDynamicObject::Update(double dt, double dt1) && ( MoverParameters->Doors.instances[ side::left ].open_permit || MoverParameters->Doors.instances[ side::right ].open_permit ) ) }; - if ((MoverParameters->Vel < 0.5) && (MoverParameters->BrakePress > 0.2 || doorisopen)) + if ((MoverParameters->Vel < 0.5) && (eimic < 0 || doorisopen || MoverParameters->Hamulec->GetEDBCP())) { MoverParameters->ShuntMode = true; } @@ -3182,8 +3182,8 @@ bool TDynamicObject::Update(double dt, double dt1) { Fzad = std::min(LBR * FmaxED, FfulED); } - if (((MoverParameters->ShuntMode) && (Frj < 0.0015 * masa)) || - (MoverParameters->V * MoverParameters->DirAbsolute < -0.2)) + if (((MoverParameters->ShuntMode) && (eimic <= 0)) /*|| + (MoverParameters->V * MoverParameters->DirAbsolute < -0.2)*/) { auto const sbd { ( ( MoverParameters->SpringBrake.IsActive && MoverParameters->ReleaseParkingBySpringBrake ) ? 0.0 : MoverParameters->StopBrakeDecc ) }; Fzad = std::max( Fzad, sbd * masa ); From 459d3eef45f1bf02a3e4e106638c953f68ae7959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=B3lik=20Uszasty?= Date: Sun, 18 Oct 2020 20:22:00 +0200 Subject: [PATCH 4/5] No more acceleration when emergency brake is active --- McZapkie/Mover.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 433beb95..11961067 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -7073,7 +7073,8 @@ void TMoverParameters::CheckEIMIC(double dt) ( ( true == Mains ) || ( Power == 0.0 ) ) && ( ( Doors.instances[ side::left ].open_permit == false ) && ( Doors.instances[ side::right ].open_permit == false ) ) - && ( !SpringBrake.IsActive ) }; + && ( !SpringBrake.IsActive ) + && ( !LockPipe ) }; eimic = clamp(eimic, -1.0, eimicpowerenabled ? 1.0 : 0.0); } From dee0bd13f453750909ed437d9053ce02b1a0c7df Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Wed, 21 Oct 2020 02:07:40 +0200 Subject: [PATCH 5/5] build 201020. ai takeover logic tweak, opengl element array binding fix --- Driver.cpp | 4 +++- opengl33renderer.cpp | 4 ++++ version.h | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index ea4791eb..55ae0230 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -7490,16 +7490,18 @@ void TController::TakeControl( bool const Aidriver, bool const Forcevehiclecheck } else { // jeśli nic nie robi + OrderNext( Prepare_engine ); if( pVehicle->MoverParameters->iLights[ ( mvOccupied->CabActive < 0 ? end::rear : end::front ) ] & ( light::headlight_left | light::headlight_right | light::headlight_upper ) ) // któreś ze świateł zapalone? { // od wersji 357 oczekujemy podania komend dla AI przez scenerię - OrderNext( Prepare_engine ); +/* if( pVehicle->MoverParameters->iLights[ mvOccupied->CabActive < 0 ? end::rear : end::front ] & light::headlight_upper ) // górne światło zapalone OrderNext( Obey_train ); // jazda pociągowa else OrderNext( Shunt ); // jazda manewrowa +*/ if( mvOccupied->Vel >= 1.0 ) // jeśli jedzie (dla 0.1 ma stać) iDrivigFlags &= ~moveStopHere; // to ma nie czekać na sygnał, tylko jechać else diff --git a/opengl33renderer.cpp b/opengl33renderer.cpp index e41a6fb4..eb93df50 100644 --- a/opengl33renderer.cpp +++ b/opengl33renderer.cpp @@ -179,6 +179,7 @@ bool opengl33_renderer::Init(GLFWwindow *Window) return false; } glfwMakeContextCurrent(m_window); + gl::vao::unbind(); gl::buffer::unbind(); if (Global.gfx_shadowmap_enabled) @@ -470,6 +471,7 @@ bool opengl33_renderer::Render() } glfwMakeContextCurrent(m_window); + gl::vao::unbind(); gl::buffer::unbind(); m_current_viewport = &(*m_viewports.front()); /* @@ -581,6 +583,7 @@ void opengl33_renderer::Render_pass(viewport_config &vp, rendermode const Mode) glDebug("context switch"); glfwMakeContextCurrent(vp.window); + gl::vao::unbind(); gl::buffer::unbind(); m_current_viewport = &vp; @@ -3925,6 +3928,7 @@ void opengl33_renderer::Render_Alpha(TSubModel *Submodel) void opengl33_renderer::Update_Pick_Control() { // context-switch workaround + gl::vao::unbind(); gl::buffer::unbind(); if (!m_picking_pbo->is_busy()) diff --git a/version.h b/version.h index 3b87a5b4..ad9cfb85 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 20 -#define VERSION_MINOR 1018 -#define VERSION_REVISION 1 +#define VERSION_MINOR 1020 +#define VERSION_REVISION 0