mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 11:39:19 +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: {
|
case user_command::viewturn: {
|
||||||
|
|
||||||
OnCursorMove(
|
OnCursorMove(
|
||||||
reinterpret_cast<double const &>( Command.param1 ) * 0.005 * Global.fMouseXScale / Global.ZoomFactor,
|
Command.param1 * 0.005 * Global.fMouseXScale / Global.ZoomFactor,
|
||||||
reinterpret_cast<double const &>( Command.param2 ) * 0.01 * Global.fMouseYScale / Global.ZoomFactor );
|
Command.param2 * 0.01 * Global.fMouseYScale / Global.ZoomFactor );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ TCamera::OnCommand( command_data const &Command ) {
|
|||||||
1.0 );
|
1.0 );
|
||||||
|
|
||||||
// left-right
|
// 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
|
// 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 ) };
|
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 );
|
0.0 );
|
||||||
|
|
||||||
// forward-back
|
// 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 ) };
|
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
|
// NOTE: z-axis is flipped given world coordinate system
|
||||||
m_moverate.z = (
|
m_moverate.z = (
|
||||||
@@ -121,7 +121,7 @@ TCamera::OnCommand( command_data const &Command ) {
|
|||||||
1.0 );
|
1.0 );
|
||||||
|
|
||||||
// up-down
|
// 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
|
// 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 ) };
|
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;
|
gamepad_input Gamepad;
|
||||||
glm::dvec2 mouse_pickmodepos; // stores last mouse position in control picking mode
|
glm::dvec2 mouse_pickmodepos; // stores last mouse position in control picking mode
|
||||||
std::unique_ptr<uart_input> uart;
|
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 ) {
|
if( Global.ControlPicking ) {
|
||||||
// switch off
|
// switch off
|
||||||
glfwGetCursorPos( window, &input::mouse_pickmodepos.x, &input::mouse_pickmodepos.y );
|
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 );
|
glfwSetCursorPos( window, 0, 0 );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// enter picking mode
|
// enter picking mode
|
||||||
glfwSetInputMode( window, GLFW_CURSOR, GLFW_CURSOR_NORMAL );
|
|
||||||
glfwSetCursorPos( window, input::mouse_pickmodepos.x, input::mouse_pickmodepos.y );
|
glfwSetCursorPos( window, input::mouse_pickmodepos.x, input::mouse_pickmodepos.y );
|
||||||
|
UILayer.set_cursor( GLFW_CURSOR_NORMAL );
|
||||||
}
|
}
|
||||||
// actually toggle the mode
|
// actually toggle the mode
|
||||||
Global.ControlPicking = !Global.ControlPicking;
|
Global.ControlPicking = !Global.ControlPicking;
|
||||||
@@ -461,6 +462,11 @@ int main(int argc, char *argv[])
|
|||||||
if( true == Global.InputMouse ) { input::Mouse.poll(); }
|
if( true == Global.InputMouse ) { input::Mouse.poll(); }
|
||||||
if( true == Global.InputGamepad ) { input::Gamepad.poll(); }
|
if( true == Global.InputGamepad ) { input::Gamepad.poll(); }
|
||||||
if( input::uart != nullptr ) { input::uart->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 ) {
|
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->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ć
|
trk->location( glm::dvec3{ -dx, 0, 200 } ); //środek, aby się mogło wyświetlić
|
||||||
simulation::Paths.insert( trk );
|
simulation::Paths.insert( trk );
|
||||||
simulation::Region->insert_path( trk, scene::scratch_data() );
|
simulation::Region->insert( trk );
|
||||||
return 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
|
// 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ć
|
trk->location( glm::dvec3{ 0.5 * ( p1 + p2 ) } ); //środek, aby się mogło wyświetlić
|
||||||
simulation::Paths.insert( trk );
|
simulation::Paths.insert( trk );
|
||||||
simulation::Region->insert_path( trk, scene::scratch_data() );
|
simulation::Region->insert( trk );
|
||||||
if( trk2 ) {
|
if( trk2 ) {
|
||||||
trk2->location( trk->location() ); // ten sam środek jest
|
trk2->location( trk->location() ); // ten sam środek jest
|
||||||
simulation::Paths.insert( trk2 );
|
simulation::Paths.insert( trk2 );
|
||||||
simulation::Region->insert_path( trk2, scene::scratch_data() );
|
simulation::Region->insert( trk2 );
|
||||||
}
|
}
|
||||||
return trk;
|
return trk;
|
||||||
};
|
};
|
||||||
|
|||||||
67
Train.cpp
67
Train.cpp
@@ -26,6 +26,12 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "mtable.h"
|
#include "mtable.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
|
|
||||||
|
namespace input {
|
||||||
|
|
||||||
|
extern user_command command;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
control_mapper::insert( TGauge const &Gauge, std::string const &Label ) {
|
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 = (
|
Train->mvControlled->LocalBrakePosA = (
|
||||||
clamp(
|
clamp(
|
||||||
reinterpret_cast<double const &>( Command.param1 ),
|
Command.param1,
|
||||||
0.0, 1.0 ) );
|
0.0, 1.0 ) );
|
||||||
/*
|
/*
|
||||||
Train->mvControlled->LocalBrakePos = (
|
Train->mvControlled->LocalBrakePos = (
|
||||||
@@ -931,7 +937,7 @@ void TTrain::OnCommand_independentbrakeset( TTrain *Train, command_data const &C
|
|||||||
0.0,
|
0.0,
|
||||||
LocalBrakePosNo,
|
LocalBrakePosNo,
|
||||||
clamp(
|
clamp(
|
||||||
reinterpret_cast<double const &>( Command.param1 ),
|
Command.param1,
|
||||||
0.0, 1.0 ) ) ) );
|
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 );
|
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 ) {
|
void TTrain::OnCommand_trainbrakeset( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
Train->mvControlled->BrakeLevelSet(
|
Train->mvOccupied->BrakeLevelSet(
|
||||||
interpolate(
|
interpolate(
|
||||||
Train->mvControlled->Handle->GetPos( bh_MIN ),
|
Train->mvOccupied->Handle->GetPos( bh_MIN ),
|
||||||
Train->mvControlled->Handle->GetPos( bh_MAX ),
|
Train->mvOccupied->Handle->GetPos( bh_MAX ),
|
||||||
clamp(
|
clamp(
|
||||||
reinterpret_cast<double const &>( Command.param1 ),
|
Command.param1,
|
||||||
0.0, 1.0 ) ) );
|
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
|
{ // Ra: TODO: odczyty klawiatury/pulpitu nie powinny być uzależnione od istnienia modelu kabiny
|
||||||
|
|
||||||
if( ( DynamicObject->Mechanik != nullptr )
|
if( ( DynamicObject->Mechanik != nullptr )
|
||||||
&& ( false == DynamicObject->Mechanik->AIControllFlag ) // nie blokujemy AI
|
&& ( false == DynamicObject->Mechanik->AIControllFlag ) ) {
|
||||||
&& ( ( mvOccupied->TrainType == dt_ET40 )
|
// nie blokujemy AI
|
||||||
|| ( mvOccupied->TrainType == dt_EP05 ) ) ) {
|
if( ( mvOccupied->TrainType == dt_ET40 )
|
||||||
// dla ET40 i EU05 automatyczne cofanie nastawnika - i tak nie będzie to działać dobrze...
|
|| ( mvOccupied->TrainType == dt_EP05 ) ) {
|
||||||
// TODO: remove direct keyboard check, use deltatime to stabilize speed
|
// dla ET40 i EU05 automatyczne cofanie nastawnika - i tak nie będzie to działać dobrze...
|
||||||
if( ( glfwGetKey( Global.window, GLFW_KEY_KP_ADD ) != GLFW_TRUE )
|
// TODO: use deltatime to stabilize speed
|
||||||
&& ( mvOccupied->MainCtrlPos > mvOccupied->MainCtrlActualPos ) ) {
|
if( false == (
|
||||||
mvOccupied->DecMainCtrl( 1 );
|
( 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 ) ) {
|
if( ( mvOccupied->BrakeHandle == FVel6 )
|
||||||
mvOccupied->IncMainCtrl( 1 ); // Ra 15-01: a to nie miało być tylko cofanie?
|
&& ( 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 TDynamicObject const *Dynamic() const { return DynamicObject; };
|
||||||
inline TMoverParameters *Controlled() { return mvControlled; };
|
inline TMoverParameters *Controlled() { return mvControlled; };
|
||||||
inline TMoverParameters const *Controlled() const { 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);
|
void DynamicSet(TDynamicObject *d);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ command_queue::pop( command_data &Command, std::size_t const Recipient ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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 ) ];
|
auto const &command = simulation::Commands_descriptions[ static_cast<std::size_t>( Command ) ];
|
||||||
if( ( command.target == command_target::vehicle )
|
if( ( command.target == command_target::vehicle )
|
||||||
|
|||||||
@@ -231,8 +231,8 @@ struct command_data {
|
|||||||
|
|
||||||
user_command command;
|
user_command command;
|
||||||
int action; // press, repeat or release
|
int action; // press, repeat or release
|
||||||
std::uint64_t param1;
|
double param1;
|
||||||
std::uint64_t param2;
|
double param2;
|
||||||
double time_delta;
|
double time_delta;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -282,7 +282,7 @@ public:
|
|||||||
// posts specified command for the specified recipient
|
// posts specified command for the specified recipient
|
||||||
// TODO: replace uint16_t with recipient handle, based on item id
|
// TODO: replace uint16_t with recipient handle, based on item id
|
||||||
void
|
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;
|
int const Action, std::uint16_t const Recipient ) const;
|
||||||
private:
|
private:
|
||||||
// types
|
// 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;
|
double const turny = -Rightstick.y * 10.0 * deltatime;
|
||||||
m_relay.post(
|
m_relay.post(
|
||||||
user_command::viewturn,
|
user_command::viewturn,
|
||||||
reinterpret_cast<std::uint64_t const &>( turnx ),
|
turnx,
|
||||||
reinterpret_cast<std::uint64_t const &>( turny ),
|
turny,
|
||||||
GLFW_PRESS,
|
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
|
// 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
|
// 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 )
|
if( ( Leftstick.x != 0.0 || Leftstick.y != 0.0 )
|
||||||
|| ( m_leftstick.x != 0.0 || m_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(
|
m_relay.post(
|
||||||
user_command::movehorizontal,
|
user_command::movehorizontal,
|
||||||
reinterpret_cast<std::uint64_t const &>( movex ),
|
Leftstick.x,
|
||||||
reinterpret_cast<std::uint64_t const &>( movez ),
|
Leftstick.y,
|
||||||
GLFW_PRESS,
|
GLFW_PRESS,
|
||||||
0 );
|
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
|
// 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
|
// TODO: pass correct entity id once the missing systems are in place
|
||||||
m_relay.post( lookup->second, 0, 0, Action, 0 );
|
m_relay.post( lookup->second, 0, 0, Action, 0 );
|
||||||
|
m_command = (
|
||||||
|
Action == GLFW_RELEASE ?
|
||||||
|
user_command::none :
|
||||||
|
lookup->second );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -600,14 +604,12 @@ keyboard_input::poll() {
|
|||||||
|
|
||||||
if( ( movementhorizontal.x != 0.f || movementhorizontal.y != 0.f )
|
if( ( movementhorizontal.x != 0.f || movementhorizontal.y != 0.f )
|
||||||
|| ( m_movementhorizontal.x != 0.f || m_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(
|
m_relay.post(
|
||||||
( true == Global.ctrlState ?
|
( true == Global.ctrlState ?
|
||||||
user_command::movehorizontalfast :
|
user_command::movehorizontalfast :
|
||||||
user_command::movehorizontal ),
|
user_command::movehorizontal ),
|
||||||
reinterpret_cast<std::uint64_t const &>( movexparam ),
|
movementhorizontal.x,
|
||||||
reinterpret_cast<std::uint64_t const &>( movezparam ),
|
movementhorizontal.y,
|
||||||
GLFW_PRESS,
|
GLFW_PRESS,
|
||||||
0 );
|
0 );
|
||||||
}
|
}
|
||||||
@@ -623,12 +625,11 @@ keyboard_input::poll() {
|
|||||||
|
|
||||||
if( ( movementvertical != 0.f )
|
if( ( movementvertical != 0.f )
|
||||||
|| ( m_movementvertical != 0.f ) ) {
|
|| ( m_movementvertical != 0.f ) ) {
|
||||||
double const moveyparam = static_cast<double>( movementvertical );
|
|
||||||
m_relay.post(
|
m_relay.post(
|
||||||
( true == Global.ctrlState ?
|
( true == Global.ctrlState ?
|
||||||
user_command::moveverticalfast :
|
user_command::moveverticalfast :
|
||||||
user_command::movevertical ),
|
user_command::movevertical ),
|
||||||
reinterpret_cast<std::uint64_t const &>( moveyparam ),
|
movementvertical,
|
||||||
0,
|
0,
|
||||||
GLFW_PRESS,
|
GLFW_PRESS,
|
||||||
0 );
|
0 );
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ public:
|
|||||||
key( int const Key, int const Action );
|
key( int const Key, int const Action );
|
||||||
void
|
void
|
||||||
poll();
|
poll();
|
||||||
|
inline
|
||||||
|
user_command const
|
||||||
|
command() const {
|
||||||
|
return m_command; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
@@ -65,6 +69,7 @@ private:
|
|||||||
|
|
||||||
// members
|
// members
|
||||||
commandsetup_sequence m_commands;
|
commandsetup_sequence m_commands;
|
||||||
|
user_command m_command; // last, if any, issued command
|
||||||
usercommand_map m_bindings;
|
usercommand_map m_bindings;
|
||||||
command_relay m_relay;
|
command_relay m_relay;
|
||||||
bool m_shift{ false };
|
bool m_shift{ false };
|
||||||
|
|||||||
169
mouseinput.cpp
169
mouseinput.cpp
@@ -16,9 +16,111 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "world.h"
|
#include "world.h"
|
||||||
#include "train.h"
|
#include "train.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
#include "uilayer.h"
|
||||||
|
|
||||||
extern TWorld World;
|
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
|
bool
|
||||||
mouse_input::init() {
|
mouse_input::init() {
|
||||||
|
|
||||||
@@ -40,8 +142,8 @@ mouse_input::move( double Mousex, double Mousey ) {
|
|||||||
// default control mode
|
// default control mode
|
||||||
m_relay.post(
|
m_relay.post(
|
||||||
user_command::viewturn,
|
user_command::viewturn,
|
||||||
reinterpret_cast<std::uint64_t const &>( Mousex ),
|
Mousex,
|
||||||
reinterpret_cast<std::uint64_t const &>( Mousey ),
|
Mousey,
|
||||||
GLFW_PRESS,
|
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
|
// 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
|
// TODO: pass correct entity id once the missing systems are in place
|
||||||
@@ -49,6 +151,17 @@ mouse_input::move( double Mousex, double Mousey ) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// control picking mode
|
// 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 ) {
|
if( false == m_pickmodepanning ) {
|
||||||
// even if the view panning isn't active we capture the cursor position in case it does get activated
|
// even if the view panning isn't active we capture the cursor position in case it does get activated
|
||||||
m_cursorposition.x = Mousex;
|
m_cursorposition.x = Mousex;
|
||||||
@@ -59,8 +172,8 @@ mouse_input::move( double Mousex, double Mousey ) {
|
|||||||
auto const viewoffset = cursorposition - m_cursorposition;
|
auto const viewoffset = cursorposition - m_cursorposition;
|
||||||
m_relay.post(
|
m_relay.post(
|
||||||
user_command::viewturn,
|
user_command::viewturn,
|
||||||
reinterpret_cast<std::uint64_t const &>( viewoffset.x ),
|
viewoffset.x,
|
||||||
reinterpret_cast<std::uint64_t const &>( viewoffset.y ),
|
viewoffset.y,
|
||||||
GLFW_PRESS,
|
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
|
// 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
|
// 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;
|
mousecommand = user_command::none;
|
||||||
}
|
}
|
||||||
else {
|
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 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 ) {
|
if( Button == GLFW_MOUSE_BUTTON_RIGHT ) {
|
||||||
m_pickmodepanning = false;
|
m_pickmodepanning = false;
|
||||||
@@ -140,11 +258,6 @@ mouse_input::button( int const Button, int const Action ) {
|
|||||||
default: { break; }
|
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 ) {
|
switch( mousecommand ) {
|
||||||
case user_command::mastercontrollerincrease:
|
case user_command::mastercontrollerincrease:
|
||||||
@@ -161,10 +274,23 @@ mouse_input::button( int const Button, int const Action ) {
|
|||||||
m_varyingpollrate = true;
|
m_varyingpollrate = true;
|
||||||
break;
|
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: {
|
default: {
|
||||||
break;
|
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 {
|
else {
|
||||||
// if we don't have any recognized element under the cursor and the right button was pressed, enter view panning mode
|
// 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
|
void
|
||||||
mouse_input::default_bindings() {
|
mouse_input::default_bindings() {
|
||||||
|
|
||||||
m_mousecommands = {
|
m_mousecommands = {
|
||||||
{ "mainctrl:", {
|
{ "mainctrl:", {
|
||||||
user_command::mastercontrollerincrease,
|
user_command::mastercontrollerset,
|
||||||
user_command::mastercontrollerdecrease } },
|
user_command::none } },
|
||||||
{ "scndctrl:", {
|
{ "scndctrl:", {
|
||||||
user_command::secondcontrollerincrease,
|
user_command::secondcontrollerset,
|
||||||
user_command::secondcontrollerdecrease } },
|
user_command::none } },
|
||||||
{ "shuntmodepower:", {
|
{ "shuntmodepower:", {
|
||||||
user_command::secondcontrollerincrease,
|
user_command::secondcontrollerincrease,
|
||||||
user_command::secondcontrollerdecrease } },
|
user_command::secondcontrollerdecrease } },
|
||||||
@@ -221,11 +356,11 @@ mouse_input::default_bindings() {
|
|||||||
user_command::reverserincrease,
|
user_command::reverserincrease,
|
||||||
user_command::reverserdecrease } },
|
user_command::reverserdecrease } },
|
||||||
{ "brakectrl:", {
|
{ "brakectrl:", {
|
||||||
user_command::trainbrakeincrease,
|
user_command::trainbrakeset,
|
||||||
user_command::trainbrakedecrease } },
|
user_command::none } },
|
||||||
{ "localbrake:", {
|
{ "localbrake:", {
|
||||||
user_command::independentbrakeincrease,
|
user_command::independentbrakeset,
|
||||||
user_command::independentbrakedecrease } },
|
user_command::none } },
|
||||||
{ "manualbrake:", {
|
{ "manualbrake:", {
|
||||||
user_command::manualbrakeincrease,
|
user_command::manualbrakeincrease,
|
||||||
user_command::manualbrakedecrease } },
|
user_command::manualbrakedecrease } },
|
||||||
|
|||||||
33
mouseinput.h
33
mouseinput.h
@@ -12,6 +12,36 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "command.h"
|
#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 {
|
class mouse_input {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -27,6 +57,8 @@ public:
|
|||||||
move( double const Mousex, double const Mousey );
|
move( double const Mousex, double const Mousey );
|
||||||
void
|
void
|
||||||
poll();
|
poll();
|
||||||
|
user_command
|
||||||
|
command() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
@@ -44,6 +76,7 @@ private:
|
|||||||
|
|
||||||
// members
|
// members
|
||||||
command_relay m_relay;
|
command_relay m_relay;
|
||||||
|
mouse_slider m_slider; // virtual control, when active translates intercepted mouse position to a value
|
||||||
controlcommands_map m_mousecommands;
|
controlcommands_map m_mousecommands;
|
||||||
user_command m_mousecommandleft { user_command::none }; // last if any command issued with left mouse button
|
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
|
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
|
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
|
// 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
|
// 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
|
// inserts provided lines in the region
|
||||||
void
|
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; }
|
if( Lines.m_data.vertices.empty() ) { return; }
|
||||||
// transform point coordinates if needed
|
// 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
|
// find a vehicle located neares to specified location, within specified radius, optionally discarding vehicles without drivers
|
||||||
std::tuple<TDynamicObject *, float>
|
std::tuple<TDynamicObject *, float>
|
||||||
basic_region::find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler ) {
|
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;
|
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
|
// checks whether specified point is within boundaries of the region
|
||||||
bool
|
bool
|
||||||
basic_region::point_inside( glm::dvec3 const &Location ) {
|
basic_region::point_inside( glm::dvec3 const &Location ) {
|
||||||
|
|||||||
53
scene.h
53
scene.h
@@ -339,34 +339,35 @@ public:
|
|||||||
RadioStop( glm::dvec3 const &Location );
|
RadioStop( glm::dvec3 const &Location );
|
||||||
// inserts provided shape in the region
|
// inserts provided shape in the region
|
||||||
void
|
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
|
// inserts provided lines in the region
|
||||||
void
|
void
|
||||||
insert_lines( lines_node Lines, scratch_data &Scratchpad );
|
insert( lines_node Lines, scratch_data &Scratchpad );
|
||||||
// inserts provided track in the region
|
// inserts provided node in the region
|
||||||
|
template <class Type_>
|
||||||
void
|
void
|
||||||
insert_path( TTrack *Path, scratch_data &Scratchpad );
|
insert( Type_ *Node ) {
|
||||||
// inserts provided track in the region
|
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
|
void
|
||||||
insert_traction( TTraction *Traction, scratch_data &Scratchpad );
|
insert_and_register( Type_ *Node ) {
|
||||||
// inserts provided instance of 3d model in the region
|
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
|
void
|
||||||
insert_instance( TAnimModel *Instance, scratch_data &Scratchpad );
|
erase( Type_ *Node ) {
|
||||||
// inserts provided sound in the region
|
auto const location{ Node->location() };
|
||||||
void
|
if( point_inside( location ) ) {
|
||||||
insert_sound( sound_source *Sound, scratch_data &Scratchpad );
|
section( location ).erase( Node ); } }
|
||||||
// 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 );
|
|
||||||
// find a vehicle located nearest to specified point, within specified radius. reurns: located vehicle and distance
|
// find a vehicle located nearest to specified point, within specified radius. reurns: located vehicle and distance
|
||||||
std::tuple<TDynamicObject *, float>
|
std::tuple<TDynamicObject *, float>
|
||||||
find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler );
|
find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler );
|
||||||
@@ -393,12 +394,6 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// methods
|
// 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
|
// checks whether specified point is within boundaries of the region
|
||||||
bool
|
bool
|
||||||
point_inside( glm::dvec3 const &Location );
|
point_inside( glm::dvec3 const &Location );
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "simulation.h"
|
#include "simulation.h"
|
||||||
|
#include "uilayer.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
|
||||||
namespace scene {
|
namespace scene {
|
||||||
@@ -46,7 +47,7 @@ basic_editor::on_mouse_button( int const Button, int const Action ) {
|
|||||||
m_node = GfxRenderer.Update_Pick_Node();
|
m_node = GfxRenderer.Update_Pick_Node();
|
||||||
m_nodesnapshot = { m_node };
|
m_nodesnapshot = { m_node };
|
||||||
if( m_node ) {
|
if( m_node ) {
|
||||||
glfwSetInputMode( Global.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED );
|
UILayer.set_cursor( GLFW_CURSOR_DISABLED );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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
|
// TODO: record the current undo step on the undo stack
|
||||||
m_nodesnapshot = { m_node };
|
m_nodesnapshot = { m_node };
|
||||||
if( 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
|
void
|
||||||
basic_editor::translate_instance( TAnimModel *Instance, glm::dvec3 const &Location ) {
|
basic_editor::translate_instance( TAnimModel *Instance, glm::dvec3 const &Location ) {
|
||||||
|
|
||||||
simulation::Region->erase_instance( Instance );
|
simulation::Region->erase( Instance );
|
||||||
Instance->location( Location );
|
Instance->location( Location );
|
||||||
simulation::Region->insert_instance( Instance, scene::scratch_data() );
|
simulation::Region->insert( Instance );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -152,9 +153,9 @@ basic_editor::translate_instance( TAnimModel *Instance, float const Offset ) {
|
|||||||
void
|
void
|
||||||
basic_editor::translate_memorycell( TMemCell *Memorycell, glm::dvec3 const &Location ) {
|
basic_editor::translate_memorycell( TMemCell *Memorycell, glm::dvec3 const &Location ) {
|
||||||
|
|
||||||
simulation::Region->erase_memorycell( Memorycell );
|
simulation::Region->erase( Memorycell );
|
||||||
Memorycell->location( Location );
|
Memorycell->location( Location );
|
||||||
simulation::Region->insert_memorycell( Memorycell, scene::scratch_data() );
|
simulation::Region->insert( Memorycell );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -182,8 +183,8 @@ basic_editor::rotate_instance( TAnimModel *Instance, glm::vec3 const &Angle ) {
|
|||||||
glm::vec3 angle = glm::dvec3 { Instance->Angles() };
|
glm::vec3 angle = glm::dvec3 { Instance->Angles() };
|
||||||
angle.y = clamp_circular( angle.y + Angle.y, 360.f );
|
angle.y = clamp_circular( angle.y + Angle.y, 360.f );
|
||||||
if( mode_snap() ) {
|
if( mode_snap() ) {
|
||||||
auto const quantizationstep { 15.f };
|
// TBD, TODO: adjustable quantization step
|
||||||
angle.y = quantizationstep * std::round( angle.y * ( 1.f / quantizationstep ) );
|
angle.y = quantize( angle.y, 15.f );
|
||||||
}
|
}
|
||||||
Instance->Angles( angle );
|
Instance->Angles( angle );
|
||||||
// update scene
|
// update scene
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
delete pathnode;
|
delete pathnode;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
simulation::Region->insert_path( path, Scratchpad );
|
simulation::Region->insert_and_register( path );
|
||||||
}
|
}
|
||||||
else if( nodedata.type == "traction" ) {
|
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 ) ) {
|
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 ) + ")" );
|
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" ) {
|
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
|
auto const cellcount = instance->TerrainCount() + 1; // zliczenie submodeli
|
||||||
for( auto i = 1; i < cellcount; ++i ) {
|
for( auto i = 1; i < cellcount; ++i ) {
|
||||||
auto *submodel = instance->TerrainSquare( i - 1 );
|
auto *submodel = instance->TerrainSquare( i - 1 );
|
||||||
simulation::Region->insert_shape(
|
simulation::Region->insert(
|
||||||
scene::shape_node().convert( submodel ),
|
scene::shape_node().convert( submodel ),
|
||||||
Scratchpad,
|
Scratchpad,
|
||||||
false );
|
false );
|
||||||
// if there's more than one group of triangles in the cell they're held as children of the primary submodel
|
// if there's more than one group of triangles in the cell they're held as children of the primary submodel
|
||||||
submodel = submodel->ChildGet();
|
submodel = submodel->ChildGet();
|
||||||
while( submodel != nullptr ) {
|
while( submodel != nullptr ) {
|
||||||
simulation::Region->insert_shape(
|
simulation::Region->insert(
|
||||||
scene::shape_node().convert( submodel ),
|
scene::shape_node().convert( submodel ),
|
||||||
Scratchpad,
|
Scratchpad,
|
||||||
false );
|
false );
|
||||||
@@ -398,7 +398,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
if( false == simulation::Instances.insert( instance ) ) {
|
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 ) + ")" );
|
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" )
|
else if( ( nodedata.type == "triangles" )
|
||||||
@@ -407,7 +407,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
|
|
||||||
if( false == Scratchpad.binary.terrain ) {
|
if( false == Scratchpad.binary.terrain ) {
|
||||||
|
|
||||||
simulation::Region->insert_shape(
|
simulation::Region->insert(
|
||||||
scene::shape_node().import(
|
scene::shape_node().import(
|
||||||
Input, nodedata ),
|
Input, nodedata ),
|
||||||
Scratchpad,
|
Scratchpad,
|
||||||
@@ -424,7 +424,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
|
|
||||||
if( false == Scratchpad.binary.terrain ) {
|
if( false == Scratchpad.binary.terrain ) {
|
||||||
|
|
||||||
simulation::Region->insert_lines(
|
simulation::Region->insert(
|
||||||
scene::lines_node().import(
|
scene::lines_node().import(
|
||||||
Input, nodedata ),
|
Input, nodedata ),
|
||||||
Scratchpad );
|
Scratchpad );
|
||||||
@@ -440,7 +440,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
if( false == simulation::Memory.insert( memorycell ) ) {
|
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 ) + ")" );
|
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" ) {
|
else if( nodedata.type == "eventlauncher" ) {
|
||||||
|
|
||||||
@@ -454,7 +454,7 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad
|
|||||||
simulation::Events.queue( eventlauncher );
|
simulation::Events.queue( eventlauncher );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
simulation::Region->insert_launcher( eventlauncher, Scratchpad );
|
simulation::Region->insert( eventlauncher );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( nodedata.type == "sound" ) {
|
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 ) ) {
|
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 ) + ")" );
|
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 ) };
|
double const position { (float)( ( (uint16_t)buffer[ 8 ] | ( (uint16_t)buffer[ 9 ] << 8 ) ) - conf.mainbrakemin ) / ( conf.mainbrakemax - conf.mainbrakemin ) };
|
||||||
relay.post(
|
relay.post(
|
||||||
user_command::trainbrakeset,
|
user_command::trainbrakeset,
|
||||||
reinterpret_cast<std::uint64_t const &>( position ),
|
position,
|
||||||
0,
|
0,
|
||||||
GLFW_PRESS,
|
GLFW_PRESS,
|
||||||
// TODO: pass correct entity id once the missing systems are in place
|
// 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 ) };
|
double const position { (float)( ( (uint16_t)buffer[ 10 ] | ( (uint16_t)buffer[ 11 ] << 8 ) ) - conf.localbrakemin ) / ( conf.localbrakemax - conf.localbrakemin ) };
|
||||||
relay.post(
|
relay.post(
|
||||||
user_command::independentbrakeset,
|
user_command::independentbrakeset,
|
||||||
reinterpret_cast<std::uint64_t const &>( position ),
|
position,
|
||||||
0,
|
0,
|
||||||
GLFW_PRESS,
|
GLFW_PRESS,
|
||||||
// TODO: pass correct entity id once the missing systems are in place
|
// 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 );
|
EditorModeFlag = ( Key == GLFW_KEY_F11 );
|
||||||
if( ( true == EditorModeFlag )
|
if( ( true == EditorModeFlag )
|
||||||
&& ( false == Global.ControlPicking ) ) {
|
&& ( false == Global.ControlPicking ) ) {
|
||||||
glfwSetInputMode( m_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL );
|
set_cursor( GLFW_CURSOR_NORMAL );
|
||||||
Global.ControlPicking = true;
|
Global.ControlPicking = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1113,6 +1113,13 @@ ui_layer::render() {
|
|||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ui_layer::set_cursor( int const Mode ) {
|
||||||
|
|
||||||
|
glfwSetInputMode( m_window, GLFW_CURSOR, Mode );
|
||||||
|
m_cursorvisible = ( Mode != GLFW_CURSOR_DISABLED );
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ui_layer::set_progress( float const Progress, float const Subtaskprogress ) {
|
ui_layer::set_progress( float const Progress, float const Subtaskprogress ) {
|
||||||
|
|
||||||
@@ -1214,6 +1221,7 @@ void
|
|||||||
ui_layer::render_tooltip() {
|
ui_layer::render_tooltip() {
|
||||||
|
|
||||||
if( m_tooltip.empty() ) { return; }
|
if( m_tooltip.empty() ) { return; }
|
||||||
|
if( false == m_cursorvisible ) { return; }
|
||||||
|
|
||||||
glm::dvec2 mousepos;
|
glm::dvec2 mousepos;
|
||||||
glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y );
|
glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y );
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ public:
|
|||||||
// draws requested UI elements
|
// draws requested UI elements
|
||||||
void
|
void
|
||||||
render();
|
render();
|
||||||
|
//
|
||||||
|
void
|
||||||
|
set_cursor( int const Mode );
|
||||||
// stores operation progress
|
// stores operation progress
|
||||||
void
|
void
|
||||||
set_progress( float const Progress = 0.0f, float const Subtaskprogress = 0.0f );
|
set_progress( float const Progress = 0.0f, float const Subtaskprogress = 0.0f );
|
||||||
@@ -114,6 +117,7 @@ private:
|
|||||||
int tprev; // poprzedni czas
|
int tprev; // poprzedni czas
|
||||||
double VelPrev; // poprzednia prędkość
|
double VelPrev; // poprzednia prędkość
|
||||||
double Acc; // przyspieszenie styczne
|
double Acc; // przyspieszenie styczne
|
||||||
|
bool m_cursorvisible { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ui_layer UILayer;
|
extern ui_layer UILayer;
|
||||||
|
|||||||
@@ -228,6 +228,13 @@ clamp_circular( Type_ Value, Type_ const Range = static_cast<Type_>(360) ) {
|
|||||||
return Value;
|
return Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Type_>
|
||||||
|
Type_
|
||||||
|
quantize( Type_ const Value, Type_ const Step ) {
|
||||||
|
|
||||||
|
return ( Step * std::round( Value / Step ) );
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Type_>
|
template <typename Type_>
|
||||||
Type_
|
Type_
|
||||||
min_speed( Type_ const Left, Type_ const Right ) {
|
min_speed( Type_ const Left, Type_ const Right ) {
|
||||||
|
|||||||
Reference in New Issue
Block a user