mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01: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;
|
||||
};
|
||||
|
||||
// calculates piece's bounding radius
|
||||
void
|
||||
TAnimModel::radius_() {
|
||||
|
||||
if( pModel != nullptr ) {
|
||||
m_area.radius = pModel->bounding_radius();
|
||||
}
|
||||
}
|
||||
|
||||
void TAnimModel::RaPrepare()
|
||||
{ // ustawia światła i animacje we wzorcu modelu przed renderowaniem egzemplarza
|
||||
bool state; // stan światła
|
||||
|
||||
@@ -157,6 +157,11 @@ public:
|
||||
// members
|
||||
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:
|
||||
// methods
|
||||
void RaPrepare(); // ustawienie animacji egzemplarza na wzorcu
|
||||
|
||||
11
EvLaunch.cpp
11
EvLaunch.cpp
@@ -121,7 +121,7 @@ bool TEventLauncher::Load(cParser *parser)
|
||||
*parser >> token;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
bool TEventLauncher::check_conditions()
|
||||
{ //"renderowanie" wyzwalacza
|
||||
@@ -184,6 +184,13 @@ bool TEventLauncher::IsGlobal() const {
|
||||
&& ( iHour >= 0 )
|
||||
&& ( iMinute >= 0 )
|
||||
&& ( 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 };
|
||||
double dRadius { 0.0 };
|
||||
|
||||
protected:
|
||||
// calculates node's bounding radius
|
||||
void
|
||||
radius_();
|
||||
|
||||
private:
|
||||
// members
|
||||
int iKey { 0 };
|
||||
|
||||
@@ -1562,6 +1562,9 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
10
MemCell.cpp
10
MemCell.cpp
@@ -29,8 +29,8 @@ http://mozilla.org/MPL/2.0/.
|
||||
TMemCell::TMemCell(vector3 *p)
|
||||
{
|
||||
fValue1 = fValue2 = 0;
|
||||
m_location =
|
||||
p ? *p : glm::dvec3(); // ustawienie współrzędnych, bo do TGroundNode nie ma dostępu
|
||||
location(
|
||||
p ? *p : glm::dvec3() ); // ustawienie współrzędnych, bo do TGroundNode nie ma dostępu
|
||||
bCommand = false; // komenda wysłana
|
||||
OnSent = NULL;
|
||||
}
|
||||
@@ -110,9 +110,9 @@ bool TMemCell::Load(cParser *parser)
|
||||
#else
|
||||
parser->getTokens( 6, false );
|
||||
*parser
|
||||
>> m_location.x
|
||||
>> m_location.y
|
||||
>> m_location.z
|
||||
>> m_area.center.x
|
||||
>> m_area.center.y
|
||||
>> m_area.center.z
|
||||
#endif
|
||||
>> szText
|
||||
>> fValue1
|
||||
|
||||
21
MemCell.h
21
MemCell.h
@@ -16,16 +16,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
class TMemCell : public editor::basic_node {
|
||||
|
||||
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
|
||||
public:
|
||||
public:
|
||||
std::string asTrackName; // McZapkie-100302 - zeby nazwe toru na ktory jest Putcommand wysylane pamietac
|
||||
|
||||
TMemCell( scene::node_data const &Nodedata );
|
||||
@@ -63,6 +54,16 @@ class TMemCell : public editor::basic_node {
|
||||
TCommandType CommandCheck();
|
||||
bool IsVelocity();
|
||||
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 ) {
|
||||
// calculate bounding radius while we're at 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 ) ) {
|
||||
squaredradius = static_cast<float>( glm::length2( vertex.position ) );
|
||||
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( Parent ) {
|
||||
// propagate radius up the chain
|
||||
Parent->m_boundingradius = std::max(
|
||||
Parent->m_boundingradius,
|
||||
m_boundingradius );
|
||||
// adjust overall radius if needed
|
||||
// NOTE: the method to access root submodel is... less than ideal
|
||||
auto *root { this };
|
||||
while( root->Parent != nullptr ) {
|
||||
root = root->Parent;
|
||||
}
|
||||
root->m_boundingradius = std::max(
|
||||
root->m_boundingradius,
|
||||
m_boundingradius );
|
||||
}
|
||||
|
||||
if( Next )
|
||||
|
||||
16
Track.cpp
16
Track.cpp
@@ -867,11 +867,11 @@ void TTrack::Load(cParser *parser, vector3 pOrigin)
|
||||
}
|
||||
|
||||
// calculate path location
|
||||
m_location = glm::dvec3{ (
|
||||
m_area.center = ( glm::dvec3{ (
|
||||
CurrentSegment()->FastGetPoint_0()
|
||||
+ CurrentSegment()->FastGetPoint( 0.5 )
|
||||
+ CurrentSegment()->FastGetPoint_1() )
|
||||
/ 3.0 };
|
||||
/ 3.0 } );
|
||||
}
|
||||
|
||||
// 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)
|
||||
{ // poprawienie przechyłki wymaga wydłużenia podsypki
|
||||
fTexHeight1 += dh;
|
||||
|
||||
11
Track.h
11
Track.h
@@ -182,9 +182,9 @@ public:
|
||||
TEnvironmentType eEnvironment = e_flat; // dźwięk i oświetlenie
|
||||
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)
|
||||
private:
|
||||
private:
|
||||
double fVelocity = -1.0; // ograniczenie prędkości // prędkość dla AI (powyżej rośnie prawdopowobieństwo wykolejenia)
|
||||
public:
|
||||
public:
|
||||
// McZapkie-100502:
|
||||
double fTrackLength = 100.0; // długość z wpisu, nigdzie nie używana
|
||||
double fRadius = 0.0; // promień, dla zwrotnicy kopiowany z tabeli
|
||||
@@ -287,7 +287,12 @@ public:
|
||||
double VelocityGet();
|
||||
void ConnectionsLog();
|
||||
|
||||
private:
|
||||
protected:
|
||||
// calculates path's bounding radius
|
||||
void
|
||||
radius_();
|
||||
|
||||
private:
|
||||
void EnvironmentSet();
|
||||
void EnvironmentReset();
|
||||
};
|
||||
|
||||
14
Traction.cpp
14
Traction.cpp
@@ -169,7 +169,7 @@ TTraction::Load( cParser *parser, glm::dvec3 const &pOrigin ) {
|
||||
Init(); // przeliczenie parametrów
|
||||
|
||||
// calculate traction location
|
||||
m_location = interpolate( pPoint2, pPoint1, 0.5 );
|
||||
location( interpolate( pPoint2, pPoint1, 0.5 ) );
|
||||
}
|
||||
|
||||
// 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?
|
||||
};
|
||||
|
||||
// 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
|
||||
TTraction::wire_color() const {
|
||||
|
||||
|
||||
@@ -64,7 +64,6 @@ class TTraction : public editor::basic_node {
|
||||
// retrieves list of the track's end points
|
||||
std::vector<glm::dvec3>
|
||||
endpoints() const;
|
||||
|
||||
// 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
|
||||
#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 PowerSet(TTractionPowerSource *ps);
|
||||
double VoltageGet(double u, double i);
|
||||
|
||||
protected:
|
||||
// calculates piece's bounding radius
|
||||
void
|
||||
radius_();
|
||||
|
||||
private:
|
||||
glm::vec3 wire_color() const;
|
||||
};
|
||||
|
||||
@@ -42,9 +42,9 @@ bool TTractionPowerSource::Load(cParser *parser) {
|
||||
#else
|
||||
parser->getTokens( 10, false );
|
||||
*parser
|
||||
>> m_location.x
|
||||
>> m_location.y
|
||||
>> m_location.z
|
||||
>> m_area.center.x
|
||||
>> m_area.center.y
|
||||
>> m_area.center.z
|
||||
#endif
|
||||
>> NominalVoltage
|
||||
>> 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ę
|
||||
*/
|
||||
std::unordered_map<std::string, TGauge &> gauges = {
|
||||
std::unordered_map<std::string, TGauge &> const gauges = {
|
||||
{ "mainctrl:", ggMainCtrl },
|
||||
{ "scndctrl:", ggScndCtrl },
|
||||
{ "dirkey:" , ggDirKey },
|
||||
|
||||
@@ -1352,7 +1352,8 @@ TWorld::Update_UI() {
|
||||
uitextline1 += " (paused)";
|
||||
}
|
||||
|
||||
if( Controlled && ( Controlled->Mechanik != nullptr ) ) {
|
||||
if( ( Controlled != nullptr )
|
||||
&& ( Controlled->Mechanik != nullptr ) ) {
|
||||
|
||||
auto const &mover = Controlled->MoverParameters;
|
||||
auto const &driver = Controlled->Mechanik;
|
||||
@@ -1374,6 +1375,11 @@ TWorld::Update_UI() {
|
||||
uitextline3 +=
|
||||
" Pressure: " + to_string( mover->BrakePress * 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 );
|
||||
::glDisable( GL_LIGHTING );
|
||||
::glDisable( GL_TEXTURE_2D );
|
||||
if( true == Global::RenderShadows ) {
|
||||
if( ( true == Global::RenderShadows ) && ( false == Global::bWireFrame ) ) {
|
||||
shadowcamera.draw( m_renderpass.camera.position() - shadowcamera.position() );
|
||||
}
|
||||
if( DebugCameraFlag ) {
|
||||
@@ -2214,11 +2214,11 @@ opengl_renderer::Render( TAnimModel *Instance ) {
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
case rendermode::shadows: {
|
||||
// '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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -2246,7 +2246,7 @@ opengl_renderer::Render( TAnimModel *Instance ) {
|
||||
Instance->pModel,
|
||||
Instance->Material(),
|
||||
distancesquared,
|
||||
Instance->m_location - m_renderpass.camera.position(),
|
||||
Instance->location() - m_renderpass.camera.position(),
|
||||
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 ) {
|
||||
|
||||
::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
|
||||
for( auto first { First }; first != Last; ++first ) {
|
||||
@@ -2824,7 +2835,16 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
|
||||
track->EnvironmentReset();
|
||||
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::pickcontrols:
|
||||
default: {
|
||||
@@ -2854,9 +2874,10 @@ opengl_renderer::Render( scene::basic_cell::path_sequence::const_iterator First,
|
||||
break;
|
||||
}
|
||||
case rendermode::shadows: {
|
||||
if( ( track->iCategoryFlag != 1 )
|
||||
|| ( track->eType != tt_Normal ) ) {
|
||||
// shadows are only calculated for trackbeds
|
||||
if( ( std::abs( track->fTexHeight1 ) < 0.35f )
|
||||
|| ( ( track->iCategoryFlag == 1 )
|
||||
&& ( track->eType != tt_Normal ) ) ) {
|
||||
// shadows are only calculated for high enough trackbeds
|
||||
continue;
|
||||
}
|
||||
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
|
||||
@@ -3218,11 +3249,11 @@ opengl_renderer::Render_Alpha( TAnimModel *Instance ) {
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
case rendermode::shadows: {
|
||||
// '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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -3238,7 +3269,7 @@ opengl_renderer::Render_Alpha( TAnimModel *Instance ) {
|
||||
Instance->pModel,
|
||||
Instance->Material(),
|
||||
distancesquared,
|
||||
Instance->m_location - m_renderpass.camera.position(),
|
||||
Instance->location() - m_renderpass.camera.position(),
|
||||
Instance->vAngle );
|
||||
}
|
||||
}
|
||||
@@ -3250,11 +3281,11 @@ opengl_renderer::Render_Alpha( TTraction *Traction ) {
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
case rendermode::shadows: {
|
||||
// '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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -3272,15 +3303,29 @@ opengl_renderer::Render_Alpha( TTraction *Traction ) {
|
||||
return;
|
||||
}
|
||||
// setup
|
||||
/*
|
||||
float const linealpha = static_cast<float>(
|
||||
std::min(
|
||||
1.25,
|
||||
5000 * Traction->WireThickness / ( distancesquared + 1.0 ) ) ); // zbyt grube nie są dobre
|
||||
::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
|
||||
auto const color { Traction->wire_color() };
|
||||
::glColor4f( color.r, color.g, color.b, linealpha );
|
||||
|
||||
::glColor4fv(
|
||||
glm::value_ptr(
|
||||
glm::vec4{
|
||||
Traction->wire_color(),
|
||||
linealpha } ) );
|
||||
// render
|
||||
m_geometry.draw( Traction->m_geometry );
|
||||
// debug data
|
||||
@@ -3318,12 +3363,15 @@ opengl_renderer::Render_Alpha( scene::lines_node const &Lines ) {
|
||||
0.5f * data.area.radius + 1.f,
|
||||
distance - ( 0.5f * data.area.radius ) ) :
|
||||
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(
|
||||
glm::value_ptr(
|
||||
glm::vec4{
|
||||
glm::vec3{ data.lighting.diffuse * Global::DayLight.ambient }, // w zaleznosci od koloru swiatla
|
||||
std::min( 1.f, linealpha ) } ) );
|
||||
::glLineWidth( clamp( 0.5f * linealpha + data.line_width * data.area.radius / 1000.f, 1.f, 8.f ) );
|
||||
// render
|
||||
m_geometry.draw( data.geometry );
|
||||
++m_debugstats.lines;
|
||||
|
||||
86
scene.cpp
86
scene.cpp
@@ -242,12 +242,9 @@ basic_cell::insert( TTrack *Path ) {
|
||||
Path->RaOwnerSet( this );
|
||||
#endif
|
||||
// re-calculate cell radius, in case track extends outside the cell's boundaries
|
||||
auto endpoints = Path->endpoints();
|
||||
for( auto &endpoint : endpoints ) {
|
||||
m_area.radius = std::max<float>(
|
||||
m_area.radius,
|
||||
glm::length( m_area.center - endpoint ) + 25.f ); // extra margin to prevent driven vehicle from flicking
|
||||
}
|
||||
m_area.radius = std::max(
|
||||
m_area.radius,
|
||||
static_cast<float>( glm::length( m_area.center - Path->location() ) + Path->radius() + 25.f ) ); // extra margin to prevent driven vehicle from flicking
|
||||
}
|
||||
|
||||
// adds provided traction piece to the cell
|
||||
@@ -258,13 +255,8 @@ basic_cell::insert( TTraction *Traction ) {
|
||||
|
||||
Traction->origin( m_area.center );
|
||||
m_traction.emplace_back( Traction );
|
||||
// re-calculate cell radius, in case traction piece extends outside the cell's boundaries
|
||||
auto endpoints = Traction->endpoints();
|
||||
for( auto &endpoint : endpoints ) {
|
||||
m_area.radius = std::max<float>(
|
||||
m_area.radius,
|
||||
glm::length( m_area.center - endpoint ) ); // adding arbitrary safety margin
|
||||
}
|
||||
// re-calculate cell bounding area, in case traction piece extends outside the cell's boundaries
|
||||
enclose_area( Traction );
|
||||
}
|
||||
|
||||
// adds provided model instance to the cell
|
||||
@@ -289,15 +281,8 @@ basic_cell::insert( TAnimModel *Instance ) {
|
||||
// opaque pieces
|
||||
m_instancesopaque.emplace_back( Instance );
|
||||
}
|
||||
// re-calculate cell radius, in case model extends outside the cell's boundaries
|
||||
if( Instance->Model() ) {
|
||||
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
|
||||
}
|
||||
}
|
||||
// re-calculate cell bounding area, in case model extends outside the cell's boundaries
|
||||
enclose_area( Instance );
|
||||
}
|
||||
|
||||
// adds provided sound instance to the cell
|
||||
@@ -316,6 +301,8 @@ basic_cell::insert( TEventLauncher *Launcher ) {
|
||||
m_active = true;
|
||||
|
||||
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
|
||||
@@ -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
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -512,7 +508,7 @@ basic_section::update_traction( TDynamicObject *Vehicle, int const Pantographind
|
||||
auto pantograph = Vehicle->pants[ Pantographindex ].fParamPants;
|
||||
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 ) {
|
||||
// we reject early cells which aren't within our area of interest
|
||||
@@ -548,6 +544,11 @@ basic_section::insert( shape_node Shape ) {
|
||||
}
|
||||
else {
|
||||
// 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 ) {
|
||||
// check first if the shape can't be merged with one of the shapes already present in the section
|
||||
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
|
||||
void
|
||||
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:
|
||||
if( true == Transform ) {
|
||||
// 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...
|
||||
auto const rotation = glm::radians( Scratchpad.location_rotation );
|
||||
auto const rotation = glm::radians( Scratchpad.location.rotation );
|
||||
for( auto &vertex : shape.m_data.vertices ) {
|
||||
vertex.position = glm::rotateZ<double>( vertex.position, rotation.z );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
if( ( false == Scratchpad.location_offset.empty() )
|
||||
&& ( Scratchpad.location_offset.top() != glm::dvec3( 0, 0, 0 ) ) ) {
|
||||
// ...and move
|
||||
auto const offset = Scratchpad.location_offset.top();
|
||||
if( ( false == Scratchpad.location.offset.empty() )
|
||||
&& ( Scratchpad.location.offset.top() != glm::dvec3( 0, 0, 0 ) ) ) {
|
||||
// ...and move
|
||||
auto const offset = Scratchpad.location.offset.top();
|
||||
for( auto &vertex : shape.m_data.vertices ) {
|
||||
vertex.position += offset;
|
||||
}
|
||||
@@ -850,19 +864,19 @@ basic_region::insert_lines( lines_node Lines, scratch_data &Scratchpad ) {
|
||||
|
||||
if( Lines.m_data.vertices.empty() ) { return; }
|
||||
// transform point coordinates if needed
|
||||
if( Scratchpad.location_rotation != glm::vec3( 0, 0, 0 ) ) {
|
||||
if( Scratchpad.location.rotation != glm::vec3( 0, 0, 0 ) ) {
|
||||
// rotate...
|
||||
auto const rotation = glm::radians( Scratchpad.location_rotation );
|
||||
auto const rotation = glm::radians( Scratchpad.location.rotation );
|
||||
for( auto &vertex : Lines.m_data.vertices ) {
|
||||
vertex.position = glm::rotateZ<double>( vertex.position, rotation.z );
|
||||
vertex.position = glm::rotateX<double>( vertex.position, rotation.x );
|
||||
vertex.position = glm::rotateY<double>( vertex.position, rotation.y );
|
||||
}
|
||||
}
|
||||
if( ( false == Scratchpad.location_offset.empty() )
|
||||
&& ( Scratchpad.location_offset.top() != glm::dvec3( 0, 0, 0 ) ) ) {
|
||||
if( ( false == Scratchpad.location.offset.empty() )
|
||||
&& ( Scratchpad.location.offset.top() != glm::dvec3( 0, 0, 0 ) ) ) {
|
||||
// ...and move
|
||||
auto const offset = Scratchpad.location_offset.top();
|
||||
auto const offset = Scratchpad.location.offset.top();
|
||||
for( auto &vertex : Lines.m_data.vertices ) {
|
||||
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 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 ) {
|
||||
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 ] };
|
||||
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 );
|
||||
}
|
||||
|
||||
27
scene.h
27
scene.h
@@ -29,8 +29,16 @@ int const EU07_REGIONSIDESECTIONCOUNT = 500; // number of sections along a side
|
||||
|
||||
struct scratch_data {
|
||||
|
||||
std::stack<glm::dvec3> location_offset;
|
||||
glm::vec3 location_rotation;
|
||||
struct binary_data {
|
||||
|
||||
bool terrain{ false };
|
||||
} binary;
|
||||
|
||||
struct location_data {
|
||||
|
||||
std::stack<glm::dvec3> offset;
|
||||
glm::vec3 rotation;
|
||||
} location;
|
||||
|
||||
struct trainset_data {
|
||||
|
||||
@@ -129,6 +137,9 @@ private:
|
||||
using instance_sequence = std::vector<TAnimModel *>;
|
||||
using sound_sequence = std::vector<TTextSound *>;
|
||||
using eventlauncher_sequence = std::vector<TEventLauncher *>;
|
||||
// methods
|
||||
void
|
||||
enclose_area( editor::basic_node *Node );
|
||||
// members
|
||||
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
|
||||
@@ -182,9 +193,9 @@ public:
|
||||
auto &targetcell { cell( Node->location() ) };
|
||||
targetcell.insert( Node );
|
||||
// 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,
|
||||
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
|
||||
template <class Type_>
|
||||
void
|
||||
@@ -223,7 +234,7 @@ private:
|
||||
cell( glm::dvec3 const &Location );
|
||||
// members
|
||||
// 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
|
||||
cell_array m_cells; // partitioning scheme
|
||||
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
|
||||
void
|
||||
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
|
||||
void
|
||||
TrackJoin( TTrack *Track );
|
||||
|
||||
@@ -259,9 +259,9 @@ shape_node::convert( TSubModel const *Submodel ) {
|
||||
squareradius,
|
||||
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,
|
||||
std::sqrt( squareradius ) );
|
||||
static_cast<float>( std::sqrt( squareradius ) ) );
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -497,5 +497,23 @@ basic_node::basic_node( scene::node_data const &Nodedata ) :
|
||||
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
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
11
scenenode.h
11
scenenode.h
@@ -288,10 +288,12 @@ public:
|
||||
return m_name; }
|
||||
void
|
||||
location( glm::dvec3 const Location ) {
|
||||
m_location = Location; }
|
||||
m_area.center = Location; }
|
||||
glm::dvec3 const &
|
||||
location() const {
|
||||
return m_location; };
|
||||
return m_area.center; };
|
||||
float const &
|
||||
radius();
|
||||
void
|
||||
visible( bool const Visible ) {
|
||||
m_visible = Visible; }
|
||||
@@ -300,8 +302,11 @@ public:
|
||||
return m_visible; }
|
||||
|
||||
protected:
|
||||
// methods
|
||||
// radius() subclass details, calculates node's bounding radius
|
||||
virtual void radius_();
|
||||
// members
|
||||
glm::dvec3 m_location;
|
||||
scene::bounding_area m_area;
|
||||
bool m_visible { true };
|
||||
double m_rangesquaredmin { 0.0 }; // visibility range, min
|
||||
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
|
||||
// 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 );
|
||||
|
||||
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
|
||||
return true;
|
||||
@@ -67,9 +72,8 @@ state_manager::update( double const Deltatime, int Iterationcount ) {
|
||||
|
||||
// restores class data from provided stream
|
||||
void
|
||||
state_manager::deserialize( cParser &Input ) {
|
||||
state_manager::deserialize( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||
|
||||
scene::scratch_data importscratchpad;
|
||||
// prepare deserialization function table
|
||||
// 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 &);
|
||||
@@ -98,7 +102,7 @@ state_manager::deserialize( cParser &Input ) {
|
||||
std::string,
|
||||
deserializefunctionbind> functionmap;
|
||||
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
|
||||
@@ -127,9 +131,9 @@ state_manager::deserialize( cParser &Input ) {
|
||||
token = Input.getToken<std::string>();
|
||||
}
|
||||
|
||||
if( false == importscratchpad.initialized ) {
|
||||
if( false == Scratchpad.initialized ) {
|
||||
// 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
|
||||
auto *event = new TEvent();
|
||||
Math3D::vector3 offset = (
|
||||
Scratchpad.location_offset.empty() ?
|
||||
Scratchpad.location.offset.empty() ?
|
||||
Math3D::vector3() :
|
||||
Math3D::vector3(
|
||||
Scratchpad.location_offset.top().x,
|
||||
Scratchpad.location_offset.top().y,
|
||||
Scratchpad.location_offset.top().z ) );
|
||||
Scratchpad.location.offset.top().x,
|
||||
Scratchpad.location.offset.top().y,
|
||||
Scratchpad.location.offset.top().z ) );
|
||||
event->Load( &Input, offset );
|
||||
|
||||
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_fan" ) ) {
|
||||
|
||||
simulation::Region->insert_shape(
|
||||
scene::shape_node().deserialize(
|
||||
Input, nodedata ),
|
||||
Scratchpad,
|
||||
true );
|
||||
if( false == Scratchpad.binary.terrain ) {
|
||||
|
||||
simulation::Region->insert_shape(
|
||||
scene::shape_node().deserialize(
|
||||
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" )
|
||||
|| ( nodedata.type == "line_strip" )
|
||||
|| ( nodedata.type == "line_loop" ) ) {
|
||||
|
||||
simulation::Region->insert_lines(
|
||||
scene::lines_node().deserialize(
|
||||
Input, nodedata ),
|
||||
Scratchpad );
|
||||
if( false == Scratchpad.binary.terrain ) {
|
||||
|
||||
simulation::Region->insert_lines(
|
||||
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" ) {
|
||||
|
||||
@@ -448,18 +466,18 @@ state_manager::deserialize_origin( cParser &Input, scene::scratch_data &Scratchp
|
||||
>> offset.y
|
||||
>> offset.z;
|
||||
// sumowanie całkowitego przesunięcia
|
||||
Scratchpad.location_offset.emplace(
|
||||
Scratchpad.location.offset.emplace(
|
||||
offset + (
|
||||
Scratchpad.location_offset.empty() ?
|
||||
Scratchpad.location.offset.empty() ?
|
||||
glm::dvec3() :
|
||||
Scratchpad.location_offset.top() ) );
|
||||
Scratchpad.location.offset.top() ) );
|
||||
}
|
||||
|
||||
void
|
||||
state_manager::deserialize_endorigin( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||
|
||||
if( false == Scratchpad.location_offset.empty() ) {
|
||||
Scratchpad.location_offset.pop();
|
||||
if( false == Scratchpad.location.offset.empty() ) {
|
||||
Scratchpad.location.offset.pop();
|
||||
}
|
||||
else {
|
||||
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
|
||||
>> Scratchpad.location_rotation.x
|
||||
>> Scratchpad.location_rotation.y
|
||||
>> Scratchpad.location_rotation.z;
|
||||
>> Scratchpad.location.rotation.x
|
||||
>> Scratchpad.location.rotation.y
|
||||
>> Scratchpad.location.rotation.z;
|
||||
}
|
||||
|
||||
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
|
||||
auto *track = new TTrack( Nodedata );
|
||||
Math3D::vector3 offset = (
|
||||
Scratchpad.location_offset.empty() ?
|
||||
Scratchpad.location.offset.empty() ?
|
||||
Math3D::vector3() :
|
||||
Math3D::vector3(
|
||||
Scratchpad.location_offset.top().x,
|
||||
Scratchpad.location_offset.top().y,
|
||||
Scratchpad.location_offset.top().z ) );
|
||||
Scratchpad.location.offset.top().x,
|
||||
Scratchpad.location.offset.top().y,
|
||||
Scratchpad.location.offset.top().z ) );
|
||||
track->Load( &Input, offset );
|
||||
|
||||
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
|
||||
auto *traction = new TTraction( Nodedata );
|
||||
auto offset = (
|
||||
Scratchpad.location_offset.empty() ?
|
||||
Scratchpad.location.offset.empty() ?
|
||||
glm::dvec3() :
|
||||
Scratchpad.location_offset.top() );
|
||||
Scratchpad.location.offset.top() );
|
||||
traction->Load( &Input, offset );
|
||||
|
||||
return traction;
|
||||
@@ -670,7 +688,7 @@ state_manager::deserialize_model( cParser &Input, scene::scratch_data &Scratchpa
|
||||
>> rotation.y;
|
||||
|
||||
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 ) ) {
|
||||
// model nie wczytał się - ignorowanie node
|
||||
@@ -838,12 +856,12 @@ state_manager::skip_until( cParser &Input, std::string const &Token ) {
|
||||
glm::dvec3
|
||||
state_manager::transform( glm::dvec3 Location, scene::scratch_data const &Scratchpad ) {
|
||||
|
||||
if( Scratchpad.location_rotation != glm::vec3( 0, 0, 0 ) ) {
|
||||
auto const rotation = glm::radians( Scratchpad.location_rotation );
|
||||
if( Scratchpad.location.rotation != glm::vec3( 0, 0, 0 ) ) {
|
||||
auto const rotation = glm::radians( Scratchpad.location.rotation );
|
||||
Location = glm::rotateY<double>( Location, rotation.y ); // Ra 2014-11: uwzględnienie rotacji
|
||||
}
|
||||
if( false == Scratchpad.location_offset.empty() ) {
|
||||
Location += Scratchpad.location_offset.top();
|
||||
if( false == Scratchpad.location.offset.empty() ) {
|
||||
Location += Scratchpad.location.offset.top();
|
||||
}
|
||||
return Location;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
private:
|
||||
// methods
|
||||
// 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_camera( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
void deserialize_config( cParser &Input, scene::scratch_data &Scratchpad );
|
||||
|
||||
Reference in New Issue
Block a user