16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-23 08:39:18 +02:00

build 180527. smoother camera rotation, semi-persistent cab camera angle between view swaps, configurable default cab camera view angle, diesel engine power calculation fix, minor refactoring and fixes for content files lookups and loading

This commit is contained in:
tmj-fstate
2018-05-27 02:31:40 +02:00
parent aa520aa3e7
commit 2c1c29600e
17 changed files with 272 additions and 169 deletions

View File

@@ -18,8 +18,7 @@ http://mozilla.org/MPL/2.0/.
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void TCamera::Init( Math3D::vector3 NPos, Math3D::vector3 NAngle) void TCamera::Init( Math3D::vector3 NPos, Math3D::vector3 NAngle) {
{
vUp = Math3D::vector3(0, 1, 0); vUp = Math3D::vector3(0, 1, 0);
Velocity = Math3D::vector3(0, 0, 0); Velocity = Math3D::vector3(0, 0, 0);
@@ -31,8 +30,15 @@ void TCamera::Init( Math3D::vector3 NPos, Math3D::vector3 NAngle)
Type = (Global.bFreeFly ? tp_Free : tp_Follow); Type = (Global.bFreeFly ? tp_Free : tp_Follow);
}; };
void TCamera::OnCursorMove(double x, double y) { void TCamera::Reset() {
Pitch = Yaw = Roll = 0;
m_rotationoffsets = {};
};
void TCamera::OnCursorMove(double x, double y) {
/*
Yaw -= x; Yaw -= x;
while( Yaw > M_PI ) { while( Yaw > M_PI ) {
Yaw -= 2 * M_PI; Yaw -= 2 * M_PI;
@@ -45,6 +51,8 @@ void TCamera::OnCursorMove(double x, double y) {
// jeżeli jazda z pojazdem ograniczenie kąta spoglądania w dół i w górę // jeżeli jazda z pojazdem ograniczenie kąta spoglądania w dół i w górę
Pitch = clamp( Pitch, -M_PI_4, M_PI_4 ); Pitch = clamp( Pitch, -M_PI_4, M_PI_4 );
} }
*/
m_rotationoffsets += glm::dvec3 { y, x, 0.0 };
} }
bool bool
@@ -151,8 +159,9 @@ void TCamera::Update()
OnCommand( command ); OnCommand( command );
} }
auto const deltatime = Timer::GetDeltaRenderTime(); // czas bez pauzy auto const deltatime { Timer::GetDeltaRenderTime() }; // czas bez pauzy
// update position
if( ( Type == tp_Free ) if( ( Type == tp_Free )
|| ( false == Global.ctrlState ) || ( false == Global.ctrlState )
|| ( true == DebugCameraFlag ) ) { || ( true == DebugCameraFlag ) ) {
@@ -170,6 +179,24 @@ void TCamera::Update()
Vec.RotateY( Yaw ); Vec.RotateY( Yaw );
Pos += Vec * 5.0 * deltatime; Pos += Vec * 5.0 * deltatime;
} }
// update rotation
auto const rotationfactor { std::min( 1.0, 20 * deltatime ) };
Yaw -= rotationfactor * m_rotationoffsets.y;
m_rotationoffsets.y *= ( 1.0 - rotationfactor );
while( Yaw > M_PI ) {
Yaw -= 2 * M_PI;
}
while( Yaw < -M_PI ) {
Yaw += 2 * M_PI;
}
Pitch -= rotationfactor * m_rotationoffsets.x;
m_rotationoffsets.x *= ( 1.0 - rotationfactor );
if( Type == tp_Follow ) {
// jeżeli jazda z pojazdem ograniczenie kąta spoglądania w dół i w górę
Pitch = clamp( Pitch, -M_PI_4, M_PI_4 );
}
} }
Math3D::vector3 TCamera::GetDirection() { Math3D::vector3 TCamera::GetDirection() {
@@ -200,11 +227,15 @@ bool TCamera::SetMatrix( glm::dmat4 &Matrix ) {
void TCamera::RaLook() void TCamera::RaLook()
{ // zmiana kierunku patrzenia - przelicza Yaw { // zmiana kierunku patrzenia - przelicza Yaw
Math3D::vector3 where = LookAt - Pos + Math3D::vector3(0, 3, 0); // trochę w górę od szyn Math3D::vector3 where = LookAt - Pos + Math3D::vector3(0, 3, 0); // trochę w górę od szyn
if ((where.x != 0.0) || (where.z != 0.0)) if( ( where.x != 0.0 ) || ( where.z != 0.0 ) ) {
Yaw = atan2( -where.x, -where.z ); // kąt horyzontalny Yaw = atan2( -where.x, -where.z ); // kąt horyzontalny
m_rotationoffsets.y = 0.0;
}
double l = Math3D::Length3(where); double l = Math3D::Length3(where);
if (l > 0.0) if( l > 0.0 ) {
Pitch = asin( where.y / l ); // kąt w pionie Pitch = asin( where.y / l ); // kąt w pionie
m_rotationoffsets.x = 0.0;
}
}; };
void TCamera::Stop() void TCamera::Stop()

View File

@@ -22,14 +22,9 @@ enum TCameraType
class TCamera { class TCamera {
private:
glm::dvec3 m_moverate;
public: // McZapkie: potrzebuje do kiwania na boki public: // McZapkie: potrzebuje do kiwania na boki
void Init( Math3D::vector3 NPos, Math3D::vector3 NAngle); void Init( Math3D::vector3 NPos, Math3D::vector3 NAngle);
inline void Reset();
void Reset() {
Pitch = Yaw = Roll = 0; };
void OnCursorMove(double const x, double const y); void OnCursorMove(double const x, double const y);
bool OnCommand( command_data const &Command ); bool OnCommand( command_data const &Command );
void Update(); void Update();
@@ -46,4 +41,9 @@ class TCamera {
Math3D::vector3 LookAt; // współrzędne punktu, na który ma patrzeć Math3D::vector3 LookAt; // współrzędne punktu, na który ma patrzeć
Math3D::vector3 vUp; Math3D::vector3 vUp;
Math3D::vector3 Velocity; Math3D::vector3 Velocity;
private:
glm::dvec3 m_moverate;
glm::dvec3 m_rotationoffsets; // requested changes to pitch, yaw and roll
}; };

View File

@@ -3222,17 +3222,24 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
iStationStart = TrainParams->StationIndex; iStationStart = TrainParams->StationIndex;
asNextStop = TrainParams->NextStop(); asNextStop = TrainParams->NextStop();
iDrivigFlags |= movePrimary; // skoro dostał rozkład, to jest teraz głównym iDrivigFlags |= movePrimary; // skoro dostał rozkład, to jest teraz głównym
NewCommand = Global.asCurrentSceneryPath + NewCommand + ".wav"; // na razie jeden NewCommand = Global.asCurrentSceneryPath + NewCommand;
if (FileExists(NewCommand)) { auto lookup =
FileExists(
{ NewCommand },
{ ".ogg", ".flac", ".wav" } );
if( false == lookup.first.empty() ) {
// wczytanie dźwięku odjazdu podawanego bezpośrenido // wczytanie dźwięku odjazdu podawanego bezpośrenido
tsGuardSignal = sound_source( sound_placement::external, 75.f ).deserialize( NewCommand, sound_type::single ); tsGuardSignal = sound_source( sound_placement::external, 75.f ).deserialize( lookup.first + lookup.second, sound_type::single );
iGuardRadio = 0; // nie przez radio iGuardRadio = 0; // nie przez radio
} }
else { else {
NewCommand = NewCommand.insert(NewCommand.rfind('.'),"radio"); // wstawienie przed kropkč auto lookup =
if (FileExists(NewCommand)) { FileExists(
{ NewCommand + "radio" },
{ ".ogg", ".flac", ".wav" } );
if( false == lookup.first.empty() ) {
// wczytanie dźwięku odjazdu w wersji radiowej (słychać tylko w kabinie) // wczytanie dźwięku odjazdu w wersji radiowej (słychać tylko w kabinie)
tsGuardSignal = sound_source( sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE ).deserialize( NewCommand, sound_type::single ); tsGuardSignal = sound_source( sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE ).deserialize( lookup.first + lookup.second, sound_type::single );
iGuardRadio = iRadioChannel; iGuardRadio = iRadioChannel;
} }
} }

View File

@@ -50,6 +50,18 @@ GetSubmodelFromName( TModel3d * const Model, std::string const Name ) {
nullptr ); nullptr );
} }
// Ra 2015-01: sprawdzenie dostępności tekstury o podanej nazwie
std::string
TextureTest( std::string const &Name ) {
auto const lookup {
FileExists(
{ Global.asCurrentTexturePath + Name, Name, szTexturePath + Name },
{ ".mat", ".dds", ".tga", ".bmp" } ) };
return ( lookup.first + lookup.second );
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void TAnimPant::AKP_4E() void TAnimPant::AKP_4E()
{ // ustawienie wymiarów dla pantografu AKP-4E { // ustawienie wymiarów dla pantografu AKP-4E
@@ -4481,7 +4493,7 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
mdModel = TModelsManager::GetModel(asModel, true); mdModel = TModelsManager::GetModel(asModel, true);
if (ReplacableSkin != "none") if (ReplacableSkin != "none")
{ {
std::string nowheretexture = TextureTest( Global.asCurrentTexturePath + "nowhere" ); // na razie prymitywnie std::string nowheretexture = TextureTest( "nowhere" ); // na razie prymitywnie
if( false == nowheretexture.empty() ) { if( false == nowheretexture.empty() ) {
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Material( nowheretexture ); m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Material( nowheretexture );
} }
@@ -6204,17 +6216,6 @@ int TDynamicObject::RouteWish(TTrack *tr)
return Mechanik ? Mechanik->CrossRoute(tr) : 0; // wg AI albo prosto return Mechanik ? Mechanik->CrossRoute(tr) : 0; // wg AI albo prosto
}; };
std::string TDynamicObject::TextureTest(std::string const &name)
{ // Ra 2015-01: sprawdzenie dostępności tekstury o podanej nazwie
std::vector<std::string> extensions = { ".mat", ".dds", ".tga", ".bmp" };
for( auto const &extension : extensions ) {
if( true == FileExists( name + extension ) ) {
return name + extension;
}
}
return ""; // nie znaleziona
};
void TDynamicObject::DestinationSet(std::string to, std::string numer) void TDynamicObject::DestinationSet(std::string to, std::string numer)
{ // ustawienie stacji docelowej oraz wymiennej tekstury 4, jeśli istnieje plik { // ustawienie stacji docelowej oraz wymiennej tekstury 4, jeśli istnieje plik
// w zasadzie, to każdy wagon mógłby mieć inną stację docelową // w zasadzie, to każdy wagon mógłby mieć inną stację docelową
@@ -6228,13 +6229,20 @@ void TDynamicObject::DestinationSet(std::string to, std::string numer)
numer = Bezogonkow(numer); numer = Bezogonkow(numer);
asDestination = to; asDestination = to;
to = Bezogonkow(to); // do szukania pliku obcinamy ogonki to = Bezogonkow(to); // do szukania pliku obcinamy ogonki
if( true == to.empty() ) {
to = "nowhere";
}
// destination textures are kept in the vehicle's directory so we point the current texture path there
auto const currenttexturepath { Global.asCurrentTexturePath };
Global.asCurrentTexturePath = asBaseDir;
// now see if we can find any version of the texture
std::vector<std::string> destinations = { std::vector<std::string> destinations = {
asBaseDir + numer + "@" + MoverParameters->TypeName, numer + '@' + MoverParameters->TypeName,
asBaseDir + numer, numer,
asBaseDir + to + "@" + MoverParameters->TypeName, to + '@' + MoverParameters->TypeName,
asBaseDir + to, to,
asBaseDir + "nowhere" }; "nowhere" + '@' + MoverParameters->TypeName,
"nowhere" };
for( auto const &destination : destinations ) { for( auto const &destination : destinations ) {
@@ -6244,6 +6252,8 @@ void TDynamicObject::DestinationSet(std::string to, std::string numer)
break; break;
} }
} }
// whether we got anything, restore previous texture path
Global.asCurrentTexturePath = currenttexturepath;
}; };
void TDynamicObject::OverheadTrack(float o) void TDynamicObject::OverheadTrack(float o)

View File

@@ -601,7 +601,6 @@ private:
// zapytanie do AI, po którym segmencie skrzyżowania jechać // zapytanie do AI, po którym segmencie skrzyżowania jechać
int RouteWish(TTrack *tr); int RouteWish(TTrack *tr);
void DestinationSet(std::string to, std::string numer); void DestinationSet(std::string to, std::string numer);
std::string TextureTest(std::string const &name);
void OverheadTrack(float o); void OverheadTrack(float o);
double MED[9][8]; // lista zmiennych do debugowania hamulca ED double MED[9][8]; // lista zmiennych do debugowania hamulca ED

View File

@@ -4426,8 +4426,7 @@ double TMoverParameters::CouplerForce(int CouplerN, double dt)
// Q: 20160714 // Q: 20160714
// oblicza sile trakcyjna lokomotywy (dla elektrowozu tez calkowity prad) // oblicza sile trakcyjna lokomotywy (dla elektrowozu tez calkowity prad)
// ************************************************************************************************* // *************************************************************************************************
double TMoverParameters::TractionForce(double dt) double TMoverParameters::TractionForce( double dt ) {
{
double PosRatio, dmoment, dtrans, tmp; double PosRatio, dmoment, dtrans, tmp;
Ft = 0; Ft = 0;
@@ -4579,13 +4578,35 @@ double TMoverParameters::TractionForce(double dt)
} }
} }
switch( EngineType ) {
case Dumb: {
PosRatio = ( MainCtrlPos + ScndCtrlPos ) / ( MainCtrlPosNo + ScndCtrlPosNo + 0.01 );
EnginePower = 1000.0 * Power * PosRatio;
break;
}
case DieselEngine: {
EnginePower = ( 2 * dizel_Mstand + dmoment ) * enrot * ( 2.0 * M_PI / 1000.0 );
if( MainCtrlPos > 1 ) {
// dodatkowe opory z powodu sprezarki}
dmoment -= dizel_Mstand * ( 0.2 * enrot / dizel_nmax );
}
break;
}
case DieselElectric: {
EnginePower = 0; // the actual calculation is done in two steps later in the method
break;
}
default: {
break;
}
}
if (ActiveDir != 0) if (ActiveDir != 0)
switch (EngineType) switch (EngineType)
{ {
case Dumb: case Dumb:
{ {
PosRatio = (MainCtrlPos + ScndCtrlPos) / (MainCtrlPosNo + ScndCtrlPosNo + 0.01); if (Mains && (CabNo != 0))
if (Mains && (ActiveDir != 0) && (CabNo != 0))
{ {
if (Vel > 0.1) if (Vel > 0.1)
{ {
@@ -4597,7 +4618,6 @@ double TMoverParameters::TractionForce(double dt)
} }
else else
Ft = 0; Ft = 0;
EnginePower = 1000.0 * Power * PosRatio;
break; break;
} // Dumb } // Dumb
@@ -4682,11 +4702,6 @@ double TMoverParameters::TractionForce(double dt)
case DieselEngine: case DieselEngine:
{ {
EnginePower = ( 2 * dizel_Mstand + dmoment ) * enrot * ( 2.0 * M_PI / 1000.0 );
if( MainCtrlPos > 1 ) {
// dodatkowe opory z powodu sprezarki}
dmoment -= dizel_Mstand * ( 0.2 * enrot / dizel_nmax );
}
Mm = dmoment; //bylo * dizel_engage Mm = dmoment; //bylo * dizel_engage
Mw = Mm * dtrans; // dmoment i dtrans policzone przy okazji enginerotation Mw = Mm * dtrans; // dmoment i dtrans policzone przy okazji enginerotation
Fw = Mw * 2.0 / WheelDiameter / NPoweredAxles; Fw = Mw * 2.0 / WheelDiameter / NPoweredAxles;
@@ -4995,9 +5010,7 @@ double TMoverParameters::TractionForce(double dt)
} }
} }
if( true == Mains ) { if( true == Mains ) {
//tempomat //tempomat
if (ScndCtrlPosNo > 1) if (ScndCtrlPosNo > 1)
{ {
if (ScndCtrlPos != NewSpeed) if (ScndCtrlPos != NewSpeed)
@@ -5021,7 +5034,6 @@ double TMoverParameters::TractionForce(double dt)
} }
} }
dtrans = Hamulec->GetEDBCP(); dtrans = Hamulec->GetEDBCP();
if (((DoorLeftOpened) || (DoorRightOpened))) if (((DoorLeftOpened) || (DoorRightOpened)))
DynamicBrakeFlag = true; DynamicBrakeFlag = true;
@@ -5241,6 +5253,20 @@ double TMoverParameters::TractionForce(double dt)
break; break;
} }
} // case EngineType } // case EngineType
switch( EngineType ) {
case DieselElectric: {
// rough approximation of extra effort to overcome friction etc
auto const rpmratio{ 60.0 * enrot / DElist[ MainCtrlPosNo ].RPM };
EnginePower += rpmratio * 0.2 * DElist[ MainCtrlPosNo ].GenPower;
break;
}
default: {
break;
}
}
return Ft; return Ft;
} }

View File

@@ -767,55 +767,22 @@ texture_manager::create( std::string Filename, bool const Loadnow ) {
Filename.erase( 0, 1 ); Filename.erase( 0, 1 );
} }
std::vector<std::string> extensions { { ".dds" }, { ".tga" }, { ".bmp" }, { ".ext" } };
// try to locate requested texture in the databank // try to locate requested texture in the databank
auto lookup = find_in_databank( Filename + Global.szDefaultExt ); auto lookup { find_in_databank( Filename ) };
if( lookup != npos ) { if( lookup != npos ) {
// start with the default extension...
return lookup; return lookup;
} }
else {
// ...then try recognized file extensions other than default
for( auto const &extension : extensions ) {
if( extension == Global.szDefaultExt ) {
// we already tried this one
continue;
}
lookup = find_in_databank( Filename + extension );
if( lookup != npos ) {
return lookup;
}
}
}
// if we don't have the texture in the databank, check if it's on disk // if we don't have the texture in the databank, check if it's on disk
std::string filename = find_on_disk( Filename + Global.szDefaultExt ); auto const disklookup { find_on_disk( Filename ) };
if( true == filename.empty() ) {
// if the default lookup fails, try other known extensions
for( auto const &extension : extensions ) {
if( extension == Global.szDefaultExt ) { if( true == disklookup.first.empty() ) {
// we already tried this one
continue;
}
filename = find_on_disk( Filename + extension );
if( false == filename.empty() ) {
// we found something, don't bother with others
break;
}
}
}
if( true == filename.empty() ) {
// there's nothing matching in the databank nor on the disk, report failure // there's nothing matching in the databank nor on the disk, report failure
ErrorLog( "Bad file: failed do locate texture file \"" + Filename + "\"", logtype::file ); ErrorLog( "Bad file: failed do locate texture file \"" + Filename + "\"", logtype::file );
return npos; return npos;
} }
auto texture = new opengl_texture(); auto texture = new opengl_texture();
texture->name = filename; texture->name = disklookup.first + disklookup.second;
if( Filename.find('#') != std::string::npos ) { if( Filename.find('#') != std::string::npos ) {
// temporary code for legacy assets -- textures with names beginning with # are to be sharpened // temporary code for legacy assets -- textures with names beginning with # are to be sharpened
traits += '#'; traits += '#';
@@ -823,9 +790,9 @@ texture_manager::create( std::string Filename, bool const Loadnow ) {
texture->traits = traits; texture->traits = traits;
auto const textureindex = (texture_handle)m_textures.size(); auto const textureindex = (texture_handle)m_textures.size();
m_textures.emplace_back( texture, std::chrono::steady_clock::time_point() ); m_textures.emplace_back( texture, std::chrono::steady_clock::time_point() );
m_texturemappings.emplace( filename, textureindex ); m_texturemappings.emplace( disklookup.first, textureindex );
WriteLog( "Created texture object for \"" + filename + "\"", logtype::texture ); WriteLog( "Created texture object for \"" + disklookup.first + disklookup.second + "\"", logtype::texture );
if( true == Loadnow ) { if( true == Loadnow ) {
@@ -942,7 +909,7 @@ texture_manager::info() const {
texture_handle texture_handle
texture_manager::find_in_databank( std::string const &Texturename ) const { texture_manager::find_in_databank( std::string const &Texturename ) const {
std::vector<std::string> filenames { std::vector<std::string> const filenames {
Global.asCurrentTexturePath + Texturename, Global.asCurrentTexturePath + Texturename,
Texturename, Texturename,
szTexturePath + Texturename }; szTexturePath + Texturename };
@@ -953,19 +920,34 @@ texture_manager::find_in_databank( std::string const &Texturename ) const {
return lookup->second; return lookup->second;
} }
} }
// all lookups failed
return npos; return npos;
} }
// checks whether specified file exists. // checks whether specified file exists.
std::string std::pair<std::string, std::string>
texture_manager::find_on_disk( std::string const &Texturename ) const { texture_manager::find_on_disk( std::string const &Texturename ) const {
std::vector<std::string> const filenames {
Global.asCurrentTexturePath + Texturename,
Texturename,
szTexturePath + Texturename };
auto lookup =
FileExists(
filenames,
{ Global.szDefaultExt } );
if( false == lookup.first.empty() ) {
return lookup;
}
// if the first attempt fails, try entire extension list
// NOTE: slightly wasteful as it means preferred extension is tested twice, but, eh
return ( return (
FileExists( Global.asCurrentTexturePath + Texturename ) ? Global.asCurrentTexturePath + Texturename : FileExists(
FileExists( Texturename ) ? Texturename : filenames,
FileExists( szTexturePath + Texturename ) ? szTexturePath + Texturename : { ".dds", ".tga", ".bmp", ".ext" } ) );
"" );
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -21,6 +21,8 @@ struct opengl_texture {
static DDPIXELFORMAT deserialize_ddpf(std::istream&); static DDPIXELFORMAT deserialize_ddpf(std::istream&);
static DDSCAPS2 deserialize_ddscaps(std::istream&); static DDSCAPS2 deserialize_ddscaps(std::istream&);
// constructors
opengl_texture() = default;
// methods // methods
void void
load(); load();
@@ -120,7 +122,7 @@ private:
texture_handle texture_handle
find_in_databank( std::string const &Texturename ) const; find_in_databank( std::string const &Texturename ) const;
// checks whether specified file exists. returns name of the located file, or empty string. // checks whether specified file exists. returns name of the located file, or empty string.
std::string std::pair<std::string, std::string>
find_on_disk( std::string const &Texturename ) const; find_on_disk( std::string const &Texturename ) const;
void void
delete_textures(); delete_textures();

View File

@@ -5882,6 +5882,10 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
sound->offset( nullvector ); sound->offset( nullvector );
sound->owner( DynamicObject ); sound->owner( DynamicObject );
} }
// reset view angles
pMechViewAngle = { 0.0, 0.0 };
Global.pCamera->Pitch = pMechViewAngle.x;
Global.pCamera->Yaw = pMechViewAngle.y;
pyScreens.reset(this); pyScreens.reset(this);
pyScreens.setLookupPath(DynamicObject->asBaseDir); pyScreens.setLookupPath(DynamicObject->asBaseDir);
@@ -5934,41 +5938,59 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
{ {
// jeśli znaleziony wpis kabiny // jeśli znaleziony wpis kabiny
Cabine[cabindex].Load(*parser); Cabine[cabindex].Load(*parser);
// NOTE: the next part is likely to break if sitpos doesn't follow pos // NOTE: the position and angle definitions depend on strict entry order
// TODO: refactor into more flexible arrangement
parser->getTokens(); parser->getTokens();
*parser >> token; *parser >> token;
if( token == std::string( "driver" + std::to_string( cabindex ) + "angle:" ) ) {
// camera view angle
parser->getTokens( 2, false );
// angle is specified in degrees but internally stored in radians
glm::vec2 viewangle;
*parser
>> viewangle.y // yaw first, then pitch
>> viewangle.x;
pMechViewAngle = glm::radians( viewangle );
Global.pCamera->Pitch = pMechViewAngle.x;
Global.pCamera->Yaw = pMechViewAngle.y;
parser->getTokens();
*parser >> token;
}
if (token == std::string("driver" + std::to_string(cabindex) + "pos:")) if (token == std::string("driver" + std::to_string(cabindex) + "pos:"))
{ {
// pozycja poczatkowa maszynisty // pozycja poczatkowa maszynisty
parser->getTokens(3, false); parser->getTokens(3, false);
*parser >> pMechOffset.x >> pMechOffset.y >> pMechOffset.z; *parser
pMechSittingPosition.x = pMechOffset.x; >> pMechOffset.x
pMechSittingPosition.y = pMechOffset.y; >> pMechOffset.y
pMechSittingPosition.z = pMechOffset.z; >> pMechOffset.z;
} pMechSittingPosition = pMechOffset;
// ABu: pozycja siedzaca mechanika
parser->getTokens(); parser->getTokens();
*parser >> token; *parser >> token;
}
// ABu: pozycja siedzaca mechanika
if (token == std::string("driver" + std::to_string(cabindex) + "sitpos:")) if (token == std::string("driver" + std::to_string(cabindex) + "sitpos:"))
{ {
// ABu 180404 pozycja siedzaca maszynisty // ABu 180404 pozycja siedzaca maszynisty
parser->getTokens(3, false); parser->getTokens(3, false);
*parser >> pMechSittingPosition.x >> pMechSittingPosition.y >> pMechSittingPosition.z; *parser
parse = true; >> pMechSittingPosition.x
>> pMechSittingPosition.y
>> pMechSittingPosition.z;
parser->getTokens();
*parser >> token;
} }
// else parse=false; // else parse=false;
do do {
{
// ABu: wstawione warunki, wczesniej tylko to:
// str=Parser->GetNextSymbol().LowerCase();
if( parse == true ) { if( parse == true ) {
token = ""; token = "";
parser->getTokens(); parser->getTokens();
*parser >> token; *parser >> token;
} }
else else {
{
parse = true; parse = true;
} }
// inicjacja kabiny // inicjacja kabiny

View File

@@ -592,6 +592,7 @@ public: // reszta może by?publiczna
Math3D::vector3 pMechSittingPosition; // ABu 180404 Math3D::vector3 pMechSittingPosition; // ABu 180404
Math3D::vector3 MirrorPosition(bool lewe); Math3D::vector3 MirrorPosition(bool lewe);
glm::vec2 pMechViewAngle { 0.0, 0.0 }; // camera pitch and yaw values, preserved while in external view
private: private:
double fBlinkTimer; double fBlinkTimer;

View File

@@ -607,6 +607,7 @@ void TWorld::InOutKey( bool const Near )
if (Train) { if (Train) {
// cache current cab position so there's no need to set it all over again after each out-in switch // cache current cab position so there's no need to set it all over again after each out-in switch
Train->pMechSittingPosition = Train->pMechOffset; Train->pMechSittingPosition = Train->pMechOffset;
Train->Dynamic()->bDisplayCab = false; Train->Dynamic()->bDisplayCab = false;
DistantView( Near ); DistantView( Near );
} }
@@ -618,9 +619,8 @@ void TWorld::InOutKey( bool const Near )
if (Train) if (Train)
{ {
Train->Dynamic()->bDisplayCab = true; Train->Dynamic()->bDisplayCab = true;
Train->Dynamic()->ABuSetModelShake( // zerowanie przesunięcia przed powrotem?
Math3D::vector3(0, 0, 0)); // zerowanie przesunięcia przed powrotem? Train->Dynamic()->ABuSetModelShake( { 0, 0, 0 } );
// Camera.Stop(); //zatrzymanie ruchu
Train->MechStop(); Train->MechStop();
FollowView(); // na pozycję mecha FollowView(); // na pozycję mecha
} }
@@ -694,14 +694,12 @@ void TWorld::FollowView(bool wycisz) {
// tu ustawić nową, bo od niej liczą się odległości // tu ustawić nową, bo od niej liczą się odległości
Global.pCameraPosition = Camera.Pos; Global.pCameraPosition = Camera.Pos;
} }
else if (Train) else if (Train) {
{ // korekcja ustawienia w kabinie - OK
if( wycisz ) {
// wyciszenie dźwięków z poprzedniej pozycji
// trzymanie prawego w kabinie daje marny efekt
// TODO: re-implement, old one kinda didn't really work
}
Camera.Pos = Train->pMechPosition; Camera.Pos = Train->pMechPosition;
// potentially restore cached camera angles
Camera.Pitch = Train->pMechViewAngle.x;
Camera.Yaw = Train->pMechViewAngle.y;
Camera.Roll = std::atan(Train->pMechShake.x * Train->fMechRoll); // hustanie kamery na boki Camera.Roll = std::atan(Train->pMechShake.x * Train->fMechRoll); // hustanie kamery na boki
Camera.Pitch -= 0.5 * std::atan(Train->vMechVelocity.z * Train->fMechPitch); // hustanie kamery przod tyl Camera.Pitch -= 0.5 * std::atan(Train->vMechVelocity.z * Train->fMechPitch); // hustanie kamery przod tyl
@@ -946,6 +944,14 @@ TWorld::Update_Camera( double const Deltatime ) {
if( DebugCameraFlag ) { DebugCamera.Update(); } if( DebugCameraFlag ) { DebugCamera.Update(); }
else { Camera.Update(); } // uwzględnienie ruchu wywołanego klawiszami else { Camera.Update(); } // uwzględnienie ruchu wywołanego klawiszami
if( ( false == FreeFlyModeFlag )
&& ( false == Global.CabWindowOpen )
&& ( Train != nullptr ) ) {
// cache cab camera view angles in case of view type switch
Train->pMechViewAngle = { Camera.Pitch, Camera.Yaw };
}
// reset window state, it'll be set again if applicable in a check below // reset window state, it'll be set again if applicable in a check below
Global.CabWindowOpen = false; Global.CabWindowOpen = false;
@@ -954,7 +960,7 @@ TWorld::Update_Camera( double const Deltatime ) {
&& ( false == DebugCameraFlag ) ) { && ( false == DebugCameraFlag ) ) {
// jeśli jazda w kabinie, przeliczyć trzeba parametry kamery // jeśli jazda w kabinie, przeliczyć trzeba parametry kamery
auto tempangle = Controlled->VectorFront() * ( Controlled->MoverParameters->ActiveCab == -1 ? -1 : 1 ); auto tempangle = Controlled->VectorFront() * ( Controlled->MoverParameters->ActiveCab == -1 ? -1 : 1 );
double modelrotate = atan2( -tempangle.x, tempangle.z ); // double modelrotate = atan2( -tempangle.x, tempangle.z );
if( ( true == Global.ctrlState ) if( ( true == Global.ctrlState )
&& ( ( glfwGetKey( Global.window, GLFW_KEY_LEFT ) == GLFW_TRUE ) && ( ( glfwGetKey( Global.window, GLFW_KEY_LEFT ) == GLFW_TRUE )
@@ -982,6 +988,11 @@ TWorld::Update_Camera( double const Deltatime ) {
} }
else { else {
// patrzenie standardowe // patrzenie standardowe
// potentially restore view angle after returning from external view
// TODO: mirror view toggle as separate method
Camera.Pitch = Train->pMechViewAngle.x;
Camera.Yaw = Train->pMechViewAngle.y;
Camera.Pos = Train->GetWorldMechPosition(); // Train.GetPosition1(); Camera.Pos = Train->GetWorldMechPosition(); // Train.GetPosition1();
if( !Global.iPause ) { if( !Global.iPause ) {
// podczas pauzy nie przeliczać kątów przypadkowymi wartościami // podczas pauzy nie przeliczać kątów przypadkowymi wartościami
@@ -991,8 +1002,8 @@ TWorld::Update_Camera( double const Deltatime ) {
// Ra: tu jest uciekanie kamery w górę!!! // Ra: tu jest uciekanie kamery w górę!!!
Camera.Pitch -= 0.5 * atan( Train->vMechVelocity.z * Train->fMechPitch ); Camera.Pitch -= 0.5 * atan( Train->vMechVelocity.z * Train->fMechPitch );
} }
// ABu011104: rzucanie pudlem
/* /*
// ABu011104: rzucanie pudlem
vector3 temp; vector3 temp;
if( abs( Train->pMechShake.y ) < 0.25 ) if( abs( Train->pMechShake.y ) < 0.25 )
temp = vector3( 0, 0, 6 * Train->pMechShake.y ); temp = vector3( 0, 0, 6 * Train->pMechShake.y );
@@ -1004,7 +1015,6 @@ TWorld::Update_Camera( double const Deltatime ) {
Controlled->ABuSetModelShake( temp ); Controlled->ABuSetModelShake( temp );
// ABu: koniec rzucania // ABu: koniec rzucania
*/ */
if( Train->Dynamic()->MoverParameters->ActiveCab == 0 ) if( Train->Dynamic()->MoverParameters->ActiveCab == 0 )
Camera.LookAt = Train->GetWorldMechPosition() + Train->GetDirection() * 5.0; // gdy w korytarzu Camera.LookAt = Train->GetWorldMechPosition() + Train->GetDirection() * 5.0; // gdy w korytarzu
else // patrzenie w kierunku osi pojazdu, z uwzględnieniem kabiny else // patrzenie w kierunku osi pojazdu, z uwzględnieniem kabiny

View File

@@ -210,8 +210,9 @@ buffer_manager::emplace( std::string Filename ) {
m_buffers.emplace_back( Filename ); m_buffers.emplace_back( Filename );
// NOTE: we store mapping without file type extension, to simplify lookups // NOTE: we store mapping without file type extension, to simplify lookups
erase_extension( Filename );
m_buffermappings.emplace( m_buffermappings.emplace(
Filename.erase( Filename.rfind( '.' ) ), Filename,
handle ); handle );
return handle; return handle;
@@ -220,26 +221,22 @@ buffer_manager::emplace( std::string Filename ) {
audio::buffer_handle audio::buffer_handle
buffer_manager::find_buffer( std::string const &Buffername ) const { buffer_manager::find_buffer( std::string const &Buffername ) const {
auto lookup = m_buffermappings.find( Buffername ); auto const lookup = m_buffermappings.find( Buffername );
if( lookup != m_buffermappings.end() ) if( lookup != std::end( m_buffermappings ) )
return lookup->second; return lookup->second;
else else
return null_handle; return null_handle;
} }
std::string std::string
buffer_manager::find_file( std::string const &Filename ) const { buffer_manager::find_file( std::string const &Filename ) const {
std::vector<std::string> const extensions { ".ogg", ".flac", ".wav" }; auto const lookup {
FileExists(
{ Filename },
{ ".ogg", ".flac", ".wav" } ) };
for( auto const &extension : extensions ) { return lookup.first + lookup.second;
if( FileExists( Filename + extension ) ) {
// valid name on success
return Filename + extension;
}
}
return {}; // empty string on failure
} }
} // audio } // audio

View File

@@ -117,23 +117,21 @@ material_manager::create( std::string const &Filename, bool const Loadnow ) {
filename.erase( 0, 1 ); filename.erase( 0, 1 );
} }
filename += ".mat";
// try to locate requested material in the databank // try to locate requested material in the databank
auto const databanklookup = find_in_databank( filename ); auto const databanklookup { find_in_databank( filename ) };
if( databanklookup != null_handle ) { if( databanklookup != null_handle ) {
return databanklookup; return databanklookup;
} }
// if this fails, try to look for it on disk // if this fails, try to look for it on disk
opengl_material material; opengl_material material;
auto const disklookup = find_on_disk( filename ); auto const disklookup { find_on_disk( filename ) };
if( disklookup != "" ) { if( false == disklookup.first.empty() ) {
cParser materialparser( disklookup, cParser::buffer_FILE ); cParser materialparser( disklookup.first + disklookup.second, cParser::buffer_FILE );
if( false == material.deserialize( materialparser, Loadnow ) ) { if( false == material.deserialize( materialparser, Loadnow ) ) {
// deserialization failed but the .mat file does exist, so we give up at this point // deserialization failed but the .mat file does exist, so we give up at this point
return null_handle; return null_handle;
} }
material.name = disklookup; material.name = disklookup.first;
} }
else { else {
// if there's no .mat file, this could be legacy method of referring just to diffuse texture directly, make a material out of it in such case // if there's no .mat file, this could be legacy method of referring just to diffuse texture directly, make a material out of it in such case
@@ -145,7 +143,7 @@ material_manager::create( std::string const &Filename, bool const Loadnow ) {
// use texture path and name to tell the newly created materials apart // use texture path and name to tell the newly created materials apart
filename = GfxRenderer.Texture( material.texture1 ).name; filename = GfxRenderer.Texture( material.texture1 ).name;
erase_extension( filename ); erase_extension( filename );
material.name = filename + ".mat"; material.name = filename;
material.has_alpha = GfxRenderer.Texture( material.texture1 ).has_alpha; material.has_alpha = GfxRenderer.Texture( material.texture1 ).has_alpha;
} }
@@ -159,7 +157,7 @@ material_manager::create( std::string const &Filename, bool const Loadnow ) {
material_handle material_handle
material_manager::find_in_databank( std::string const &Materialname ) const { material_manager::find_in_databank( std::string const &Materialname ) const {
std::vector<std::string> filenames { std::vector<std::string> const filenames {
Global.asCurrentTexturePath + Materialname, Global.asCurrentTexturePath + Materialname,
Materialname, Materialname,
szTexturePath + Materialname }; szTexturePath + Materialname };
@@ -170,20 +168,19 @@ material_manager::find_in_databank( std::string const &Materialname ) const {
return lookup->second; return lookup->second;
} }
} }
// all lookups failed
return null_handle; return null_handle;
} }
// checks whether specified file exists. // checks whether specified file exists.
// NOTE: this is direct copy of the method used by texture manager. TBD, TODO: refactor into common routine? // NOTE: technically could be static, but we might want to switch from global texture path to instance-specific at some point
std::string std::pair<std::string, std::string>
material_manager::find_on_disk( std::string const &Materialname ) const { material_manager::find_on_disk( std::string const &Materialname ) const {
return ( return (
FileExists( Global.asCurrentTexturePath + Materialname ) ? Global.asCurrentTexturePath + Materialname : FileExists(
FileExists( Materialname ) ? Materialname : { Global.asCurrentTexturePath + Materialname, Materialname, szTexturePath + Materialname },
FileExists( szTexturePath + Materialname ) ? szTexturePath + Materialname : { ".mat" } ) );
"" );
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -25,6 +25,9 @@ struct opengl_material {
bool has_alpha { false }; // alpha state, calculated from presence of alpha in texture1 bool has_alpha { false }; // alpha state, calculated from presence of alpha in texture1
std::string name; std::string name;
// constructors
opengl_material() = default;
// methods // methods
bool bool
deserialize( cParser &Input, bool const Loadnow ); deserialize( cParser &Input, bool const Loadnow );
@@ -59,7 +62,7 @@ private:
material_handle material_handle
find_in_databank( std::string const &Materialname ) const; find_in_databank( std::string const &Materialname ) const;
// checks whether specified file exists. returns name of the located file, or empty string. // checks whether specified file exists. returns name of the located file, or empty string.
std::string std::pair<std::string, std::string>
find_on_disk( std::string const &Materialname ) const; find_on_disk( std::string const &Materialname ) const;
// members: // members:
material_sequence m_materials; material_sequence m_materials;

View File

@@ -330,6 +330,20 @@ FileExists( std::string const &Filename ) {
return( true == file.is_open() ); return( true == file.is_open() );
} }
std::pair<std::string, std::string>
FileExists( std::vector<std::string> const &Names, std::vector<std::string> const &Extensions ) {
for( auto const &name : Names ) {
for( auto const &extension : Extensions ) {
if( FileExists( name + extension ) ) {
return { name, extension };
}
}
}
// nothing found
return { {}, {} };
}
// returns time of last modification for specified file // returns time of last modification for specified file
std::time_t std::time_t
last_modified( std::string const &Filename ) { last_modified( std::string const &Filename ) {

View File

@@ -179,6 +179,8 @@ extract_value( bool &Variable, std::string const &Key, std::string const &Input,
bool FileExists( std::string const &Filename ); bool FileExists( std::string const &Filename );
std::pair<std::string, std::string> FileExists( std::vector<std::string> const &Names, std::vector<std::string> const &Extensions );
// returns time of last modification for specified file // returns time of last modification for specified file
std::time_t last_modified( std::string const &Filename ); std::time_t last_modified( std::string const &Filename );

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define VERSION_MAJOR 18 #define VERSION_MAJOR 18
#define VERSION_MINOR 521 #define VERSION_MINOR 527
#define VERSION_REVISION 0 #define VERSION_REVISION 0