mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 15:39:19 +02:00
build 171027: bounding area calculation fixes, novice ui obstacle indicator, minor traction render enhancement, shadow calculations for tall enough platforms
This commit is contained in:
@@ -583,6 +583,15 @@ void TAnimModel::RaAnimate( unsigned int const Framestamp ) {
|
|||||||
m_framestamp = Framestamp;
|
m_framestamp = Framestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// calculates piece's bounding radius
|
||||||
|
void
|
||||||
|
TAnimModel::radius_() {
|
||||||
|
|
||||||
|
if( pModel != nullptr ) {
|
||||||
|
m_area.radius = pModel->bounding_radius();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TAnimModel::RaPrepare()
|
void TAnimModel::RaPrepare()
|
||||||
{ // ustawia światła i animacje we wzorcu modelu przed renderowaniem egzemplarza
|
{ // ustawia światła i animacje we wzorcu modelu przed renderowaniem egzemplarza
|
||||||
bool state; // stan światła
|
bool state; // stan światła
|
||||||
|
|||||||
@@ -157,6 +157,11 @@ public:
|
|||||||
// members
|
// members
|
||||||
static TAnimContainer *acAnimList; // lista animacji z eventem, które muszą być przeliczane również bez wyświetlania
|
static TAnimContainer *acAnimList; // lista animacji z eventem, które muszą być przeliczane również bez wyświetlania
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// calculates piece's bounding radius
|
||||||
|
void
|
||||||
|
radius_();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// methods
|
// methods
|
||||||
void RaPrepare(); // ustawienie animacji egzemplarza na wzorcu
|
void RaPrepare(); // ustawienie animacji egzemplarza na wzorcu
|
||||||
|
|||||||
11
EvLaunch.cpp
11
EvLaunch.cpp
@@ -121,7 +121,7 @@ bool TEventLauncher::Load(cParser *parser)
|
|||||||
*parser >> token;
|
*parser >> token;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
}
|
||||||
|
|
||||||
bool TEventLauncher::check_conditions()
|
bool TEventLauncher::check_conditions()
|
||||||
{ //"renderowanie" wyzwalacza
|
{ //"renderowanie" wyzwalacza
|
||||||
@@ -184,6 +184,13 @@ bool TEventLauncher::IsGlobal() const {
|
|||||||
&& ( iHour >= 0 )
|
&& ( iHour >= 0 )
|
||||||
&& ( iMinute >= 0 )
|
&& ( iMinute >= 0 )
|
||||||
&& ( dRadius < 0.0 ) ); // bez ograniczenia zasięgu
|
&& ( dRadius < 0.0 ) ); // bez ograniczenia zasięgu
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// calculates node's bounding radius
|
||||||
|
void
|
||||||
|
TEventLauncher::radius_() {
|
||||||
|
|
||||||
|
m_area.radius = std::sqrt( dRadius );
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ public:
|
|||||||
int iCheckMask { 0 };
|
int iCheckMask { 0 };
|
||||||
double dRadius { 0.0 };
|
double dRadius { 0.0 };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// calculates node's bounding radius
|
||||||
|
void
|
||||||
|
radius_();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// members
|
// members
|
||||||
int iKey { 0 };
|
int iKey { 0 };
|
||||||
|
|||||||
@@ -1562,6 +1562,9 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|||||||
10
MemCell.cpp
10
MemCell.cpp
@@ -29,8 +29,8 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
TMemCell::TMemCell(vector3 *p)
|
TMemCell::TMemCell(vector3 *p)
|
||||||
{
|
{
|
||||||
fValue1 = fValue2 = 0;
|
fValue1 = fValue2 = 0;
|
||||||
m_location =
|
location(
|
||||||
p ? *p : glm::dvec3(); // ustawienie współrzędnych, bo do TGroundNode nie ma dostępu
|
p ? *p : glm::dvec3() ); // ustawienie współrzędnych, bo do TGroundNode nie ma dostępu
|
||||||
bCommand = false; // komenda wysłana
|
bCommand = false; // komenda wysłana
|
||||||
OnSent = NULL;
|
OnSent = NULL;
|
||||||
}
|
}
|
||||||
@@ -110,9 +110,9 @@ bool TMemCell::Load(cParser *parser)
|
|||||||
#else
|
#else
|
||||||
parser->getTokens( 6, false );
|
parser->getTokens( 6, false );
|
||||||
*parser
|
*parser
|
||||||
>> m_location.x
|
>> m_area.center.x
|
||||||
>> m_location.y
|
>> m_area.center.y
|
||||||
>> m_location.z
|
>> m_area.center.z
|
||||||
#endif
|
#endif
|
||||||
>> szText
|
>> szText
|
||||||
>> fValue1
|
>> fValue1
|
||||||
|
|||||||
21
MemCell.h
21
MemCell.h
@@ -16,16 +16,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
class TMemCell : public editor::basic_node {
|
class TMemCell : public editor::basic_node {
|
||||||
|
|
||||||
private:
|
public:
|
||||||
// content
|
|
||||||
std::string szText;
|
|
||||||
double fValue1 { 0.0 };
|
|
||||||
double fValue2 { 0.0 };
|
|
||||||
// other
|
|
||||||
TCommandType eCommand { cm_Unknown };
|
|
||||||
bool bCommand { false }; // czy zawiera komendę dla zatrzymanego AI
|
|
||||||
TEvent *OnSent { nullptr }; // event dodawany do kolejki po wysłaniu komendy zatrzymującej skład
|
|
||||||
public:
|
|
||||||
std::string asTrackName; // McZapkie-100302 - zeby nazwe toru na ktory jest Putcommand wysylane pamietac
|
std::string asTrackName; // McZapkie-100302 - zeby nazwe toru na ktory jest Putcommand wysylane pamietac
|
||||||
|
|
||||||
TMemCell( scene::node_data const &Nodedata );
|
TMemCell( scene::node_data const &Nodedata );
|
||||||
@@ -63,6 +54,16 @@ class TMemCell : public editor::basic_node {
|
|||||||
TCommandType CommandCheck();
|
TCommandType CommandCheck();
|
||||||
bool IsVelocity();
|
bool IsVelocity();
|
||||||
void AssignEvents(TEvent *e);
|
void AssignEvents(TEvent *e);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// content
|
||||||
|
std::string szText;
|
||||||
|
double fValue1 { 0.0 };
|
||||||
|
double fValue2 { 0.0 };
|
||||||
|
// other
|
||||||
|
TCommandType eCommand { cm_Unknown };
|
||||||
|
bool bCommand { false }; // czy zawiera komendę dla zatrzymanego AI
|
||||||
|
TEvent *OnSent { nullptr }; // event dodawany do kolejki po wysłaniu komendy zatrzymującej skład
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
18
Model3d.cpp
18
Model3d.cpp
@@ -1008,7 +1008,10 @@ TSubModel::create_geometry( std::size_t &Dataoffset, geometrybank_handle const &
|
|||||||
if( m_geometry != NULL ) {
|
if( m_geometry != NULL ) {
|
||||||
// calculate bounding radius while we're at it
|
// calculate bounding radius while we're at it
|
||||||
// NOTE: doesn't take into account transformation hierarchy TODO: implement it
|
// NOTE: doesn't take into account transformation hierarchy TODO: implement it
|
||||||
float squaredradius{ 0.f };
|
float squaredradius { 0.f };
|
||||||
|
// if this happens to be root node it may already have non-squared radius of the largest child
|
||||||
|
// since we're comparing squared radii, we need to square it back for correct results
|
||||||
|
m_boundingradius *= m_boundingradius;
|
||||||
for( auto const &vertex : GfxRenderer.Vertices( m_geometry ) ) {
|
for( auto const &vertex : GfxRenderer.Vertices( m_geometry ) ) {
|
||||||
squaredradius = static_cast<float>( glm::length2( vertex.position ) );
|
squaredradius = static_cast<float>( glm::length2( vertex.position ) );
|
||||||
if( squaredradius > m_boundingradius ) {
|
if( squaredradius > m_boundingradius ) {
|
||||||
@@ -1016,12 +1019,15 @@ TSubModel::create_geometry( std::size_t &Dataoffset, geometrybank_handle const &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( m_boundingradius > 0.f ) { m_boundingradius = std::sqrt( m_boundingradius ); }
|
if( m_boundingradius > 0.f ) { m_boundingradius = std::sqrt( m_boundingradius ); }
|
||||||
if( Parent ) {
|
// adjust overall radius if needed
|
||||||
// propagate radius up the chain
|
// NOTE: the method to access root submodel is... less than ideal
|
||||||
Parent->m_boundingradius = std::max(
|
auto *root { this };
|
||||||
Parent->m_boundingradius,
|
while( root->Parent != nullptr ) {
|
||||||
m_boundingradius );
|
root = root->Parent;
|
||||||
}
|
}
|
||||||
|
root->m_boundingradius = std::max(
|
||||||
|
root->m_boundingradius,
|
||||||
|
m_boundingradius );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Next )
|
if( Next )
|
||||||
|
|||||||
16
Track.cpp
16
Track.cpp
@@ -867,11 +867,11 @@ void TTrack::Load(cParser *parser, vector3 pOrigin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// calculate path location
|
// calculate path location
|
||||||
m_location = glm::dvec3{ (
|
m_area.center = ( glm::dvec3{ (
|
||||||
CurrentSegment()->FastGetPoint_0()
|
CurrentSegment()->FastGetPoint_0()
|
||||||
+ CurrentSegment()->FastGetPoint( 0.5 )
|
+ CurrentSegment()->FastGetPoint( 0.5 )
|
||||||
+ CurrentSegment()->FastGetPoint_1() )
|
+ CurrentSegment()->FastGetPoint_1() )
|
||||||
/ 3.0 };
|
/ 3.0 } );
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: refactor this mess
|
// TODO: refactor this mess
|
||||||
@@ -2821,6 +2821,18 @@ TTrack::endpoints() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// calculates path's bounding radius
|
||||||
|
void
|
||||||
|
TTrack::radius_() {
|
||||||
|
|
||||||
|
auto const points = endpoints();
|
||||||
|
for( auto &point : points ) {
|
||||||
|
m_area.radius = std::max(
|
||||||
|
m_area.radius,
|
||||||
|
static_cast<float>( glm::length( m_area.center - point ) ) ); // extra margin to prevent driven vehicle from flicking
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TTrack::MovedUp1(float const dh)
|
void TTrack::MovedUp1(float const dh)
|
||||||
{ // poprawienie przechyłki wymaga wydłużenia podsypki
|
{ // poprawienie przechyłki wymaga wydłużenia podsypki
|
||||||
fTexHeight1 += dh;
|
fTexHeight1 += dh;
|
||||||
|
|||||||
11
Track.h
11
Track.h
@@ -182,9 +182,9 @@ public:
|
|||||||
TEnvironmentType eEnvironment = e_flat; // dźwięk i oświetlenie
|
TEnvironmentType eEnvironment = e_flat; // dźwięk i oświetlenie
|
||||||
int iAction = 0; // czy modyfikowany eventami (specjalna obsługa przy skanowaniu)
|
int iAction = 0; // czy modyfikowany eventami (specjalna obsługa przy skanowaniu)
|
||||||
float fOverhead = -1.0; // można normalnie pobierać prąd (0 dla jazdy bezprądowej po danym odcinku, >0-z opuszczonym i ograniczeniem prędkości)
|
float fOverhead = -1.0; // można normalnie pobierać prąd (0 dla jazdy bezprądowej po danym odcinku, >0-z opuszczonym i ograniczeniem prędkości)
|
||||||
private:
|
private:
|
||||||
double fVelocity = -1.0; // ograniczenie prędkości // prędkość dla AI (powyżej rośnie prawdopowobieństwo wykolejenia)
|
double fVelocity = -1.0; // ograniczenie prędkości // prędkość dla AI (powyżej rośnie prawdopowobieństwo wykolejenia)
|
||||||
public:
|
public:
|
||||||
// McZapkie-100502:
|
// McZapkie-100502:
|
||||||
double fTrackLength = 100.0; // długość z wpisu, nigdzie nie używana
|
double fTrackLength = 100.0; // długość z wpisu, nigdzie nie używana
|
||||||
double fRadius = 0.0; // promień, dla zwrotnicy kopiowany z tabeli
|
double fRadius = 0.0; // promień, dla zwrotnicy kopiowany z tabeli
|
||||||
@@ -287,7 +287,12 @@ public:
|
|||||||
double VelocityGet();
|
double VelocityGet();
|
||||||
void ConnectionsLog();
|
void ConnectionsLog();
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
|
// calculates path's bounding radius
|
||||||
|
void
|
||||||
|
radius_();
|
||||||
|
|
||||||
|
private:
|
||||||
void EnvironmentSet();
|
void EnvironmentSet();
|
||||||
void EnvironmentReset();
|
void EnvironmentReset();
|
||||||
};
|
};
|
||||||
|
|||||||
14
Traction.cpp
14
Traction.cpp
@@ -169,7 +169,7 @@ TTraction::Load( cParser *parser, glm::dvec3 const &pOrigin ) {
|
|||||||
Init(); // przeliczenie parametrów
|
Init(); // przeliczenie parametrów
|
||||||
|
|
||||||
// calculate traction location
|
// calculate traction location
|
||||||
m_location = interpolate( pPoint2, pPoint1, 0.5 );
|
location( interpolate( pPoint2, pPoint1, 0.5 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// retrieves list of the track's end points
|
// retrieves list of the track's end points
|
||||||
@@ -543,6 +543,18 @@ double TTraction::VoltageGet(double u, double i)
|
|||||||
return 0.0; // gdy nie podłączony wcale?
|
return 0.0; // gdy nie podłączony wcale?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// calculates path's bounding radius
|
||||||
|
void
|
||||||
|
TTraction::radius_() {
|
||||||
|
|
||||||
|
auto const points = endpoints();
|
||||||
|
for( auto &point : points ) {
|
||||||
|
m_area.radius = std::max(
|
||||||
|
m_area.radius,
|
||||||
|
static_cast<float>( glm::length( m_area.center - point ) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3
|
glm::vec3
|
||||||
TTraction::wire_color() const {
|
TTraction::wire_color() const {
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ class TTraction : public editor::basic_node {
|
|||||||
// retrieves list of the track's end points
|
// retrieves list of the track's end points
|
||||||
std::vector<glm::dvec3>
|
std::vector<glm::dvec3>
|
||||||
endpoints() const;
|
endpoints() const;
|
||||||
|
|
||||||
// creates geometry data in specified geometry bank. returns: number of created elements, or NULL
|
// creates geometry data in specified geometry bank. returns: number of created elements, or NULL
|
||||||
// NOTE: deleting nodes doesn't currently release geometry data owned by the node. TODO: implement erasing individual geometry chunks and banks
|
// NOTE: deleting nodes doesn't currently release geometry data owned by the node. TODO: implement erasing individual geometry chunks and banks
|
||||||
#ifdef EU07_USE_OLD_GROUNDCODE
|
#ifdef EU07_USE_OLD_GROUNDCODE
|
||||||
@@ -79,6 +78,12 @@ class TTraction : public editor::basic_node {
|
|||||||
void ResistanceCalc(int d = -1, double r = 0, TTractionPowerSource *ps = nullptr);
|
void ResistanceCalc(int d = -1, double r = 0, TTractionPowerSource *ps = nullptr);
|
||||||
void PowerSet(TTractionPowerSource *ps);
|
void PowerSet(TTractionPowerSource *ps);
|
||||||
double VoltageGet(double u, double i);
|
double VoltageGet(double u, double i);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// calculates piece's bounding radius
|
||||||
|
void
|
||||||
|
radius_();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
glm::vec3 wire_color() const;
|
glm::vec3 wire_color() const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -42,9 +42,9 @@ bool TTractionPowerSource::Load(cParser *parser) {
|
|||||||
#else
|
#else
|
||||||
parser->getTokens( 10, false );
|
parser->getTokens( 10, false );
|
||||||
*parser
|
*parser
|
||||||
>> m_location.x
|
>> m_area.center.x
|
||||||
>> m_location.y
|
>> m_area.center.y
|
||||||
>> m_location.z
|
>> m_area.center.z
|
||||||
#endif
|
#endif
|
||||||
>> NominalVoltage
|
>> NominalVoltage
|
||||||
>> VoltageFrequency
|
>> VoltageFrequency
|
||||||
|
|||||||
@@ -7029,7 +7029,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
/*
|
/*
|
||||||
TGauge *gg { nullptr }; // roboczy wskaźnik na obiekt animujący gałkę
|
TGauge *gg { nullptr }; // roboczy wskaźnik na obiekt animujący gałkę
|
||||||
*/
|
*/
|
||||||
std::unordered_map<std::string, TGauge &> gauges = {
|
std::unordered_map<std::string, TGauge &> const gauges = {
|
||||||
{ "mainctrl:", ggMainCtrl },
|
{ "mainctrl:", ggMainCtrl },
|
||||||
{ "scndctrl:", ggScndCtrl },
|
{ "scndctrl:", ggScndCtrl },
|
||||||
{ "dirkey:" , ggDirKey },
|
{ "dirkey:" , ggDirKey },
|
||||||
|
|||||||
@@ -1352,7 +1352,8 @@ TWorld::Update_UI() {
|
|||||||
uitextline1 += " (paused)";
|
uitextline1 += " (paused)";
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Controlled && ( Controlled->Mechanik != nullptr ) ) {
|
if( ( Controlled != nullptr )
|
||||||
|
&& ( Controlled->Mechanik != nullptr ) ) {
|
||||||
|
|
||||||
auto const &mover = Controlled->MoverParameters;
|
auto const &mover = Controlled->MoverParameters;
|
||||||
auto const &driver = Controlled->Mechanik;
|
auto const &driver = Controlled->Mechanik;
|
||||||
@@ -1374,6 +1375,11 @@ TWorld::Update_UI() {
|
|||||||
uitextline3 +=
|
uitextline3 +=
|
||||||
" Pressure: " + to_string( mover->BrakePress * 100.0, 2 ) + " kPa"
|
" Pressure: " + to_string( mover->BrakePress * 100.0, 2 ) + " kPa"
|
||||||
+ " (train pipe: " + to_string( mover->PipePress * 100.0, 2 ) + " kPa)";
|
+ " (train pipe: " + to_string( mover->PipePress * 100.0, 2 ) + " kPa)";
|
||||||
|
|
||||||
|
auto const trackblockdistance{ std::abs( Controlled->Mechanik->TrackBlock() ) };
|
||||||
|
if( trackblockdistance <= 75.0 ) {
|
||||||
|
uitextline4 = " Another vehicle ahead (distance: " + to_string( trackblockdistance, 1 ) + " m)";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
82
renderer.cpp
82
renderer.cpp
@@ -420,7 +420,7 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
|
|||||||
::glColor4f( 1.f, 0.9f, 0.8f, 1.f );
|
::glColor4f( 1.f, 0.9f, 0.8f, 1.f );
|
||||||
::glDisable( GL_LIGHTING );
|
::glDisable( GL_LIGHTING );
|
||||||
::glDisable( GL_TEXTURE_2D );
|
::glDisable( GL_TEXTURE_2D );
|
||||||
if( true == Global::RenderShadows ) {
|
if( ( true == Global::RenderShadows ) && ( false == Global::bWireFrame ) ) {
|
||||||
shadowcamera.draw( m_renderpass.camera.position() - shadowcamera.position() );
|
shadowcamera.draw( m_renderpass.camera.position() - shadowcamera.position() );
|
||||||
}
|
}
|
||||||
if( DebugCameraFlag ) {
|
if( DebugCameraFlag ) {
|
||||||
@@ -2214,11 +2214,11 @@ opengl_renderer::Render( TAnimModel *Instance ) {
|
|||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows: {
|
||||||
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
||||||
distancesquared = SquareMagnitude( ( Instance->m_location - Global::pCameraPosition ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
distancesquared = SquareMagnitude( ( Instance->location() - Global::pCameraPosition ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
distancesquared = SquareMagnitude( ( Instance->m_location - m_renderpass.camera.position() ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
distancesquared = SquareMagnitude( ( Instance->location() - m_renderpass.camera.position() ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2246,7 +2246,7 @@ opengl_renderer::Render( TAnimModel *Instance ) {
|
|||||||
Instance->pModel,
|
Instance->pModel,
|
||||||
Instance->Material(),
|
Instance->Material(),
|
||||||
distancesquared,
|
distancesquared,
|
||||||
Instance->m_location - m_renderpass.camera.position(),
|
Instance->location() - m_renderpass.camera.position(),
|
||||||
Instance->vAngle );
|
Instance->vAngle );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2799,6 +2799,17 @@ void
|
|||||||
opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First, scene::basic_cell::path_sequence::const_iterator Last ) {
|
opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First, scene::basic_cell::path_sequence::const_iterator Last ) {
|
||||||
|
|
||||||
::glColor3fv( glm::value_ptr( colors::white ) );
|
::glColor3fv( glm::value_ptr( colors::white ) );
|
||||||
|
// setup
|
||||||
|
switch( m_renderpass.draw_mode ) {
|
||||||
|
case rendermode::shadows: {
|
||||||
|
// NOTE: roads-based platforms tend to miss parts of shadows if rendered with either back or front culling
|
||||||
|
::glDisable( GL_CULL_FACE );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// first pass, material 1
|
// first pass, material 1
|
||||||
for( auto first { First }; first != Last; ++first ) {
|
for( auto first { First }; first != Last; ++first ) {
|
||||||
@@ -2824,7 +2835,16 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
|
|||||||
track->EnvironmentReset();
|
track->EnvironmentReset();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case rendermode::shadows: // shadows are calculated only for trackbeds
|
case rendermode::shadows: {
|
||||||
|
if( ( std::abs( track->fTexHeight1 ) < 0.35f )
|
||||||
|
|| ( track->iCategoryFlag != 2 ) ) {
|
||||||
|
// shadows are only calculated for high enough roads, typically meaning track platforms
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Bind_Material( track->m_material1 );
|
||||||
|
m_geometry.draw( std::begin( track->Geometry1 ), std::end( track->Geometry1 ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
case rendermode::pickscenery: // pick scenery mode uses piece-by-piece approach
|
case rendermode::pickscenery: // pick scenery mode uses piece-by-piece approach
|
||||||
case rendermode::pickcontrols:
|
case rendermode::pickcontrols:
|
||||||
default: {
|
default: {
|
||||||
@@ -2854,9 +2874,10 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows: {
|
||||||
if( ( track->iCategoryFlag != 1 )
|
if( ( std::abs( track->fTexHeight1 ) < 0.35f )
|
||||||
|| ( track->eType != tt_Normal ) ) {
|
|| ( ( track->iCategoryFlag == 1 )
|
||||||
// shadows are only calculated for trackbeds
|
&& ( track->eType != tt_Normal ) ) ) {
|
||||||
|
// shadows are only calculated for high enough trackbeds
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Bind_Material( track->m_material2 );
|
Bind_Material( track->m_material2 );
|
||||||
@@ -2870,6 +2891,16 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// post-render reset
|
||||||
|
switch( m_renderpass.draw_mode ) {
|
||||||
|
case rendermode::shadows: {
|
||||||
|
::glEnable( GL_CULL_FACE );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -3218,11 +3249,11 @@ opengl_renderer::Render_Alpha( TAnimModel *Instance ) {
|
|||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows: {
|
||||||
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
||||||
distancesquared = SquareMagnitude( ( Instance->m_location - Global::pCameraPosition ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
distancesquared = SquareMagnitude( ( Instance->location() - Global::pCameraPosition ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
distancesquared = SquareMagnitude( ( Instance->m_location - m_renderpass.camera.position() ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
distancesquared = SquareMagnitude( ( Instance->location() - m_renderpass.camera.position() ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3238,7 +3269,7 @@ opengl_renderer::Render_Alpha( TAnimModel *Instance ) {
|
|||||||
Instance->pModel,
|
Instance->pModel,
|
||||||
Instance->Material(),
|
Instance->Material(),
|
||||||
distancesquared,
|
distancesquared,
|
||||||
Instance->m_location - m_renderpass.camera.position(),
|
Instance->location() - m_renderpass.camera.position(),
|
||||||
Instance->vAngle );
|
Instance->vAngle );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3250,11 +3281,11 @@ opengl_renderer::Render_Alpha( TTraction *Traction ) {
|
|||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows: {
|
||||||
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
// 'camera' for the light pass is the light source, but we need to draw what the 'real' camera sees
|
||||||
distancesquared = SquareMagnitude( ( Traction->m_location - Global::pCameraPosition ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
distancesquared = SquareMagnitude( ( Traction->location() - Global::pCameraPosition ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
distancesquared = SquareMagnitude( ( Traction->m_location - m_renderpass.camera.position() ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
distancesquared = SquareMagnitude( ( Traction->location() - m_renderpass.camera.position() ) / Global::ZoomFactor ) / Global::fDistanceFactor;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3272,15 +3303,29 @@ opengl_renderer::Render_Alpha( TTraction *Traction ) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// setup
|
// setup
|
||||||
|
/*
|
||||||
float const linealpha = static_cast<float>(
|
float const linealpha = static_cast<float>(
|
||||||
std::min(
|
std::min(
|
||||||
1.25,
|
1.25,
|
||||||
5000 * Traction->WireThickness / ( distancesquared + 1.0 ) ) ); // zbyt grube nie są dobre
|
5000 * Traction->WireThickness / ( distancesquared + 1.0 ) ) ); // zbyt grube nie są dobre
|
||||||
::glLineWidth( linealpha );
|
::glLineWidth( linealpha );
|
||||||
|
*/
|
||||||
|
auto const distance { static_cast<float>( std::sqrt( distancesquared ) ) };
|
||||||
|
auto const linealpha {
|
||||||
|
20.f * Traction->WireThickness
|
||||||
|
/ std::max(
|
||||||
|
0.5f * Traction->radius() + 1.f,
|
||||||
|
distance - ( 0.5f * Traction->radius() ) ) };
|
||||||
|
::glLineWidth(
|
||||||
|
clamp(
|
||||||
|
0.5f * linealpha + Traction->WireThickness * Traction->radius() / 1000.f,
|
||||||
|
1.f, 1.5f ) );
|
||||||
// McZapkie-261102: kolor zalezy od materialu i zasniedzenia
|
// McZapkie-261102: kolor zalezy od materialu i zasniedzenia
|
||||||
auto const color { Traction->wire_color() };
|
::glColor4fv(
|
||||||
::glColor4f( color.r, color.g, color.b, linealpha );
|
glm::value_ptr(
|
||||||
|
glm::vec4{
|
||||||
|
Traction->wire_color(),
|
||||||
|
linealpha } ) );
|
||||||
// render
|
// render
|
||||||
m_geometry.draw( Traction->m_geometry );
|
m_geometry.draw( Traction->m_geometry );
|
||||||
// debug data
|
// debug data
|
||||||
@@ -3318,12 +3363,15 @@ opengl_renderer::Render_Alpha( scene::lines_node const &Lines ) {
|
|||||||
0.5f * data.area.radius + 1.f,
|
0.5f * data.area.radius + 1.f,
|
||||||
distance - ( 0.5f * data.area.radius ) ) :
|
distance - ( 0.5f * data.area.radius ) ) :
|
||||||
1.f ); // negative width means the lines are always opague
|
1.f ); // negative width means the lines are always opague
|
||||||
|
::glLineWidth(
|
||||||
|
clamp(
|
||||||
|
0.5f * linealpha + data.line_width * data.area.radius / 1000.f,
|
||||||
|
1.f, 8.f ) );
|
||||||
::glColor4fv(
|
::glColor4fv(
|
||||||
glm::value_ptr(
|
glm::value_ptr(
|
||||||
glm::vec4{
|
glm::vec4{
|
||||||
glm::vec3{ data.lighting.diffuse * Global::DayLight.ambient }, // w zaleznosci od koloru swiatla
|
glm::vec3{ data.lighting.diffuse * Global::DayLight.ambient }, // w zaleznosci od koloru swiatla
|
||||||
std::min( 1.f, linealpha ) } ) );
|
std::min( 1.f, linealpha ) } ) );
|
||||||
::glLineWidth( clamp( 0.5f * linealpha + data.line_width * data.area.radius / 1000.f, 1.f, 8.f ) );
|
|
||||||
// render
|
// render
|
||||||
m_geometry.draw( data.geometry );
|
m_geometry.draw( data.geometry );
|
||||||
++m_debugstats.lines;
|
++m_debugstats.lines;
|
||||||
|
|||||||
86
scene.cpp
86
scene.cpp
@@ -242,12 +242,9 @@ basic_cell::insert( TTrack *Path ) {
|
|||||||
Path->RaOwnerSet( this );
|
Path->RaOwnerSet( this );
|
||||||
#endif
|
#endif
|
||||||
// re-calculate cell radius, in case track extends outside the cell's boundaries
|
// re-calculate cell radius, in case track extends outside the cell's boundaries
|
||||||
auto endpoints = Path->endpoints();
|
m_area.radius = std::max(
|
||||||
for( auto &endpoint : endpoints ) {
|
m_area.radius,
|
||||||
m_area.radius = std::max<float>(
|
static_cast<float>( glm::length( m_area.center - Path->location() ) + Path->radius() + 25.f ) ); // extra margin to prevent driven vehicle from flicking
|
||||||
m_area.radius,
|
|
||||||
glm::length( m_area.center - endpoint ) + 25.f ); // extra margin to prevent driven vehicle from flicking
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds provided traction piece to the cell
|
// adds provided traction piece to the cell
|
||||||
@@ -258,13 +255,8 @@ basic_cell::insert( TTraction *Traction ) {
|
|||||||
|
|
||||||
Traction->origin( m_area.center );
|
Traction->origin( m_area.center );
|
||||||
m_traction.emplace_back( Traction );
|
m_traction.emplace_back( Traction );
|
||||||
// re-calculate cell radius, in case traction piece extends outside the cell's boundaries
|
// re-calculate cell bounding area, in case traction piece extends outside the cell's boundaries
|
||||||
auto endpoints = Traction->endpoints();
|
enclose_area( Traction );
|
||||||
for( auto &endpoint : endpoints ) {
|
|
||||||
m_area.radius = std::max<float>(
|
|
||||||
m_area.radius,
|
|
||||||
glm::length( m_area.center - endpoint ) ); // adding arbitrary safety margin
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds provided model instance to the cell
|
// adds provided model instance to the cell
|
||||||
@@ -289,15 +281,8 @@ basic_cell::insert( TAnimModel *Instance ) {
|
|||||||
// opaque pieces
|
// opaque pieces
|
||||||
m_instancesopaque.emplace_back( Instance );
|
m_instancesopaque.emplace_back( Instance );
|
||||||
}
|
}
|
||||||
// re-calculate cell radius, in case model extends outside the cell's boundaries
|
// re-calculate cell bounding area, in case model extends outside the cell's boundaries
|
||||||
if( Instance->Model() ) {
|
enclose_area( Instance );
|
||||||
auto const modelradius{ Instance->Model()->bounding_radius() };
|
|
||||||
if( modelradius > 0.f ) {
|
|
||||||
m_area.radius = std::max<float>(
|
|
||||||
m_area.radius,
|
|
||||||
glm::length( m_area.center - Instance->location() ) + modelradius ); // adding arbitrary safety margin
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds provided sound instance to the cell
|
// adds provided sound instance to the cell
|
||||||
@@ -316,6 +301,8 @@ basic_cell::insert( TEventLauncher *Launcher ) {
|
|||||||
m_active = true;
|
m_active = true;
|
||||||
|
|
||||||
m_eventlaunchers.emplace_back( Launcher );
|
m_eventlaunchers.emplace_back( Launcher );
|
||||||
|
// re-calculate cell bounding area, in case launcher range extends outside the cell's boundaries
|
||||||
|
enclose_area( Launcher );
|
||||||
}
|
}
|
||||||
|
|
||||||
// registers provided path in the lookup directory of the cell
|
// registers provided path in the lookup directory of the cell
|
||||||
@@ -485,6 +472,15 @@ basic_cell::create_geometry( geometrybank_handle const &Bank ) {
|
|||||||
m_geometrycreated = true; // helper for legacy animation code, get rid of it after refactoring
|
m_geometrycreated = true; // helper for legacy animation code, get rid of it after refactoring
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// adjusts cell bounding area to enclose specified node
|
||||||
|
void
|
||||||
|
basic_cell::enclose_area( editor::basic_node *Node ) {
|
||||||
|
|
||||||
|
m_area.radius = std::max(
|
||||||
|
m_area.radius,
|
||||||
|
static_cast<float>( glm::length( m_area.center - Node->location() ) + Node->radius() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// legacy method, updates sounds and polls event launchers within radius around specified point
|
// legacy method, updates sounds and polls event launchers within radius around specified point
|
||||||
@@ -512,7 +508,7 @@ basic_section::update_traction( TDynamicObject *Vehicle, int const Pantographind
|
|||||||
auto pantograph = Vehicle->pants[ Pantographindex ].fParamPants;
|
auto pantograph = Vehicle->pants[ Pantographindex ].fParamPants;
|
||||||
auto const pantographposition = position + ( vLeft * pantograph->vPos.z ) + ( vUp * pantograph->vPos.y ) + ( vFront * pantograph->vPos.x );
|
auto const pantographposition = position + ( vLeft * pantograph->vPos.z ) + ( vUp * pantograph->vPos.y ) + ( vFront * pantograph->vPos.x );
|
||||||
|
|
||||||
auto const radius { EU07_CELLSIZE * 0.5 };
|
auto const radius { EU07_CELLSIZE * 0.5 }; // redius around point of interest
|
||||||
|
|
||||||
for( auto &cell : m_cells ) {
|
for( auto &cell : m_cells ) {
|
||||||
// we reject early cells which aren't within our area of interest
|
// we reject early cells which aren't within our area of interest
|
||||||
@@ -548,6 +544,11 @@ basic_section::insert( shape_node Shape ) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// large, opaque shapes are placed on section level
|
// large, opaque shapes are placed on section level
|
||||||
|
// re-calculate section radius, in case shape geometry extends outside the section's boundaries
|
||||||
|
m_area.radius = std::max<float>(
|
||||||
|
m_area.radius,
|
||||||
|
static_cast<float>( glm::length( m_area.center - Shape.data().area.center ) + Shape.data().area.radius ) );
|
||||||
|
|
||||||
for( auto &shape : m_shapes ) {
|
for( auto &shape : m_shapes ) {
|
||||||
// check first if the shape can't be merged with one of the shapes already present in the section
|
// check first if the shape can't be merged with one of the shapes already present in the section
|
||||||
if( true == shape.merge( Shape ) ) {
|
if( true == shape.merge( Shape ) ) {
|
||||||
@@ -739,6 +740,19 @@ basic_region::update_traction( TDynamicObject *Vehicle, int const Pantographinde
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stores content of the class in file with specified name
|
||||||
|
void
|
||||||
|
basic_region::serialize( std::string const &Scenariofile ) {
|
||||||
|
// TODO: implement
|
||||||
|
}
|
||||||
|
|
||||||
|
// restores content of the class from file with specified name. returns: true on success, false otherwise
|
||||||
|
bool
|
||||||
|
basic_region::deserialize( std::string const &Scenariofile ) {
|
||||||
|
// TODO: implement
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// legacy method, links specified path piece with potential neighbours
|
// legacy method, links specified path piece with potential neighbours
|
||||||
void
|
void
|
||||||
basic_region::TrackJoin( TTrack *Track ) {
|
basic_region::TrackJoin( TTrack *Track ) {
|
||||||
@@ -792,9 +806,9 @@ basic_region::insert_shape( shape_node Shape, scratch_data &Scratchpad, bool con
|
|||||||
// adjust input if necessary:
|
// adjust input if necessary:
|
||||||
if( true == Transform ) {
|
if( true == Transform ) {
|
||||||
// shapes generated from legacy terrain come with world space coordinates and don't need processing
|
// shapes generated from legacy terrain come with world space coordinates and don't need processing
|
||||||
if( Scratchpad.location_rotation != glm::vec3( 0, 0, 0 ) ) {
|
if( Scratchpad.location.rotation != glm::vec3( 0, 0, 0 ) ) {
|
||||||
// rotate...
|
// rotate...
|
||||||
auto const rotation = glm::radians( Scratchpad.location_rotation );
|
auto const rotation = glm::radians( Scratchpad.location.rotation );
|
||||||
for( auto &vertex : shape.m_data.vertices ) {
|
for( auto &vertex : shape.m_data.vertices ) {
|
||||||
vertex.position = glm::rotateZ<double>( vertex.position, rotation.z );
|
vertex.position = glm::rotateZ<double>( vertex.position, rotation.z );
|
||||||
vertex.position = glm::rotateX<double>( vertex.position, rotation.x );
|
vertex.position = glm::rotateX<double>( vertex.position, rotation.x );
|
||||||
@@ -804,10 +818,10 @@ basic_region::insert_shape( shape_node Shape, scratch_data &Scratchpad, bool con
|
|||||||
vertex.normal = glm::rotateY( vertex.normal, rotation.y );
|
vertex.normal = glm::rotateY( vertex.normal, rotation.y );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( ( false == Scratchpad.location_offset.empty() )
|
if( ( false == Scratchpad.location.offset.empty() )
|
||||||
&& ( Scratchpad.location_offset.top() != glm::dvec3( 0, 0, 0 ) ) ) {
|
&& ( Scratchpad.location.offset.top() != glm::dvec3( 0, 0, 0 ) ) ) {
|
||||||
// ...and move
|
// ...and move
|
||||||
auto const offset = Scratchpad.location_offset.top();
|
auto const offset = Scratchpad.location.offset.top();
|
||||||
for( auto &vertex : shape.m_data.vertices ) {
|
for( auto &vertex : shape.m_data.vertices ) {
|
||||||
vertex.position += offset;
|
vertex.position += offset;
|
||||||
}
|
}
|
||||||
@@ -850,19 +864,19 @@ basic_region::insert_lines( lines_node Lines, scratch_data &Scratchpad ) {
|
|||||||
|
|
||||||
if( Lines.m_data.vertices.empty() ) { return; }
|
if( Lines.m_data.vertices.empty() ) { return; }
|
||||||
// transform point coordinates if needed
|
// transform point coordinates if needed
|
||||||
if( Scratchpad.location_rotation != glm::vec3( 0, 0, 0 ) ) {
|
if( Scratchpad.location.rotation != glm::vec3( 0, 0, 0 ) ) {
|
||||||
// rotate...
|
// rotate...
|
||||||
auto const rotation = glm::radians( Scratchpad.location_rotation );
|
auto const rotation = glm::radians( Scratchpad.location.rotation );
|
||||||
for( auto &vertex : Lines.m_data.vertices ) {
|
for( auto &vertex : Lines.m_data.vertices ) {
|
||||||
vertex.position = glm::rotateZ<double>( vertex.position, rotation.z );
|
vertex.position = glm::rotateZ<double>( vertex.position, rotation.z );
|
||||||
vertex.position = glm::rotateX<double>( vertex.position, rotation.x );
|
vertex.position = glm::rotateX<double>( vertex.position, rotation.x );
|
||||||
vertex.position = glm::rotateY<double>( vertex.position, rotation.y );
|
vertex.position = glm::rotateY<double>( vertex.position, rotation.y );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( ( false == Scratchpad.location_offset.empty() )
|
if( ( false == Scratchpad.location.offset.empty() )
|
||||||
&& ( Scratchpad.location_offset.top() != glm::dvec3( 0, 0, 0 ) ) ) {
|
&& ( Scratchpad.location.offset.top() != glm::dvec3( 0, 0, 0 ) ) ) {
|
||||||
// ...and move
|
// ...and move
|
||||||
auto const offset = Scratchpad.location_offset.top();
|
auto const offset = Scratchpad.location.offset.top();
|
||||||
for( auto &vertex : Lines.m_data.vertices ) {
|
for( auto &vertex : Lines.m_data.vertices ) {
|
||||||
vertex.position += offset;
|
vertex.position += offset;
|
||||||
}
|
}
|
||||||
@@ -1073,7 +1087,7 @@ basic_region::sections( glm::dvec3 const &Point, float const Radius ) {
|
|||||||
int const originx = centerx - sectioncount / 2;
|
int const originx = centerx - sectioncount / 2;
|
||||||
int const originz = centerz - sectioncount / 2;
|
int const originz = centerz - sectioncount / 2;
|
||||||
|
|
||||||
auto const squaredradii { std::pow( ( 0.5 * M_SQRT2 * EU07_SECTIONSIZE + 0.25 * EU07_SECTIONSIZE ) + Radius, 2 ) };
|
auto const padding { 0.0 }; // { EU07_SECTIONSIZE * 0.25 }; // TODO: check if we can get away with padding of 0
|
||||||
|
|
||||||
for( int row = originz; row <= originz + sectioncount; ++row ) {
|
for( int row = originz; row <= originz + sectioncount; ++row ) {
|
||||||
if( row < 0 ) { continue; }
|
if( row < 0 ) { continue; }
|
||||||
@@ -1084,7 +1098,7 @@ basic_region::sections( glm::dvec3 const &Point, float const Radius ) {
|
|||||||
|
|
||||||
auto *section { m_sections[ row * EU07_REGIONSIDESECTIONCOUNT + column ] };
|
auto *section { m_sections[ row * EU07_REGIONSIDESECTIONCOUNT + column ] };
|
||||||
if( ( section != nullptr )
|
if( ( section != nullptr )
|
||||||
&& ( glm::length2( section->area().center - Point ) < squaredradii ) ) {
|
&& ( glm::length2( section->area().center - Point ) <= ( ( section->area().radius + padding + Radius ) * ( section->area().radius + padding + Radius ) ) ) ) {
|
||||||
|
|
||||||
m_scratchpad.sections.emplace_back( section );
|
m_scratchpad.sections.emplace_back( section );
|
||||||
}
|
}
|
||||||
|
|||||||
27
scene.h
27
scene.h
@@ -29,8 +29,16 @@ int const EU07_REGIONSIDESECTIONCOUNT = 500; // number of sections along a side
|
|||||||
|
|
||||||
struct scratch_data {
|
struct scratch_data {
|
||||||
|
|
||||||
std::stack<glm::dvec3> location_offset;
|
struct binary_data {
|
||||||
glm::vec3 location_rotation;
|
|
||||||
|
bool terrain{ false };
|
||||||
|
} binary;
|
||||||
|
|
||||||
|
struct location_data {
|
||||||
|
|
||||||
|
std::stack<glm::dvec3> offset;
|
||||||
|
glm::vec3 rotation;
|
||||||
|
} location;
|
||||||
|
|
||||||
struct trainset_data {
|
struct trainset_data {
|
||||||
|
|
||||||
@@ -129,6 +137,9 @@ private:
|
|||||||
using instance_sequence = std::vector<TAnimModel *>;
|
using instance_sequence = std::vector<TAnimModel *>;
|
||||||
using sound_sequence = std::vector<TTextSound *>;
|
using sound_sequence = std::vector<TTextSound *>;
|
||||||
using eventlauncher_sequence = std::vector<TEventLauncher *>;
|
using eventlauncher_sequence = std::vector<TEventLauncher *>;
|
||||||
|
// methods
|
||||||
|
void
|
||||||
|
enclose_area( editor::basic_node *Node );
|
||||||
// members
|
// members
|
||||||
scene::bounding_area m_area { glm::dvec3(), static_cast<float>( 0.5 * M_SQRT2 * EU07_CELLSIZE ) };
|
scene::bounding_area m_area { glm::dvec3(), static_cast<float>( 0.5 * M_SQRT2 * EU07_CELLSIZE ) };
|
||||||
bool m_active { false }; // whether the cell holds any actual data
|
bool m_active { false }; // whether the cell holds any actual data
|
||||||
@@ -182,9 +193,9 @@ public:
|
|||||||
auto &targetcell { cell( Node->location() ) };
|
auto &targetcell { cell( Node->location() ) };
|
||||||
targetcell.insert( Node );
|
targetcell.insert( Node );
|
||||||
// some node types can extend bounding area of the target cell
|
// some node types can extend bounding area of the target cell
|
||||||
m_area.radius = std::max<float>(
|
m_area.radius = std::max(
|
||||||
m_area.radius,
|
m_area.radius,
|
||||||
glm::length( m_area.center - targetcell.area().center ) + targetcell.area().radius ); }
|
static_cast<float>( glm::length( m_area.center - targetcell.area().center ) + targetcell.area().radius ) ); }
|
||||||
// registers provided node in the lookup directory of the section enclosing specified point
|
// registers provided node in the lookup directory of the section enclosing specified point
|
||||||
template <class Type_>
|
template <class Type_>
|
||||||
void
|
void
|
||||||
@@ -223,7 +234,7 @@ private:
|
|||||||
cell( glm::dvec3 const &Location );
|
cell( glm::dvec3 const &Location );
|
||||||
// members
|
// members
|
||||||
// placement and visibility
|
// placement and visibility
|
||||||
scene::bounding_area m_area { glm::dvec3(), static_cast<float>( 0.5 * M_SQRT2 * EU07_SECTIONSIZE + 0.25 * EU07_SECTIONSIZE ) };
|
scene::bounding_area m_area { glm::dvec3(), static_cast<float>( 0.5 * M_SQRT2 * EU07_SECTIONSIZE ) };
|
||||||
// content
|
// content
|
||||||
cell_array m_cells; // partitioning scheme
|
cell_array m_cells; // partitioning scheme
|
||||||
shapenode_sequence m_shapes; // large pieces of opaque geometry and (legacy) terrain
|
shapenode_sequence m_shapes; // large pieces of opaque geometry and (legacy) terrain
|
||||||
@@ -250,6 +261,12 @@ public:
|
|||||||
// legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
|
// legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
|
||||||
void
|
void
|
||||||
update_traction( TDynamicObject *Vehicle, int const Pantographindex );
|
update_traction( TDynamicObject *Vehicle, int const Pantographindex );
|
||||||
|
// stores content of the class in file with specified name
|
||||||
|
void
|
||||||
|
serialize( std::string const &Scenariofile );
|
||||||
|
// restores content of the class from file with specified name. returns: true on success, false otherwise
|
||||||
|
bool
|
||||||
|
deserialize( std::string const &Scenariofile );
|
||||||
// legacy method, links specified path piece with potential neighbours
|
// legacy method, links specified path piece with potential neighbours
|
||||||
void
|
void
|
||||||
TrackJoin( TTrack *Track );
|
TrackJoin( TTrack *Track );
|
||||||
|
|||||||
@@ -259,9 +259,9 @@ shape_node::convert( TSubModel const *Submodel ) {
|
|||||||
squareradius,
|
squareradius,
|
||||||
glm::length2( vertex.position - m_data.area.center ) );
|
glm::length2( vertex.position - m_data.area.center ) );
|
||||||
}
|
}
|
||||||
m_data.area.radius = std::max<float>(
|
m_data.area.radius = std::max(
|
||||||
m_data.area.radius,
|
m_data.area.radius,
|
||||||
std::sqrt( squareradius ) );
|
static_cast<float>( std::sqrt( squareradius ) ) );
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -497,5 +497,23 @@ basic_node::basic_node( scene::node_data const &Nodedata ) :
|
|||||||
std::numeric_limits<double>::max() );
|
std::numeric_limits<double>::max() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float const &
|
||||||
|
basic_node::radius() {
|
||||||
|
|
||||||
|
if( m_area.radius == -1.0 ) {
|
||||||
|
// calculate if needed
|
||||||
|
radius_();
|
||||||
|
}
|
||||||
|
return m_area.radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
// radius() subclass details, calculates node's bounding radius
|
||||||
|
// by default nodes are 'virtual don't extend from their center point
|
||||||
|
void
|
||||||
|
basic_node::radius_() {
|
||||||
|
|
||||||
|
m_area.radius = 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
} // editor
|
} // editor
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
11
scenenode.h
11
scenenode.h
@@ -288,10 +288,12 @@ public:
|
|||||||
return m_name; }
|
return m_name; }
|
||||||
void
|
void
|
||||||
location( glm::dvec3 const Location ) {
|
location( glm::dvec3 const Location ) {
|
||||||
m_location = Location; }
|
m_area.center = Location; }
|
||||||
glm::dvec3 const &
|
glm::dvec3 const &
|
||||||
location() const {
|
location() const {
|
||||||
return m_location; };
|
return m_area.center; };
|
||||||
|
float const &
|
||||||
|
radius();
|
||||||
void
|
void
|
||||||
visible( bool const Visible ) {
|
visible( bool const Visible ) {
|
||||||
m_visible = Visible; }
|
m_visible = Visible; }
|
||||||
@@ -300,8 +302,11 @@ public:
|
|||||||
return m_visible; }
|
return m_visible; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// methods
|
||||||
|
// radius() subclass details, calculates node's bounding radius
|
||||||
|
virtual void radius_();
|
||||||
// members
|
// members
|
||||||
glm::dvec3 m_location;
|
scene::bounding_area m_area;
|
||||||
bool m_visible { true };
|
bool m_visible { true };
|
||||||
double m_rangesquaredmin { 0.0 }; // visibility range, min
|
double m_rangesquaredmin { 0.0 }; // visibility range, min
|
||||||
double m_rangesquaredmax { 0.0 }; // visibility range, max
|
double m_rangesquaredmax { 0.0 }; // visibility range, max
|
||||||
|
|||||||
@@ -38,11 +38,16 @@ state_manager::deserialize( std::string const &Scenariofile ) {
|
|||||||
|
|
||||||
// TODO: check first for presence of serialized binary files
|
// TODO: check first for presence of serialized binary files
|
||||||
// if this fails, fall back on the legacy text format
|
// if this fails, fall back on the legacy text format
|
||||||
|
scene::scratch_data importscratchpad;
|
||||||
|
importscratchpad.binary.terrain = Region->deserialize( Scenariofile );
|
||||||
|
// NOTE: for the time being import from text format is a given, since we don't have full binary serialization
|
||||||
cParser scenarioparser( Scenariofile, cParser::buffer_FILE, Global::asCurrentSceneryPath, Global::bLoadTraction );
|
cParser scenarioparser( Scenariofile, cParser::buffer_FILE, Global::asCurrentSceneryPath, Global::bLoadTraction );
|
||||||
|
|
||||||
if( false == scenarioparser.ok() ) { return false; }
|
if( false == scenarioparser.ok() ) { return false; }
|
||||||
|
|
||||||
deserialize( scenarioparser );
|
deserialize( scenarioparser, importscratchpad );
|
||||||
|
// if we didn't find usable binary version of the scenario files, create them now for future use
|
||||||
|
if( false == importscratchpad.binary.terrain ) { Region->serialize( Scenariofile ); }
|
||||||
|
|
||||||
Global::iPause &= ~0x10; // koniec pauzy wczytywania
|
Global::iPause &= ~0x10; // koniec pauzy wczytywania
|
||||||
return true;
|
return true;
|
||||||
@@ -67,9 +72,8 @@ state_manager::update( double const Deltatime, int Iterationcount ) {
|
|||||||
|
|
||||||
// restores class data from provided stream
|
// restores class data from provided stream
|
||||||
void
|
void
|
||||||
state_manager::deserialize( cParser &Input ) {
|
state_manager::deserialize( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
scene::scratch_data importscratchpad;
|
|
||||||
// prepare deserialization function table
|
// prepare deserialization function table
|
||||||
// since all methods use the same objects, we can have simple, hard-coded binds or lambdas for the task
|
// since all methods use the same objects, we can have simple, hard-coded binds or lambdas for the task
|
||||||
using deserializefunction = void(state_manager::*)(cParser &, scene::scratch_data &);
|
using deserializefunction = void(state_manager::*)(cParser &, scene::scratch_data &);
|
||||||
@@ -98,7 +102,7 @@ state_manager::deserialize( cParser &Input ) {
|
|||||||
std::string,
|
std::string,
|
||||||
deserializefunctionbind> functionmap;
|
deserializefunctionbind> functionmap;
|
||||||
for( auto &function : functionlist ) {
|
for( auto &function : functionlist ) {
|
||||||
functionmap.emplace( function.first, std::bind( function.second, this, std::ref( Input ), std::ref( importscratchpad ) ) );
|
functionmap.emplace( function.first, std::bind( function.second, this, std::ref( Input ), std::ref( Scratchpad ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// deserialize content from the provided input
|
// deserialize content from the provided input
|
||||||
@@ -127,9 +131,9 @@ state_manager::deserialize( cParser &Input ) {
|
|||||||
token = Input.getToken<std::string>();
|
token = Input.getToken<std::string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( false == importscratchpad.initialized ) {
|
if( false == Scratchpad.initialized ) {
|
||||||
// manually perform scenario initialization
|
// manually perform scenario initialization
|
||||||
deserialize_firstinit( Input, importscratchpad );
|
deserialize_firstinit( Input, Scratchpad );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,12 +240,12 @@ state_manager::deserialize_event( cParser &Input, scene::scratch_data &Scratchpa
|
|||||||
// TODO: refactor event class and its de/serialization. do offset and rotation after deserialization is done
|
// TODO: refactor event class and its de/serialization. do offset and rotation after deserialization is done
|
||||||
auto *event = new TEvent();
|
auto *event = new TEvent();
|
||||||
Math3D::vector3 offset = (
|
Math3D::vector3 offset = (
|
||||||
Scratchpad.location_offset.empty() ?
|
Scratchpad.location.offset.empty() ?
|
||||||
Math3D::vector3() :
|
Math3D::vector3() :
|
||||||
Math3D::vector3(
|
Math3D::vector3(
|
||||||
Scratchpad.location_offset.top().x,
|
Scratchpad.location.offset.top().x,
|
||||||
Scratchpad.location_offset.top().y,
|
Scratchpad.location.offset.top().y,
|
||||||
Scratchpad.location_offset.top().z ) );
|
Scratchpad.location.offset.top().z ) );
|
||||||
event->Load( &Input, offset );
|
event->Load( &Input, offset );
|
||||||
|
|
||||||
if( false == simulation::Events.insert( event ) ) {
|
if( false == simulation::Events.insert( event ) ) {
|
||||||
@@ -386,20 +390,34 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
|| ( nodedata.type == "triangle_strip" )
|
|| ( nodedata.type == "triangle_strip" )
|
||||||
|| ( nodedata.type == "triangle_fan" ) ) {
|
|| ( nodedata.type == "triangle_fan" ) ) {
|
||||||
|
|
||||||
simulation::Region->insert_shape(
|
if( false == Scratchpad.binary.terrain ) {
|
||||||
scene::shape_node().deserialize(
|
|
||||||
Input, nodedata ),
|
simulation::Region->insert_shape(
|
||||||
Scratchpad,
|
scene::shape_node().deserialize(
|
||||||
true );
|
Input, nodedata ),
|
||||||
|
Scratchpad,
|
||||||
|
true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// all shapes were already loaded from the binary version of the file
|
||||||
|
skip_until( Input, "endtri" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( ( nodedata.type == "lines" )
|
else if( ( nodedata.type == "lines" )
|
||||||
|| ( nodedata.type == "line_strip" )
|
|| ( nodedata.type == "line_strip" )
|
||||||
|| ( nodedata.type == "line_loop" ) ) {
|
|| ( nodedata.type == "line_loop" ) ) {
|
||||||
|
|
||||||
simulation::Region->insert_lines(
|
if( false == Scratchpad.binary.terrain ) {
|
||||||
scene::lines_node().deserialize(
|
|
||||||
Input, nodedata ),
|
simulation::Region->insert_lines(
|
||||||
Scratchpad );
|
scene::lines_node().deserialize(
|
||||||
|
Input, nodedata ),
|
||||||
|
Scratchpad );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// all lines were already loaded from the binary version of the file
|
||||||
|
skip_until( Input, "endline" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( nodedata.type == "memcell" ) {
|
else if( nodedata.type == "memcell" ) {
|
||||||
|
|
||||||
@@ -448,18 +466,18 @@ state_manager::deserialize_origin( cParser &Input, scene::scratch_data &Scratchp
|
|||||||
>> offset.y
|
>> offset.y
|
||||||
>> offset.z;
|
>> offset.z;
|
||||||
// sumowanie całkowitego przesunięcia
|
// sumowanie całkowitego przesunięcia
|
||||||
Scratchpad.location_offset.emplace(
|
Scratchpad.location.offset.emplace(
|
||||||
offset + (
|
offset + (
|
||||||
Scratchpad.location_offset.empty() ?
|
Scratchpad.location.offset.empty() ?
|
||||||
glm::dvec3() :
|
glm::dvec3() :
|
||||||
Scratchpad.location_offset.top() ) );
|
Scratchpad.location.offset.top() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::deserialize_endorigin( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_manager::deserialize_endorigin( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
if( false == Scratchpad.location_offset.empty() ) {
|
if( false == Scratchpad.location.offset.empty() ) {
|
||||||
Scratchpad.location_offset.pop();
|
Scratchpad.location.offset.pop();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ErrorLog( "Bad origin: endorigin instruction with empty origin stack in file \"" + Input.Name() + "\" (line " + std::to_string( Input.Line() - 1 ) + ")" );
|
ErrorLog( "Bad origin: endorigin instruction with empty origin stack in file \"" + Input.Name() + "\" (line " + std::to_string( Input.Line() - 1 ) + ")" );
|
||||||
@@ -471,9 +489,9 @@ state_manager::deserialize_rotate( cParser &Input, scene::scratch_data &Scratchp
|
|||||||
|
|
||||||
Input.getTokens( 3 );
|
Input.getTokens( 3 );
|
||||||
Input
|
Input
|
||||||
>> Scratchpad.location_rotation.x
|
>> Scratchpad.location.rotation.x
|
||||||
>> Scratchpad.location_rotation.y
|
>> Scratchpad.location.rotation.y
|
||||||
>> Scratchpad.location_rotation.z;
|
>> Scratchpad.location.rotation.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -584,12 +602,12 @@ state_manager::deserialize_path( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
// TODO: refactor track and wrapper classes and their de/serialization. do offset and rotation after deserialization is done
|
// TODO: refactor track and wrapper classes and their de/serialization. do offset and rotation after deserialization is done
|
||||||
auto *track = new TTrack( Nodedata );
|
auto *track = new TTrack( Nodedata );
|
||||||
Math3D::vector3 offset = (
|
Math3D::vector3 offset = (
|
||||||
Scratchpad.location_offset.empty() ?
|
Scratchpad.location.offset.empty() ?
|
||||||
Math3D::vector3() :
|
Math3D::vector3() :
|
||||||
Math3D::vector3(
|
Math3D::vector3(
|
||||||
Scratchpad.location_offset.top().x,
|
Scratchpad.location.offset.top().x,
|
||||||
Scratchpad.location_offset.top().y,
|
Scratchpad.location.offset.top().y,
|
||||||
Scratchpad.location_offset.top().z ) );
|
Scratchpad.location.offset.top().z ) );
|
||||||
track->Load( &Input, offset );
|
track->Load( &Input, offset );
|
||||||
|
|
||||||
return track;
|
return track;
|
||||||
@@ -605,9 +623,9 @@ state_manager::deserialize_traction( cParser &Input, scene::scratch_data &Scratc
|
|||||||
// TODO: refactor track and wrapper classes and their de/serialization. do offset and rotation after deserialization is done
|
// TODO: refactor track and wrapper classes and their de/serialization. do offset and rotation after deserialization is done
|
||||||
auto *traction = new TTraction( Nodedata );
|
auto *traction = new TTraction( Nodedata );
|
||||||
auto offset = (
|
auto offset = (
|
||||||
Scratchpad.location_offset.empty() ?
|
Scratchpad.location.offset.empty() ?
|
||||||
glm::dvec3() :
|
glm::dvec3() :
|
||||||
Scratchpad.location_offset.top() );
|
Scratchpad.location.offset.top() );
|
||||||
traction->Load( &Input, offset );
|
traction->Load( &Input, offset );
|
||||||
|
|
||||||
return traction;
|
return traction;
|
||||||
@@ -670,7 +688,7 @@ state_manager::deserialize_model( cParser &Input, scene::scratch_data &Scratchpa
|
|||||||
>> rotation.y;
|
>> rotation.y;
|
||||||
|
|
||||||
auto *instance = new TAnimModel( Nodedata );
|
auto *instance = new TAnimModel( Nodedata );
|
||||||
instance->RaAnglesSet( Scratchpad.location_rotation + rotation ); // dostosowanie do pochylania linii
|
instance->RaAnglesSet( Scratchpad.location.rotation + rotation ); // dostosowanie do pochylania linii
|
||||||
|
|
||||||
if( false == instance->Load( &Input, false ) ) {
|
if( false == instance->Load( &Input, false ) ) {
|
||||||
// model nie wczytał się - ignorowanie node
|
// model nie wczytał się - ignorowanie node
|
||||||
@@ -838,12 +856,12 @@ state_manager::skip_until( cParser &Input, std::string const &Token ) {
|
|||||||
glm::dvec3
|
glm::dvec3
|
||||||
state_manager::transform( glm::dvec3 Location, scene::scratch_data const &Scratchpad ) {
|
state_manager::transform( glm::dvec3 Location, scene::scratch_data const &Scratchpad ) {
|
||||||
|
|
||||||
if( Scratchpad.location_rotation != glm::vec3( 0, 0, 0 ) ) {
|
if( Scratchpad.location.rotation != glm::vec3( 0, 0, 0 ) ) {
|
||||||
auto const rotation = glm::radians( Scratchpad.location_rotation );
|
auto const rotation = glm::radians( Scratchpad.location.rotation );
|
||||||
Location = glm::rotateY<double>( Location, rotation.y ); // Ra 2014-11: uwzględnienie rotacji
|
Location = glm::rotateY<double>( Location, rotation.y ); // Ra 2014-11: uwzględnienie rotacji
|
||||||
}
|
}
|
||||||
if( false == Scratchpad.location_offset.empty() ) {
|
if( false == Scratchpad.location.offset.empty() ) {
|
||||||
Location += Scratchpad.location_offset.top();
|
Location += Scratchpad.location.offset.top();
|
||||||
}
|
}
|
||||||
return Location;
|
return Location;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
// methods
|
// methods
|
||||||
// restores class data from provided stream
|
// restores class data from provided stream
|
||||||
void deserialize( cParser &Input );
|
void deserialize( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
void deserialize_atmo( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize_atmo( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
void deserialize_camera( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize_camera( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
void deserialize_config( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize_config( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
|
|||||||
Reference in New Issue
Block a user