mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 12:09:18 +02:00
virtual slider mouse input mode, minor refactoring, minor bug fixes
This commit is contained in:
10
Camera.cpp
10
Camera.cpp
@@ -67,8 +67,8 @@ TCamera::OnCommand( command_data const &Command ) {
|
||||
case user_command::viewturn: {
|
||||
|
||||
OnCursorMove(
|
||||
reinterpret_cast<double const &>( Command.param1 ) * 0.005 * Global.fMouseXScale / Global.ZoomFactor,
|
||||
reinterpret_cast<double const &>( Command.param2 ) * 0.01 * Global.fMouseYScale / Global.ZoomFactor );
|
||||
Command.param1 * 0.005 * Global.fMouseXScale / Global.ZoomFactor,
|
||||
Command.param2 * 0.01 * Global.fMouseYScale / Global.ZoomFactor );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ TCamera::OnCommand( command_data const &Command ) {
|
||||
1.0 );
|
||||
|
||||
// left-right
|
||||
auto const movexparam { reinterpret_cast<double const &>( Command.param1 ) };
|
||||
auto const movexparam { Command.param1 };
|
||||
// 2/3rd of the stick range enables walk speed, past that we lerp between walk and run speed
|
||||
auto const movex { walkspeed + ( std::max( 0.0, std::abs( movexparam ) - 0.65 ) / 0.35 ) * ( movespeed - walkspeed ) };
|
||||
|
||||
@@ -96,7 +96,7 @@ TCamera::OnCommand( command_data const &Command ) {
|
||||
0.0 );
|
||||
|
||||
// forward-back
|
||||
double const movezparam { reinterpret_cast<double const &>( Command.param2 ) };
|
||||
double const movezparam { Command.param2 };
|
||||
auto const movez { walkspeed + ( std::max( 0.0, std::abs( movezparam ) - 0.65 ) / 0.35 ) * ( movespeed - walkspeed ) };
|
||||
// NOTE: z-axis is flipped given world coordinate system
|
||||
m_moverate.z = (
|
||||
@@ -121,7 +121,7 @@ TCamera::OnCommand( command_data const &Command ) {
|
||||
1.0 );
|
||||
|
||||
// up-down
|
||||
auto const moveyparam { reinterpret_cast<double const &>( Command.param1 ) };
|
||||
auto const moveyparam { Command.param1 };
|
||||
// 2/3rd of the stick range enables walk speed, past that we lerp between walk and run speed
|
||||
auto const movey { walkspeed + ( std::max( 0.0, std::abs( moveyparam ) - 0.65 ) / 0.35 ) * ( movespeed - walkspeed ) };
|
||||
|
||||
|
||||
10
EU07.cpp
10
EU07.cpp
@@ -72,6 +72,7 @@ mouse_input Mouse;
|
||||
gamepad_input Gamepad;
|
||||
glm::dvec2 mouse_pickmodepos; // stores last mouse position in control picking mode
|
||||
std::unique_ptr<uart_input> uart;
|
||||
user_command command; // currently issued control command, if any
|
||||
|
||||
}
|
||||
|
||||
@@ -170,13 +171,13 @@ void key_callback( GLFWwindow *window, int key, int scancode, int action, int mo
|
||||
if( Global.ControlPicking ) {
|
||||
// switch off
|
||||
glfwGetCursorPos( window, &input::mouse_pickmodepos.x, &input::mouse_pickmodepos.y );
|
||||
glfwSetInputMode( window, GLFW_CURSOR, GLFW_CURSOR_DISABLED );
|
||||
UILayer.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
glfwSetCursorPos( window, 0, 0 );
|
||||
}
|
||||
else {
|
||||
// enter picking mode
|
||||
glfwSetInputMode( window, GLFW_CURSOR, GLFW_CURSOR_NORMAL );
|
||||
glfwSetCursorPos( window, input::mouse_pickmodepos.x, input::mouse_pickmodepos.y );
|
||||
UILayer.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
}
|
||||
// actually toggle the mode
|
||||
Global.ControlPicking = !Global.ControlPicking;
|
||||
@@ -461,6 +462,11 @@ int main(int argc, char *argv[])
|
||||
if( true == Global.InputMouse ) { input::Mouse.poll(); }
|
||||
if( true == Global.InputGamepad ) { input::Gamepad.poll(); }
|
||||
if( input::uart != nullptr ) { input::uart->poll(); }
|
||||
// TODO: wrap current command in object, include other input sources
|
||||
input::command = (
|
||||
input::Mouse.command() != user_command::none ?
|
||||
input::Mouse.command() :
|
||||
input::Keyboard.command() );
|
||||
}
|
||||
}
|
||||
catch( std::bad_alloc const &Error ) {
|
||||
|
||||
@@ -179,7 +179,7 @@ TTrack * TTrack::Create400m(int what, double dx)
|
||||
trk->Segment->Init( Math3D::vector3( -dx, 0, 0 ), Math3D::vector3( -dx, 0, 400 ), 10.0, 0, 0 ); // prosty
|
||||
trk->location( glm::dvec3{ -dx, 0, 200 } ); //środek, aby się mogło wyświetlić
|
||||
simulation::Paths.insert( trk );
|
||||
simulation::Region->insert_path( trk, scene::scratch_data() );
|
||||
simulation::Region->insert( trk );
|
||||
return trk;
|
||||
};
|
||||
|
||||
@@ -273,11 +273,11 @@ TTrack * TTrack::NullCreate(int dir)
|
||||
// trzeba jeszcze dodać do odpowiedniego segmentu, aby się renderowały z niego pojazdy
|
||||
trk->location( glm::dvec3{ 0.5 * ( p1 + p2 ) } ); //środek, aby się mogło wyświetlić
|
||||
simulation::Paths.insert( trk );
|
||||
simulation::Region->insert_path( trk, scene::scratch_data() );
|
||||
simulation::Region->insert( trk );
|
||||
if( trk2 ) {
|
||||
trk2->location( trk->location() ); // ten sam środek jest
|
||||
simulation::Paths.insert( trk2 );
|
||||
simulation::Region->insert_path( trk2, scene::scratch_data() );
|
||||
simulation::Region->insert( trk2 );
|
||||
}
|
||||
return trk;
|
||||
};
|
||||
|
||||
67
Train.cpp
67
Train.cpp
@@ -26,6 +26,12 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "mtable.h"
|
||||
#include "Console.h"
|
||||
|
||||
namespace input {
|
||||
|
||||
extern user_command command;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
control_mapper::insert( TGauge const &Gauge, std::string const &Label ) {
|
||||
|
||||
@@ -922,7 +928,7 @@ void TTrain::OnCommand_independentbrakeset( TTrain *Train, command_data const &C
|
||||
|
||||
Train->mvControlled->LocalBrakePosA = (
|
||||
clamp(
|
||||
reinterpret_cast<double const &>( Command.param1 ),
|
||||
Command.param1,
|
||||
0.0, 1.0 ) );
|
||||
/*
|
||||
Train->mvControlled->LocalBrakePos = (
|
||||
@@ -931,7 +937,7 @@ void TTrain::OnCommand_independentbrakeset( TTrain *Train, command_data const &C
|
||||
0.0,
|
||||
LocalBrakePosNo,
|
||||
clamp(
|
||||
reinterpret_cast<double const &>( Command.param1 ),
|
||||
Command.param1,
|
||||
0.0, 1.0 ) ) ) );
|
||||
*/
|
||||
}
|
||||
@@ -1003,26 +1009,16 @@ void TTrain::OnCommand_trainbrakedecrease( TTrain *Train, command_data const &Co
|
||||
Train->set_train_brake( Train->mvOccupied->BrakeCtrlPos - Global.fBrakeStep );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// release
|
||||
if( ( Train->mvOccupied->BrakeCtrlPos == -1 )
|
||||
&& ( Train->mvOccupied->BrakeHandle == FVel6 )
|
||||
&& ( Train->DynamicObject->Controller != AIdriver )
|
||||
&& ( Global.iFeedbackMode < 3 ) ) {
|
||||
// Odskakiwanie hamulce EP
|
||||
Train->set_train_brake( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_trainbrakeset( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
Train->mvControlled->BrakeLevelSet(
|
||||
Train->mvOccupied->BrakeLevelSet(
|
||||
interpolate(
|
||||
Train->mvControlled->Handle->GetPos( bh_MIN ),
|
||||
Train->mvControlled->Handle->GetPos( bh_MAX ),
|
||||
Train->mvOccupied->Handle->GetPos( bh_MIN ),
|
||||
Train->mvOccupied->Handle->GetPos( bh_MAX ),
|
||||
clamp(
|
||||
reinterpret_cast<double const &>( Command.param1 ),
|
||||
Command.param1,
|
||||
0.0, 1.0 ) ) );
|
||||
}
|
||||
|
||||
@@ -4334,18 +4330,35 @@ bool TTrain::Update( double const Deltatime )
|
||||
{ // Ra: TODO: odczyty klawiatury/pulpitu nie powinny być uzależnione od istnienia modelu kabiny
|
||||
|
||||
if( ( DynamicObject->Mechanik != nullptr )
|
||||
&& ( false == DynamicObject->Mechanik->AIControllFlag ) // nie blokujemy AI
|
||||
&& ( ( mvOccupied->TrainType == dt_ET40 )
|
||||
|| ( mvOccupied->TrainType == dt_EP05 ) ) ) {
|
||||
// dla ET40 i EU05 automatyczne cofanie nastawnika - i tak nie będzie to działać dobrze...
|
||||
// TODO: remove direct keyboard check, use deltatime to stabilize speed
|
||||
if( ( glfwGetKey( Global.window, GLFW_KEY_KP_ADD ) != GLFW_TRUE )
|
||||
&& ( mvOccupied->MainCtrlPos > mvOccupied->MainCtrlActualPos ) ) {
|
||||
mvOccupied->DecMainCtrl( 1 );
|
||||
&& ( false == DynamicObject->Mechanik->AIControllFlag ) ) {
|
||||
// nie blokujemy AI
|
||||
if( ( mvOccupied->TrainType == dt_ET40 )
|
||||
|| ( mvOccupied->TrainType == dt_EP05 ) ) {
|
||||
// dla ET40 i EU05 automatyczne cofanie nastawnika - i tak nie będzie to działać dobrze...
|
||||
// TODO: use deltatime to stabilize speed
|
||||
if( false == (
|
||||
( input::command == user_command::mastercontrollerset )
|
||||
|| ( input::command == user_command::mastercontrollerincrease )
|
||||
|| ( input::command == user_command::mastercontrollerdecrease ) ) ) {
|
||||
if( mvOccupied->MainCtrlPos > mvOccupied->MainCtrlActualPos ) {
|
||||
mvOccupied->DecMainCtrl( 1 );
|
||||
}
|
||||
else if( mvOccupied->MainCtrlPos < mvOccupied->MainCtrlActualPos ) {
|
||||
// Ra 15-01: a to nie miało być tylko cofanie?
|
||||
mvOccupied->IncMainCtrl( 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ( glfwGetKey( Global.window, GLFW_KEY_KP_SUBTRACT ) != GLFW_TRUE )
|
||||
&& ( mvOccupied->MainCtrlPos < mvOccupied->MainCtrlActualPos ) ) {
|
||||
mvOccupied->IncMainCtrl( 1 ); // Ra 15-01: a to nie miało być tylko cofanie?
|
||||
|
||||
if( ( mvOccupied->BrakeHandle == FVel6 )
|
||||
&& ( mvOccupied->fBrakeCtrlPos < 0.0 )
|
||||
&& ( Global.iFeedbackMode < 3 ) ) {
|
||||
// Odskakiwanie hamulce EP
|
||||
if( false == (
|
||||
( input::command == user_command::trainbrakeset )
|
||||
|| ( input::command == user_command::trainbrakedecrease ) ) ) {
|
||||
set_train_brake( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
Train.h
2
Train.h
@@ -648,6 +648,8 @@ private:
|
||||
inline TDynamicObject const *Dynamic() const { return DynamicObject; };
|
||||
inline TMoverParameters *Controlled() { return mvControlled; };
|
||||
inline TMoverParameters const *Controlled() const { return mvControlled; };
|
||||
inline TMoverParameters *Occupied() { return mvOccupied; };
|
||||
inline TMoverParameters const *Occupied() const { return mvOccupied; };
|
||||
void DynamicSet(TDynamicObject *d);
|
||||
|
||||
};
|
||||
|
||||
@@ -243,7 +243,7 @@ command_queue::pop( command_data &Command, std::size_t const Recipient ) {
|
||||
}
|
||||
|
||||
void
|
||||
command_relay::post( user_command const Command, std::uint64_t const Param1, std::uint64_t const Param2, int const Action, std::uint16_t const Recipient ) const {
|
||||
command_relay::post( user_command const Command, double const Param1, double const Param2, int const Action, std::uint16_t const Recipient ) const {
|
||||
|
||||
auto const &command = simulation::Commands_descriptions[ static_cast<std::size_t>( Command ) ];
|
||||
if( ( command.target == command_target::vehicle )
|
||||
|
||||
@@ -231,8 +231,8 @@ struct command_data {
|
||||
|
||||
user_command command;
|
||||
int action; // press, repeat or release
|
||||
std::uint64_t param1;
|
||||
std::uint64_t param2;
|
||||
double param1;
|
||||
double param2;
|
||||
double time_delta;
|
||||
};
|
||||
|
||||
@@ -282,7 +282,7 @@ public:
|
||||
// posts specified command for the specified recipient
|
||||
// TODO: replace uint16_t with recipient handle, based on item id
|
||||
void
|
||||
post( user_command const Command, std::uint64_t const Param1, std::uint64_t const Param2,
|
||||
post( user_command const Command, double const Param1, double const Param2,
|
||||
int const Action, std::uint16_t const Recipient ) const;
|
||||
private:
|
||||
// types
|
||||
|
||||
@@ -198,8 +198,8 @@ gamepad_input::process_axes( glm::vec2 Leftstick, glm::vec2 const &Rightstick, g
|
||||
double const turny = -Rightstick.y * 10.0 * deltatime;
|
||||
m_relay.post(
|
||||
user_command::viewturn,
|
||||
reinterpret_cast<std::uint64_t const &>( turnx ),
|
||||
reinterpret_cast<std::uint64_t const &>( turny ),
|
||||
turnx,
|
||||
turny,
|
||||
GLFW_PRESS,
|
||||
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
|
||||
// TODO: pass correct entity id once the missing systems are in place
|
||||
@@ -211,12 +211,10 @@ gamepad_input::process_axes( glm::vec2 Leftstick, glm::vec2 const &Rightstick, g
|
||||
|
||||
if( ( Leftstick.x != 0.0 || Leftstick.y != 0.0 )
|
||||
|| ( m_leftstick.x != 0.0 || m_leftstick.y != 0.0 ) ) {
|
||||
double const movex = static_cast<double>( Leftstick.x );
|
||||
double const movez = static_cast<double>( Leftstick.y );
|
||||
m_relay.post(
|
||||
user_command::movehorizontal,
|
||||
reinterpret_cast<std::uint64_t const &>( movex ),
|
||||
reinterpret_cast<std::uint64_t const &>( movez ),
|
||||
Leftstick.x,
|
||||
Leftstick.y,
|
||||
GLFW_PRESS,
|
||||
0 );
|
||||
}
|
||||
|
||||
@@ -161,6 +161,10 @@ keyboard_input::key( int const Key, int const Action ) {
|
||||
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
|
||||
// TODO: pass correct entity id once the missing systems are in place
|
||||
m_relay.post( lookup->second, 0, 0, Action, 0 );
|
||||
m_command = (
|
||||
Action == GLFW_RELEASE ?
|
||||
user_command::none :
|
||||
lookup->second );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -600,14 +604,12 @@ keyboard_input::poll() {
|
||||
|
||||
if( ( movementhorizontal.x != 0.f || movementhorizontal.y != 0.f )
|
||||
|| ( m_movementhorizontal.x != 0.f || m_movementhorizontal.y != 0.f ) ) {
|
||||
double const movexparam = static_cast<double>( movementhorizontal.x );
|
||||
double const movezparam = static_cast<double>( movementhorizontal.y );
|
||||
m_relay.post(
|
||||
( true == Global.ctrlState ?
|
||||
user_command::movehorizontalfast :
|
||||
user_command::movehorizontal ),
|
||||
reinterpret_cast<std::uint64_t const &>( movexparam ),
|
||||
reinterpret_cast<std::uint64_t const &>( movezparam ),
|
||||
movementhorizontal.x,
|
||||
movementhorizontal.y,
|
||||
GLFW_PRESS,
|
||||
0 );
|
||||
}
|
||||
@@ -623,12 +625,11 @@ keyboard_input::poll() {
|
||||
|
||||
if( ( movementvertical != 0.f )
|
||||
|| ( m_movementvertical != 0.f ) ) {
|
||||
double const moveyparam = static_cast<double>( movementvertical );
|
||||
m_relay.post(
|
||||
( true == Global.ctrlState ?
|
||||
user_command::moveverticalfast :
|
||||
user_command::movevertical ),
|
||||
reinterpret_cast<std::uint64_t const &>( moveyparam ),
|
||||
movementvertical,
|
||||
0,
|
||||
GLFW_PRESS,
|
||||
0 );
|
||||
|
||||
@@ -28,6 +28,10 @@ public:
|
||||
key( int const Key, int const Action );
|
||||
void
|
||||
poll();
|
||||
inline
|
||||
user_command const
|
||||
command() const {
|
||||
return m_command; }
|
||||
|
||||
private:
|
||||
// types
|
||||
@@ -65,6 +69,7 @@ private:
|
||||
|
||||
// members
|
||||
commandsetup_sequence m_commands;
|
||||
user_command m_command; // last, if any, issued command
|
||||
usercommand_map m_bindings;
|
||||
command_relay m_relay;
|
||||
bool m_shift{ false };
|
||||
|
||||
169
mouseinput.cpp
169
mouseinput.cpp
@@ -16,9 +16,111 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "world.h"
|
||||
#include "train.h"
|
||||
#include "renderer.h"
|
||||
#include "uilayer.h"
|
||||
|
||||
extern TWorld World;
|
||||
|
||||
void
|
||||
mouse_slider::bind( user_command const &Command ) {
|
||||
|
||||
m_command = Command;
|
||||
|
||||
auto const *train { World.train() };
|
||||
TMoverParameters const *vehicle { nullptr };
|
||||
switch( m_command ) {
|
||||
case user_command::mastercontrollerset:
|
||||
case user_command::secondcontrollerset: {
|
||||
vehicle = ( train ? train->Controlled() : nullptr );
|
||||
break;
|
||||
}
|
||||
case user_command::trainbrakeset:
|
||||
case user_command::independentbrakeset: {
|
||||
vehicle = ( train ? train->Occupied() : nullptr );
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( vehicle == nullptr ) { return; }
|
||||
|
||||
// calculate initial value and accepted range
|
||||
switch( m_command ) {
|
||||
case user_command::mastercontrollerset: {
|
||||
m_valuerange = (
|
||||
vehicle->CoupledCtrl ?
|
||||
vehicle->MainCtrlPosNo + vehicle->ScndCtrlPosNo :
|
||||
vehicle->MainCtrlPosNo );
|
||||
m_value = (
|
||||
vehicle->CoupledCtrl ?
|
||||
vehicle->MainCtrlPos + vehicle->ScndCtrlPos :
|
||||
vehicle->MainCtrlPos );
|
||||
m_analogue = false;
|
||||
break;
|
||||
}
|
||||
case user_command::secondcontrollerset: {
|
||||
m_valuerange = vehicle->ScndCtrlPosNo;
|
||||
m_value = vehicle->ScndCtrlPos;
|
||||
m_analogue = false;
|
||||
break;
|
||||
}
|
||||
case user_command::trainbrakeset: {
|
||||
m_valuerange = 1.0;
|
||||
m_value = ( vehicle->fBrakeCtrlPos - vehicle->Handle->GetPos( bh_MIN ) ) / ( vehicle->Handle->GetPos( bh_MAX ) - vehicle->Handle->GetPos( bh_MIN ) );
|
||||
m_analogue = true;
|
||||
break;
|
||||
}
|
||||
case user_command::independentbrakeset: {
|
||||
m_valuerange = 1.0;
|
||||
m_value = vehicle->LocalBrakePosA;
|
||||
m_analogue = true;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
m_valuerange = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// hide the cursor and place it in accordance with current slider value
|
||||
glfwGetCursorPos( Global.window, &m_cursorposition.x, &m_cursorposition.y );
|
||||
UILayer.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
|
||||
auto const controlsize { Global.iWindowHeight * 0.75 };
|
||||
auto const controledge { Global.iWindowHeight * 0.5 + controlsize * 0.5 };
|
||||
auto const stepsize { controlsize / m_valuerange };
|
||||
|
||||
glfwSetCursorPos(
|
||||
Global.window,
|
||||
Global.iWindowWidth * 0.5,
|
||||
( m_analogue ?
|
||||
controledge - ( 1.0 - m_value ) * controlsize :
|
||||
controledge - m_value * stepsize - 0.5 * stepsize ) );
|
||||
}
|
||||
|
||||
void
|
||||
mouse_slider::release() {
|
||||
|
||||
m_command = user_command::none;
|
||||
glfwSetCursorPos( Global.window, m_cursorposition.x, m_cursorposition.y );
|
||||
UILayer.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
}
|
||||
|
||||
void
|
||||
mouse_slider::on_move( double const Mousex, double const Mousey ) {
|
||||
|
||||
auto const controlsize { Global.iWindowHeight * 0.75 };
|
||||
auto const controledge { Global.iWindowHeight * 0.5 + controlsize * 0.5 };
|
||||
auto const stepsize { controlsize / m_valuerange };
|
||||
|
||||
auto mousey = clamp( Mousey, controledge - controlsize, controledge );
|
||||
m_value = (
|
||||
m_analogue ?
|
||||
1.0 - ( ( controledge - mousey ) / controlsize ) :
|
||||
std::floor( ( controledge - mousey ) / stepsize ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
mouse_input::init() {
|
||||
|
||||
@@ -40,8 +142,8 @@ mouse_input::move( double Mousex, double Mousey ) {
|
||||
// default control mode
|
||||
m_relay.post(
|
||||
user_command::viewturn,
|
||||
reinterpret_cast<std::uint64_t const &>( Mousex ),
|
||||
reinterpret_cast<std::uint64_t const &>( Mousey ),
|
||||
Mousex,
|
||||
Mousey,
|
||||
GLFW_PRESS,
|
||||
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
|
||||
// TODO: pass correct entity id once the missing systems are in place
|
||||
@@ -49,6 +151,17 @@ mouse_input::move( double Mousex, double Mousey ) {
|
||||
}
|
||||
else {
|
||||
// control picking mode
|
||||
if( m_slider.command() != user_command::none ) {
|
||||
m_slider.on_move( Mousex, Mousey );
|
||||
m_relay.post(
|
||||
m_slider.command(),
|
||||
m_slider.value(),
|
||||
0,
|
||||
GLFW_PRESS,
|
||||
// TODO: pass correct entity id once the missing systems are in place
|
||||
0 );
|
||||
}
|
||||
|
||||
if( false == m_pickmodepanning ) {
|
||||
// even if the view panning isn't active we capture the cursor position in case it does get activated
|
||||
m_cursorposition.x = Mousex;
|
||||
@@ -59,8 +172,8 @@ mouse_input::move( double Mousex, double Mousey ) {
|
||||
auto const viewoffset = cursorposition - m_cursorposition;
|
||||
m_relay.post(
|
||||
user_command::viewturn,
|
||||
reinterpret_cast<std::uint64_t const &>( viewoffset.x ),
|
||||
reinterpret_cast<std::uint64_t const &>( viewoffset.y ),
|
||||
viewoffset.x,
|
||||
viewoffset.y,
|
||||
GLFW_PRESS,
|
||||
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
|
||||
// TODO: pass correct entity id once the missing systems are in place
|
||||
@@ -109,6 +222,11 @@ mouse_input::button( int const Button, int const Action ) {
|
||||
mousecommand = user_command::none;
|
||||
}
|
||||
else {
|
||||
if( Button == GLFW_MOUSE_BUTTON_LEFT ) {
|
||||
if( m_slider.command() != user_command::none ) {
|
||||
m_slider.release();
|
||||
}
|
||||
}
|
||||
// if it's the right mouse button that got released and we had no command active, we were potentially in view panning mode; stop it
|
||||
if( Button == GLFW_MOUSE_BUTTON_RIGHT ) {
|
||||
m_pickmodepanning = false;
|
||||
@@ -140,11 +258,6 @@ mouse_input::button( int const Button, int const Action ) {
|
||||
default: { break; }
|
||||
}
|
||||
}
|
||||
// NOTE: basic keyboard controls don't have any parameters
|
||||
// NOTE: as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
|
||||
// TODO: pass correct entity id once the missing systems are in place
|
||||
m_relay.post( mousecommand, 0, 0, Action, 0 );
|
||||
m_updateaccumulator = -0.25; // prevent potential command repeat right after issuing one
|
||||
|
||||
switch( mousecommand ) {
|
||||
case user_command::mastercontrollerincrease:
|
||||
@@ -161,10 +274,23 @@ mouse_input::button( int const Button, int const Action ) {
|
||||
m_varyingpollrate = true;
|
||||
break;
|
||||
}
|
||||
case user_command::mastercontrollerset:
|
||||
case user_command::secondcontrollerset:
|
||||
case user_command::trainbrakeset:
|
||||
case user_command::independentbrakeset: {
|
||||
m_slider.bind( mousecommand );
|
||||
mousecommand = user_command::none;
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// NOTE: basic keyboard controls don't have any parameters
|
||||
// NOTE: as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
|
||||
// TODO: pass correct entity id once the missing systems are in place
|
||||
m_relay.post( mousecommand, 0, 0, Action, 0 );
|
||||
m_updateaccumulator = -0.25; // prevent potential command repeat right after issuing one
|
||||
}
|
||||
else {
|
||||
// if we don't have any recognized element under the cursor and the right button was pressed, enter view panning mode
|
||||
@@ -204,16 +330,25 @@ mouse_input::poll() {
|
||||
}
|
||||
}
|
||||
|
||||
user_command
|
||||
mouse_input::command() const {
|
||||
|
||||
return (
|
||||
m_slider.command() != user_command::none ? m_slider.command() :
|
||||
m_mousecommandleft != user_command::none ? m_mousecommandleft :
|
||||
m_mousecommandright );
|
||||
}
|
||||
|
||||
void
|
||||
mouse_input::default_bindings() {
|
||||
|
||||
m_mousecommands = {
|
||||
{ "mainctrl:", {
|
||||
user_command::mastercontrollerincrease,
|
||||
user_command::mastercontrollerdecrease } },
|
||||
user_command::mastercontrollerset,
|
||||
user_command::none } },
|
||||
{ "scndctrl:", {
|
||||
user_command::secondcontrollerincrease,
|
||||
user_command::secondcontrollerdecrease } },
|
||||
user_command::secondcontrollerset,
|
||||
user_command::none } },
|
||||
{ "shuntmodepower:", {
|
||||
user_command::secondcontrollerincrease,
|
||||
user_command::secondcontrollerdecrease } },
|
||||
@@ -221,11 +356,11 @@ mouse_input::default_bindings() {
|
||||
user_command::reverserincrease,
|
||||
user_command::reverserdecrease } },
|
||||
{ "brakectrl:", {
|
||||
user_command::trainbrakeincrease,
|
||||
user_command::trainbrakedecrease } },
|
||||
user_command::trainbrakeset,
|
||||
user_command::none } },
|
||||
{ "localbrake:", {
|
||||
user_command::independentbrakeincrease,
|
||||
user_command::independentbrakedecrease } },
|
||||
user_command::independentbrakeset,
|
||||
user_command::none } },
|
||||
{ "manualbrake:", {
|
||||
user_command::manualbrakeincrease,
|
||||
user_command::manualbrakedecrease } },
|
||||
|
||||
33
mouseinput.h
33
mouseinput.h
@@ -12,6 +12,36 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include <unordered_map>
|
||||
#include "command.h"
|
||||
|
||||
// virtual slider; value determined by position of the mouse
|
||||
class mouse_slider {
|
||||
|
||||
public:
|
||||
// constructors
|
||||
mouse_slider() = default;
|
||||
// methods
|
||||
void
|
||||
bind( user_command const &Command );
|
||||
void
|
||||
release();
|
||||
void
|
||||
on_move( double const Mousex, double const Mousey );
|
||||
inline
|
||||
user_command
|
||||
command() const {
|
||||
return m_command; }
|
||||
double
|
||||
value() const {
|
||||
return m_value; }
|
||||
|
||||
private:
|
||||
// members
|
||||
user_command m_command { user_command::none };
|
||||
double m_value { 0.0 };
|
||||
double m_valuerange { 0.0 };
|
||||
bool m_analogue { false };
|
||||
glm::dvec2 m_cursorposition { 0.0 };
|
||||
};
|
||||
|
||||
class mouse_input {
|
||||
|
||||
public:
|
||||
@@ -27,6 +57,8 @@ public:
|
||||
move( double const Mousex, double const Mousey );
|
||||
void
|
||||
poll();
|
||||
user_command
|
||||
command() const;
|
||||
|
||||
private:
|
||||
// types
|
||||
@@ -44,6 +76,7 @@ private:
|
||||
|
||||
// members
|
||||
command_relay m_relay;
|
||||
mouse_slider m_slider; // virtual control, when active translates intercepted mouse position to a value
|
||||
controlcommands_map m_mousecommands;
|
||||
user_command m_mousecommandleft { user_command::none }; // last if any command issued with left mouse button
|
||||
user_command m_mousecommandright { user_command::none }; // last if any command issued with right mouse button
|
||||
|
||||
151
scene.cpp
151
scene.cpp
@@ -1118,7 +1118,7 @@ basic_region::RadioStop( glm::dvec3 const &Location ) {
|
||||
}
|
||||
|
||||
void
|
||||
basic_region::insert_shape( shape_node Shape, scratch_data &Scratchpad, bool const Transform ) {
|
||||
basic_region::insert( shape_node Shape, scratch_data &Scratchpad, bool const Transform ) {
|
||||
|
||||
// shape might need to be split into smaller pieces, so we create list of nodes instead of just single one
|
||||
// using deque so we can do single pass iterating and addding generated pieces without invalidating anything
|
||||
@@ -1182,7 +1182,7 @@ basic_region::insert_shape( shape_node Shape, scratch_data &Scratchpad, bool con
|
||||
|
||||
// inserts provided lines in the region
|
||||
void
|
||||
basic_region::insert_lines( lines_node Lines, scratch_data &Scratchpad ) {
|
||||
basic_region::insert( lines_node Lines, scratch_data &Scratchpad ) {
|
||||
|
||||
if( Lines.m_data.vertices.empty() ) { return; }
|
||||
// transform point coordinates if needed
|
||||
@@ -1224,135 +1224,6 @@ basic_region::insert_lines( lines_node Lines, scratch_data &Scratchpad ) {
|
||||
}
|
||||
}
|
||||
|
||||
// inserts provided track in the region
|
||||
void
|
||||
basic_region::insert_path( TTrack *Path, scratch_data &Scratchpad ) {
|
||||
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
||||
auto location = Path->location();
|
||||
|
||||
if( point_inside( location ) ) {
|
||||
// NOTE: nodes placed outside of region boundaries are discarded
|
||||
section( location ).insert( Path );
|
||||
}
|
||||
else {
|
||||
// tracks are guaranteed to hava a name so we can skip the check
|
||||
ErrorLog( "Bad scenario: track node \"" + Path->name() + "\" placed in location outside region bounds (" + to_string( location ) + ")" );
|
||||
}
|
||||
// also register path ends in appropriate sections, for path merging lookups
|
||||
// TODO: clean this up during track refactoring
|
||||
for( auto &point : Path->endpoints() ) {
|
||||
register_path( Path, point );
|
||||
}
|
||||
}
|
||||
|
||||
// inserts provided track in the region
|
||||
void
|
||||
basic_region::insert_traction( TTraction *Traction, scratch_data &Scratchpad ) {
|
||||
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
||||
auto location = Traction->location();
|
||||
|
||||
if( point_inside( location ) ) {
|
||||
// NOTE: nodes placed outside of region boundaries are discarded
|
||||
section( location ).insert( Traction );
|
||||
}
|
||||
else {
|
||||
// tracks are guaranteed to hava a name so we can skip the check
|
||||
ErrorLog( "Bad scenario: traction node \"" + Traction->name() + "\" placed in location outside region bounds (" + to_string( location ) + ")" );
|
||||
}
|
||||
// also register traction ends in appropriate sections, for path merging lookups
|
||||
// TODO: clean this up during track refactoring
|
||||
for( auto &point : Traction->endpoints() ) {
|
||||
register_traction( Traction, point );
|
||||
}
|
||||
}
|
||||
|
||||
// inserts provided instance of 3d model in the region
|
||||
void
|
||||
basic_region::insert_instance( TAnimModel *Instance, scratch_data &Scratchpad ) {
|
||||
|
||||
auto const location { Instance->location() };
|
||||
|
||||
if( point_inside( location ) ) {
|
||||
// NOTE: nodes placed outside of region boundaries are discarded
|
||||
section( location ).insert( Instance );
|
||||
}
|
||||
else {
|
||||
// tracks are guaranteed to hava a name so we can skip the check
|
||||
ErrorLog( "Bad scenario: model node \"" + Instance->name() + "\" placed in location outside region bounds (" + to_string( location ) + ")" );
|
||||
}
|
||||
}
|
||||
|
||||
// removes specified instance of 3d model from the region
|
||||
void
|
||||
basic_region::erase_instance( TAnimModel *Instance ) {
|
||||
|
||||
auto const location { Instance->location() };
|
||||
|
||||
if( point_inside( location ) ) {
|
||||
// NOTE: nodes placed outside of region boundaries are discarded
|
||||
section( location ).erase( Instance );
|
||||
}
|
||||
}
|
||||
|
||||
// removes specified memory cell from the region
|
||||
void
|
||||
basic_region::erase_memorycell( TMemCell *Memorycell ) {
|
||||
|
||||
auto const location { Memorycell->location() };
|
||||
|
||||
if( point_inside( location ) ) {
|
||||
section( location ).erase( Memorycell );
|
||||
}
|
||||
}
|
||||
|
||||
// inserts provided sound in the region
|
||||
void
|
||||
basic_region::insert_sound( sound_source *Sound, scratch_data &Scratchpad ) {
|
||||
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
||||
auto location = Sound->location();
|
||||
|
||||
if( point_inside( location ) ) {
|
||||
// NOTE: nodes placed outside of region boundaries are discarded
|
||||
section( location ).insert( Sound );
|
||||
}
|
||||
else {
|
||||
// tracks are guaranteed to hava a name so we can skip the check
|
||||
ErrorLog( "Bad scenario: sound node \"" + Sound->name() + "\" placed in location outside region bounds (" + to_string( location ) + ")" );
|
||||
}
|
||||
}
|
||||
|
||||
// inserts provided event launcher in the region
|
||||
void
|
||||
basic_region::insert_launcher( TEventLauncher *Launcher, scratch_data &Scratchpad ) {
|
||||
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
||||
auto location = Launcher->location();
|
||||
|
||||
if( point_inside( location ) ) {
|
||||
// NOTE: nodes placed outside of region boundaries are discarded
|
||||
section( location ).insert( Launcher );
|
||||
}
|
||||
else {
|
||||
// tracks are guaranteed to hava a name so we can skip the check
|
||||
ErrorLog( "Bad scenario: event launcher \"" + Launcher->name() + "\" placed in location outside region bounds (" + to_string( location ) + ")" );
|
||||
}
|
||||
}
|
||||
|
||||
// inserts provided memory cell in the region
|
||||
void
|
||||
basic_region::insert_memorycell( TMemCell *Memorycell, scratch_data &Scratchpad ) {
|
||||
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
|
||||
auto location = Memorycell->location();
|
||||
|
||||
if( point_inside( location ) ) {
|
||||
// NOTE: nodes placed outside of region boundaries are discarded
|
||||
section( location ).insert( Memorycell );
|
||||
}
|
||||
else {
|
||||
// tracks are guaranteed to hava a name so we can skip the check
|
||||
ErrorLog( "Bad scenario: memory cell \"" + Memorycell->name() + "\" placed in location outside region bounds (" + to_string( location ) + ")" );
|
||||
}
|
||||
}
|
||||
|
||||
// find a vehicle located neares to specified location, within specified radius, optionally discarding vehicles without drivers
|
||||
std::tuple<TDynamicObject *, float>
|
||||
basic_region::find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler ) {
|
||||
@@ -1463,24 +1334,6 @@ basic_region::sections( glm::dvec3 const &Point, float const Radius ) {
|
||||
return m_scratchpad.sections;
|
||||
}
|
||||
|
||||
// registers specified path in the lookup directory of a cell enclosing specified point
|
||||
void
|
||||
basic_region::register_path( TTrack *Path, glm::dvec3 const &Point ) {
|
||||
|
||||
if( point_inside( Point ) ) {
|
||||
section( Point ).register_node( Path, Point );
|
||||
}
|
||||
}
|
||||
|
||||
// registers specified end point of the provided traction piece in the lookup directory of the region
|
||||
void
|
||||
basic_region::register_traction( TTraction *Traction, glm::dvec3 const &Point ) {
|
||||
|
||||
if( point_inside( Point ) ) {
|
||||
section( Point ).register_node( Traction, Point );
|
||||
}
|
||||
}
|
||||
|
||||
// checks whether specified point is within boundaries of the region
|
||||
bool
|
||||
basic_region::point_inside( glm::dvec3 const &Location ) {
|
||||
|
||||
53
scene.h
53
scene.h
@@ -339,34 +339,35 @@ public:
|
||||
RadioStop( glm::dvec3 const &Location );
|
||||
// inserts provided shape in the region
|
||||
void
|
||||
insert_shape( shape_node Shape, scratch_data &Scratchpad, bool const Transform );
|
||||
insert( shape_node Shape, scratch_data &Scratchpad, bool const Transform );
|
||||
// inserts provided lines in the region
|
||||
void
|
||||
insert_lines( lines_node Lines, scratch_data &Scratchpad );
|
||||
// inserts provided track in the region
|
||||
insert( lines_node Lines, scratch_data &Scratchpad );
|
||||
// inserts provided node in the region
|
||||
template <class Type_>
|
||||
void
|
||||
insert_path( TTrack *Path, scratch_data &Scratchpad );
|
||||
// inserts provided track in the region
|
||||
insert( Type_ *Node ) {
|
||||
auto const location { Node->location() };
|
||||
if( false == point_inside( location ) ) {
|
||||
// NOTE: nodes placed outside of region boundaries are discarded
|
||||
// TBD, TODO: clamp coordinates to region boundaries?
|
||||
return; }
|
||||
section( location ).insert( Node ); }
|
||||
// inserts provided node in the region and registers its ends in lookup directory
|
||||
template <class Type_>
|
||||
void
|
||||
insert_traction( TTraction *Traction, scratch_data &Scratchpad );
|
||||
// inserts provided instance of 3d model in the region
|
||||
insert_and_register( Type_ *Node ) {
|
||||
insert( Node );
|
||||
for( auto const &point : Node->endpoints() ) {
|
||||
if( point_inside( point ) ) {
|
||||
section( point ).register_node( Node, point ); } } }
|
||||
// removes specified node from the region
|
||||
template <class Type_>
|
||||
void
|
||||
insert_instance( TAnimModel *Instance, scratch_data &Scratchpad );
|
||||
// inserts provided sound in the region
|
||||
void
|
||||
insert_sound( sound_source *Sound, scratch_data &Scratchpad );
|
||||
// inserts provided event launcher in the region
|
||||
void
|
||||
insert_launcher( TEventLauncher *Launcher, scratch_data &Scratchpad );
|
||||
// inserts provided memory cell in the region
|
||||
void
|
||||
insert_memorycell( TMemCell *Memorycell, scratch_data &Scratchpad );
|
||||
// removes specified instance of 3d model from the region
|
||||
void
|
||||
erase_instance( TAnimModel *Instance );
|
||||
// removes specified memory cell from the region
|
||||
void
|
||||
erase_memorycell( TMemCell *Memorycell );
|
||||
erase( Type_ *Node ) {
|
||||
auto const location{ Node->location() };
|
||||
if( point_inside( location ) ) {
|
||||
section( location ).erase( Node ); } }
|
||||
// find a vehicle located nearest to specified point, within specified radius. reurns: located vehicle and distance
|
||||
std::tuple<TDynamicObject *, float>
|
||||
find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler );
|
||||
@@ -393,12 +394,6 @@ private:
|
||||
};
|
||||
|
||||
// methods
|
||||
// registers specified end point of the provided path in the lookup directory of the region
|
||||
void
|
||||
register_path( TTrack *Path, glm::dvec3 const &Point );
|
||||
// registers specified end point of the provided traction piece in the lookup directory of the region
|
||||
void
|
||||
register_traction( TTraction *Traction, glm::dvec3 const &Point );
|
||||
// checks whether specified point is within boundaries of the region
|
||||
bool
|
||||
point_inside( glm::dvec3 const &Location );
|
||||
|
||||
@@ -12,6 +12,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "globals.h"
|
||||
#include "simulation.h"
|
||||
#include "uilayer.h"
|
||||
#include "renderer.h"
|
||||
|
||||
namespace scene {
|
||||
@@ -46,7 +47,7 @@ basic_editor::on_mouse_button( int const Button, int const Action ) {
|
||||
m_node = GfxRenderer.Update_Pick_Node();
|
||||
m_nodesnapshot = { m_node };
|
||||
if( m_node ) {
|
||||
glfwSetInputMode( Global.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED );
|
||||
UILayer.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -54,7 +55,7 @@ basic_editor::on_mouse_button( int const Button, int const Action ) {
|
||||
// TODO: record the current undo step on the undo stack
|
||||
m_nodesnapshot = { m_node };
|
||||
if( m_node ) {
|
||||
glfwSetInputMode( Global.window, GLFW_CURSOR, GLFW_CURSOR_NORMAL );
|
||||
UILayer.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,9 +137,9 @@ basic_editor::translate( float const Offset ) {
|
||||
void
|
||||
basic_editor::translate_instance( TAnimModel *Instance, glm::dvec3 const &Location ) {
|
||||
|
||||
simulation::Region->erase_instance( Instance );
|
||||
simulation::Region->erase( Instance );
|
||||
Instance->location( Location );
|
||||
simulation::Region->insert_instance( Instance, scene::scratch_data() );
|
||||
simulation::Region->insert( Instance );
|
||||
}
|
||||
|
||||
void
|
||||
@@ -152,9 +153,9 @@ basic_editor::translate_instance( TAnimModel *Instance, float const Offset ) {
|
||||
void
|
||||
basic_editor::translate_memorycell( TMemCell *Memorycell, glm::dvec3 const &Location ) {
|
||||
|
||||
simulation::Region->erase_memorycell( Memorycell );
|
||||
simulation::Region->erase( Memorycell );
|
||||
Memorycell->location( Location );
|
||||
simulation::Region->insert_memorycell( Memorycell, scene::scratch_data() );
|
||||
simulation::Region->insert( Memorycell );
|
||||
}
|
||||
|
||||
void
|
||||
@@ -182,8 +183,8 @@ basic_editor::rotate_instance( TAnimModel *Instance, glm::vec3 const &Angle ) {
|
||||
glm::vec3 angle = glm::dvec3 { Instance->Angles() };
|
||||
angle.y = clamp_circular( angle.y + Angle.y, 360.f );
|
||||
if( mode_snap() ) {
|
||||
auto const quantizationstep { 15.f };
|
||||
angle.y = quantizationstep * std::round( angle.y * ( 1.f / quantizationstep ) );
|
||||
// TBD, TODO: adjustable quantization step
|
||||
angle.y = quantize( angle.y, 15.f );
|
||||
}
|
||||
Instance->Angles( angle );
|
||||
// update scene
|
||||
|
||||
@@ -327,7 +327,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
||||
delete pathnode;
|
||||
*/
|
||||
}
|
||||
simulation::Region->insert_path( path, Scratchpad );
|
||||
simulation::Region->insert_and_register( path );
|
||||
}
|
||||
else if( nodedata.type == "traction" ) {
|
||||
|
||||
@@ -338,7 +338,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
||||
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 ) + ")" );
|
||||
}
|
||||
simulation::Region->insert_traction( traction, Scratchpad );
|
||||
simulation::Region->insert_and_register( traction );
|
||||
}
|
||||
else if( nodedata.type == "tractionpowersource" ) {
|
||||
|
||||
@@ -367,14 +367,14 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
||||
auto const cellcount = instance->TerrainCount() + 1; // zliczenie submodeli
|
||||
for( auto i = 1; i < cellcount; ++i ) {
|
||||
auto *submodel = instance->TerrainSquare( i - 1 );
|
||||
simulation::Region->insert_shape(
|
||||
simulation::Region->insert(
|
||||
scene::shape_node().convert( submodel ),
|
||||
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(
|
||||
scene::shape_node().convert( submodel ),
|
||||
Scratchpad,
|
||||
false );
|
||||
@@ -398,7 +398,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
||||
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 ) + ")" );
|
||||
}
|
||||
simulation::Region->insert_instance( instance, Scratchpad );
|
||||
simulation::Region->insert( instance );
|
||||
}
|
||||
}
|
||||
else if( ( nodedata.type == "triangles" )
|
||||
@@ -407,7 +407,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
||||
|
||||
if( false == Scratchpad.binary.terrain ) {
|
||||
|
||||
simulation::Region->insert_shape(
|
||||
simulation::Region->insert(
|
||||
scene::shape_node().import(
|
||||
Input, nodedata ),
|
||||
Scratchpad,
|
||||
@@ -424,7 +424,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
||||
|
||||
if( false == Scratchpad.binary.terrain ) {
|
||||
|
||||
simulation::Region->insert_lines(
|
||||
simulation::Region->insert(
|
||||
scene::lines_node().import(
|
||||
Input, nodedata ),
|
||||
Scratchpad );
|
||||
@@ -440,7 +440,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
||||
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 ) + ")" );
|
||||
}
|
||||
simulation::Region->insert_memorycell( memorycell, Scratchpad );
|
||||
simulation::Region->insert( memorycell );
|
||||
}
|
||||
else if( nodedata.type == "eventlauncher" ) {
|
||||
|
||||
@@ -454,7 +454,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
||||
simulation::Events.queue( eventlauncher );
|
||||
}
|
||||
else {
|
||||
simulation::Region->insert_launcher( eventlauncher, Scratchpad );
|
||||
simulation::Region->insert( eventlauncher );
|
||||
}
|
||||
}
|
||||
else if( nodedata.type == "sound" ) {
|
||||
@@ -463,7 +463,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
||||
if( false == simulation::Sounds.insert( sound ) ) {
|
||||
ErrorLog( "Bad scenario: sound node with duplicate name \"" + sound->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
|
||||
}
|
||||
simulation::Region->insert_sound( sound, Scratchpad );
|
||||
simulation::Region->insert( sound );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
4
uart.cpp
4
uart.cpp
@@ -208,7 +208,7 @@ void uart_input::poll()
|
||||
double const position { (float)( ( (uint16_t)buffer[ 8 ] | ( (uint16_t)buffer[ 9 ] << 8 ) ) - conf.mainbrakemin ) / ( conf.mainbrakemax - conf.mainbrakemin ) };
|
||||
relay.post(
|
||||
user_command::trainbrakeset,
|
||||
reinterpret_cast<std::uint64_t const &>( position ),
|
||||
position,
|
||||
0,
|
||||
GLFW_PRESS,
|
||||
// TODO: pass correct entity id once the missing systems are in place
|
||||
@@ -219,7 +219,7 @@ void uart_input::poll()
|
||||
double const position { (float)( ( (uint16_t)buffer[ 10 ] | ( (uint16_t)buffer[ 11 ] << 8 ) ) - conf.localbrakemin ) / ( conf.localbrakemax - conf.localbrakemin ) };
|
||||
relay.post(
|
||||
user_command::independentbrakeset,
|
||||
reinterpret_cast<std::uint64_t const &>( position ),
|
||||
position,
|
||||
0,
|
||||
GLFW_PRESS,
|
||||
// TODO: pass correct entity id once the missing systems are in place
|
||||
|
||||
10
uilayer.cpp
10
uilayer.cpp
@@ -109,7 +109,7 @@ ui_layer::on_key( int const Key, int const Action ) {
|
||||
EditorModeFlag = ( Key == GLFW_KEY_F11 );
|
||||
if( ( true == EditorModeFlag )
|
||||
&& ( false == Global.ControlPicking ) ) {
|
||||
glfwSetInputMode( m_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL );
|
||||
set_cursor( GLFW_CURSOR_NORMAL );
|
||||
Global.ControlPicking = true;
|
||||
}
|
||||
}
|
||||
@@ -1113,6 +1113,13 @@ ui_layer::render() {
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
void
|
||||
ui_layer::set_cursor( int const Mode ) {
|
||||
|
||||
glfwSetInputMode( m_window, GLFW_CURSOR, Mode );
|
||||
m_cursorvisible = ( Mode != GLFW_CURSOR_DISABLED );
|
||||
}
|
||||
|
||||
void
|
||||
ui_layer::set_progress( float const Progress, float const Subtaskprogress ) {
|
||||
|
||||
@@ -1214,6 +1221,7 @@ void
|
||||
ui_layer::render_tooltip() {
|
||||
|
||||
if( m_tooltip.empty() ) { return; }
|
||||
if( false == m_cursorvisible ) { return; }
|
||||
|
||||
glm::dvec2 mousepos;
|
||||
glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y );
|
||||
|
||||
@@ -52,6 +52,9 @@ public:
|
||||
// draws requested UI elements
|
||||
void
|
||||
render();
|
||||
//
|
||||
void
|
||||
set_cursor( int const Mode );
|
||||
// stores operation progress
|
||||
void
|
||||
set_progress( float const Progress = 0.0f, float const Subtaskprogress = 0.0f );
|
||||
@@ -114,6 +117,7 @@ private:
|
||||
int tprev; // poprzedni czas
|
||||
double VelPrev; // poprzednia prędkość
|
||||
double Acc; // przyspieszenie styczne
|
||||
bool m_cursorvisible { false };
|
||||
};
|
||||
|
||||
extern ui_layer UILayer;
|
||||
|
||||
@@ -228,6 +228,13 @@ clamp_circular( Type_ Value, Type_ const Range = static_cast<Type_>(360) ) {
|
||||
return Value;
|
||||
}
|
||||
|
||||
template <typename Type_>
|
||||
Type_
|
||||
quantize( Type_ const Value, Type_ const Step ) {
|
||||
|
||||
return ( Step * std::round( Value / Step ) );
|
||||
}
|
||||
|
||||
template <typename Type_>
|
||||
Type_
|
||||
min_speed( Type_ const Left, Type_ const Right ) {
|
||||
|
||||
Reference in New Issue
Block a user