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

compartment lighting system enhancement, lowpoly system tweaks, minor bug fixes

This commit is contained in:
tmj-fstate
2018-11-12 23:26:29 +01:00
parent c59b53067a
commit 8d910e434f
15 changed files with 507 additions and 339 deletions

View File

@@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/.
#include "Button.h" #include "Button.h"
#include "parser.h" #include "parser.h"
#include "Model3d.h" #include "Model3d.h"
#include "DynObj.h"
#include "Console.h" #include "Console.h"
#include "Logs.h" #include "Logs.h"
#include "renderer.h" #include "renderer.h"
@@ -25,17 +26,19 @@ void TButton::Clear(int i)
Update(); // kasowanie bitu Feedback, o ile jakiś ustawiony 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" ); pModelOn = pModel->GetFromName( asName + "_on" );
pModelOff = pModel->GetFromName( asName + "_off" ); pModelOff = pModel->GetFromName( asName + "_off" );
m_state = bNewOn; m_state = bNewOn;
Update(); 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; std::string submodelname;
@@ -57,21 +60,17 @@ void TButton::Load( cParser &Parser, TDynamicObject const *Owner, TModel3d *pMod
m_soundfxincrease.owner( Owner ); m_soundfxincrease.owner( Owner );
m_soundfxdecrease.owner( Owner ); m_soundfxdecrease.owner( Owner );
if( pModel1 ) { std::array<TModel3d *, 3> sources { Owner->mdKabina, Owner->mdLowPolyInt, Owner->mdModel };
// poszukiwanie submodeli w modelu for( auto const *source : sources ) {
Init( submodelname, pModel1, false ); 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 ) if( ( pModelOn == nullptr )
&& ( pModelOff == nullptr ) ) { && ( pModelOff == nullptr ) ) {
// if we failed to locate even one state submodel, cry // 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 // pass submodel location to defined sounds

View File

@@ -31,8 +31,8 @@ public:
return ( ( pModelOn != nullptr ) return ( ( pModelOn != nullptr )
|| ( pModelOff != nullptr ) ); } || ( pModelOff != nullptr ) ); }
void Update(); void Update();
void Init( std::string const &asName, TModel3d *pModel, bool bNewOn = false ); bool Init( std::string const &asName, TModel3d const *pModel, bool bNewOn = false );
void Load( cParser &Parser, TDynamicObject const *Owner, TModel3d *pModel1, TModel3d *pModel2 = nullptr ); void Load( cParser &Parser, TDynamicObject const *Owner );
void AssignBool(bool const *bValue); void AssignBool(bool const *bValue);
// returns offset of submodel associated with the button from the model centre // returns offset of submodel associated with the button from the model centre
glm::vec3 model_offset() const; glm::vec3 model_offset() const;

View File

@@ -648,16 +648,14 @@ TDynamicObject::toggle_lights() {
} }
void void
TDynamicObject::set_cab_lights( float const Level ) { TDynamicObject::set_cab_lights( int const Cab, float const Level ) {
if( Level == InteriorLightLevel ) { return; }
InteriorLightLevel = Level;
for( auto &section : Sections ) { for( auto &section : Sections ) {
// cab compartments are placed at the beginning of the list, so we can bail out as soon as we find different compartment type // 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 }; auto const sectionname { section.compartment->pName };
if( sectionname.size() < 4 ) { return; }
if( sectionname.find( "cab" ) != 0 ) { return; } if( sectionname.find( "cab" ) != 0 ) { return; }
if( sectionname[ 3 ] != Cab + '0' ) { continue; } // match the cab with correct index
section.light_level = Level; section.light_level = Level;
} }
@@ -985,7 +983,8 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
btnOn = true; 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 ) && ( ( Mechanik->GetAction() != TAction::actSleep )
|| ( MoverParameters->Battery ) ) ) { || ( MoverParameters->Battery ) ) ) {
// rysowanie figurki mechanika // rysowanie figurki mechanika
@@ -1040,10 +1039,19 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
// else btHeadSignals23.TurnOff(); // else btHeadSignals23.TurnOff();
} }
// interior light levels // interior light levels
auto sectionlightcolor { glm::vec4( 1.f ) };
for( auto const &section : Sections ) { for( auto const &section : 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 ) { if( section.load != nullptr ) {
section.load->SetLightLevel( section.light_level, true ); section.load->SetLightLevel( sectionlightcolor, true );
} }
} }
// load chunks visibility // load chunks visibility
@@ -1062,7 +1070,17 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
sectionchunk = sectionchunk->NextGet(); 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 ************************************* // 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 // 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 // TODO: definition of relevant compartments in the .mmd file
TSubModel *submodel { nullptr }; TSubModel *submodel { nullptr };
if( ( submodel = mdLowPolyInt->GetFromName( "cab1" ) ) != nullptr ) { Sections.push_back( { submodel, nullptr, 0.0f } ); } if( ( submodel = mdLowPolyInt->GetFromName( "cab0" ) ) != nullptr ) {
if( ( submodel = mdLowPolyInt->GetFromName( "cab2" ) ) != nullptr ) { Sections.push_back( { submodel, nullptr, 0.0f } ); } 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 // passenger car compartments
std::vector<std::string> nameprefixes = { "corridor", "korytarz", "compartment", "przedzial" }; std::vector<std::string> nameprefixes = { "corridor", "korytarz", "compartment", "przedzial" };
for( auto const &nameprefix : nameprefixes ) { for( auto const &nameprefix : nameprefixes ) {
@@ -5899,6 +5926,10 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
>> HuntingShake.fadein_end; >> HuntingShake.fadein_end;
} }
else if( token == "jointcabs:" ) {
parser.getTokens();
parser >> JointCabs;
}
} while( token != "" ); } while( token != "" );

View File

@@ -197,6 +197,8 @@ public:
TModel3d *mdLoad; // model zmiennego ładunku TModel3d *mdLoad; // model zmiennego ładunku
TModel3d *mdKabina; // model kabiny dla użytkownika; McZapkie-030303: to z train.h TModel3d *mdKabina; // model kabiny dla użytkownika; McZapkie-030303: to z train.h
TModel3d *mdLowPolyInt; // ABu 010305: wnetrze lowpoly 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 fShade; // zacienienie: 0:normalnie, -1:w ciemności, +1:dodatkowe światło (brak koloru?)
float LoadOffset { 0.f }; 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? 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 Damage(char flag);
void RaLightsSet(int head, int rear); void RaLightsSet(int head, int rear);
int LightList( side const Side ) const { return iInventory[ Side ]; } 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); TDynamicObject * FirstFind(int &coupler_nr, int cf = 1);
float GetEPP(); // wyliczanie sredniego cisnienia w PG float GetEPP(); // wyliczanie sredniego cisnienia w PG
int DirectionSet(int d); // ustawienie kierunku w składzie int DirectionSet(int d); // ustawienie kierunku w składzie

View File

@@ -17,6 +17,7 @@ http://mozilla.org/MPL/2.0/.
#include "Gauge.h" #include "Gauge.h"
#include "parser.h" #include "parser.h"
#include "Model3d.h" #include "Model3d.h"
#include "DynObj.h"
#include "Timer.h" #include "Timer.h"
#include "Logs.h" #include "Logs.h"
#include "renderer.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; std::string submodelname, gaugetypename;
float scale, endscale, endvalue, offset, friction; float scale, endscale, endvalue, offset, friction;
@@ -138,13 +139,17 @@ bool TGauge::Load( cParser &Parser, TDynamicObject const *Owner, TModel3d *md1,
if( interpolatescale ) { if( interpolatescale ) {
endscale *= mul; endscale *= mul;
} }
TSubModel *submodel = md1->GetFromName( submodelname ); TSubModel *submodel { nullptr };
if (submodel) // jeśli nie znaleziony std::array<TModel3d *, 2> sources { Owner->mdKabina, Owner->mdLowPolyInt };
md2 = nullptr; // informacja, że znaleziony for( auto const *source : sources ) {
else if (md2) // a jest podany drugi model (np. zewnętrzny) if( ( source != nullptr )
submodel = md2->GetFromName(submodelname); // to może tam będzie, co za różnica gdzie && ( submodel = source->GetFromName( submodelname ) ) != nullptr ) {
// got what we wanted, bail out
break;
}
}
if( submodel == nullptr ) { 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 { 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 ); 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 bool

View File

@@ -38,7 +38,7 @@ public:
void Clear() { void Clear() {
*this = TGauge(); } *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 ); 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 );
void UpdateValue( float fNewDesired, sound_source &Fallbacksound ); void UpdateValue( float fNewDesired, sound_source &Fallbacksound );
void PutValue(float fNewDesired); void PutValue(float fNewDesired);

View File

@@ -109,9 +109,12 @@ TSubModel::SetVisibilityLevel( float const Level, bool const Includechildren, bo
// sets light level (alpha component of illumination color) to specified value // sets light level (alpha component of illumination color) to specified value
void void
TSubModel::SetLightLevel( float const Level, bool const Includechildren, bool const Includesiblings ) { TSubModel::SetLightLevel( glm::vec4 const &Level, bool const Includechildren, bool const Includesiblings ) {
/*
f4Emision.a = Level; f4Emision = Level;
*/
f4Diffuse = { Level.r, Level.g, Level.b, f4Diffuse.a };
f4Emision.a = Level.a;
if( true == Includesiblings ) { if( true == Includesiblings ) {
auto sibling { this }; auto sibling { this };
while( ( sibling = sibling->Next ) != nullptr ) { while( ( sibling = sibling->Next ) != nullptr ) {

View File

@@ -198,7 +198,7 @@ public:
// sets visibility level (alpha component) to specified value // sets visibility level (alpha component) to specified value
void SetVisibilityLevel( float const Level, bool const Includechildren = false, bool const Includesiblings = false ); void SetVisibilityLevel( float const Level, bool const Includechildren = false, bool const Includesiblings = false );
// sets light level (alpha component of illumination color) to specified value // 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() { inline float3 Translation1Get() {
return fMatrix ? *(fMatrix->TranslationGet()) + v_TransVector : v_TransVector; } return fMatrix ? *(fMatrix->TranslationGet()) + v_TransVector : v_TransVector; }
inline float3 Translation2Get() { inline float3 Translation2Get() {

527
Train.cpp

File diff suppressed because it is too large Load Diff

20
Train.h
View File

@@ -33,16 +33,21 @@ public:
// methods // methods
void Load(cParser &Parser); void Load(cParser &Parser);
void Update(); void Update();
TGauge &Gauge( int n = -1 ); // pobranie adresu obiektu
TButton &Button( int n = -1 ); // pobranie adresu obiektu
// members // members
Math3D::vector3 CabPos1 { 0, 1, 1 }; Math3D::vector3 CabPos1 { 0, 1, 1 };
Math3D::vector3 CabPos2 { 0, 1, -1 }; Math3D::vector3 CabPos2 { 0, 1, -1 };
bool bEnabled { false }; bool bEnabled { false };
bool bOccupied { true }; bool bOccupied { true };
/*
glm::vec3 dimm; // McZapkie-120503: tlumienie swiatla glm::vec3 dimm; // McZapkie-120503: tlumienie swiatla
glm::vec3 intlit; // McZapkie-120503: oswietlenie kabiny glm::vec3 intlit; // McZapkie-120503: oswietlenie kabiny
glm::vec3 intlitlow; // McZapkie-120503: przyciemnione 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: private:
// members // members
@@ -121,7 +126,7 @@ class TTrain
void clear_cab_controls(); void clear_cab_controls();
// sets cabin controls based on current state of the vehicle // 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 // 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 // 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); 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 // 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 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 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 }; sound_source m_radiostop { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
/*
int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne) int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne)
bool bCabLight; // hunter-091012: czy swiatlo jest zapalone? bool bCabLight; // hunter-091012: czy swiatlo jest zapalone?
bool bCabLightDim; // hunter-091012: czy przyciemnienie kabiny jest zapalone? bool bCabLightDim; // hunter-091012: czy przyciemnienie kabiny jest zapalone?
*/
// McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc // McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc
TCab Cabine[ maxcab + 1 ]; // przedzial maszynowy, kabina 1 (A), kabina 2 (B) std::array<TCab, maxcab + 1> Cabine; // przedzial maszynowy, kabina 1 (A), kabina 2 (B)
int iCabn; int iCabn { 0 };
// McZapkie: do poruszania sie po kabinie // McZapkie: do poruszania sie po kabinie
Math3D::vector3 pMechSittingPosition; // ABu 180404 Math3D::vector3 pMechSittingPosition; // ABu 180404
Math3D::vector3 MirrorPosition( bool lewe ); Math3D::vector3 MirrorPosition( bool lewe );
@@ -638,6 +643,7 @@ private:
bool bHeat[8]; // grzanie bool bHeat[8]; // grzanie
// McZapkie: do syczenia // McZapkie: do syczenia
float fPPress, fNPress; float fPPress, fNPress;
bool m_mastercontrollerinuse { false };
int iRadioChannel { 1 }; // numer aktualnego kana?u radiowego int iRadioChannel { 1 }; // numer aktualnego kana?u radiowego
std::vector<std::pair<std::string, texture_handle>> m_screens; std::vector<std::pair<std::string, texture_handle>> m_screens;

View File

@@ -27,13 +27,13 @@ http://mozilla.org/MPL/2.0/.
#include "renderer.h" #include "renderer.h"
#include "utilities.h" #include "utilities.h"
#include "Logs.h" #include "Logs.h"
/*
namespace input { namespace input {
user_command command; // currently issued control command, if any user_command command; // currently issued control command, if any
} }
*/
void void
driver_mode::drivermode_input::poll() { driver_mode::drivermode_input::poll() {
@@ -47,11 +47,13 @@ driver_mode::drivermode_input::poll() {
if( uart != nullptr ) { if( uart != nullptr ) {
uart->poll(); uart->poll();
} }
/*
// TBD, TODO: wrap current command in object, include other input sources? // TBD, TODO: wrap current command in object, include other input sources?
input::command = ( input::command = (
mouse.command() != user_command::none ? mouse.command() != user_command::none ?
mouse.command() : mouse.command() :
keyboard.command() ); keyboard.command() );
*/
} }
bool bool
@@ -468,6 +470,15 @@ driver_mode::update_camera( double const Deltatime ) {
simulation::Train->pMechViewAngle = { Camera.Angle.x, Camera.Angle.y }; simulation::Train->pMechViewAngle = { Camera.Angle.x, Camera.Angle.y };
simulation::Train->pMechOffset = Camera.m_owneroffset; 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 { else {
// debug camera // debug camera
@@ -567,13 +578,13 @@ driver_mode::update_camera( double const Deltatime ) {
// gdy w korytarzu // gdy w korytarzu
Camera.LookAt = Camera.LookAt =
Camera.m_owner->GetWorldPosition( Camera.m_owneroffset ) Camera.m_owner->GetWorldPosition( Camera.m_owneroffset )
+ simulation::Train->GetDirection() * 5.0; + Camera.m_owner->VectorFront() * 5.0;
} }
else { else {
// patrzenie w kierunku osi pojazdu, z uwzględnieniem kabiny // patrzenie w kierunku osi pojazdu, z uwzględnieniem kabiny
Camera.LookAt = Camera.LookAt =
Camera.m_owner->GetWorldPosition( Camera.m_owneroffset ) 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 * simulation::Train->Occupied()->ActiveCab; //-1 albo 1
} }
Camera.vUp = simulation::Train->GetUp(); Camera.vUp = simulation::Train->GetUp();
@@ -914,18 +925,26 @@ driver_mode::ExternalView() {
Camera.m_owner = owner; Camera.m_owner = owner;
auto const offsetflip { auto const &viewconfig { m_externalviewconfigs[ m_externalviewmode ] };
( vehicle->MoverParameters->ActiveCab == 0 ? 1 : vehicle->MoverParameters->ActiveCab ) if( owner == viewconfig.owner ) {
* ( vehicle->MoverParameters->ActiveDir == 0 ? 1 : vehicle->MoverParameters->ActiveDir ) }; // 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 = { Camera.m_owneroffset = {
1.5 * owner->MoverParameters->Dim.W * offsetflip, 1.5 * owner->MoverParameters->Dim.W * offsetflip,
std::max( 5.0, 1.25 * owner->MoverParameters->Dim.H ), std::max( 5.0, 1.25 * owner->MoverParameters->Dim.H ),
- 0.4 * owner->MoverParameters->Dim.L * offsetflip }; -0.4 * owner->MoverParameters->Dim.L * offsetflip };
Camera.Angle.y = glm::radians( ( vehicle->MoverParameters->ActiveDir < 0 ? 180.0 : 0.0 ) ); Camera.Angle.y = glm::radians( ( vehicle->MoverParameters->ActiveDir < 0 ? 180.0 : 0.0 ) );
}
auto const shakeangles { owner->shake_angles() }; auto const shakeangles{ owner->shake_angles() };
Camera.Angle.x -= 0.5 * shakeangles.second; // hustanie kamery przod tyl Camera.Angle.x -= 0.5 * shakeangles.second; // hustanie kamery przod tyl
Camera.Angle.z = shakeangles.first; // hustanie kamery na boki Camera.Angle.z = shakeangles.first; // hustanie kamery na boki
@@ -937,18 +956,26 @@ driver_mode::ExternalView() {
Camera.m_owner = owner; Camera.m_owner = owner;
auto const offsetflip { auto const &viewconfig{ m_externalviewconfigs[ m_externalviewmode ] };
( vehicle->MoverParameters->ActiveCab == 0 ? 1 : vehicle->MoverParameters->ActiveCab ) if( owner == viewconfig.owner ) {
* ( vehicle->MoverParameters->ActiveDir == 0 ? 1 : vehicle->MoverParameters->ActiveDir ) // restore view config for previous owner
* -1 }; 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 = { Camera.m_owneroffset = {
1.5 * owner->MoverParameters->Dim.W * offsetflip, 1.5 * owner->MoverParameters->Dim.W * offsetflip,
std::max( 5.0, 1.25 * owner->MoverParameters->Dim.H ), std::max( 5.0, 1.25 * owner->MoverParameters->Dim.H ),
0.2 * owner->MoverParameters->Dim.L * offsetflip }; 0.2 * owner->MoverParameters->Dim.L * offsetflip };
Camera.Angle.y = glm::radians( ( vehicle->MoverParameters->ActiveDir < 0 ? 0.0 : 180.0 ) );
Camera.Angle.y = glm::radians( ( vehicle->MoverParameters->ActiveDir < 0 ? 0.0 : 180.0 ) );
}
auto const shakeangles { owner->shake_angles() }; auto const shakeangles { owner->shake_angles() };
Camera.Angle.x -= 0.5 * shakeangles.second; // hustanie kamery przod tyl Camera.Angle.x -= 0.5 * shakeangles.second; // hustanie kamery przod tyl
Camera.Angle.z = shakeangles.first; // hustanie kamery na boki Camera.Angle.z = shakeangles.first; // hustanie kamery na boki
@@ -959,17 +986,25 @@ driver_mode::ExternalView() {
Camera.m_owner = owner; Camera.m_owner = owner;
auto const offsetflip { auto const &viewconfig{ m_externalviewconfigs[ m_externalviewmode ] };
( vehicle->MoverParameters->ActiveCab == 0 ? 1 : vehicle->MoverParameters->ActiveCab ) if( owner == viewconfig.owner ) {
* ( vehicle->MoverParameters->ActiveDir == 0 ? 1 : vehicle->MoverParameters->ActiveDir ) }; // 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 = { Camera.m_owneroffset = {
- 0.65 * owner->MoverParameters->Dim.W * offsetflip, -0.65 * owner->MoverParameters->Dim.W * offsetflip,
0.90, 0.90,
0.15 * owner->MoverParameters->Dim.L * offsetflip }; 0.15 * owner->MoverParameters->Dim.L * offsetflip };
Camera.Angle.y = glm::radians( ( vehicle->MoverParameters->ActiveDir < 0 ? 180.0 : 0.0 ) );
Camera.Angle.y = glm::radians( ( vehicle->MoverParameters->ActiveDir < 0 ? 180.0 : 0.0 ) );
}
auto const shakeangles { owner->shake_angles() }; auto const shakeangles { owner->shake_angles() };
Camera.Angle.x -= 0.5 * shakeangles.second; // hustanie kamery przod tyl Camera.Angle.x -= 0.5 * shakeangles.second; // hustanie kamery przod tyl
Camera.Angle.z = shakeangles.first; // hustanie kamery na boki Camera.Angle.z = shakeangles.first; // hustanie kamery na boki

View File

@@ -60,6 +60,12 @@ private:
count_ count_
}; };
struct view_config {
TDynamicObject const *owner { nullptr };
Math3D::vector3 offset {};
Math3D::vector3 angle {};
};
struct drivermode_input { struct drivermode_input {
gamepad_input gamepad; gamepad_input gamepad;
@@ -91,6 +97,7 @@ private:
TCamera DebugCamera; TCamera DebugCamera;
int m_externalviewmode { view::consistfront }; // selected external view mode int m_externalviewmode { view::consistfront }; // selected external view mode
bool m_externalview { false }; 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 TDynamicObject *pDynamicNearest { nullptr }; // vehicle nearest to the active camera. TODO: move to camera
double fTime50Hz { 0.0 }; // bufor czasu dla komunikacji z PoKeys double fTime50Hz { 0.0 }; // bufor czasu dla komunikacji z PoKeys
double const m_primaryupdaterate { 1.0 / 100.0 }; double const m_primaryupdaterate { 1.0 / 100.0 };

View File

@@ -319,6 +319,7 @@ drivermouse_input::button( int const Button, int const Action ) {
else { else {
if( Button == GLFW_MOUSE_BUTTON_LEFT ) { if( Button == GLFW_MOUSE_BUTTON_LEFT ) {
if( m_slider.command() != user_command::none ) { if( m_slider.command() != user_command::none ) {
m_relay.post( m_slider.command(), 0, 0, Action, 0 );
m_slider.release(); m_slider.release();
} }
} }

View File

@@ -562,7 +562,7 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
if( vehicle->InteriorLightLevel > 0.f ) { if( vehicle->InteriorLightLevel > 0.f ) {
setup_shadow_color( glm::min( colors::white, shadowcolor + glm::vec4( vehicle->InteriorLight * vehicle->InteriorLightLevel, 1.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 ) { if( vehicle->InteriorLightLevel > 0.f ) {
setup_shadow_color( shadowcolor ); setup_shadow_color( shadowcolor );
} }
@@ -581,17 +581,17 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix ); setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix );
// cache shadow colour in case we need to account for cab light // cache shadow colour in case we need to account for cab light
auto const shadowcolor{ m_shadowcolor }; auto const shadowcolor{ m_shadowcolor };
auto const *vehicle{ simulation::Train->Dynamic() }; auto const *vehicle { simulation::Train->Dynamic() };
if( vehicle->InteriorLightLevel > 0.f ) { if( vehicle->InteriorLightLevel > 0.f ) {
setup_shadow_color( glm::min( colors::white, shadowcolor + glm::vec4( vehicle->InteriorLight * vehicle->InteriorLightLevel, 1.f ) ) ); setup_shadow_color( glm::min( colors::white, shadowcolor + glm::vec4( vehicle->InteriorLight * vehicle->InteriorLightLevel, 1.f ) ) );
} }
if( Global.Overcast > 1.f ) { if( Global.Overcast > 1.f ) {
// with active precipitation draw the opaque cab parts here to mask rain/snow placed 'inside' the cab // with active precipitation draw the opaque cab parts here to mask rain/snow placed 'inside' the cab
setup_drawing( false ); setup_drawing( false );
Render_cab( vehicle, false ); Render_cab( vehicle, vehicle->InteriorLightLevel, false );
setup_drawing( true ); setup_drawing( true );
} }
Render_cab( vehicle, true ); Render_cab( vehicle, vehicle->InteriorLightLevel, true );
if( vehicle->InteriorLightLevel > 0.f ) { if( vehicle->InteriorLightLevel > 0.f ) {
setup_shadow_color( shadowcolor ); setup_shadow_color( shadowcolor );
} }
@@ -681,8 +681,8 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
#else #else
setup_units( false, false, false ); setup_units( false, false, false );
#endif #endif
Render_cab( simulation::Train->Dynamic(), false ); Render_cab( simulation::Train->Dynamic(), 0.f, false );
Render_cab( simulation::Train->Dynamic(), true ); Render_cab( simulation::Train->Dynamic(), 0.f, true );
m_cabshadowpass = m_renderpass; m_cabshadowpass = m_renderpass;
// post-render restore // post-render restore
@@ -745,7 +745,10 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
setup_drawing( false ); setup_drawing( false );
setup_units( false, false, false ); setup_units( false, false, false );
// cab render skips translucent parts, so we can do it here // 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 // post-render cleanup
} }
break; break;
@@ -816,7 +819,7 @@ opengl_renderer::setup_pass( renderpass_config &Config, rendermode const Mode, f
switch( Mode ) { switch( Mode ) {
case rendermode::color: { Config.draw_range = Global.BaseDrawRange; break; } case rendermode::color: { Config.draw_range = Global.BaseDrawRange; break; }
case rendermode::shadows: { Config.draw_range = Global.BaseDrawRange * 0.5f; 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::reflections: { Config.draw_range = Global.BaseDrawRange; break; }
case rendermode::pickcontrols: { Config.draw_range = 50.f; break; } case rendermode::pickcontrols: { Config.draw_range = 50.f; break; }
case rendermode::pickscenery: { Config.draw_range = Global.BaseDrawRange * 0.5f; break; } case rendermode::pickscenery: { Config.draw_range = Global.BaseDrawRange * 0.5f; break; }
@@ -2158,7 +2161,10 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
// render // render
if( Dynamic->mdLowPolyInt ) { if( Dynamic->mdLowPolyInt ) {
// low poly interior // low poly interior
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) { /*
if( ( true == FreeFlyModeFlag )
|| ( ( Dynamic->mdKabina == nullptr ) || ( false == Dynamic->bDisplayCab ) ) ) {
*/
/* /*
// enable cab light if needed // enable cab light if needed
if( Dynamic->InteriorLightLevel > 0.0f ) { if( Dynamic->InteriorLightLevel > 0.0f ) {
@@ -2174,7 +2180,9 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( m_baseambient ) ); ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( m_baseambient ) );
} }
*/ */
/*
} }
*/
} }
if( Dynamic->mdModel ) if( Dynamic->mdModel )
Render( Dynamic->mdModel, Dynamic->Material(), squaredistance ); Render( Dynamic->mdModel, Dynamic->Material(), squaredistance );
@@ -2191,9 +2199,9 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
case rendermode::shadows: { case rendermode::shadows: {
if( Dynamic->mdLowPolyInt ) { if( Dynamic->mdLowPolyInt ) {
// low poly interior // low poly interior
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) { // if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
Render( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance ); Render( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
} // }
} }
if( Dynamic->mdModel ) if( Dynamic->mdModel )
Render( Dynamic->mdModel, Dynamic->Material(), squaredistance ); Render( Dynamic->mdModel, Dynamic->Material(), squaredistance );
@@ -2202,7 +2210,13 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
// post-render cleanup // post-render cleanup
break; break;
} }
case rendermode::pickcontrols: case rendermode::pickcontrols: {
if( Dynamic->mdLowPolyInt ) {
// low poly interior
Render( Dynamic->mdLowPolyInt, Dynamic->Material(), squaredistance );
}
break;
}
case rendermode::pickscenery: case rendermode::pickscenery:
default: { default: {
break; break;
@@ -2220,7 +2234,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
// rendering kabiny gdy jest oddzielnym modelem i ma byc wyswietlana // rendering kabiny gdy jest oddzielnym modelem i ma byc wyswietlana
bool 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 ) { 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 // change light level based on light level of the occupied track
m_sunlight.apply_intensity( Dynamic->fShade ); 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 // 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 // render
if( true == Alpha ) { 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 // change light level based on light level of the occupied track
m_sunlight.apply_intensity(); m_sunlight.apply_intensity();
} }
if( Dynamic->InteriorLightLevel > 0.0f ) { if( Lightlevel > 0.f ) {
// reset the overall ambient // reset the overall ambient
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr(m_baseambient) ); ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr(m_baseambient) );
} }
@@ -2435,9 +2449,10 @@ opengl_renderer::Render( TSubModel *Submodel ) {
} }
// ...luminance // ...luminance
auto const unitstate = m_unitstate; 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 // 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 // disable shadows so they don't obstruct self-lit items
/* /*
setup_shadow_color( colors::white ); setup_shadow_color( colors::white );
@@ -2466,7 +2481,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
if( ( true == m_renderspecular ) && ( m_sunlight.specular.a > 0.01f ) ) { if( ( true == m_renderspecular ) && ( m_sunlight.specular.a > 0.01f ) ) {
::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( colors::none ) ); ::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( colors::none ) );
} }
if( Global.fLuminance < Submodel->fLight ) { if( isemissive ) {
// restore default (lack of) brightness // restore default (lack of) brightness
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) ); ::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) );
/* /*
@@ -3245,7 +3260,7 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
// render // render
if( Dynamic->mdLowPolyInt ) { if( Dynamic->mdLowPolyInt ) {
// low poly interior // low poly interior
if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) { // if( FreeFlyModeFlag ? true : !Dynamic->mdKabina || !Dynamic->bDisplayCab ) {
/* /*
// enable cab light if needed // enable cab light if needed
if( Dynamic->InteriorLightLevel > 0.0f ) { 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 ) ); ::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( m_baseambient ) );
} }
*/ */
} // }
} }
if( Dynamic->mdModel ) if( Dynamic->mdModel )
@@ -3403,9 +3418,10 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
} }
// ...luminance // ...luminance
auto const unitstate = m_unitstate; 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 // 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 // disable shadows so they don't obstruct self-lit items
/* /*
setup_shadow_color( colors::white ); 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 ) ) { if( ( true == m_renderspecular ) && ( m_sunlight.specular.a > 0.01f ) ) {
::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( colors::none ) ); ::glMaterialfv( GL_FRONT, GL_SPECULAR, glm::value_ptr( colors::none ) );
} }
if( Global.fLuminance < Submodel->fLight ) { if( isemissive ) {
// restore default (lack of) brightness // restore default (lack of) brightness
::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) ); ::glMaterialfv( GL_FRONT, GL_EMISSION, glm::value_ptr( colors::none ) );
/* /*

View File

@@ -292,7 +292,7 @@ private:
void void
Render( scene::basic_cell::path_sequence::const_iterator First, scene::basic_cell::path_sequence::const_iterator Last ); Render( scene::basic_cell::path_sequence::const_iterator First, scene::basic_cell::path_sequence::const_iterator Last );
bool bool
Render_cab( TDynamicObject const *Dynamic, bool const Alpha = false ); Render_cab( TDynamicObject const *Dynamic, float const Lightlevel, bool const Alpha = false );
void void
Render( TMemCell *Memcell ); Render( TMemCell *Memcell );
void void