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

Merge branch 'tmj-dev' into lua

This commit is contained in:
milek7
2017-10-31 14:01:53 +01:00
26 changed files with 745 additions and 249 deletions

View File

@@ -413,14 +413,6 @@ TAnimModel::TAnimModel( scene::node_data const &Nodedata ) : basic_node( Nodedat
} }
} }
TAnimModel::TAnimModel() {
// TODO: wrap these in a tuple and move to underlying model
for( int index = 0; index < iMaxNumLights; ++index ) {
LightsOn[index] = LightsOff[index] = nullptr; // normalnie nie ma
lsLights[index] = ls_Off; // a jeśli są, to wyłączone
}
}
TAnimModel::~TAnimModel() TAnimModel::~TAnimModel()
{ {
delete pAdvanced; // nie ma zaawansowanej animacji delete pAdvanced; // nie ma zaawansowanej animacji

View File

@@ -126,7 +126,6 @@ class TAnimModel : public editor::basic_node {
public: public:
// constructors // constructors
TAnimModel( scene::node_data const &Nodedata ); TAnimModel( scene::node_data const &Nodedata );
TAnimModel();
// destructor // destructor
~TAnimModel(); ~TAnimModel();
// methods // methods

View File

@@ -141,5 +141,5 @@ include_directories(${libserialport_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${libserialport_LIBRARY}) target_link_libraries(${PROJECT_NAME} ${libserialport_LIBRARY})
if (UNIX) if (UNIX)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -g") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
endif() endif()

View File

@@ -4326,11 +4326,11 @@ TController::UpdateSituation(double dt) {
vehicle->fTrackBlock ); vehicle->fTrackBlock );
double k = coupler->Connected->Vel; // prędkość pojazdu z przodu (zakładając, double k = coupler->Connected->Vel; // prędkość pojazdu z przodu (zakładając,
// że jedzie w tę samą stronę!!!) // że jedzie w tę samą stronę!!!)
if( k < vel + 10 ) { if( k - vel < 10 ) {
// porównanie modułów prędkości [km/h] // porównanie modułów prędkości [km/h]
// zatroszczyć się trzeba, jeśli tamten nie jedzie znacząco szybciej // zatroszczyć się trzeba, jeśli tamten nie jedzie znacząco szybciej
double const distance = vehicle->fTrackBlock - fMaxProximityDist - ( fBrakeDist * 1.15 ); // odległość bezpieczna zależy od prędkości double const distance = vehicle->fTrackBlock - fMaxProximityDist - ( fBrakeDist * 1.15 ); // odległość bezpieczna zależy od prędkości
if( distance < 0 ) { if( distance < 0.0 ) {
// jeśli odległość jest zbyt mała // jeśli odległość jest zbyt mała
if( k < 10.0 ) // k - prędkość tego z przodu if( k < 10.0 ) // k - prędkość tego z przodu
{ // jeśli tamten porusza się z niewielką prędkością albo stoi { // jeśli tamten porusza się z niewielką prędkością albo stoi
@@ -4539,10 +4539,19 @@ TController::UpdateSituation(double dt) {
*/ */
if( VelNext == 0.0 ) { if( VelNext == 0.0 ) {
if( mvOccupied->CategoryFlag & 1 ) { if( mvOccupied->CategoryFlag & 1 ) {
// hamowanie tak, aby stanąć // trains
VelDesired = VelNext; if( ( OrderCurrentGet() & Shunt )
AccDesired = ( VelNext * VelNext - vel * vel ) / ( 25.92 * ( ActualProximityDist + 0.1 - 0.5*fMinProximityDist ) ); && ( pVehicles[0]->fTrackBlock < 50.0 ) ) {
AccDesired = std::min( AccDesired, fAccThreshold ); // crude detection of edge case, if approaching another vehicle coast slowly until min distance
// this should allow to bunch up trainsets more on sidings
VelDesired = Global::Min0RSpeed( VelDesired, 5.0 );
}
else {
// hamowanie tak, aby stanąć
VelDesired = VelNext;
AccDesired = ( VelNext * VelNext - vel * vel ) / ( 25.92 * ( ActualProximityDist + 0.1 - 0.5*fMinProximityDist ) );
AccDesired = std::min( AccDesired, fAccThreshold );
}
} }
else { else {
// for cars (and others) coast at low speed until we hit min proximity range // for cars (and others) coast at low speed until we hit min proximity range

View File

@@ -1463,7 +1463,7 @@ void TDynamicObject::ABuScanObjects( int Direction, double Distance )
if( distance < 100.0 ) { if( distance < 100.0 ) {
// at short distances start to calculate range between couplers directly // at short distances start to calculate range between couplers directly
// odległość do najbliższego pojazdu w linii prostej // odległość do najbliższego pojazdu w linii prostej
fTrackBlock = std::min( fTrackBlock, MoverParameters->Couplers[ mycoupler ].CoupleDist ); fTrackBlock = MoverParameters->Couplers[ mycoupler ].CoupleDist;
} }
if( ( false == TestFlag( track->iCategoryFlag, 1 ) ) if( ( false == TestFlag( track->iCategoryFlag, 1 ) )
&& ( distance > 50.0 ) ) { && ( distance > 50.0 ) ) {
@@ -2618,14 +2618,14 @@ bool TDynamicObject::Update(double dt, double dt1)
// if (Global::bLiveTraction) // if (Global::bLiveTraction)
{ // Ra 2013-12: to niżej jest chyba trochę bez sensu { // Ra 2013-12: to niżej jest chyba trochę bez sensu
double v = MoverParameters->PantRearVolt; double v = MoverParameters->PantRearVolt;
if (v == 0.0) if (v == 0.0) {
{
v = MoverParameters->PantFrontVolt; v = MoverParameters->PantFrontVolt;
if (v == 0.0) if( v == 0.0 ) {
if ((MoverParameters->TrainType & (dt_EZT | dt_ET40 | dt_ET41 | dt_ET42)) && if( MoverParameters->TrainType & ( dt_EZT | dt_ET40 | dt_ET41 | dt_ET42 ) ) {
MoverParameters->EngineType != // dwuczłony mogą mieć sprzęg WN
ElectricInductionMotor) // dwuczłony mogą mieć sprzęg WN
v = MoverParameters->GetTrainsetVoltage(); // ostatnia szansa v = MoverParameters->GetTrainsetVoltage(); // ostatnia szansa
}
}
} }
if (v != 0.0) if (v != 0.0)
{ // jeśli jest zasilanie { // jeśli jest zasilanie
@@ -2640,21 +2640,21 @@ bool TDynamicObject::Update(double dt, double dt1)
if( MoverParameters->Vel > 0.5 ) { if( MoverParameters->Vel > 0.5 ) {
// jeśli jedzie // jeśli jedzie
// Ra 2014-07: doraźna blokada logowania zimnych lokomotyw - zrobić to trzeba inaczej // Ra 2014-07: doraźna blokada logowania zimnych lokomotyw - zrobić to trzeba inaczej
if( MoverParameters->PantFrontUp || MoverParameters->PantRearUp ) if( MoverParameters->PantFrontUp
// if (NoVoltTime>0.02) //tu można ograniczyć czas rozłączenia || MoverParameters->PantRearUp ) {
// if (DebugModeFlag) //logowanie nie zawsze
if( ( MoverParameters->Mains ) if( ( MoverParameters->Mains )
&& ( ( MoverParameters->EngineType != ElectricInductionMotor ) && ( MoverParameters->GetTrainsetVoltage() < 0.1f ) ) {
|| ( MoverParameters->GetTrainsetVoltage() < 0.1f ) ) ) { // Ra 15-01: logować tylko, jeśli WS załączony
// Ra 15-01: logować tylko, jeśli WS załączony // yB 16-03: i nie jest to asynchron zasilany z daleka
// yB 16-03: i nie jest to asynchron zasilany z daleka // Ra 15-01: bezwzględne współrzędne pantografu nie są dostępne,
// Ra 15-01: bezwzględne współrzędne pantografu nie są dostępne, // więc lepiej się tego nie zaloguje
// więc lepiej się tego nie zaloguje
ErrorLog( ErrorLog(
"Bad traction: " + MoverParameters->Name "Bad traction: " + MoverParameters->Name
+ " lost power for " + to_string( NoVoltTime, 2 ) + " sec. at " + " lost power for " + to_string( NoVoltTime, 2 ) + " sec. at "
+ to_string( glm::dvec3{ vPosition } ) ); + to_string( glm::dvec3{ vPosition } ) );
} }
}
} }
// Ra 2F1H: nie było sensu wpisywać tu zera po upływie czasu, bo zmienna była // Ra 2F1H: nie było sensu wpisywać tu zera po upływie czasu, bo zmienna była
// tymczasowa, a napięcie zerowane od razu // tymczasowa, a napięcie zerowane od razu
@@ -3521,7 +3521,7 @@ void TDynamicObject::RenderSounds()
// McZapkie-010302: ulepszony dzwiek silnika // McZapkie-010302: ulepszony dzwiek silnika
double freq; double freq;
double vol = 0; double vol = 0;
double dt = Timer::GetDeltaTime(); double dt = Timer::GetDeltaRenderTime();
// double sounddist; // double sounddist;
// sounddist=SquareMagnitude(Global::pCameraPosition-vPosition); // sounddist=SquareMagnitude(Global::pCameraPosition-vPosition);

View File

@@ -143,10 +143,10 @@ TGauge::Load_mapping( cParser &Input ) {
sound_man->create_sound(value) : sound_man->create_sound(value) :
nullptr ); nullptr );
} }
else if( key.find( "sound" ) == 0 ) { else if( key.compare( 0, std::min<std::size_t>( key.size(), 5 ), "sound" ) == 0 ) {
// sounds assigned to specific gauge values, defined by key soundFoo: where Foo = value // sounds assigned to specific gauge values, defined by key soundFoo: where Foo = value
auto const indexstart = key.find_first_of( "-1234567890" ); auto const indexstart { key.find_first_of( "-1234567890" ) };
auto const indexend = key.find_first_not_of( "-1234567890", indexstart ); auto const indexend { key.find_first_not_of( "-1234567890", indexstart ) };
if( indexstart != std::string::npos ) { if( indexstart != std::string::npos ) {
m_soundfxvalues.emplace( m_soundfxvalues.emplace(
std::stoi( key.substr( indexstart, indexend - indexstart ) ), std::stoi( key.substr( indexstart, indexend - indexstart ) ),

View File

@@ -4697,14 +4697,6 @@ double TMoverParameters::TractionForce(double dt)
dmoment = eimv[eimv_Fful]; dmoment = eimv[eimv_Fful];
// NOTE: the commands to operate the sandbox are likely to conflict with other similar ai decisions // NOTE: the commands to operate the sandbox are likely to conflict with other similar ai decisions
// TODO: gather these in single place so they can be resolved together // TODO: gather these in single place so they can be resolved together
if( ( std::abs( ( PosRatio + 9.66 * dizel_fill ) * dmoment * 100 ) > 0.95 * Adhesive( RunningTrack.friction ) * TotalMassxg ) ) {
PosRatio = 0;
tmp = 4;
} // przeciwposlizg
if( ( std::abs( ( PosRatio + 9.80 * dizel_fill ) * dmoment * 100 ) > 0.95 * Adhesive( RunningTrack.friction ) * TotalMassxg ) ) {
PosRatio = 0;
tmp = 9;
} // przeciwposlizg
if( ( SlippingWheels ) ) { if( ( SlippingWheels ) ) {
PosRatio = 0; PosRatio = 0;
tmp = 9; tmp = 9;

View File

@@ -19,18 +19,6 @@ http://mozilla.org/MPL/2.0/.
#include "simulation.h" #include "simulation.h"
#include "Logs.h" #include "Logs.h"
//---------------------------------------------------------------------------
// legacy constructor
TMemCell::TMemCell(vector3 *p)
{
fValue1 = fValue2 = 0;
location(
p ? *p : vector3() ); // ustawienie współrzędnych, bo do TGroundNode nie ma dostępu
bCommand = false; // komenda wysłana
OnSent = NULL;
}
TMemCell::TMemCell( scene::node_data const &Nodedata ) : basic_node( Nodedata ) {} TMemCell::TMemCell( scene::node_data const &Nodedata ) : basic_node( Nodedata ) {}
void TMemCell::UpdateValues( std::string const &szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask ) void TMemCell::UpdateValues( std::string const &szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask )

View File

@@ -20,8 +20,6 @@ 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 );
// legacy constructor
TMemCell( Math3D::vector3 *p );
void void
UpdateValues( std::string const &szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask ); UpdateValues( std::string const &szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask );

View File

@@ -130,12 +130,6 @@ void TIsolated::Modify(int i, TDynamicObject *o)
// tworzenie nowego odcinka ruchu // tworzenie nowego odcinka ruchu
TTrack::TTrack( scene::node_data const &Nodedata ) : basic_node( Nodedata ) {} TTrack::TTrack( scene::node_data const &Nodedata ) : basic_node( Nodedata ) {}
// legacy constructor
TTrack::TTrack( std::string Name ) {
m_name = Name;
}
TTrack::~TTrack() TTrack::~TTrack()
{ // likwidacja odcinka { // likwidacja odcinka
if( eType == tt_Cross ) { if( eType == tt_Cross ) {
@@ -175,7 +169,9 @@ TTrack::sort_by_material( TTrack const *Left, TTrack const *Right ) {
TTrack * TTrack::Create400m(int what, double dx) TTrack * TTrack::Create400m(int what, double dx)
{ // tworzenie toru do wstawiania taboru podczas konwersji na E3D { // tworzenie toru do wstawiania taboru podczas konwersji na E3D
auto *trk = new TTrack( "auto_400m" ); scene::node_data nodedata;
nodedata.name = "auto_400m"; // track isn't visible so only name is needed
auto *trk = new TTrack( nodedata );
trk->m_visible = false; // nie potrzeba pokazywać, zresztą i tak nie ma tekstur trk->m_visible = false; // nie potrzeba pokazywać, zresztą i tak nie ma tekstur
trk->iCategoryFlag = what; // taki sam typ plus informacja, że dodatkowy trk->iCategoryFlag = what; // taki sam typ plus informacja, że dodatkowy
trk->Init(); // utworzenie segmentu trk->Init(); // utworzenie segmentu
@@ -191,7 +187,9 @@ TTrack * TTrack::NullCreate(int dir)
TTrack TTrack
*trk { nullptr }, *trk { nullptr },
*trk2 { nullptr }; *trk2 { nullptr };
trk = new TTrack( "auto_null" ); scene::node_data nodedata;
nodedata.name = "auto_null"; // track isn't visible so only name is needed
trk = new TTrack( nodedata );
trk->m_visible = false; // nie potrzeba pokazywać, zresztą i tak nie ma tekstur trk->m_visible = false; // nie potrzeba pokazywać, zresztą i tak nie ma tekstur
trk->iCategoryFlag = (iCategoryFlag & 15) | 0x80; // taki sam typ plus informacja, że dodatkowy trk->iCategoryFlag = (iCategoryFlag & 15) | 0x80; // taki sam typ plus informacja, że dodatkowy
float r1, r2; float r1, r2;
@@ -234,7 +232,7 @@ TTrack * TTrack::NullCreate(int dir)
trk->fVelocity = 20.0; // zawracanie powoli trk->fVelocity = 20.0; // zawracanie powoli
trk->fRadius = 20.0; // promień, aby się dodawało do tabelki prędkości i liczyło narastająco trk->fRadius = 20.0; // promień, aby się dodawało do tabelki prędkości i liczyło narastająco
trk->Init(); // utworzenie segmentu trk->Init(); // utworzenie segmentu
trk2 = new TTrack( "auto_null" ); trk2 = new TTrack( nodedata );
trk2->iCategoryFlag = trk2->iCategoryFlag =
(iCategoryFlag & 15) | 0x80; // taki sam typ plus informacja, że dodatkowy (iCategoryFlag & 15) | 0x80; // taki sam typ plus informacja, że dodatkowy
trk2->m_visible = false; trk2->m_visible = false;

View File

@@ -185,8 +185,6 @@ public:
TGroundNode *nFouling[ 2 ] = { nullptr, nullptr }; // współrzędne ukresu albo oporu kozła TGroundNode *nFouling[ 2 ] = { nullptr, nullptr }; // współrzędne ukresu albo oporu kozła
TTrack( scene::node_data const &Nodedata ); TTrack( scene::node_data const &Nodedata );
// legacy constructor
TTrack( std::string Name );
virtual ~TTrack(); virtual ~TTrack();
void Init(); void Init();

View File

@@ -91,11 +91,6 @@ sekcji z sąsiedniego przęsła).
*/ */
TTraction::TTraction( scene::node_data const &Nodedata ) : basic_node( Nodedata ) {} TTraction::TTraction( scene::node_data const &Nodedata ) : basic_node( Nodedata ) {}
// legacy constructor
TTraction::TTraction( std::string Name ) {
m_name = Name;
}
glm::dvec3 LoadPoint( cParser &Input ) { glm::dvec3 LoadPoint( cParser &Input ) {
// pobranie współrzędnych punktu // pobranie współrzędnych punktu

View File

@@ -54,8 +54,6 @@ class TTraction : public editor::basic_node {
geometry_handle m_geometry; geometry_handle m_geometry;
TTraction( scene::node_data const &Nodedata ); TTraction( scene::node_data const &Nodedata );
// legacy constructor
TTraction( std::string Name );
void Load( cParser *parser, glm::dvec3 const &pOrigin ); void Load( cParser *parser, glm::dvec3 const &pOrigin );
// set origin point // set origin point

View File

@@ -22,10 +22,6 @@ http://mozilla.org/MPL/2.0/.
TTractionPowerSource::TTractionPowerSource( scene::node_data const &Nodedata ) : basic_node( Nodedata ) {} TTractionPowerSource::TTractionPowerSource( scene::node_data const &Nodedata ) : basic_node( Nodedata ) {}
// legacy constructor // legacy constructor
TTractionPowerSource::TTractionPowerSource( std::string Name ) {
m_name = Name;
}
void TTractionPowerSource::Init(double const u, double const i) void TTractionPowerSource::Init(double const u, double const i)
{ // ustawianie zasilacza przy braku w scenerii { // ustawianie zasilacza przy braku w scenerii

View File

@@ -40,8 +40,6 @@ public:
bool bSection = false; // czy jest sekcją bool bSection = false; // czy jest sekcją
TTractionPowerSource( scene::node_data const &Nodedata ); TTractionPowerSource( scene::node_data const &Nodedata );
// legacy constructor
TTractionPowerSource( std::string Name );
void Init(double const u, double const i); void Init(double const u, double const i);
bool Load(cParser *parser); bool Load(cParser *parser);

View File

@@ -1039,7 +1039,7 @@ bool TWorld::Update() {
} }
simulation::Events.update(); simulation::Events.update();
simulation::Region->update(); simulation::Region->update_events();
simulation::Lights.update(); simulation::Lights.update();
// render time routines follow: // render time routines follow:
@@ -1083,6 +1083,7 @@ bool TWorld::Update() {
Timer::subsystem.sim_total.stop(); Timer::subsystem.sim_total.stop();
simulation::Region->update_sounds();
GfxRenderer.Update( dt ); GfxRenderer.Update( dt );
ResourceSweep(); ResourceSweep();

273
scene.cpp
View File

@@ -14,34 +14,11 @@ http://mozilla.org/MPL/2.0/.
#include "Globals.h" #include "Globals.h"
#include "Timer.h" #include "Timer.h"
#include "Logs.h" #include "Logs.h"
#include "sn_utils.h"
namespace scene { namespace scene {
// legacy method, updates sounds and polls event launchers within radius around specified point std::string const EU07_FILEEXTENSION_REGION { ".sbt" };
void
basic_cell::update() {
// event launchers
for( auto *launcher : m_eventlaunchers ) {
if( ( true == launcher->check_conditions() )
&& ( SquareMagnitude( launcher->location() - Global::pCameraPosition ) < launcher->dRadius ) ) {
WriteLog( "Eventlauncher " + launcher->name() );
if( ( true == Global::shiftState )
&& ( launcher->Event2 != nullptr ) ) {
simulation::Events.AddToQuery( launcher->Event2, nullptr );
}
else if( launcher->Event1 ) {
simulation::Events.AddToQuery( launcher->Event1, nullptr );
}
}
}
// TBD, TODO: move to sound renderer
for( auto *path : m_paths ) {
// dźwięki pojazdów, również niewidocznych
path->RenderDynSounds();
}
}
// 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
@@ -120,6 +97,37 @@ basic_cell::update_traction( TDynamicObject *Vehicle, int const Pantographindex
} }
} }
// legacy method, updates sounds and polls event launchers within radius around specified point
void
basic_cell::update_events() {
// event launchers
for( auto *launcher : m_eventlaunchers ) {
if( ( true == launcher->check_conditions() )
&& ( SquareMagnitude( launcher->location() - Global::pCameraPosition ) < launcher->dRadius ) ) {
WriteLog( "Eventlauncher " + launcher->name() );
if( ( true == Global::shiftState )
&& ( launcher->Event2 != nullptr ) ) {
simulation::Events.AddToQuery( launcher->Event2, nullptr );
}
else if( launcher->Event1 ) {
simulation::Events.AddToQuery( launcher->Event1, nullptr );
}
}
}
}
// legacy method, updates sounds and polls event launchers within radius around specified point
void
basic_cell::update_sounds() {
// TBD, TODO: move to sound renderer
for( auto *path : m_paths ) {
// dźwięki pojazdów, również niewidocznych
path->RenderDynSounds();
}
}
// legacy method, triggers radio-stop procedure for all vehicles located on paths in the cell // legacy method, triggers radio-stop procedure for all vehicles located on paths in the cell
void void
basic_cell::radio_stop() { basic_cell::radio_stop() {
@@ -158,6 +166,56 @@ basic_cell::RaAnimate( unsigned int const Framestamp ) {
m_framestamp = Framestamp; m_framestamp = Framestamp;
} }
// sends content of the class to provided stream
void
basic_cell::serialize( std::ostream &Output ) const {
// region file version 0, cell data
// bounding area
m_area.serialize( Output );
// NOTE: cell activation flag is set dynamically on load
// cell shapes
// shape count followed by opaque shape data
sn_utils::ls_uint32( Output, m_shapesopaque.size() );
for( auto const &shape : m_shapesopaque ) {
shape.serialize( Output );
}
// shape count followed by translucent shape data
sn_utils::ls_uint32( Output, m_shapestranslucent.size() );
for( auto const &shape : m_shapestranslucent ) {
shape.serialize( Output );
}
// cell lines
// line count followed by lines data
sn_utils::ls_uint32( Output, m_lines.size() );
for( auto const &lines : m_lines ) {
lines.serialize( Output );
}
}
// restores content of the class from provided stream
void
basic_cell::deserialize( std::istream &Input ) {
// region file version 0, cell data
// bounding area
m_area.deserialize( Input );
// cell shapes
// shape count followed by opaque shape data
auto itemcount { sn_utils::ld_uint32( Input ) };
while( itemcount-- ) {
m_shapesopaque.emplace_back( shape_node().deserialize( Input ) );
}
itemcount = sn_utils::ld_uint32( Input );
while( itemcount-- ) {
m_shapestranslucent.emplace_back( shape_node().deserialize( Input ) );
}
itemcount = sn_utils::ld_uint32( Input );
while( itemcount-- ) {
m_lines.emplace_back( lines_node().deserialize( Input ) );
}
}
// adds provided shape to the cell // adds provided shape to the cell
void void
basic_cell::insert( shape_node Shape ) { basic_cell::insert( shape_node Shape ) {
@@ -469,19 +527,6 @@ basic_cell::enclose_area( editor::basic_node *Node ) {
// legacy method, updates sounds and polls event launchers within radius around specified point
void
basic_section::update( glm::dvec3 const &Location, float const Radius ) {
for( auto &cell : m_cells ) {
if( glm::length2( cell.area().center - Location ) < ( ( cell.area().radius + Radius ) * ( cell.area().radius + Radius ) ) ) {
// we reject cells which aren't within our area of interest
cell.update();
}
}
}
// legacy method, finds and assigns traction piece(s) to pantographs of provided vehicle // legacy method, finds and assigns traction piece(s) to pantographs of provided vehicle
void void
basic_section::update_traction( TDynamicObject *Vehicle, int const Pantographindex ) { basic_section::update_traction( TDynamicObject *Vehicle, int const Pantographindex ) {
@@ -504,6 +549,32 @@ basic_section::update_traction( TDynamicObject *Vehicle, int const Pantographind
} }
} }
// legacy method, polls event launchers within radius around specified point
void
basic_section::update_events( glm::dvec3 const &Location, float const Radius ) {
for( auto &cell : m_cells ) {
if( glm::length2( cell.area().center - Location ) < ( ( cell.area().radius + Radius ) * ( cell.area().radius + Radius ) ) ) {
// we reject cells which aren't within our area of interest
cell.update_events();
}
}
}
// legacy method, updates sounds within radius around specified point
void
basic_section::update_sounds( glm::dvec3 const &Location, float const Radius ) {
for( auto &cell : m_cells ) {
if( glm::length2( cell.area().center - Location ) < ( ( cell.area().radius + Radius ) * ( cell.area().radius + Radius ) ) ) {
// we reject cells which aren't within our area of interest
cell.update_sounds();
}
}
}
// legacy method, triggers radio-stop procedure for all vehicles in 2km radius around specified location // legacy method, triggers radio-stop procedure for all vehicles in 2km radius around specified location
void void
basic_section::radio_stop( glm::dvec3 const &Location, float const Radius ) { basic_section::radio_stop( glm::dvec3 const &Location, float const Radius ) {
@@ -517,6 +588,51 @@ basic_section::radio_stop( glm::dvec3 const &Location, float const Radius ) {
} }
} }
// sends content of the class to provided stream
void
basic_section::serialize( std::ostream &Output ) const {
auto const sectionstartpos { Output.tellp() };
// region file version 0, section data
// section size
sn_utils::ls_uint32( Output, 0 );
// bounding area
m_area.serialize( Output );
// section shapes: shape count followed by shape data
sn_utils::ls_uint32( Output, m_shapes.size() );
for( auto const &shape : m_shapes ) {
shape.serialize( Output );
}
// partitioned data
for( auto const &cell : m_cells ) {
cell.serialize( Output );
}
// all done; calculate and record section size
auto const sectionendpos { Output.tellp() };
Output.seekp( sectionstartpos );
sn_utils::ls_uint32( Output, static_cast<uint32_t>( ( sizeof( uint32_t ) + ( sectionendpos - sectionstartpos ) ) ) );
Output.seekp( sectionendpos );
}
// restores content of the class from provided stream
void
basic_section::deserialize( std::istream &Input ) {
// region file version 0, section data
// bounding area
m_area.deserialize( Input );
// section shapes: shape count followed by shape data
auto shapecount { sn_utils::ld_uint32( Input ) };
while( shapecount-- ) {
m_shapes.emplace_back( shape_node().deserialize( Input ) );
}
// partitioned data
for( auto &cell : m_cells ) {
cell.deserialize( Input );
}
}
// adds provided shape to the section // adds provided shape to the section
void void
basic_section::insert( shape_node Shape ) { basic_section::insert( shape_node Shape ) {
@@ -696,14 +812,25 @@ basic_region::~basic_region() {
for( auto *section : m_sections ) { if( section != nullptr ) { delete section; } } for( auto *section : m_sections ) { if( section != nullptr ) { delete section; } }
} }
// legacy method, polls event launchers around camera
void
basic_region::update_events() {
// render events and sounds from sectors near enough to the viewer
auto const range = EU07_SECTIONSIZE; // arbitrary range
auto const &sectionlist = sections( Global::pCameraPosition, range );
for( auto *section : sectionlist ) {
section->update_events( Global::pCameraPosition, range );
}
}
// legacy method, updates sounds and polls event launchers around camera // legacy method, updates sounds and polls event launchers around camera
void void
basic_region::update() { basic_region::update_sounds() {
// render events and sounds from sectors near enough to the viewer // render events and sounds from sectors near enough to the viewer
auto const range = 2750.f; // audible range of 100 db sound auto const range = 2750.f; // audible range of 100 db sound
auto const &sectionlist = sections( Global::pCameraPosition, range ); auto const &sectionlist = sections( Global::pCameraPosition, range );
for( auto *section : sectionlist ) { for( auto *section : sectionlist ) {
section->update( Global::pCameraPosition, range ); section->update_sounds( Global::pCameraPosition, range );
} }
} }
@@ -728,15 +855,73 @@ basic_region::update_traction( TDynamicObject *Vehicle, int const Pantographinde
// stores content of the class in file with specified name // stores content of the class in file with specified name
void void
basic_region::serialize( std::string const &Scenariofile ) { basic_region::serialize( std::string const &Scenariofile ) const {
// TODO: implement
auto filename { Global::asCurrentSceneryPath + Scenariofile };
if( ( filename.rfind( '.' ) != std::string::npos )
&& ( filename.rfind( '.' ) != filename.rfind( ".." ) + 1 ) ) {
// trim extension, it's typically going to be for different file type
filename.erase( filename.rfind( '.' ) );
}
filename += EU07_FILEEXTENSION_REGION;
std::ofstream output { filename, std::ios::binary };
// region file version 0
// header: EU07SBT + version (0-255)
sn_utils::ls_uint32( output, MAKE_ID4( 'E', 'U', '0', '7' ) );
sn_utils::ls_uint32( output, MAKE_ID4( 'S', 'B', 'T', 0 ) );
// sections
// TBD, TODO: build table of sections and file offsets, if we postpone section loading until they're within range
for( auto section : m_sections ) {
// length of section data, followed by section data (if any)
if( section != nullptr ) {
section->serialize( output ); }
else {
sn_utils::ls_uint32( output, 0 ); }
}
} }
// restores content of the class from file with specified name. returns: true on success, false otherwise // restores content of the class from file with specified name. returns: true on success, false otherwise
bool bool
basic_region::deserialize( std::string const &Scenariofile ) { basic_region::deserialize( std::string const &Scenariofile ) {
// TODO: implement
return false; auto filename { Global::asCurrentSceneryPath + Scenariofile };
if( ( filename.rfind( '.' ) != std::string::npos )
&& ( filename.rfind( '.' ) != filename.rfind( ".." ) + 1 ) ) {
// trim extension, it's typically going to be for different file type
filename.erase( filename.rfind( '.' ) );
}
filename += EU07_FILEEXTENSION_REGION;
if( false == FileExists( filename ) ) {
return false;
}
// region file version 0
// file type and version check
std::ifstream input( filename, std::ios::binary );
uint32_t headermain { sn_utils::ld_uint32( input ) };
uint32_t headertype { sn_utils::ld_uint32( input ) };
if( ( headermain != MAKE_ID4( 'E', 'U', '0', '7' )
|| ( headertype != MAKE_ID4( 'S', 'B', 'T', 0 ) ) ) ) {
// wrong file type
ErrorLog( "Bad file: \"" + filename + "\" is of either unrecognized type or version" );
return false;
}
// sections
// TBD, TODO: build table of sections and file offsets, if we postpone section loading until they're within range
for( auto &section : m_sections ) {
// length of section data, followed by section data (if any)
auto const sectionsize { sn_utils::ld_uint32( input ) };
if( sectionsize != 0 ) {
section = new basic_section();
section->deserialize( input );
}
}
return true;
} }
// legacy method, links specified path piece with potential neighbours // legacy method, links specified path piece with potential neighbours

47
scene.h
View File

@@ -48,7 +48,7 @@ struct scratch_data {
float offset { 0.f }; float offset { 0.f };
float velocity { 0.f }; float velocity { 0.f };
std::vector<TDynamicObject *> vehicles; std::vector<TDynamicObject *> vehicles;
std::vector<std::int8_t> couplings; std::vector<int> couplings;
TDynamicObject * driver { nullptr }; TDynamicObject * driver { nullptr };
bool is_open { false }; bool is_open { false };
} trainset; } trainset;
@@ -64,12 +64,15 @@ class basic_cell {
public: public:
// methods // methods
// legacy method, updates sounds and polls event launchers within radius around specified point
void
update();
// 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 );
// legacy method, polls event launchers within radius around specified point
void
update_events();
// legacy method, updates sounds within radius around specified point
void
update_sounds();
// legacy method, triggers radio-stop procedure for all vehicles located on paths in the cell // legacy method, triggers radio-stop procedure for all vehicles located on paths in the cell
void void
radio_stop(); radio_stop();
@@ -79,6 +82,12 @@ public:
// legacy method, updates geometry for pieces in the animation list // legacy method, updates geometry for pieces in the animation list
void void
RaAnimate( unsigned int const Framestamp ); RaAnimate( unsigned int const Framestamp );
// sends content of the class to provided stream
void
serialize( std::ostream &Output ) const;
// restores content of the class from provided stream
void
deserialize( std::istream &Input );
// adds provided shape to the cell // adds provided shape to the cell
void void
insert( shape_node Shape ); insert( shape_node Shape );
@@ -171,15 +180,24 @@ class basic_section {
public: public:
// methods // methods
// legacy method, updates sounds and polls event launchers within radius around specified point // legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
void
update( glm::dvec3 const &Location, float const Radius );
// 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 );
// legacy method, updates sounds and polls event launchers within radius around specified point
void
update_events( glm::dvec3 const &Location, float const Radius );
// legacy method, updates sounds and polls event launchers within radius around specified point
void
update_sounds( glm::dvec3 const &Location, float const Radius );
// legacy method, triggers radio-stop procedure for all vehicles in 2km radius around specified location // legacy method, triggers radio-stop procedure for all vehicles in 2km radius around specified location
void void
radio_stop( glm::dvec3 const &Location, float const Radius ); radio_stop( glm::dvec3 const &Location, float const Radius );
// sends content of the class to provided stream
void
serialize( std::ostream &Output ) const;
// restores content of the class from provided stream
void
deserialize( std::istream &Input );
// adds provided shape to the section // adds provided shape to the section
void void
insert( shape_node Shape ); insert( shape_node Shape );
@@ -255,15 +273,18 @@ public:
// destructor // destructor
~basic_region(); ~basic_region();
// methods // methods
// legacy method, updates sounds and polls event launchers around camera // legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
void
update();
// 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 );
// legacy method, polls event launchers around camera
void
update_events();
// legacy method, updates sounds around camera
void
update_sounds();
// stores content of the class in file with specified name // stores content of the class in file with specified name
void void
serialize( std::string const &Scenariofile ); serialize( std::string const &Scenariofile ) const;
// restores content of the class from file with specified name. returns: true on success, false otherwise // restores content of the class from file with specified name. returns: true on success, false otherwise
bool bool
deserialize( std::string const &Scenariofile ); deserialize( std::string const &Scenariofile );

View File

@@ -12,10 +12,123 @@ http://mozilla.org/MPL/2.0/.
#include "renderer.h" #include "renderer.h"
#include "Logs.h" #include "Logs.h"
#include "sn_utils.h"
// stores content of the struct in provided output stream
void
lighting_data::serialize( std::ostream &Output ) const {
sn_utils::s_vec4( Output, diffuse );
sn_utils::s_vec4( Output, ambient );
sn_utils::s_vec4( Output, specular );
}
// restores content of the struct from provided input stream
void
lighting_data::deserialize( std::istream &Input ) {
diffuse = sn_utils::d_vec4( Input );
ambient = sn_utils::d_vec4( Input );
specular = sn_utils::d_vec4( Input );
}
namespace scene { namespace scene {
// restores content of the node from provded input stream // stores content of the struct in provided output stream
void
bounding_area::serialize( std::ostream &Output ) const {
// center
sn_utils::s_dvec3( Output, center );
// radius
sn_utils::ls_float32( Output, radius );
}
// restores content of the struct from provided input stream
void
bounding_area::deserialize( std::istream &Input ) {
center = sn_utils::d_dvec3( Input );
radius = sn_utils::ld_float32( Input );
}
// sends content of the struct to provided stream
void
shape_node::shapenode_data::serialize( std::ostream &Output ) const {
// bounding area
area.serialize( Output );
// visibility
sn_utils::ls_float64( Output, rangesquared_min );
sn_utils::ls_float64( Output, rangesquared_max );
sn_utils::s_bool( Output, visible );
// material
sn_utils::s_bool( Output, translucent );
// NOTE: material handle is created dynamically on load
sn_utils::s_str(
Output,
( material != null_handle ?
GfxRenderer.Material( material ).name :
"" ) );
lighting.serialize( Output );
// geometry
sn_utils::s_dvec3( Output, origin );
// NOTE: geometry handle is created dynamically on load
// vertex count, followed by vertex data
sn_utils::ls_uint32( Output, vertices.size() );
for( auto const &vertex : vertices ) {
vertex.serialize( Output );
}
}
// restores content of the struct from provided input stream
void
shape_node::shapenode_data::deserialize( std::istream &Input ) {
// bounding area
area.deserialize( Input );
// visibility
rangesquared_min = sn_utils::ld_float64( Input );
rangesquared_max = sn_utils::ld_float64( Input );
visible = sn_utils::d_bool( Input );
// material
translucent = sn_utils::d_bool( Input );
auto const materialname { sn_utils::d_str( Input ) };
if( false == materialname.empty() ) {
material = GfxRenderer.Fetch_Material( materialname );
}
lighting.deserialize( Input );
// geometry
origin = sn_utils::d_dvec3( Input );
// NOTE: geometry handle is acquired during geometry creation
// vertex data
vertices.resize( sn_utils::ld_uint32( Input ) );
for( auto &vertex : vertices ) {
vertex.deserialize( Input );
}
}
// sends content of the class to provided stream
void
shape_node::serialize( std::ostream &Output ) const {
// name
sn_utils::s_str( Output, m_name );
// node data
m_data.serialize( Output );
}
// restores content of the node from provided input stream
shape_node &
shape_node::deserialize( std::istream &Input ) {
// name
m_name = sn_utils::d_str( Input );
// node data
m_data.deserialize( Input );
return *this;
}
// restores content of the node from provided input stream
shape_node & shape_node &
shape_node::deserialize( cParser &Input, scene::node_data const &Nodedata ) { shape_node::deserialize( cParser &Input, scene::node_data const &Nodedata ) {
@@ -104,7 +217,9 @@ shape_node::deserialize( cParser &Input, scene::node_data const &Nodedata ) {
triangles, triangles,
triangle_strip, triangle_strip,
triangle_fan triangle_fan
} const nodetype = ( };
subtype const nodetype = (
Nodedata.type == "triangles" ? triangles : Nodedata.type == "triangles" ? triangles :
Nodedata.type == "triangle_strip" ? triangle_strip : Nodedata.type == "triangle_strip" ? triangle_strip :
triangle_fan ); triangle_fan );
@@ -320,6 +435,72 @@ shape_node::compute_radius() {
// sends content of the struct to provided stream
void
lines_node::linesnode_data::serialize( std::ostream &Output ) const {
// bounding area
area.serialize( Output );
// visibility
sn_utils::ls_float64( Output, rangesquared_min );
sn_utils::ls_float64( Output, rangesquared_max );
sn_utils::s_bool( Output, visible );
// material
sn_utils::ls_float32( Output, line_width );
lighting.serialize( Output );
// geometry
sn_utils::s_dvec3( Output, origin );
// NOTE: geometry handle is created dynamically on load
// vertex count, followed by vertex data
sn_utils::ls_uint32( Output, vertices.size() );
for( auto const &vertex : vertices ) {
vertex.serialize( Output );
}
}
// restores content of the struct from provided input stream
void
lines_node::linesnode_data::deserialize( std::istream &Input ) {
// bounding area
area.deserialize( Input );
// visibility
rangesquared_min = sn_utils::ld_float64( Input );
rangesquared_max = sn_utils::ld_float64( Input );
visible = sn_utils::d_bool( Input );
// material
line_width = sn_utils::ld_float32( Input );
lighting.deserialize( Input );
// geometry
origin = sn_utils::d_dvec3( Input );
// NOTE: geometry handle is acquired during geometry creation
// vertex data
vertices.resize( sn_utils::ld_uint32( Input ) );
for( auto &vertex : vertices ) {
vertex.deserialize( Input );
}
}
// sends content of the class to provided stream
void
lines_node::serialize( std::ostream &Output ) const {
// name
sn_utils::s_str( Output, m_name );
// node data
m_data.serialize( Output );
}
// restores content of the node from provided input stream
lines_node &
lines_node::deserialize( std::istream &Input ) {
// name
m_name = sn_utils::d_str( Input );
// node data
m_data.deserialize( Input );
return *this;
}
// restores content of the node from provded input stream // restores content of the node from provded input stream
lines_node & lines_node &
lines_node::deserialize( cParser &Input, scene::node_data const &Nodedata ) { lines_node::deserialize( cParser &Input, scene::node_data const &Nodedata ) {
@@ -350,7 +531,9 @@ lines_node::deserialize( cParser &Input, scene::node_data const &Nodedata ) {
lines, lines,
line_strip, line_strip,
line_loop line_loop
} const nodetype = ( };
subtype const nodetype = (
Nodedata.type == "lines" ? lines : Nodedata.type == "lines" ? lines :
Nodedata.type == "line_strip" ? line_strip : Nodedata.type == "line_strip" ? line_strip :
line_loop ); line_loop );

View File

@@ -22,6 +22,13 @@ struct lighting_data {
glm::vec4 diffuse { 0.8f, 0.8f, 0.8f, 1.0f }; glm::vec4 diffuse { 0.8f, 0.8f, 0.8f, 1.0f };
glm::vec4 ambient { 0.2f, 0.2f, 0.2f, 1.0f }; glm::vec4 ambient { 0.2f, 0.2f, 0.2f, 1.0f };
glm::vec4 specular { 0.0f, 0.0f, 0.0f, 1.0f }; glm::vec4 specular { 0.0f, 0.0f, 0.0f, 1.0f };
// stores content of the struct in provided output stream
void
serialize( std::ostream &Output ) const;
// restores content of the struct from provided input stream
void
deserialize( std::istream &Input );
}; };
inline inline
@@ -29,12 +36,14 @@ bool
operator==( lighting_data const &Left, lighting_data const &Right ) { operator==( lighting_data const &Left, lighting_data const &Right ) {
return ( ( Left.diffuse == Right.diffuse ) return ( ( Left.diffuse == Right.diffuse )
&& ( Left.ambient == Right.ambient ) && ( Left.ambient == Right.ambient )
&& ( Left.specular == Right.specular ) ); } && ( Left.specular == Right.specular ) );
}
inline inline
bool bool
operator!=( lighting_data const &Left, lighting_data const &Right ) { operator!=( lighting_data const &Left, lighting_data const &Right ) {
return !( Left == Right ); } return !( Left == Right );
}
namespace scene { namespace scene {
@@ -48,27 +57,13 @@ struct bounding_area {
center( Center ), center( Center ),
radius( Radius ) radius( Radius )
{} {}
// stores content of the struct in provided output stream
void
serialize( std::ostream &Output ) const;
// restores content of the struct from provided input stream
void
deserialize( std::istream &Input );
}; };
/*
enum nodetype {
unknown,
model,
triangles,
lines,
dynamic,
track,
traction,
powersource,
sound,
memorycell,
eventlauncher
};
class node_manager {
};
*/
struct node_data { struct node_data {
@@ -86,23 +81,37 @@ class shape_node {
public: public:
// types // types
struct shapenode_data { struct shapenode_data {
// members:
// placement and visibility // placement and visibility
scene::bounding_area area; // bounding area, in world coordinates scene::bounding_area area; // bounding area, in world coordinates
bool visible { true }; // visibility flag
double rangesquared_min { 0.0 }; // visibility range, min double rangesquared_min { 0.0 }; // visibility range, min
double rangesquared_max { 0.0 }; // visibility range, max double rangesquared_max { 0.0 }; // visibility range, max
bool visible { true }; // visibility flag
// material data // material data
material_handle material { 0 };
lighting_data lighting;
bool translucent { false }; // whether opaque or translucent bool translucent { false }; // whether opaque or translucent
material_handle material { null_handle };
lighting_data lighting;
// geometry data // geometry data
std::vector<world_vertex> vertices; // world space source data of the geometry
glm::dvec3 origin; // world position of the relative coordinate system origin glm::dvec3 origin; // world position of the relative coordinate system origin
geometry_handle geometry { 0, 0 }; // relative origin-centered chunk of geometry held by gfx renderer geometry_handle geometry { 0, 0 }; // relative origin-centered chunk of geometry held by gfx renderer
std::vector<world_vertex> vertices; // world space source data of the geometry
// methods:
// sends content of the struct to provided stream
void
serialize( std::ostream &Output ) const;
// restores content of the struct from provided input stream
void
deserialize( std::istream &Input );
}; };
// methods // methods
// restores content of the node from provded input stream // sends content of the class to provided stream
void
serialize( std::ostream &Output ) const;
// restores content of the node from provided input stream
shape_node &
deserialize( std::istream &Input );
// restores content of the node from provided input stream
shape_node & shape_node &
deserialize( cParser &Input, scene::node_data const &Nodedata ); deserialize( cParser &Input, scene::node_data const &Nodedata );
// imports data from provided submodel // imports data from provided submodel
@@ -119,16 +128,13 @@ public:
compute_radius(); compute_radius();
// set visibility // set visibility
void void
visible( bool State ) { visible( bool State );
m_data.visible = State; }
// set origin point // set origin point
void void
origin( glm::dvec3 Origin ) { origin( glm::dvec3 Origin );
m_data.origin = Origin; }
// data access // data access
shapenode_data const & shapenode_data const &
data() const { data() const;
return m_data; }
private: private:
// members // members
@@ -136,6 +142,27 @@ private:
shapenode_data m_data; shapenode_data m_data;
}; };
// set visibility
inline
void
shape_node::visible( bool State ) {
m_data.visible = State;
}
// set origin point
inline
void
shape_node::origin( glm::dvec3 Origin ) {
m_data.origin = Origin;
}
// data access
inline
shape_node::shapenode_data const &
shape_node::data() const {
return m_data;
}
// holds a group of untextured lines // holds a group of untextured lines
class lines_node { class lines_node {
@@ -144,22 +171,36 @@ class lines_node {
public: public:
// types // types
struct linesnode_data { struct linesnode_data {
// members:
// placement and visibility // placement and visibility
scene::bounding_area area; // bounding area, in world coordinates scene::bounding_area area; // bounding area, in world coordinates
bool visible { true }; // visibility flag
double rangesquared_min { 0.0 }; // visibility range, min double rangesquared_min { 0.0 }; // visibility range, min
double rangesquared_max { 0.0 }; // visibility range, max double rangesquared_max { 0.0 }; // visibility range, max
bool visible { true }; // visibility flag
// material data // material data
float line_width { 1.f }; // thickness of stored lines
lighting_data lighting; lighting_data lighting;
float line_width; // thickness of stored lines
// geometry data // geometry data
std::vector<world_vertex> vertices; // world space source data of the geometry
glm::dvec3 origin; // world position of the relative coordinate system origin glm::dvec3 origin; // world position of the relative coordinate system origin
geometry_handle geometry { 0, 0 }; // relative origin-centered chunk of geometry held by gfx renderer geometry_handle geometry { 0, 0 }; // relative origin-centered chunk of geometry held by gfx renderer
std::vector<world_vertex> vertices; // world space source data of the geometry
// methods:
// sends content of the struct to provided stream
void
serialize( std::ostream &Output ) const;
// restores content of the struct from provided input stream
void
deserialize( std::istream &Input );
}; };
// methods // methods
// restores content of the node from provded input stream // sends content of the class to provided stream
void
serialize( std::ostream &Output ) const;
// restores content of the node from provided input stream
lines_node &
deserialize( std::istream &Input );
// restores content of the node from provided input stream
lines_node & lines_node &
deserialize( cParser &Input, scene::node_data const &Nodedata ); deserialize( cParser &Input, scene::node_data const &Nodedata );
// adds content of provided node to already enclosed geometry. returns: true if merge could be performed // adds content of provided node to already enclosed geometry. returns: true if merge could be performed
@@ -173,16 +214,13 @@ public:
compute_radius(); compute_radius();
// set visibility // set visibility
void void
visible( bool State ) { visible( bool State );
m_data.visible = State; }
// set origin point // set origin point
void void
origin( glm::dvec3 Origin ) { origin( glm::dvec3 Origin );
m_data.origin = Origin; }
// data access // data access
linesnode_data const & linesnode_data const &
data() const { data() const;
return m_data; }
private: private:
// members // members
@@ -190,6 +228,26 @@ private:
linesnode_data m_data; linesnode_data m_data;
}; };
// set visibility
inline
void
lines_node::visible( bool State ) {
m_data.visible = State;
}
// set origin point
inline
void
lines_node::origin( glm::dvec3 Origin ) {
m_data.origin = Origin;
}
// data access
inline
lines_node::linesnode_data const &
lines_node::data() const {
return m_data;
}
/* /*
// holds geometry for specific piece of track/road/waterway // holds geometry for specific piece of track/road/waterway
class path_node { class path_node {
@@ -238,39 +296,10 @@ private:
TTrack * m_path; TTrack * m_path;
}; };
*/ */
/*
// holds reference to memory cell
class memorycell_node {
friend class basic_region; // region might want to modify node content when it's being inserted
public:
// types
struct memorynode_data {
// placement and visibility
bounding_area area; // bounding area, in world coordinates
bool visible { false }; // visibility flag
};
// methods
// restores content of the node from provded input stream
// TODO: implement
memory_node &
deserialize( cParser &Input, node_data const &Nodedata );
void
cell( TMemCell *Cell ) {
m_memorycell = Cell; }
TMemCell *
cell() {
return m_memorycell; }
private:
// members
memorynode_data m_data;
TMemCell * m_memorycell;
};
*/
} // scene } // scene
namespace editor { namespace editor {
// base interface for nodes which can be actvated in scenario editor // base interface for nodes which can be actvated in scenario editor
@@ -278,28 +307,22 @@ struct basic_node {
public: public:
// constructor // constructor
basic_node() = default; // TODO: remove after refactor
basic_node( scene::node_data const &Nodedata ); basic_node( scene::node_data const &Nodedata );
// destructor // destructor
virtual ~basic_node() = default; virtual ~basic_node() = default;
// methods // methods
std::string const & std::string const &
name() const { name() const;
return m_name; }
void void
location( glm::dvec3 const Location ) { location( glm::dvec3 const Location );
m_area.center = Location; }
glm::dvec3 const & glm::dvec3 const &
location() const { location() const;
return m_area.center; };
float const & float const &
radius(); radius();
void void
visible( bool const Visible ) { visible( bool const Visible );
m_visible = Visible; }
bool bool
visible() const { visible() const;
return m_visible; }
protected: protected:
// methods // methods
@@ -313,6 +336,36 @@ protected:
std::string m_name; std::string m_name;
}; };
inline
std::string const &
basic_node::name() const {
return m_name;
}
inline
void
basic_node::location( glm::dvec3 const Location ) {
m_area.center = Location;
}
inline
glm::dvec3 const &
basic_node::location() const {
return m_area.center;
}
inline
void
basic_node::visible( bool const Visible ) {
m_visible = Visible;
}
inline
bool
basic_node::visible() const {
return m_visible;
}
} // editor } // editor
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -358,30 +358,37 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
else if( nodedata.type == "model" ) { else if( nodedata.type == "model" ) {
if( nodedata.range_min < 0.0 ) { if( nodedata.range_min < 0.0 ) {
// convert and import 3d terrain // 3d terrain
auto *instance { deserialize_model( Input, Scratchpad, nodedata ) }; if( false == Scratchpad.binary.terrain ) {
// model import can potentially fail // if we're loading data from text .scn file convert and import
if( instance == nullptr ) { return; } auto *instance { deserialize_model( Input, Scratchpad, nodedata ) };
// go through submodels, and import them as shapes // model import can potentially fail
auto const cellcount = instance->TerrainCount() + 1; // zliczenie submodeli if( instance == nullptr ) { return; }
for( auto i = 1; i < cellcount; ++i ) { // go through submodels, and import them as shapes
auto *submodel = instance->TerrainSquare( i - 1 ); auto const cellcount = instance->TerrainCount() + 1; // zliczenie submodeli
simulation::Region->insert_shape( for( auto i = 1; i < cellcount; ++i ) {
scene::shape_node().convert( submodel ), auto *submodel = instance->TerrainSquare( i - 1 );
Scratchpad,
false );
// if there's more than one group of triangles in the cell they're held as children of the primary submodel
submodel = submodel->ChildGet();
while( submodel != nullptr ) {
simulation::Region->insert_shape( simulation::Region->insert_shape(
scene::shape_node().convert( submodel ), scene::shape_node().convert( submodel ),
Scratchpad, Scratchpad,
false ); false );
submodel = submodel->NextGet(); // if there's more than one group of triangles in the cell they're held as children of the primary submodel
submodel = submodel->ChildGet();
while( submodel != nullptr ) {
simulation::Region->insert_shape(
scene::shape_node().convert( submodel ),
Scratchpad,
false );
submodel = submodel->NextGet();
}
} }
// with the import done we can get rid of the source model
delete instance;
}
else {
// if binary terrain file was present, we already have this data
skip_until( Input, "endmodel" );
} }
// with the import done we can get rid of the source model
delete instance;
} }
else { else {
// regular instance of 3d mesh // regular instance of 3d mesh

View File

@@ -75,6 +75,28 @@ std::string sn_utils::d_str(std::istream &s)
return r; return r;
} }
bool sn_utils::d_bool(std::istream& s)
{
return ( ld_uint16( s ) == 1 );
}
glm::dvec3 sn_utils::d_dvec3(std::istream& s)
{
return {
ld_float64(s),
ld_float64(s),
ld_float64(s) };
}
glm::vec4 sn_utils::d_vec4( std::istream& s)
{
return {
ld_float32(s),
ld_float32(s),
ld_float32(s),
ld_float32(s) };
}
void sn_utils::ls_uint16(std::ostream &s, uint16_t v) void sn_utils::ls_uint16(std::ostream &s, uint16_t v)
{ {
uint8_t buf[2]; uint8_t buf[2];
@@ -134,3 +156,27 @@ void sn_utils::s_str(std::ostream &s, std::string v)
const char* buf = v.c_str(); const char* buf = v.c_str();
s.write(buf, v.size() + 1); s.write(buf, v.size() + 1);
} }
void sn_utils::s_bool(std::ostream &s, bool v)
{
ls_uint16(
s,
( true == v ?
1 :
0 ) );
}
void sn_utils::s_dvec3(std::ostream &s, glm::dvec3 const &v)
{
ls_float64(s, v.x);
ls_float64(s, v.y);
ls_float64(s, v.z);
}
void sn_utils::s_vec4(std::ostream &s, glm::vec4 const &v)
{
ls_float32(s, v.x);
ls_float32(s, v.y);
ls_float32(s, v.z);
ls_float32(s, v.w);
}

View File

@@ -13,6 +13,9 @@ public:
static float ld_float32(std::istream&); static float ld_float32(std::istream&);
static double ld_float64(std::istream&); static double ld_float64(std::istream&);
static std::string d_str(std::istream&); static std::string d_str(std::istream&);
static bool d_bool(std::istream&);
static glm::dvec3 d_dvec3(std::istream&);
static glm::vec4 d_vec4(std::istream&);
static void ls_uint16(std::ostream&, uint16_t); static void ls_uint16(std::ostream&, uint16_t);
static void ls_uint32(std::ostream&, uint32_t); static void ls_uint32(std::ostream&, uint32_t);
@@ -20,4 +23,7 @@ public:
static void ls_float32(std::ostream&, float); static void ls_float32(std::ostream&, float);
static void ls_float64(std::ostream&, double); static void ls_float64(std::ostream&, double);
static void s_str(std::ostream&, std::string); static void s_str(std::ostream&, std::string);
static void s_bool(std::ostream&, bool);
static void s_dvec3(std::ostream&, glm::dvec3 const &);
static void s_vec4(std::ostream&, glm::vec4 const &);
}; };

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define VERSION_MAJOR 17 #define VERSION_MAJOR 17
#define VERSION_MINOR 1027 #define VERSION_MINOR 1030
#define VERSION_REVISION 0 #define VERSION_REVISION 0

View File

@@ -9,6 +9,37 @@ http://mozilla.org/MPL/2.0/.
#include "stdafx.h" #include "stdafx.h"
#include "vertex.h" #include "vertex.h"
#include "sn_utils.h"
void
world_vertex::serialize( std::ostream &s ) const {
sn_utils::ls_float64( s, position.x );
sn_utils::ls_float64( s, position.y );
sn_utils::ls_float64( s, position.z );
sn_utils::ls_float32( s, normal.x );
sn_utils::ls_float32( s, normal.y );
sn_utils::ls_float32( s, normal.z );
sn_utils::ls_float32( s, texture.x );
sn_utils::ls_float32( s, texture.y );
}
void
world_vertex::deserialize( std::istream &s ) {
position.x = sn_utils::ld_float64( s );
position.y = sn_utils::ld_float64( s );
position.z = sn_utils::ld_float64( s );
normal.x = sn_utils::ld_float32( s );
normal.y = sn_utils::ld_float32( s );
normal.z = sn_utils::ld_float32( s );
texture.x = sn_utils::ld_float32( s );
texture.y = sn_utils::ld_float32( s );
}
template <> template <>
world_vertex & world_vertex &

View File

@@ -50,6 +50,8 @@ struct world_vertex {
Left *= Right; Left *= Right;
return Left; } return Left; }
// methods // methods
void serialize( std::ostream& ) const;
void deserialize( std::istream& );
// wyliczenie współrzędnych i mapowania punktu na środku odcinka v1<->v2 // wyliczenie współrzędnych i mapowania punktu na środku odcinka v1<->v2
void void
set_half( world_vertex const &Vertex1, world_vertex const &Vertex2 ) { set_half( world_vertex const &Vertex1, world_vertex const &Vertex2 ) {