From ba26ad1918b1da3e6c22674a3de162740009259b Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Tue, 2 Jan 2018 20:35:02 +0100 Subject: [PATCH] submodel location calculation fix for t3d files --- Model3d.cpp | 32 ++++++++++++++++++++++---------- Train.cpp | 41 ++++++++++++++--------------------------- 2 files changed, 36 insertions(+), 37 deletions(-) diff --git a/Model3d.cpp b/Model3d.cpp index 737ef26e..4ae944fb 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -653,13 +653,14 @@ void TSubModel::InitialRotate(bool doit) if (fMatrix->IdentityIs()) iFlags &= ~0x8000; // jednak jednostkowa po obróceniu } - if (Child) - Child->InitialRotate(false); // potomnych nie obracamy już, tylko - // ewentualnie optymalizujemy - else if (Global::iConvertModels & 2) // optymalizacja jest opcjonalna + if( Child ) { + // potomnych nie obracamy już, tylko ewentualnie optymalizujemy + Child->InitialRotate( false ); + } + else if (Global::iConvertModels & 2) { + // optymalizacja jest opcjonalna if ((iFlags & 0xC000) == 0x8000) // o ile nie ma animacji - { // jak nie ma potomnych, można wymnożyć przez transform i wyjedynkować - // go + { // jak nie ma potomnych, można wymnożyć przez transform i wyjedynkować go float4x4 *mat = GetMatrix(); // transform submodelu if( false == Vertices.empty() ) { for( auto &vertex : Vertices ) { @@ -680,6 +681,7 @@ void TSubModel::InitialRotate(bool doit) mat->Identity(); // jedynkowanie transformu po przeliczeniu wierzchołków iFlags &= ~0x8000; // transform jedynkowy } + } } else // jak jest jednostkowy i nie ma animacji if (doit) @@ -1165,11 +1167,11 @@ TSubModel::offset( float const Geometrytestoffsetthreshold ) const { auto offset { glm::vec3 { glm::make_mat4( parentmatrix.readArray() ) * glm::vec4 { 0, 0, 0, 1 } } }; if( glm::length2( offset ) < Geometrytestoffsetthreshold ) { - // offset of zero generally means the submodel has optimized identity matrix - // for such cases we resort to an estimate from submodel geometry - // TODO: do proper bounding area calculation for submodel when loading mesh and grab the centre point from it here + // offset of zero generally means the submodel has optimized identity matrix + // for such cases we resort to an estimate from submodel geometry + // TODO: do proper bounding area calculation for submodel when loading mesh and grab the centre point from it here if( m_geometry != null_handle ) { - auto const &vertices{ GfxRenderer.Vertices( m_geometry ) }; + auto const &vertices { GfxRenderer.Vertices( m_geometry ) }; if( false == vertices.empty() ) { // transformation matrix for the submodel can still contain rotation and/or scaling, // so we pass the vertex positions through it rather than just grab them directly @@ -1183,6 +1185,16 @@ TSubModel::offset( float const Geometrytestoffsetthreshold ) const { } } + if( true == TestFlag( iFlags, 0x0200 ) ) { + // flip coordinates for t3d file which wasn't yet initialized + if( std::abs( offset.y ) > offset.z ) { + // NOTE, HACK: results require flipping if the model wasn't yet initialized, so we're using crude method to detect possible cases + // TODO: sort out this mess, either unify offset lookups to take place before (or after) initialization, + // or provide way to determine on submodel level whether the initialization took place + offset = { -offset.x, offset.z, offset.y }; + } + } + return offset; } diff --git a/Train.cpp b/Train.cpp index 32739395..fd0dbe04 100644 --- a/Train.cpp +++ b/Train.cpp @@ -5690,14 +5690,12 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) *parser >> token; if (token != "none") { - - Global::asCurrentTexturePath = - DynamicObject->asBaseDir; // bieżąca sciezka do tekstur to dynamic/... - TModel3d *kabina = - TModelsManager::GetModel(DynamicObject->asBaseDir + token, - true); // szukaj kabinę jako oddzielny model - Global::asCurrentTexturePath = - szTexturePath; // z powrotem defaultowa sciezka do tekstur + // bieżąca sciezka do tekstur to dynamic/... + Global::asCurrentTexturePath = DynamicObject->asBaseDir; + // szukaj kabinę jako oddzielny model + TModel3d *kabina = TModelsManager::GetModel(DynamicObject->asBaseDir + token, true); + // z powrotem defaultowa sciezka do tekstur + Global::asCurrentTexturePath = szTexturePath; // if (DynamicObject->mdKabina!=k) if (kabina != nullptr) { @@ -5708,16 +5706,11 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) // else // break; //wyjście z pętli, bo model zostaje bez zmian } - else if (cabindex == 1) - { + else if (cabindex == 1) { // model tylko, gdy nie ma kabiny 1 - DynamicObject->mdKabina = - DynamicObject - ->mdModel; // McZapkie-170103: szukaj elementy kabiny w glownym modelu + // McZapkie-170103: szukaj elementy kabiny w glownym modelu + DynamicObject->mdKabina = DynamicObject->mdModel; } -/* - Universal4Active = false; -*/ clear_cab_controls(); } if (nullptr == DynamicObject->mdKabina) @@ -5737,8 +5730,7 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) } else if (token == "pyscreen:") { - pyScreens.init(*parser, DynamicObject->mdKabina, DynamicObject->name(), - NewCabNo); + pyScreens.init(*parser, DynamicObject->mdKabina, DynamicObject->name(), NewCabNo); } // btLampkaUnknown.Init("unknown",mdKabina,false); } while (token != ""); @@ -5750,9 +5742,6 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) pyScreens.start(); if (DynamicObject->mdKabina) { - DynamicObject->mdKabina->Init(); // obrócenie modelu oraz optymalizacja, również zapisanie binarnego - set_cab_controls(); - // configure placement of sound emitters which aren't bound with any device model, and weren't placed manually // try first to bind sounds to location of possible devices if( dsbReverserKey.offset() == nullvector ) { @@ -5800,12 +5789,10 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) sound->offset( caboffset ); } } -/* - // HACK: for some reason simulation at the start is slow until a sound is played - // until we do a proper fix, try to play a 'silent' sound when cab is entered - // TBD: it could be instead a legit sound of door closing - play_sound( dsbSwitch, DSBVOLUME_MIN ); -*/ + + DynamicObject->mdKabina->Init(); // obrócenie modelu oraz optymalizacja, również zapisanie binarnego + set_cab_controls(); + return true; } return (token == "none");