mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 20:19:19 +02:00
compartment lighting system enhancement, lowpoly system tweaks, minor bug fixes
This commit is contained in:
27
Button.cpp
27
Button.cpp
@@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "Button.h"
|
||||
#include "parser.h"
|
||||
#include "Model3d.h"
|
||||
#include "DynObj.h"
|
||||
#include "Console.h"
|
||||
#include "Logs.h"
|
||||
#include "renderer.h"
|
||||
@@ -25,17 +26,19 @@ void TButton::Clear(int i)
|
||||
Update(); // kasowanie bitu Feedback, o ile jakiś ustawiony
|
||||
};
|
||||
|
||||
void TButton::Init( std::string const &asName, TModel3d *pModel, bool bNewOn ) {
|
||||
bool TButton::Init( std::string const &asName, TModel3d const *pModel, bool bNewOn ) {
|
||||
|
||||
if( pModel == nullptr ) { return; }
|
||||
if( pModel == nullptr ) { return false; }
|
||||
|
||||
pModelOn = pModel->GetFromName( asName + "_on" );
|
||||
pModelOff = pModel->GetFromName( asName + "_off" );
|
||||
m_state = bNewOn;
|
||||
Update();
|
||||
|
||||
return( ( pModelOn != nullptr ) || ( pModelOff != nullptr ) );
|
||||
};
|
||||
|
||||
void TButton::Load( cParser &Parser, TDynamicObject const *Owner, TModel3d *pModel1, TModel3d *pModel2 ) {
|
||||
void TButton::Load( cParser &Parser, TDynamicObject const *Owner ) {
|
||||
|
||||
std::string submodelname;
|
||||
|
||||
@@ -57,21 +60,17 @@ void TButton::Load( cParser &Parser, TDynamicObject const *Owner, TModel3d *pMod
|
||||
m_soundfxincrease.owner( Owner );
|
||||
m_soundfxdecrease.owner( Owner );
|
||||
|
||||
if( pModel1 ) {
|
||||
// poszukiwanie submodeli w modelu
|
||||
Init( submodelname, pModel1, false );
|
||||
std::array<TModel3d *, 3> sources { Owner->mdKabina, Owner->mdLowPolyInt, Owner->mdModel };
|
||||
for( auto const *source : sources ) {
|
||||
if( true == Init( submodelname, source, false ) ) {
|
||||
// got what we wanted, bail out
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( ( pModelOn == nullptr )
|
||||
&& ( pModelOff == nullptr )
|
||||
&& ( pModel2 != nullptr ) ) {
|
||||
// poszukiwanie submodeli w modelu
|
||||
Init( submodelname, pModel2, false );
|
||||
}
|
||||
|
||||
if( ( pModelOn == nullptr )
|
||||
&& ( pModelOff == nullptr ) ) {
|
||||
// if we failed to locate even one state submodel, cry
|
||||
ErrorLog( "Bad model: failed to locate sub-model \"" + submodelname + "\" in 3d model \"" + ( pModel1 != nullptr ? pModel1->NameGet() : pModel2 != nullptr ? pModel2->NameGet() : "NULL" ) + "\"", logtype::model );
|
||||
ErrorLog( "Bad model: failed to locate sub-model \"" + submodelname + "\" in 3d model(s) of \"" + Owner->name() + "\"", logtype::model );
|
||||
}
|
||||
|
||||
// pass submodel location to defined sounds
|
||||
|
||||
4
Button.h
4
Button.h
@@ -31,8 +31,8 @@ public:
|
||||
return ( ( pModelOn != nullptr )
|
||||
|| ( pModelOff != nullptr ) ); }
|
||||
void Update();
|
||||
void Init( std::string const &asName, TModel3d *pModel, bool bNewOn = false );
|
||||
void Load( cParser &Parser, TDynamicObject const *Owner, TModel3d *pModel1, TModel3d *pModel2 = nullptr );
|
||||
bool Init( std::string const &asName, TModel3d const *pModel, bool bNewOn = false );
|
||||
void Load( cParser &Parser, TDynamicObject const *Owner );
|
||||
void AssignBool(bool const *bValue);
|
||||
// returns offset of submodel associated with the button from the model centre
|
||||
glm::vec3 model_offset() const;
|
||||
|
||||
55
DynObj.cpp
55
DynObj.cpp
@@ -648,16 +648,14 @@ TDynamicObject::toggle_lights() {
|
||||
}
|
||||
|
||||
void
|
||||
TDynamicObject::set_cab_lights( float const Level ) {
|
||||
|
||||
if( Level == InteriorLightLevel ) { return; }
|
||||
|
||||
InteriorLightLevel = Level;
|
||||
TDynamicObject::set_cab_lights( int const Cab, float const Level ) {
|
||||
|
||||
for( auto §ion : Sections ) {
|
||||
// cab compartments are placed at the beginning of the list, so we can bail out as soon as we find different compartment type
|
||||
auto const sectionname { section.compartment->pName };
|
||||
if( sectionname.size() < 4 ) { return; }
|
||||
if( sectionname.find( "cab" ) != 0 ) { return; }
|
||||
if( sectionname[ 3 ] != Cab + '0' ) { continue; } // match the cab with correct index
|
||||
|
||||
section.light_level = Level;
|
||||
}
|
||||
@@ -985,7 +983,8 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||||
btnOn = true;
|
||||
}
|
||||
|
||||
if( ( Mechanik != nullptr )
|
||||
if( ( false == bDisplayCab ) // edge case, lowpoly may act as a stand-in for the hi-fi cab, so make sure not to show the driver when inside
|
||||
&& ( Mechanik != nullptr )
|
||||
&& ( ( Mechanik->GetAction() != TAction::actSleep )
|
||||
|| ( MoverParameters->Battery ) ) ) {
|
||||
// rysowanie figurki mechanika
|
||||
@@ -1040,10 +1039,19 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||||
// else btHeadSignals23.TurnOff();
|
||||
}
|
||||
// interior light levels
|
||||
auto sectionlightcolor { glm::vec4( 1.f ) };
|
||||
for( auto const §ion : Sections ) {
|
||||
section.compartment->SetLightLevel( section.light_level, true );
|
||||
/*
|
||||
sectionlightcolor = glm::vec4( InteriorLight, section.light_level );
|
||||
*/
|
||||
sectionlightcolor = glm::vec4(
|
||||
( ( ( section.light_level == 0.f ) || ( Global.fLuminance > section.compartment->fLight ) ) ?
|
||||
glm::vec3( 240.f / 255.f ) : // TBD: save and restore initial submodel diffuse instead of enforcing one?
|
||||
InteriorLight ), // TODO: per-compartment (type) light color
|
||||
section.light_level );
|
||||
section.compartment->SetLightLevel( sectionlightcolor, true );
|
||||
if( section.load != nullptr ) {
|
||||
section.load->SetLightLevel( section.light_level, true );
|
||||
section.load->SetLightLevel( sectionlightcolor, true );
|
||||
}
|
||||
}
|
||||
// load chunks visibility
|
||||
@@ -1062,7 +1070,17 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||||
sectionchunk = sectionchunk->NextGet();
|
||||
}
|
||||
}
|
||||
|
||||
// driver cabs visibility
|
||||
for( int cabidx = 0; cabidx < LowPolyIntCabs.size(); ++cabidx ) {
|
||||
if( LowPolyIntCabs[ cabidx ] == nullptr ) { continue; }
|
||||
LowPolyIntCabs[ cabidx ]->iVisible = (
|
||||
mdKabina == nullptr ? true : // there's no hi-fi cab
|
||||
bDisplayCab == false ? true : // we're in external view
|
||||
simulation::Train == nullptr ? true : // not a player-driven vehicle, implies external view
|
||||
simulation::Train->Dynamic() != this ? true : // not a player-driven vehicle, implies external view
|
||||
JointCabs ? false : // internal view, all cabs share the model so hide them 'all'
|
||||
( simulation::Train->iCabn != cabidx ) ); // internal view, hide occupied cab and show others
|
||||
}
|
||||
}
|
||||
// ABu 29.01.05 koniec przeklejenia *************************************
|
||||
|
||||
@@ -2185,9 +2203,18 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
// check the low poly interior for potential compartments of interest, ie ones which can be individually lit
|
||||
// TODO: definition of relevant compartments in the .mmd file
|
||||
TSubModel *submodel { nullptr };
|
||||
if( ( submodel = mdLowPolyInt->GetFromName( "cab1" ) ) != nullptr ) { Sections.push_back( { submodel, nullptr, 0.0f } ); }
|
||||
if( ( submodel = mdLowPolyInt->GetFromName( "cab2" ) ) != nullptr ) { Sections.push_back( { submodel, nullptr, 0.0f } ); }
|
||||
if( ( submodel = mdLowPolyInt->GetFromName( "cab0" ) ) != nullptr ) { Sections.push_back( { submodel, nullptr, 0.0f } ); }
|
||||
if( ( submodel = mdLowPolyInt->GetFromName( "cab0" ) ) != nullptr ) {
|
||||
Sections.push_back( { submodel, nullptr, 0.0f } );
|
||||
LowPolyIntCabs[ 0 ] = submodel;
|
||||
}
|
||||
if( ( submodel = mdLowPolyInt->GetFromName( "cab1" ) ) != nullptr ) {
|
||||
Sections.push_back( { submodel, nullptr, 0.0f } );
|
||||
LowPolyIntCabs[ 1 ] = submodel;
|
||||
}
|
||||
if( ( submodel = mdLowPolyInt->GetFromName( "cab2" ) ) != nullptr ) {
|
||||
Sections.push_back( { submodel, nullptr, 0.0f } );
|
||||
LowPolyIntCabs[ 2 ] = submodel;
|
||||
}
|
||||
// passenger car compartments
|
||||
std::vector<std::string> nameprefixes = { "corridor", "korytarz", "compartment", "przedzial" };
|
||||
for( auto const &nameprefix : nameprefixes ) {
|
||||
@@ -5899,6 +5926,10 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
||||
>> HuntingShake.fadein_end;
|
||||
}
|
||||
|
||||
else if( token == "jointcabs:" ) {
|
||||
parser.getTokens();
|
||||
parser >> JointCabs;
|
||||
}
|
||||
|
||||
} while( token != "" );
|
||||
|
||||
|
||||
4
DynObj.h
4
DynObj.h
@@ -197,6 +197,8 @@ public:
|
||||
TModel3d *mdLoad; // model zmiennego ładunku
|
||||
TModel3d *mdKabina; // model kabiny dla użytkownika; McZapkie-030303: to z train.h
|
||||
TModel3d *mdLowPolyInt; // ABu 010305: wnetrze lowpoly
|
||||
std::array<TSubModel *, 3> LowPolyIntCabs {}; // pointers to low fidelity version of individual driver cabs
|
||||
bool JointCabs{ false }; // flag for vehicles with multiple virtual 'cabs' sharing location and 3d model(s)
|
||||
float fShade; // zacienienie: 0:normalnie, -1:w ciemności, +1:dodatkowe światło (brak koloru?)
|
||||
float LoadOffset { 0.f };
|
||||
glm::vec3 InteriorLight { 0.9f * 255.f / 255.f, 0.9f * 216.f / 255.f, 0.9f * 176.f / 255.f }; // tungsten light. TODO: allow definition of light type?
|
||||
@@ -616,7 +618,7 @@ private:
|
||||
void Damage(char flag);
|
||||
void RaLightsSet(int head, int rear);
|
||||
int LightList( side const Side ) const { return iInventory[ Side ]; }
|
||||
void set_cab_lights( float const Level );
|
||||
void set_cab_lights( int const Cab, float const Level );
|
||||
TDynamicObject * FirstFind(int &coupler_nr, int cf = 1);
|
||||
float GetEPP(); // wyliczanie sredniego cisnienia w PG
|
||||
int DirectionSet(int d); // ustawienie kierunku w składzie
|
||||
|
||||
21
Gauge.cpp
21
Gauge.cpp
@@ -17,6 +17,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "Gauge.h"
|
||||
#include "parser.h"
|
||||
#include "Model3d.h"
|
||||
#include "DynObj.h"
|
||||
#include "Timer.h"
|
||||
#include "Logs.h"
|
||||
#include "renderer.h"
|
||||
@@ -76,7 +77,7 @@ void TGauge::Init(TSubModel *Submodel, TGaugeAnimation Type, float Scale, float
|
||||
}
|
||||
};
|
||||
|
||||
bool TGauge::Load( cParser &Parser, TDynamicObject const *Owner, TModel3d *md1, TModel3d *md2, double mul ) {
|
||||
void TGauge::Load( cParser &Parser, TDynamicObject const *Owner, double const mul ) {
|
||||
|
||||
std::string submodelname, gaugetypename;
|
||||
float scale, endscale, endvalue, offset, friction;
|
||||
@@ -138,13 +139,17 @@ bool TGauge::Load( cParser &Parser, TDynamicObject const *Owner, TModel3d *md1,
|
||||
if( interpolatescale ) {
|
||||
endscale *= mul;
|
||||
}
|
||||
TSubModel *submodel = md1->GetFromName( submodelname );
|
||||
if (submodel) // jeśli nie znaleziony
|
||||
md2 = nullptr; // informacja, że znaleziony
|
||||
else if (md2) // a jest podany drugi model (np. zewnętrzny)
|
||||
submodel = md2->GetFromName(submodelname); // to może tam będzie, co za różnica gdzie
|
||||
TSubModel *submodel { nullptr };
|
||||
std::array<TModel3d *, 2> sources { Owner->mdKabina, Owner->mdLowPolyInt };
|
||||
for( auto const *source : sources ) {
|
||||
if( ( source != nullptr )
|
||||
&& ( submodel = source->GetFromName( submodelname ) ) != nullptr ) {
|
||||
// got what we wanted, bail out
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( submodel == nullptr ) {
|
||||
ErrorLog( "Bad model: failed to locate sub-model \"" + submodelname + "\" in 3d model \"" + md1->NameGet() + "\"", logtype::model );
|
||||
ErrorLog( "Bad model: failed to locate sub-model \"" + submodelname + "\" in 3d model(s) of \"" + Owner->name() + "\"", logtype::model );
|
||||
}
|
||||
|
||||
std::map<std::string, TGaugeAnimation> gaugetypes {
|
||||
@@ -163,7 +168,7 @@ bool TGauge::Load( cParser &Parser, TDynamicObject const *Owner, TModel3d *md1,
|
||||
|
||||
Init( submodel, type, scale, offset, friction, 0, endvalue, endscale, interpolatescale );
|
||||
|
||||
return md2 != nullptr; // true, gdy podany model zewnętrzny, a w kabinie nie było
|
||||
// return md2 != nullptr; // true, gdy podany model zewnętrzny, a w kabinie nie było
|
||||
};
|
||||
|
||||
bool
|
||||
|
||||
2
Gauge.h
2
Gauge.h
@@ -38,7 +38,7 @@ public:
|
||||
void Clear() {
|
||||
*this = TGauge(); }
|
||||
void Init(TSubModel *Submodel, TGaugeAnimation Type, float Scale = 1, float Offset = 0, float Friction = 0, float Value = 0, float const Endvalue = -1.0, float const Endscale = -1.0, bool const Interpolate = false );
|
||||
bool Load(cParser &Parser, TDynamicObject const *Owner, TModel3d *md1, TModel3d *md2 = nullptr, double mul = 1.0);
|
||||
void Load(cParser &Parser, TDynamicObject const *Owner, double const mul = 1.0);
|
||||
void UpdateValue( float fNewDesired );
|
||||
void UpdateValue( float fNewDesired, sound_source &Fallbacksound );
|
||||
void PutValue(float fNewDesired);
|
||||
|
||||
@@ -109,9 +109,12 @@ TSubModel::SetVisibilityLevel( float const Level, bool const Includechildren, bo
|
||||
|
||||
// sets light level (alpha component of illumination color) to specified value
|
||||
void
|
||||
TSubModel::SetLightLevel( float const Level, bool const Includechildren, bool const Includesiblings ) {
|
||||
|
||||
f4Emision.a = Level;
|
||||
TSubModel::SetLightLevel( glm::vec4 const &Level, bool const Includechildren, bool const Includesiblings ) {
|
||||
/*
|
||||
f4Emision = Level;
|
||||
*/
|
||||
f4Diffuse = { Level.r, Level.g, Level.b, f4Diffuse.a };
|
||||
f4Emision.a = Level.a;
|
||||
if( true == Includesiblings ) {
|
||||
auto sibling { this };
|
||||
while( ( sibling = sibling->Next ) != nullptr ) {
|
||||
|
||||
@@ -198,7 +198,7 @@ public:
|
||||
// sets visibility level (alpha component) to specified value
|
||||
void SetVisibilityLevel( float const Level, bool const Includechildren = false, bool const Includesiblings = false );
|
||||
// sets light level (alpha component of illumination color) to specified value
|
||||
void SetLightLevel( float const Level, bool const Includechildren = false, bool const Includesiblings = false );
|
||||
void SetLightLevel( glm::vec4 const &Level, bool const Includechildren = false, bool const Includesiblings = false );
|
||||
inline float3 Translation1Get() {
|
||||
return fMatrix ? *(fMatrix->TranslationGet()) + v_TransVector : v_TransVector; }
|
||||
inline float3 Translation2Get() {
|
||||
|
||||
20
Train.h
20
Train.h
@@ -33,16 +33,21 @@ public:
|
||||
// methods
|
||||
void Load(cParser &Parser);
|
||||
void Update();
|
||||
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 };
|
||||
bool bEnabled { false };
|
||||
bool bOccupied { true };
|
||||
/*
|
||||
glm::vec3 dimm; // McZapkie-120503: tlumienie swiatla
|
||||
glm::vec3 intlit; // McZapkie-120503: oswietlenie kabiny
|
||||
glm::vec3 intlitlow; // McZapkie-120503: przyciemnione oswietlenie kabiny
|
||||
TGauge &Gauge( int n = -1 ); // pobranie adresu obiektu
|
||||
TButton &Button( int n = -1 ); // pobranie adresu obiektu
|
||||
*/
|
||||
bool bLight { false }; // hunter-091012: czy swiatlo jest zapalone?
|
||||
bool bLightDim { false }; // hunter-091012: czy przyciemnienie kabiny jest zapalone?
|
||||
float LightLevel{ 0.f }; // last calculated interior light level
|
||||
|
||||
private:
|
||||
// members
|
||||
@@ -121,7 +126,7 @@ class TTrain
|
||||
void clear_cab_controls();
|
||||
// sets cabin controls based on current state of the vehicle
|
||||
// NOTE: we can get rid of this function once we have per-cab persistent state
|
||||
void set_cab_controls();
|
||||
void set_cab_controls( int const Cab );
|
||||
// initializes a gauge matching provided label. returns: true if the label was found, false otherwise
|
||||
bool initialize_gauge(cParser &Parser, std::string const &Label, int const Cabindex);
|
||||
// initializes a button matching provided label. returns: true if the label was found, false otherwise
|
||||
@@ -589,14 +594,14 @@ public: // reszta może by?publiczna
|
||||
sound_source m_radiosound { sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // cached template for radio messages
|
||||
std::vector<std::pair<int, std::shared_ptr<sound_source>>> m_radiomessages; // list of currently played radio messages
|
||||
sound_source m_radiostop { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
||||
|
||||
/*
|
||||
int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne)
|
||||
bool bCabLight; // hunter-091012: czy swiatlo jest zapalone?
|
||||
bool bCabLightDim; // hunter-091012: czy przyciemnienie kabiny jest zapalone?
|
||||
|
||||
*/
|
||||
// McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc
|
||||
TCab Cabine[ maxcab + 1 ]; // przedzial maszynowy, kabina 1 (A), kabina 2 (B)
|
||||
int iCabn;
|
||||
std::array<TCab, maxcab + 1> Cabine; // przedzial maszynowy, kabina 1 (A), kabina 2 (B)
|
||||
int iCabn { 0 };
|
||||
// McZapkie: do poruszania sie po kabinie
|
||||
Math3D::vector3 pMechSittingPosition; // ABu 180404
|
||||
Math3D::vector3 MirrorPosition( bool lewe );
|
||||
@@ -638,6 +643,7 @@ private:
|
||||
bool bHeat[8]; // grzanie
|
||||
// McZapkie: do syczenia
|
||||
float fPPress, fNPress;
|
||||
bool m_mastercontrollerinuse { false };
|
||||
int iRadioChannel { 1 }; // numer aktualnego kana?u radiowego
|
||||
std::vector<std::pair<std::string, texture_handle>> m_screens;
|
||||
|
||||
|
||||
101
drivermode.cpp
101
drivermode.cpp
@@ -27,13 +27,13 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "renderer.h"
|
||||
#include "utilities.h"
|
||||
#include "Logs.h"
|
||||
|
||||
/*
|
||||
namespace input {
|
||||
|
||||
user_command command; // currently issued control command, if any
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
void
|
||||
driver_mode::drivermode_input::poll() {
|
||||
|
||||
@@ -47,11 +47,13 @@ driver_mode::drivermode_input::poll() {
|
||||
if( uart != nullptr ) {
|
||||
uart->poll();
|
||||
}
|
||||
/*
|
||||
// TBD, TODO: wrap current command in object, include other input sources?
|
||||
input::command = (
|
||||
mouse.command() != user_command::none ?
|
||||
mouse.command() :
|
||||
keyboard.command() );
|
||||
*/
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -468,6 +470,15 @@ driver_mode::update_camera( double const Deltatime ) {
|
||||
simulation::Train->pMechViewAngle = { Camera.Angle.x, Camera.Angle.y };
|
||||
simulation::Train->pMechOffset = Camera.m_owneroffset;
|
||||
}
|
||||
|
||||
if( ( true == FreeFlyModeFlag )
|
||||
&& ( Camera.m_owner != nullptr ) ) {
|
||||
// cache external view config
|
||||
auto &externalviewconfig { m_externalviewconfigs[ m_externalviewmode ] };
|
||||
externalviewconfig.owner = Camera.m_owner;
|
||||
externalviewconfig.offset = Camera.m_owneroffset;
|
||||
externalviewconfig.angle = Camera.Angle;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// debug camera
|
||||
@@ -567,13 +578,13 @@ driver_mode::update_camera( double const Deltatime ) {
|
||||
// gdy w korytarzu
|
||||
Camera.LookAt =
|
||||
Camera.m_owner->GetWorldPosition( Camera.m_owneroffset )
|
||||
+ simulation::Train->GetDirection() * 5.0;
|
||||
+ Camera.m_owner->VectorFront() * 5.0;
|
||||
}
|
||||
else {
|
||||
// patrzenie w kierunku osi pojazdu, z uwzględnieniem kabiny
|
||||
Camera.LookAt =
|
||||
Camera.m_owner->GetWorldPosition( Camera.m_owneroffset )
|
||||
+ simulation::Train->GetDirection() * 5.0
|
||||
+ Camera.m_owner->VectorFront() * 5.0
|
||||
* simulation::Train->Occupied()->ActiveCab; //-1 albo 1
|
||||
}
|
||||
Camera.vUp = simulation::Train->GetUp();
|
||||
@@ -914,18 +925,26 @@ driver_mode::ExternalView() {
|
||||
|
||||
Camera.m_owner = owner;
|
||||
|
||||
auto const offsetflip {
|
||||
( vehicle->MoverParameters->ActiveCab == 0 ? 1 : vehicle->MoverParameters->ActiveCab )
|
||||
* ( vehicle->MoverParameters->ActiveDir == 0 ? 1 : vehicle->MoverParameters->ActiveDir ) };
|
||||
auto const &viewconfig { m_externalviewconfigs[ m_externalviewmode ] };
|
||||
if( owner == viewconfig.owner ) {
|
||||
// restore view config for previous owner
|
||||
Camera.m_owneroffset = viewconfig.offset;
|
||||
Camera.Angle = viewconfig.angle;
|
||||
}
|
||||
else {
|
||||
// default view setup
|
||||
auto const offsetflip{
|
||||
( vehicle->MoverParameters->ActiveCab == 0 ? 1 : vehicle->MoverParameters->ActiveCab )
|
||||
* ( vehicle->MoverParameters->ActiveDir == 0 ? 1 : vehicle->MoverParameters->ActiveDir ) };
|
||||
|
||||
Camera.m_owneroffset = {
|
||||
1.5 * owner->MoverParameters->Dim.W * offsetflip,
|
||||
std::max( 5.0, 1.25 * owner->MoverParameters->Dim.H ),
|
||||
- 0.4 * owner->MoverParameters->Dim.L * offsetflip };
|
||||
Camera.m_owneroffset = {
|
||||
1.5 * owner->MoverParameters->Dim.W * offsetflip,
|
||||
std::max( 5.0, 1.25 * owner->MoverParameters->Dim.H ),
|
||||
-0.4 * owner->MoverParameters->Dim.L * offsetflip };
|
||||
|
||||
Camera.Angle.y = glm::radians( ( vehicle->MoverParameters->ActiveDir < 0 ? 180.0 : 0.0 ) );
|
||||
|
||||
auto const shakeangles { owner->shake_angles() };
|
||||
Camera.Angle.y = glm::radians( ( vehicle->MoverParameters->ActiveDir < 0 ? 180.0 : 0.0 ) );
|
||||
}
|
||||
auto const shakeangles{ owner->shake_angles() };
|
||||
Camera.Angle.x -= 0.5 * shakeangles.second; // hustanie kamery przod tyl
|
||||
Camera.Angle.z = shakeangles.first; // hustanie kamery na boki
|
||||
|
||||
@@ -937,18 +956,26 @@ driver_mode::ExternalView() {
|
||||
|
||||
Camera.m_owner = owner;
|
||||
|
||||
auto const offsetflip {
|
||||
( vehicle->MoverParameters->ActiveCab == 0 ? 1 : vehicle->MoverParameters->ActiveCab )
|
||||
* ( vehicle->MoverParameters->ActiveDir == 0 ? 1 : vehicle->MoverParameters->ActiveDir )
|
||||
* -1 };
|
||||
auto const &viewconfig{ m_externalviewconfigs[ m_externalviewmode ] };
|
||||
if( owner == viewconfig.owner ) {
|
||||
// restore view config for previous owner
|
||||
Camera.m_owneroffset = viewconfig.offset;
|
||||
Camera.Angle = viewconfig.angle;
|
||||
}
|
||||
else {
|
||||
// default view setup
|
||||
auto const offsetflip{
|
||||
( vehicle->MoverParameters->ActiveCab == 0 ? 1 : vehicle->MoverParameters->ActiveCab )
|
||||
* ( vehicle->MoverParameters->ActiveDir == 0 ? 1 : vehicle->MoverParameters->ActiveDir )
|
||||
* -1 };
|
||||
|
||||
Camera.m_owneroffset = {
|
||||
1.5 * owner->MoverParameters->Dim.W * offsetflip,
|
||||
std::max( 5.0, 1.25 * owner->MoverParameters->Dim.H ),
|
||||
0.2 * owner->MoverParameters->Dim.L * offsetflip };
|
||||
|
||||
Camera.Angle.y = glm::radians( ( vehicle->MoverParameters->ActiveDir < 0 ? 0.0 : 180.0 ) );
|
||||
Camera.m_owneroffset = {
|
||||
1.5 * owner->MoverParameters->Dim.W * offsetflip,
|
||||
std::max( 5.0, 1.25 * owner->MoverParameters->Dim.H ),
|
||||
0.2 * owner->MoverParameters->Dim.L * offsetflip };
|
||||
|
||||
Camera.Angle.y = glm::radians( ( vehicle->MoverParameters->ActiveDir < 0 ? 0.0 : 180.0 ) );
|
||||
}
|
||||
auto const shakeangles { owner->shake_angles() };
|
||||
Camera.Angle.x -= 0.5 * shakeangles.second; // hustanie kamery przod tyl
|
||||
Camera.Angle.z = shakeangles.first; // hustanie kamery na boki
|
||||
@@ -959,17 +986,25 @@ driver_mode::ExternalView() {
|
||||
|
||||
Camera.m_owner = owner;
|
||||
|
||||
auto const offsetflip {
|
||||
( vehicle->MoverParameters->ActiveCab == 0 ? 1 : vehicle->MoverParameters->ActiveCab )
|
||||
* ( vehicle->MoverParameters->ActiveDir == 0 ? 1 : vehicle->MoverParameters->ActiveDir ) };
|
||||
auto const &viewconfig{ m_externalviewconfigs[ m_externalviewmode ] };
|
||||
if( owner == viewconfig.owner ) {
|
||||
// restore view config for previous owner
|
||||
Camera.m_owneroffset = viewconfig.offset;
|
||||
Camera.Angle = viewconfig.angle;
|
||||
}
|
||||
else {
|
||||
// default view setup
|
||||
auto const offsetflip{
|
||||
( vehicle->MoverParameters->ActiveCab == 0 ? 1 : vehicle->MoverParameters->ActiveCab )
|
||||
* ( vehicle->MoverParameters->ActiveDir == 0 ? 1 : vehicle->MoverParameters->ActiveDir ) };
|
||||
|
||||
Camera.m_owneroffset = {
|
||||
- 0.65 * owner->MoverParameters->Dim.W * offsetflip,
|
||||
0.90,
|
||||
0.15 * owner->MoverParameters->Dim.L * offsetflip };
|
||||
|
||||
Camera.Angle.y = glm::radians( ( vehicle->MoverParameters->ActiveDir < 0 ? 180.0 : 0.0 ) );
|
||||
Camera.m_owneroffset = {
|
||||
-0.65 * owner->MoverParameters->Dim.W * offsetflip,
|
||||
0.90,
|
||||
0.15 * owner->MoverParameters->Dim.L * offsetflip };
|
||||
|
||||
Camera.Angle.y = glm::radians( ( vehicle->MoverParameters->ActiveDir < 0 ? 180.0 : 0.0 ) );
|
||||
}
|
||||
auto const shakeangles { owner->shake_angles() };
|
||||
Camera.Angle.x -= 0.5 * shakeangles.second; // hustanie kamery przod tyl
|
||||
Camera.Angle.z = shakeangles.first; // hustanie kamery na boki
|
||||
|
||||
@@ -60,6 +60,12 @@ private:
|
||||
count_
|
||||
};
|
||||
|
||||
struct view_config {
|
||||
TDynamicObject const *owner { nullptr };
|
||||
Math3D::vector3 offset {};
|
||||
Math3D::vector3 angle {};
|
||||
};
|
||||
|
||||
struct drivermode_input {
|
||||
|
||||
gamepad_input gamepad;
|
||||
@@ -91,6 +97,7 @@ private:
|
||||
TCamera DebugCamera;
|
||||
int m_externalviewmode { view::consistfront }; // selected external view mode
|
||||
bool m_externalview { false };
|
||||
std::array<view_config, view::count_> m_externalviewconfigs;
|
||||
TDynamicObject *pDynamicNearest { nullptr }; // vehicle nearest to the active camera. TODO: move to camera
|
||||
double fTime50Hz { 0.0 }; // bufor czasu dla komunikacji z PoKeys
|
||||
double const m_primaryupdaterate { 1.0 / 100.0 };
|
||||
|
||||
@@ -319,6 +319,7 @@ drivermouse_input::button( int const Button, int const Action ) {
|
||||
else {
|
||||
if( Button == GLFW_MOUSE_BUTTON_LEFT ) {
|
||||
if( m_slider.command() != user_command::none ) {
|
||||
m_relay.post( m_slider.command(), 0, 0, Action, 0 );
|
||||
m_slider.release();
|
||||
}
|
||||
}
|
||||
|
||||
64
renderer.cpp
64
renderer.cpp
@@ -562,7 +562,7 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
if( vehicle->InteriorLightLevel > 0.f ) {
|
||||
setup_shadow_color( glm::min( colors::white, shadowcolor + glm::vec4( vehicle->InteriorLight * vehicle->InteriorLightLevel, 1.f ) ) );
|
||||
}
|
||||
Render_cab( vehicle, false );
|
||||
Render_cab( vehicle, vehicle->InteriorLightLevel, false );
|
||||
if( vehicle->InteriorLightLevel > 0.f ) {
|
||||
setup_shadow_color( shadowcolor );
|
||||
}
|
||||
@@ -581,17 +581,17 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix );
|
||||
// cache shadow colour in case we need to account for cab light
|
||||
auto const shadowcolor{ m_shadowcolor };
|
||||
auto const *vehicle{ simulation::Train->Dynamic() };
|
||||
auto const *vehicle { simulation::Train->Dynamic() };
|
||||
if( vehicle->InteriorLightLevel > 0.f ) {
|
||||
setup_shadow_color( glm::min( colors::white, shadowcolor + glm::vec4( vehicle->InteriorLight * vehicle->InteriorLightLevel, 1.f ) ) );
|
||||
}
|
||||
if( Global.Overcast > 1.f ) {
|
||||
// with active precipitation draw the opaque cab parts here to mask rain/snow placed 'inside' the cab
|
||||
setup_drawing( false );
|
||||
Render_cab( vehicle, false );
|
||||
Render_cab( vehicle, vehicle->InteriorLightLevel, false );
|
||||
setup_drawing( true );
|
||||
}
|
||||
Render_cab( vehicle, true );
|
||||
Render_cab( vehicle, vehicle->InteriorLightLevel, true );
|
||||
if( vehicle->InteriorLightLevel > 0.f ) {
|
||||
setup_shadow_color( shadowcolor );
|
||||
}
|
||||
@@ -681,8 +681,8 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
#else
|
||||
setup_units( false, false, false );
|
||||
#endif
|
||||
Render_cab( simulation::Train->Dynamic(), false );
|
||||
Render_cab( simulation::Train->Dynamic(), true );
|
||||
Render_cab( simulation::Train->Dynamic(), 0.f, false );
|
||||
Render_cab( simulation::Train->Dynamic(), 0.f, true );
|
||||
m_cabshadowpass = m_renderpass;
|
||||
|
||||
// post-render restore
|
||||
@@ -745,7 +745,10 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
||||
setup_drawing( false );
|
||||
setup_units( false, false, false );
|
||||
// cab render skips translucent parts, so we can do it here
|
||||
if( simulation::Train != nullptr ) { Render_cab( simulation::Train->Dynamic() ); }
|
||||
if( simulation::Train != nullptr ) {
|
||||
Render_cab( simulation::Train->Dynamic(), 0.f );
|
||||
Render( simulation::Train->Dynamic() );
|
||||
}
|
||||
// post-render cleanup
|
||||
}
|
||||
break;
|
||||
@@ -816,7 +819,7 @@ opengl_renderer::setup_pass( renderpass_config &Config, rendermode const Mode, f
|
||||
switch( Mode ) {
|
||||
case rendermode::color: { Config.draw_range = Global.BaseDrawRange; break; }
|
||||
case rendermode::shadows: { Config.draw_range = Global.BaseDrawRange * 0.5f; break; }
|
||||
case rendermode::cabshadows: { Config.draw_range = ( simulation::Train->Occupied()->ActiveCab != 0 ? 10.f : 20.f ); break; }
|
||||
case rendermode::cabshadows: { Config.draw_range = simulation::Train->Occupied()->Dim.L; break; }
|
||||
case rendermode::reflections: { Config.draw_range = Global.BaseDrawRange; break; }
|
||||
case rendermode::pickcontrols: { Config.draw_range = 50.f; break; }
|
||||
case rendermode::pickscenery: { Config.draw_range = Global.BaseDrawRange * 0.5f; break; }
|
||||
@@ -2158,7 +2161,10 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
// render
|
||||
if( Dynamic->mdLowPolyInt ) {
|
||||
// low poly interior
|
||||
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
|
||||
/*
|
||||
if( ( true == FreeFlyModeFlag )
|
||||
|| ( ( Dynamic->mdKabina == nullptr ) || ( false == Dynamic->bDisplayCab ) ) ) {
|
||||
*/
|
||||
/*
|
||||
// enable cab light if needed
|
||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
||||
@@ -2174,7 +2180,9 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( m_baseambient ) );
|
||||
}
|
||||
*/
|
||||
/*
|
||||
}
|
||||
*/
|
||||
}
|
||||
if( Dynamic->mdModel )
|
||||
Render( Dynamic->mdModel, Dynamic->Material(), squaredistance );
|
||||
@@ -2191,9 +2199,9 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
case rendermode::shadows: {
|
||||
if( Dynamic->mdLowPolyInt ) {
|
||||
// low poly interior
|
||||
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
|
||||
// if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
|
||||
Render( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
|
||||
}
|
||||
// }
|
||||
}
|
||||
if( Dynamic->mdModel )
|
||||
Render( Dynamic->mdModel, Dynamic->Material(), squaredistance );
|
||||
@@ -2202,7 +2210,13 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
// post-render cleanup
|
||||
break;
|
||||
}
|
||||
case rendermode::pickcontrols:
|
||||
case rendermode::pickcontrols: {
|
||||
if( Dynamic->mdLowPolyInt ) {
|
||||
// low poly interior
|
||||
Render( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case rendermode::pickscenery:
|
||||
default: {
|
||||
break;
|
||||
@@ -2220,7 +2234,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
|
||||
// rendering kabiny gdy jest oddzielnym modelem i ma byc wyswietlana
|
||||
bool
|
||||
opengl_renderer::Render_cab( TDynamicObject const *Dynamic, bool const Alpha ) {
|
||||
opengl_renderer::Render_cab( TDynamicObject const *Dynamic, float const Lightlevel, bool const Alpha ) {
|
||||
|
||||
if( Dynamic == nullptr ) {
|
||||
|
||||
@@ -2252,9 +2266,9 @@ opengl_renderer::Render_cab( TDynamicObject const *Dynamic, bool const Alpha ) {
|
||||
// change light level based on light level of the occupied track
|
||||
m_sunlight.apply_intensity( Dynamic->fShade );
|
||||
}
|
||||
if( Dynamic->InteriorLightLevel > 0.f ) {
|
||||
if( Lightlevel > 0.f ) {
|
||||
// crude way to light the cabin, until we have something more complete in place
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( Dynamic->InteriorLight * Dynamic->InteriorLightLevel ) );
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( Dynamic->InteriorLight * Lightlevel ) );
|
||||
}
|
||||
// render
|
||||
if( true == Alpha ) {
|
||||
@@ -2270,7 +2284,7 @@ opengl_renderer::Render_cab( TDynamicObject const *Dynamic, bool const Alpha ) {
|
||||
// change light level based on light level of the occupied track
|
||||
m_sunlight.apply_intensity();
|
||||
}
|
||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
||||
if( Lightlevel > 0.f ) {
|
||||
// reset the overall ambient
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr(m_baseambient) );
|
||||
}
|
||||
@@ -2435,9 +2449,10 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
}
|
||||
// ...luminance
|
||||
auto const unitstate = m_unitstate;
|
||||
if( Global.fLuminance < Submodel->fLight ) {
|
||||
auto const isemissive { ( Submodel->f4Emision.a > 0.f ) && ( Global.fLuminance < Submodel->fLight ) };
|
||||
if( isemissive ) {
|
||||
// zeby swiecilo na kolorowo
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( Submodel->f4Diffuse * Submodel->f4Emision.a ) );
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( /* Submodel->f4Emision */ Submodel->f4Diffuse * Submodel->f4Emision.a ) );
|
||||
// disable shadows so they don't obstruct self-lit items
|
||||
/*
|
||||
setup_shadow_color( colors::white );
|
||||
@@ -2466,7 +2481,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
||||
if( ( true == m_renderspecular ) && ( m_sunlight.specular.a > 0.01f ) ) {
|
||||
::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( colors::none ) );
|
||||
}
|
||||
if( Global.fLuminance < Submodel->fLight ) {
|
||||
if( isemissive ) {
|
||||
// restore default (lack of) brightness
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) );
|
||||
/*
|
||||
@@ -3245,7 +3260,7 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||
// render
|
||||
if( Dynamic->mdLowPolyInt ) {
|
||||
// low poly interior
|
||||
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
|
||||
// if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
|
||||
/*
|
||||
// enable cab light if needed
|
||||
if( Dynamic->InteriorLightLevel > 0.0f ) {
|
||||
@@ -3261,7 +3276,7 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( m_baseambient ) );
|
||||
}
|
||||
*/
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
if( Dynamic->mdModel )
|
||||
@@ -3403,9 +3418,10 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
||||
}
|
||||
// ...luminance
|
||||
auto const unitstate = m_unitstate;
|
||||
if( Global.fLuminance < Submodel->fLight ) {
|
||||
auto const isemissive { ( Submodel->f4Emision.a > 0.f ) && ( Global.fLuminance < Submodel->fLight ) };
|
||||
if( isemissive ) {
|
||||
// zeby swiecilo na kolorowo
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( Submodel->f4Diffuse * Submodel->f4Emision.a ) );
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( /* Submodel->f4Emision */ Submodel->f4Diffuse * Submodel->f4Emision.a ) );
|
||||
// disable shadows so they don't obstruct self-lit items
|
||||
/*
|
||||
setup_shadow_color( colors::white );
|
||||
@@ -3420,7 +3436,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
|
||||
if( ( true == m_renderspecular ) && ( m_sunlight.specular.a > 0.01f ) ) {
|
||||
::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( colors::none ) );
|
||||
}
|
||||
if( Global.fLuminance < Submodel->fLight ) {
|
||||
if( isemissive ) {
|
||||
// restore default (lack of) brightness
|
||||
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) );
|
||||
/*
|
||||
|
||||
@@ -292,7 +292,7 @@ private:
|
||||
void
|
||||
Render( scene::basic_cell::path_sequence::const_iterator First, scene::basic_cell::path_sequence::const_iterator Last );
|
||||
bool
|
||||
Render_cab( TDynamicObject const *Dynamic, bool const Alpha = false );
|
||||
Render_cab( TDynamicObject const *Dynamic, float const Lightlevel, bool const Alpha = false );
|
||||
void
|
||||
Render( TMemCell *Memcell );
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user