build 180809. scenery node groups, AI shunt mode braking tweaks

This commit is contained in:
tmj-fstate
2018-08-09 22:24:42 +02:00
parent 249e01375b
commit cbaa5f7817
13 changed files with 398 additions and 75 deletions

View File

@@ -4350,8 +4350,10 @@ TController::UpdateSituation(double dt) {
}
case Shunt: {
// na jaką odleglość i z jaką predkością ma podjechać
/*
fMinProximityDist = 5.0;
fMaxProximityDist = 10.0; //[m]
if( pVehicles[ 0 ] != pVehicles[ 1 ] ) {
// for larger consists increase margins to account for slower braking etc
// NOTE: this will affect also multi-unit vehicles TBD: is this what we want?
@@ -4367,6 +4369,15 @@ TController::UpdateSituation(double dt) {
}
}
}
*/
fMinProximityDist = std::min( 5 + iVehicles, 25 );
fMaxProximityDist = std::min( 10 + iVehicles, 50 );
if( ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 )
&& ( fBrake_a0[ 0 ] >= 0.35 ) ) {
// cargo trains with high braking threshold may require even larger safety margin
fMaxProximityDist *= 1.5;
}
fVelPlus = 2.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania
// margines prędkości powodujący załączenie napędu
// były problemy z jazdą np. 3km/h podczas ładowania wagonów

View File

@@ -224,7 +224,7 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
f4Specular = glm::vec4{ 0.0f, 0.0f, 0.0f, 1.0f };
}
}
parser.ignoreTokens(1); // zignorowanie nazwy "SelfIllum:"
parser.ignoreToken(); // zignorowanie nazwy "SelfIllum:"
{
std::string light = parser.getToken<std::string>();
if (light == "true")

View File

@@ -22,6 +22,7 @@ http://mozilla.org/MPL/2.0/.
#include "Logs.h"
#include "MdlMngr.h"
#include "model3d.h"
#include "dumb3d.h"
#include "Timer.h"
#include "Driver.h"
#include "dynobj.h"
@@ -6243,7 +6244,7 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
}
std::string cabstr("cab" + std::to_string(cabindex) + "definition:");
std::shared_ptr<cParser> parser = std::make_shared<cParser>(asFileName, cParser::buffer_FILE);
cParser parser(asFileName, cParser::buffer_FILE);
// NOTE: yaml-style comments are disabled until conflict in use of # is resolved
// parser.addCommentStyle( "#", "\n" );
std::string token;
@@ -6251,11 +6252,45 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
{
// szukanie kabiny
token = "";
parser->getTokens();
*parser >> token;
parser.getTokens();
parser >> token;
/*
if( token == "locations:" ) {
do {
token = "";
parser.getTokens(); parser >> token;
if( token == "radio:" ) {
// point in 3d space, in format [ x, y, z ]
glm::vec3 radiolocation;
parser.getTokens( 3, false, "\n\r\t ,;[]" );
parser
>> radiolocation.x
>> radiolocation.y
>> radiolocation.z;
radiolocation *= glm::vec3( NewCabNo, 1, NewCabNo );
m_radiosound.offset( radiolocation );
}
else if( token == "alerter:" ) {
// point in 3d space, in format [ x, y, z ]
glm::vec3 alerterlocation;
parser.getTokens( 3, false, "\n\r\t ,;[]" );
parser
>> alerterlocation.x
>> alerterlocation.y
>> alerterlocation.z;
alerterlocation *= glm::vec3( NewCabNo, 1, NewCabNo );
dsbBuzzer.offset( alerterlocation );
}
} while( ( token != "" )
&& ( token != "endlocations" ) );
} // locations:
*/
} while ((token != "") && (token != cabstr));
/*
if ((cabindex != 1) && (token != cabstr))
{
// jeśli nie znaleziony wpis kabiny, próba szukania kabiny 1
@@ -6267,65 +6302,66 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
do
{
token = "";
parser->getTokens();
*parser >> token;
parser.getTokens();
parser >> token;
} while ((token != "") && (token != cabstr));
}
*/
if (token == cabstr)
{
// jeśli znaleziony wpis kabiny
Cabine[cabindex].Load(*parser);
Cabine[cabindex].Load(parser);
// NOTE: the position and angle definitions depend on strict entry order
// TODO: refactor into more flexible arrangement
parser->getTokens();
*parser >> token;
parser.getTokens();
parser >> token;
if( token == std::string( "driver" + std::to_string( cabindex ) + "angle:" ) ) {
// camera view angle
parser->getTokens( 2, false );
parser.getTokens( 2, false );
// angle is specified in degrees but internally stored in radians
glm::vec2 viewangle;
*parser
parser
>> viewangle.y // yaw first, then pitch
>> viewangle.x;
pMechViewAngle = glm::radians( viewangle );
Global.pCamera.Pitch = pMechViewAngle.x;
Global.pCamera.Yaw = pMechViewAngle.y;
parser->getTokens();
*parser >> token;
parser.getTokens();
parser >> token;
}
if (token == std::string("driver" + std::to_string(cabindex) + "pos:"))
{
// pozycja poczatkowa maszynisty
parser->getTokens(3, false);
*parser
parser.getTokens(3, false);
parser
>> pMechOffset.x
>> pMechOffset.y
>> pMechOffset.z;
pMechSittingPosition = pMechOffset;
parser->getTokens();
*parser >> token;
parser.getTokens();
parser >> token;
}
// ABu: pozycja siedzaca mechanika
if (token == std::string("driver" + std::to_string(cabindex) + "sitpos:"))
{
// ABu 180404 pozycja siedzaca maszynisty
parser->getTokens(3, false);
*parser
parser.getTokens(3, false);
parser
>> pMechSittingPosition.x
>> pMechSittingPosition.y
>> pMechSittingPosition.z;
parser->getTokens();
*parser >> token;
parser.getTokens();
parser >> token;
}
// else parse=false;
do {
if( parse == true ) {
token = "";
parser->getTokens();
*parser >> token;
parser.getTokens();
parser >> token;
}
else {
parse = true;
@@ -6338,8 +6374,8 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
if (token == std::string("cab" + std::to_string(cabindex) + "model:"))
{
// model kabiny
parser->getTokens();
*parser >> token;
parser.getTokens();
parser >> token;
if (token != "none")
{
// bieżąca sciezka do tekstur to dynamic/...
@@ -6375,19 +6411,19 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
// don't bother with other parts until the cab is initialised
continue;
}
else if (true == initialize_gauge(*parser, token, cabindex))
else if (true == initialize_gauge(parser, token, cabindex))
{
// matched the token, grab the next one
continue;
}
else if (true == initialize_button(*parser, token, cabindex))
else if (true == initialize_button(parser, token, cabindex))
{
// matched the token, grab the next one
continue;
}
else if (token == "pyscreen:")
{
pyScreens.init(*parser, DynamicObject->mdKabina, DynamicObject->name(), NewCabNo);
pyScreens.init(parser, DynamicObject->mdKabina, DynamicObject->name(), NewCabNo);
}
// btLampkaUnknown.Init("unknown",mdKabina,false);
} while (token != "");
@@ -6415,10 +6451,10 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
}
// radio has two potential items which can provide the position
if( m_radiosound.offset() == nullvector ) {
m_radiosound.offset( ggRadioButton.model_offset() );
m_radiosound.offset( btLampkaRadio.model_offset() );
}
if( m_radiosound.offset() == nullvector ) {
m_radiosound.offset( btLampkaRadio.model_offset() );
m_radiosound.offset( ggRadioButton.model_offset() );
}
if( m_radiostop.offset() == nullvector ) {
m_radiostop.offset( m_radiosound.offset() );

View File

@@ -303,6 +303,9 @@
<ClCompile Include="keyboardinput.cpp">
<Filter>Source Files\application\input</Filter>
</ClCompile>
<ClCompile Include="scenenodegroups.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Globals.h">
@@ -572,6 +575,9 @@
<ClInclude Include="keyboardinput.h">
<Filter>Header Files\application\input</Filter>
</ClInclude>
<ClInclude Include="scenenodegroups.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="maszyna.rc">

View File

@@ -9,8 +9,11 @@ http://mozilla.org/MPL/2.0/.
#include "stdafx.h"
#include "parser.h"
#include "utilities.h"
#include "logs.h"
#include "scenenodegroups.h"
/*
MaSzyna EU07 locomotive simulator parser
Copyright (C) 2003 TOLARIS
@@ -24,11 +27,6 @@ http://mozilla.org/MPL/2.0/.
cParser::cParser( std::string const &Stream, buffertype const Type, std::string Path, bool const Loadtraction, std::vector<std::string> Parameters ) :
mPath(Path),
LoadTraction( Loadtraction ) {
// build comments map
mComments.insert(commentmap::value_type("/*", "*/"));
mComments.insert(commentmap::value_type("//", "\n"));
// mComments.insert(commentmap::value_type("--","\n")); //Ra: to chyba nie używane
// store to calculate sub-sequent includes from relative path
if( Type == buffertype::buffer_FILE ) {
mFile = Stream;
@@ -38,6 +36,12 @@ cParser::cParser( std::string const &Stream, buffertype const Type, std::string
case buffer_FILE: {
Path.append( Stream );
mStream = std::make_shared<std::ifstream>( Path );
// content of *.inc files is potentially grouped together
if( ( Stream.size() >= 4 )
&& ( ToLower( Stream.substr( Stream.size() - 4 ) ) == ".inc" ) ) {
mIncFile = true;
scene::Groups.begin();
}
break;
}
case buffer_TEXT: {
@@ -69,7 +73,10 @@ cParser::cParser( std::string const &Stream, buffertype const Type, std::string
// destructor
cParser::~cParser() {
mComments.clear();
if( true == mIncFile ) {
// wrap up the node group holding content of processed file
scene::Groups.end();
}
}
template<>

View File

@@ -47,11 +47,6 @@ class cParser //: public std::stringstream
ignoreToken() {
readToken(); };
inline
void
ignoreTokens(int count) {
for( int i = 0; i < count; ++i ) {
readToken(); } };
inline
bool
expectToken( std::string const &Value ) {
return readToken() == Value; };
@@ -97,14 +92,17 @@ class cParser //: public std::stringstream
std::size_t count();
// members:
bool m_autoclear { true }; // not retrieved tokens are discarded when another read command is issued (legacy behaviour)
bool LoadTraction; // load traction?
bool LoadTraction { true }; // load traction?
std::shared_ptr<std::istream> mStream; // relevant kind of buffer is attached on creation.
std::string mFile; // name of the open file, if any
std::string mPath; // path to open stream, for relative path lookups.
std::streamoff mSize { 0 }; // size of open stream, for progress report.
std::size_t mLine { 0 }; // currently processed line
bool mIncFile { false }; // the parser is processing an *.inc file
typedef std::map<std::string, std::string> commentmap;
commentmap mComments;
commentmap mComments {
commentmap::value_type( "/*", "*/" ),
commentmap::value_type( "//", "\n" ) };
std::shared_ptr<cParser> mIncludeParser; // child class to handle include directives.
std::vector<std::string> parameters; // parameter list for included file.
std::deque<std::string> tokens;

View File

@@ -9,6 +9,7 @@ http://mozilla.org/MPL/2.0/.
#include "stdafx.h"
#include "sceneeditor.h"
#include "scenenodegroups.h"
#include "globals.h"
#include "application.h"
@@ -22,20 +23,26 @@ namespace scene {
void
basic_editor::translate( scene::basic_node *Node, glm::dvec3 const &Location, bool const Snaptoground ) {
auto *node { Node }; // placeholder for operations on multiple nodes
auto location { Location };
auto const initiallocation { Node->location() };
auto targetlocation { Location };
if( false == Snaptoground ) {
location.y = node->location().y;
targetlocation.y = initiallocation.y;
}
// NOTE: bit of a waste for single nodes, for the sake of less varied code down the road
auto const translation { targetlocation - initiallocation };
if( typeid( *node ) == typeid( TAnimModel ) ) {
translate_instance( static_cast<TAnimModel *>( node ), location );
if( Node->group() == null_handle ) {
translate_node( Node, Node->location() + translation );
}
else if( typeid( *node ) == typeid( TMemCell ) ) {
translate_memorycell( static_cast<TMemCell *>( node ), location );
else {
// translate entire group
// TODO: contextual switch between group and item translation
auto nodegroup { scene::Groups.group( Node->group() ) };
std::for_each(
nodegroup.first, nodegroup.second,
[&]( auto *node ) {
translate_node( node, node->location() + translation ); } );
}
}
void
@@ -44,15 +51,41 @@ basic_editor::translate( scene::basic_node *Node, float const Offset ) {
// NOTE: offset scaling is calculated early so the same multiplier can be applied to potential whole group
auto location { Node->location() };
auto const distance { glm::length( location - glm::dvec3{ Global.pCamera.Pos } ) };
auto const offset { Offset * std::max( 1.0, distance * 0.01 ) };
auto const offset { static_cast<float>( Offset * std::max( 1.0, distance * 0.01 ) ) };
auto *node { Node }; // placeholder for operations on multiple nodes
if( typeid( *node ) == typeid( TAnimModel ) ) {
translate_instance( static_cast<TAnimModel *>( node ), offset );
if( Node->group() == null_handle ) {
translate_node( Node, offset );
}
else if( typeid( *node ) == typeid( TMemCell ) ) {
translate_memorycell( static_cast<TMemCell *>( node ), offset );
else {
// translate entire group
// TODO: contextual switch between group and item translation
auto nodegroup { scene::Groups.group( Node->group() ) };
std::for_each(
nodegroup.first, nodegroup.second,
[&]( auto *node ) {
translate_node( node, offset ); } );
}
}
void
basic_editor::translate_node( scene::basic_node *Node, glm::dvec3 const &Location ) {
if( typeid( *Node ) == typeid( TAnimModel ) ) {
translate_instance( static_cast<TAnimModel *>( Node ), Location );
}
else if( typeid( *Node ) == typeid( TMemCell ) ) {
translate_memorycell( static_cast<TMemCell *>( Node ), Location );
}
}
void
basic_editor::translate_node( scene::basic_node *Node, float const Offset ) {
if( typeid( *Node ) == typeid( TAnimModel ) ) {
translate_instance( static_cast<TAnimModel *>( Node ), Offset );
}
else if( typeid( *Node ) == typeid( TMemCell ) ) {
translate_memorycell( static_cast<TMemCell *>( Node ), Offset );
}
}
@@ -91,25 +124,62 @@ basic_editor::translate_memorycell( TMemCell *Memorycell, float const Offset ) {
void
basic_editor::rotate( scene::basic_node *Node, glm::vec3 const &Angle, float const Quantization ) {
auto *node { Node }; // placeholder for operations on multiple nodes
glm::vec3 rotation { 0, Angle.y, 0 };
if( typeid( *node ) == typeid( TAnimModel ) ) {
rotate_instance( static_cast<TAnimModel *>( node ), Angle, Quantization );
// quantize resulting angle if requested and type of the node allows it
// TBD, TODO: angle quantization for types other than instanced models
if( ( Quantization > 0.f )
&& ( typeid( *Node ) == typeid( TAnimModel ) ) ) {
auto const initialangle { static_cast<TAnimModel *>( Node )->Angles() };
rotation += initialangle;
// TBD, TODO: adjustable quantization step
rotation.y = quantize( rotation.y, Quantization );
rotation -= initialangle;
}
if( Node->group() == null_handle ) {
rotate_node( Node, rotation );
}
else {
// rotate entire group
// TODO: contextual switch between group and item rotation
auto const rotationcenter { Node->location() };
auto nodegroup { scene::Groups.group( Node->group() ) };
std::for_each(
nodegroup.first, nodegroup.second,
[&]( auto *node ) {
rotate_node( node, rotation );
if( node != Node ) {
translate_node(
node,
rotationcenter
+ glm::rotateY(
node->location() - rotationcenter,
glm::radians<double>( rotation.y ) ) ); } } );
}
}
void
basic_editor::rotate_instance( TAnimModel *Instance, glm::vec3 const &Angle, float const Quantization ) {
basic_editor::rotate_node( scene::basic_node *Node, glm::vec3 const &Angle ) {
// adjust node data
glm::vec3 angle = glm::dvec3 { Instance->Angles() };
angle.y = clamp_circular( angle.y + Angle.y, 360.f );
if( Quantization > 0.f ) {
// TBD, TODO: adjustable quantization step
angle.y = quantize( angle.y, Quantization );
if( typeid( *Node ) == typeid( TAnimModel ) ) {
rotate_instance( static_cast<TAnimModel *>( Node ), Angle );
}
Instance->Angles( angle );
// update scene
}
void
basic_editor::rotate_instance( TAnimModel *Instance, glm::vec3 const &Angle ) {
auto targetangle { Instance->Angles() + Angle };
targetangle.x = clamp_circular( targetangle.x, 360.f );
targetangle.y = clamp_circular( targetangle.y, 360.f );
targetangle.z = clamp_circular( targetangle.z, 360.f );
Instance->Angles( targetangle );
}
} // scene

View File

@@ -36,6 +36,15 @@ public:
translate( scene::basic_node *Node, glm::dvec3 const &Location, bool const Snaptoground );
void
translate( scene::basic_node *Node, float const Offset );
void
rotate( scene::basic_node *Node, glm::vec3 const &Angle, float const Quantization );
private:
// methods
void
translate_node( scene::basic_node *Node, glm::dvec3 const &Location );
void
translate_node( scene::basic_node *Node, float const Offset );
void
translate_instance( TAnimModel *Instance, glm::dvec3 const &Location );
void
@@ -45,9 +54,9 @@ public:
void
translate_memorycell( TMemCell *Memorycell, float const Offset );
void
rotate( scene::basic_node *Node, glm::vec3 const &Angle, float const Quantization );
rotate_node( scene::basic_node *Node, glm::vec3 const &Angle );
void
rotate_instance( TAnimModel *Instance, glm::vec3 const &Angle, float const Quantization );
rotate_instance( TAnimModel *Instance, glm::vec3 const &Angle );
};
} // scene

View File

@@ -64,6 +64,8 @@ struct bounding_area {
deserialize( std::istream &Input );
};
using group_handle = std::size_t;
struct node_data {
double range_min { 0.0 };
@@ -330,9 +332,14 @@ public:
visible( bool const Visible );
bool
visible() const;
void
group( scene::group_handle Group );
scene::group_handle
group() const;
protected:
// members
scene::group_handle m_group { null_handle }; // group this node belongs to, if any
scene::bounding_area m_area;
double m_rangesquaredmin { 0.0 }; // visibility range, min
double m_rangesquaredmax { 0.0 }; // visibility range, max
@@ -381,6 +388,18 @@ basic_node::visible() const {
return m_visible;
}
inline
void
basic_node::group( scene::group_handle Group ) {
m_group = Group;
}
inline
scene::group_handle
basic_node::group() const {
return m_group;
}
} // scene
//---------------------------------------------------------------------------

97
scenenodegroups.cpp Normal file
View File

@@ -0,0 +1,97 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#include "stdafx.h"
#include "scenenodegroups.h"
namespace scene {
node_groups Groups;
// requests creation of a new node group. returns: handle to the group
scene::group_handle
node_groups::begin() {
m_activegroup.push( create_handle() );
return handle();
}
// indicates creation of current group ended. returns: handle to the parent group or null_handle if group stack is empty
scene::group_handle
node_groups::end() {
if( false == m_activegroup.empty() ) {
auto const closinggroup { m_activegroup.top() };
m_activegroup.pop();
// if the completed group holds only one item and there's no chance more items will be added, disband it
if( ( true == m_activegroup.empty() )
|| ( m_activegroup.top() != closinggroup ) ) {
auto lookup { m_groupmap.find( closinggroup ) };
if( ( lookup != m_groupmap.end() )
&& ( lookup->second.size() <= 1 ) ) {
erase( lookup );
}
}
}
return handle();
}
// returns current active group, or null_handle if group stack is empty
group_handle
node_groups::handle() const {
return (
m_activegroup.empty() ?
null_handle :
m_activegroup.top() );
}
// places provided node in specified group
void
node_groups::register_node( scene::basic_node *Node, scene::group_handle const Group ) {
// TBD, TODO: automatically unregister the node from its current group?
Node->group( Group );
if( Group == null_handle ) { return; }
auto &nodesequence { m_groupmap[ Group ] };
if( std::find( std::begin( nodesequence ), std::end( nodesequence ), Node ) == std::end( nodesequence ) ) {
// don't add the same node twice
nodesequence.emplace_back( Node );
}
}
// removes specified group from the group list and group information from the group's nodes
void
node_groups::erase( group_map::const_iterator Group ) {
for( auto *node : Group->second ) {
node->group( null_handle );
}
m_groupmap.erase( Group );
}
// creates handle for a new group
group_handle
node_groups::create_handle() {
// NOTE: for simplification nested group structure are flattened
return(
m_activegroup.empty() ?
m_groupmap.size() + 1 : // new group isn't created until node registration
m_activegroup.top() );
}
} // scene
//---------------------------------------------------------------------------

64
scenenodegroups.h Normal file
View File

@@ -0,0 +1,64 @@
/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "scenenode.h"
namespace scene {
// holds lists of grouped scene nodes
class node_groups {
// NOTE: during scenario deserialization encountering *.inc file causes creation of a new group on the group stack
// this allows all nodes listed in this *.inc file to be grouped and potentially modified together by the editor.
private:
// types
using node_sequence = std::vector<scene::basic_node *>;
public:
// constructors
node_groups() = default;
// methods
// requests creation of a new node group. returns: handle to the group
group_handle
begin();
// indicates creation of current group ended. returns: handle to the parent group or null_handle if group stack is empty
group_handle
end();
// returns current active group, or null_handle if group stack is empty
group_handle
handle() const;
// places provided node in specified group
void
register_node( scene::basic_node *Node, scene::group_handle const Group );
std::pair<node_sequence::iterator, node_sequence::iterator>
group( scene::group_handle const Group ) {
auto &group { m_groupmap[ Group ] };
return { std::begin( group ), std::end( group ) }; }
private:
// types
using group_map = std::unordered_map<scene::group_handle, node_sequence>;
// methods
// removes specified group from the group list and group information from the group's nodes
void
erase( group_map::const_iterator Group );
// creates handle for a new group
group_handle
create_handle();
// members
group_map m_groupmap; // map of established node groups
std::stack<scene::group_handle> m_activegroup; // helper, group to be assigned to newly created nodes
};
extern node_groups Groups;
} // scene
//---------------------------------------------------------------------------

View File

@@ -15,6 +15,7 @@ http://mozilla.org/MPL/2.0/.
#include "globals.h"
#include "simulation.h"
#include "simulationtime.h"
#include "scenenodegroups.h"
#include "event.h"
#include "driver.h"
#include "dynobj.h"
@@ -304,6 +305,7 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
delete pathnode;
*/
}
scene::Groups.register_node( path, scene::Groups.handle() );
simulation::Region->insert_and_register( path );
}
else if( nodedata.type == "traction" ) {
@@ -315,6 +317,7 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
if( false == simulation::Traction.insert( traction ) ) {
ErrorLog( "Bad scenario: traction piece with duplicate name \"" + traction->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
}
scene::Groups.register_node( traction, scene::Groups.handle() );
simulation::Region->insert_and_register( traction );
}
else if( nodedata.type == "tractionpowersource" ) {
@@ -375,6 +378,7 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
if( false == simulation::Instances.insert( instance ) ) {
ErrorLog( "Bad scenario: 3d model instance with duplicate name \"" + instance->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
}
scene::Groups.register_node( instance, scene::Groups.handle() );
simulation::Region->insert( instance );
}
}
@@ -417,6 +421,7 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
if( false == simulation::Memory.insert( memorycell ) ) {
ErrorLog( "Bad scenario: memory memorycell with duplicate name \"" + memorycell->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
}
scene::Groups.register_node( memorycell, scene::Groups.handle() );
simulation::Region->insert( memorycell );
}
else if( nodedata.type == "eventlauncher" ) {
@@ -431,6 +436,7 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
simulation::Events.queue( eventlauncher );
}
else {
scene::Groups.register_node( eventlauncher, scene::Groups.handle() );
simulation::Region->insert( eventlauncher );
}
}

View File

@@ -1,5 +1,5 @@
#pragma once
#define VERSION_MAJOR 18
#define VERSION_MINOR 805
#define VERSION_MINOR 809
#define VERSION_REVISION 0