mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-21 12:29:04 -06:00
Merge pull request #1787 from OpenSpace/feature/multiple-joysticks
Feature/multiple joysticks
This commit is contained in:
@@ -369,27 +369,34 @@ void mainPreSyncFunc() {
|
||||
|
||||
std::fill(state.axes.begin(), state.axes.end(), 0.f);
|
||||
std::fill(state.buttons.begin(), state.buttons.end(), JoystickAction::Idle);
|
||||
|
||||
// Check axes and buttons
|
||||
glfwGetJoystickAxes(i, &state.nAxes);
|
||||
if (state.nAxes > JoystickInputState::MaxAxes) {
|
||||
LWARNING(fmt::format(
|
||||
"Joystick/Gamepad {} has {} axes, but only {} axes are supported. "
|
||||
"All excess axes are ignored",
|
||||
state.name, state.nAxes, JoystickInputState::MaxAxes
|
||||
));
|
||||
}
|
||||
glfwGetJoystickButtons(i, &state.nButtons);
|
||||
if (state.nButtons > JoystickInputState::MaxButtons) {
|
||||
LWARNING(fmt::format(
|
||||
"Joystick/Gamepad {} has {} buttons, but only {} buttons are "
|
||||
"supported. All excess buttons are ignored",
|
||||
state.name, state.nButtons, JoystickInputState::MaxButtons
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
const float* axes = glfwGetJoystickAxes(i, &state.nAxes);
|
||||
if (state.nAxes > JoystickInputState::MaxAxes) {
|
||||
LWARNING(fmt::format(
|
||||
"Joystick/Gamepad {} has {} axes, but only {} axes are supported. "
|
||||
"All excess axes are ignored",
|
||||
state.name, state.nAxes, JoystickInputState::MaxAxes
|
||||
));
|
||||
state.nAxes = JoystickInputState::MaxAxes;
|
||||
}
|
||||
std::memcpy(state.axes.data(), axes, state.nAxes * sizeof(float));
|
||||
|
||||
const unsigned char* buttons = glfwGetJoystickButtons(i, &state.nButtons);
|
||||
|
||||
if (state.nButtons > JoystickInputState::MaxButtons) {
|
||||
LWARNING(fmt::format(
|
||||
"Joystick/Gamepad {} has {} buttons, but only {} buttons are "
|
||||
"supported. All excess buttons are ignored",
|
||||
state.name, state.nButtons, JoystickInputState::MaxButtons
|
||||
));
|
||||
state.nButtons = JoystickInputState::MaxButtons;
|
||||
}
|
||||
|
||||
|
||||
90
data/assets/examples/joystickProperty.asset
Normal file
90
data/assets/examples/joystickProperty.asset
Normal file
@@ -0,0 +1,90 @@
|
||||
-- Allowed values for the third parameter of bindJoystickAxis:
|
||||
-- "None"
|
||||
-- "Orbit X"
|
||||
-- "Orbit Y"
|
||||
-- "Zoom" -- both in and out
|
||||
-- "Zoom In"
|
||||
-- "Zoom Out"
|
||||
-- "LocalRoll X"
|
||||
-- "LocalRoll Y"
|
||||
-- "GlobalRoll X"
|
||||
-- "GlobalRoll Y"
|
||||
-- "Pan X"
|
||||
-- "Pan Y"
|
||||
-- Fourth parameter determines whether the axis should be inverted
|
||||
-- Fifth parameter determines whether the axis behaves like a joystick or a Trigger.
|
||||
-- Allowed values are "JoystickLike" and "TriggerLike", the first one is the default
|
||||
-- Sixth parameters determins if the axis should be "Sticky" or not.
|
||||
-- The axis values can either go back to 0 when the joystick is released or it can
|
||||
-- stay at the value it was before the joystick was released.
|
||||
-- The latter is called a sticky axis, when the values don't go back to 0.
|
||||
-- Seventh parameter is the sensitivity for the axis
|
||||
|
||||
|
||||
-- Parameters for bindJoystickAxisProperty:
|
||||
-- First - Name of the joystick that should be bound
|
||||
-- Second - Which axis should be bound of this joystick
|
||||
-- Third - The property uri
|
||||
-- Fourth - (optional) The smallest value that you wnat to allow this property on the joystick
|
||||
-- Fifth - (optional) The largest value that you wnat to allow this property on the joystick
|
||||
-- Sixth - (optional) Determines whether the axis should be inverted
|
||||
-- Seventh - (optional) Should this property change be sent to other connected remote sessions
|
||||
|
||||
local XBoxController = {
|
||||
LeftThumbStick = { 0 , 1 },
|
||||
RightThumbStick = { 2, 3 },
|
||||
LeftTrigger = 4,
|
||||
RightTrigger = 5,
|
||||
A = 0,
|
||||
B = 1,
|
||||
X = 2,
|
||||
Y = 3,
|
||||
LB = 4,
|
||||
RB = 5,
|
||||
Select = 6,
|
||||
Start = 7,
|
||||
LeftStickButton = 8,
|
||||
RightStickButton = 9,
|
||||
DPad = {
|
||||
Up = 10,
|
||||
Right = 11,
|
||||
Down = 12,
|
||||
Left = 13
|
||||
}
|
||||
}
|
||||
|
||||
local freezeValue = function(name, axis, min, max)
|
||||
return [[
|
||||
local joystickType = openspace.navigation.joystickAxis(']] .. name .. "', " .. axis .. [[);
|
||||
local isPropertyBound = true;
|
||||
if joystickType == "None" then
|
||||
isPropertyBound = false;
|
||||
else
|
||||
isPropertyBound = true;
|
||||
end
|
||||
|
||||
if isPropertyBound then
|
||||
openspace.navigation.bindJoystickAxis(']] .. name .. "', " .. axis .. [[, "None");
|
||||
isPropertyBound = false;
|
||||
else
|
||||
openspace.navigation.bindJoystickAxisProperty(']] .. name .. "', " .. axis .. [[, 'Scene.Earth.Scale.Scale', ]] .. min ..", " .. max.. [[);
|
||||
isPropertyBound = true;
|
||||
end
|
||||
]]
|
||||
end
|
||||
|
||||
asset.onInitialize(function()
|
||||
local controller = XBoxController;
|
||||
local name = "Xbox Controller";
|
||||
|
||||
-- Bind Right trigger to Earth Scale
|
||||
openspace.navigation.bindJoystickAxisProperty(name, controller.RightTrigger, "Scene.Earth.Scale.Scale", 0.1, 100);
|
||||
|
||||
-- Bind 'A' button to freeze current value
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.A,
|
||||
freezeValue(name, controller.RightTrigger, 0.1, 100),
|
||||
"Freeze current scale for Earth. Or release it to the trigger again."
|
||||
)
|
||||
end)
|
||||
@@ -4,58 +4,62 @@ Joystick.State = {}
|
||||
Joystick.State.IsInRollMode = false
|
||||
Joystick.State.Axis = {}
|
||||
|
||||
local bindLocalRoll = function(axis)
|
||||
local bindLocalRoll = function(name, axis)
|
||||
return [[
|
||||
-- We only want to store the current state in the first mode that is enabled, otherwise we will overwrite the backup
|
||||
if not Joystick.State.IsInRollMode then
|
||||
-- Save current axis state
|
||||
Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity = openspace.navigation.joystickAxis(]] .. axis .. [[)
|
||||
Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.JoystickType, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity, Joystick.State.Axis.PropertyUri, Joystick.State.Axis.MinValue, Joystick.State.Axis.MaxValue, Joystick.State.Axis.IsRemote = openspace.navigation.joystickAxis("]] .. name .. "\", " .. axis .. [[);
|
||||
end
|
||||
|
||||
-- Set new axis state
|
||||
openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "LocalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity);
|
||||
openspace.navigation.bindJoystickAxis("]] .. name .. "\", " .. axis .. [[, "LocalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.JoystickType, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity);
|
||||
Joystick.State.IsInRollMode = true
|
||||
]]
|
||||
end
|
||||
|
||||
local bindGlobalRoll = function(axis)
|
||||
local bindGlobalRoll = function(name, axis)
|
||||
return [[
|
||||
-- We only want to store the current state in the first mode that is enabled, otherwise we will overwrite the backup
|
||||
if not Joystick.State.IsInRollMode then
|
||||
-- Save current axis state
|
||||
Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity = openspace.navigation.joystickAxis(]] .. axis .. [[)
|
||||
Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.JoystickType, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity, Joystick.State.Axis.PropertyUri, Joystick.State.Axis.MinValue, Joystick.State.Axis.MaxValue, Joystick.State.Axis.IsRemote = openspace.navigation.joystickAxis("]] .. name .. "\", " .. axis .. [[);
|
||||
end
|
||||
|
||||
-- Set new axis state
|
||||
openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "GlobalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity);
|
||||
openspace.navigation.bindJoystickAxis("]] .. name .. "\", " .. axis .. [[, "GlobalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.JoystickType, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity);
|
||||
Joystick.State.IsInRollMode = true
|
||||
]]
|
||||
end
|
||||
|
||||
local permaBindLocalRoll = function(axis)
|
||||
local permaBindLocalRoll = function(name, axis)
|
||||
return [[
|
||||
-- Save current axis state
|
||||
Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity = openspace.navigation.joystickAxis(]] .. axis .. [[)
|
||||
Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.JoystickType, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity, Joystick.State.Axis.PropertyUri, Joystick.State.Axis.MinValue, Joystick.State.Axis.MaxValue, Joystick.State.Axis.IsRemote = openspace.navigation.joystickAxis("]] .. name .. "\", " .. axis .. [[);
|
||||
|
||||
-- Set new axis state
|
||||
openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "LocalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity);
|
||||
openspace.navigation.bindJoystickAxis("]] .. name .. "\", " .. axis .. [[, "LocalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.JoystickType, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity);
|
||||
]]
|
||||
end
|
||||
|
||||
local permaBindGlobalRoll = function(axis)
|
||||
local permaBindGlobalRoll = function(name, axis)
|
||||
return [[
|
||||
-- Save current axis state
|
||||
Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity = openspace.navigation.joystickAxis(]] .. axis .. [[)
|
||||
Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.JoystickType, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity, Joystick.State.Axis.PropertyUri, Joystick.State.Axis.MinValue, Joystick.State.Axis.MaxValue, Joystick.State.Axis.IsRemote = openspace.navigation.joystickAxis("]] .. name .. "\", " .. axis .. [[);
|
||||
|
||||
-- Set new axis state
|
||||
openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "GlobalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity);
|
||||
openspace.navigation.bindJoystickAxis("]] .. name .. "\", " .. axis .. [[, "GlobalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.JoystickType, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity);
|
||||
]]
|
||||
end
|
||||
|
||||
local unbindRoll = function(axis)
|
||||
local unbindRoll = function(name, axis)
|
||||
return [[
|
||||
-- Reset previous state
|
||||
openspace.navigation.bindJoystickAxis(]] .. axis .. [[, Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity);
|
||||
if(Joystick.State.Axis.Type == "Property") then
|
||||
openspace.navigation.bindJoystickAxisProperty("]] .. name .. "\", " .. axis .. [[, Joystick.State.Axis.PropertyUri, Joystick.State.Axis.MinValue, Joystick.State.Axis.MaxValue, Joystick.State.Axis.Inverted, Joystick.State.Axis.IsRemote);
|
||||
else
|
||||
openspace.navigation.bindJoystickAxis("]] .. name .. "\", " .. axis .. [[, Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.JoystickType, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity);
|
||||
end
|
||||
]]
|
||||
end
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local propertyHelper = asset.require('../property_helper')
|
||||
local joystickHelper = asset.require('./joystick_helper')
|
||||
|
||||
-- Allowed values for the second parameter of bindJoystickAxis:
|
||||
-- Allowed values for the third parameter of bindJoystickAxis:
|
||||
-- "None"
|
||||
-- "Orbit X"
|
||||
-- "Orbit Y"
|
||||
@@ -14,13 +14,14 @@ local joystickHelper = asset.require('./joystick_helper')
|
||||
-- "GlobalRoll Y"
|
||||
-- "Pan X"
|
||||
-- "Pan Y"
|
||||
-- Third parameter determines whether the axis should be inverted
|
||||
-- Fourth parameter determines whether the axis should be normalized from [-1,1] to [0,1]
|
||||
-- Fifth parameters determins if the axis should be "Sticky" or not.
|
||||
-- Fourth parameter determines whether the axis should be inverted
|
||||
-- Fifth parameter determines whether the axis behaves like a joystick or a Trigger.
|
||||
-- Allowed values are "JoystickLike" and "TriggerLike", the first one is the default
|
||||
-- Sixth parameters determins if the axis should be "Sticky" or not.
|
||||
-- The axis values can either go back to 0 when the joystick is released or it can
|
||||
-- stay at the value it was before the joystick was released.
|
||||
-- The latter is called a sticky axis, when the values don't go back to 0.
|
||||
-- Sixth parameter is the sensitivity for the axis
|
||||
-- Seventh parameter is the sensitivity for the axis
|
||||
|
||||
local PS4Controller = {
|
||||
LeftThumbStick = { 0 , 1 },
|
||||
@@ -49,59 +50,70 @@ local PS4Controller = {
|
||||
|
||||
asset.onInitialize(function()
|
||||
local controller = PS4Controller;
|
||||
local name = "Wireless Controller";
|
||||
|
||||
openspace.navigation.setAxisDeadZone(controller.LeftThumbStick[1], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(controller.LeftThumbStick[2], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(controller.RightThumbStick[1], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(controller.RightThumbStick[2], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(name, controller.LeftThumbStick[1], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(name, controller.LeftThumbStick[2], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(name, controller.RightThumbStick[1], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(name, controller.RightThumbStick[2], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(name, controller.L2, 0.05)
|
||||
openspace.navigation.setAxisDeadZone(name, controller.R2, 0.05)
|
||||
|
||||
openspace.navigation.bindJoystickAxis(controller.LeftThumbStick[1], "Orbit X");
|
||||
openspace.navigation.bindJoystickAxis(controller.LeftThumbStick[2], "Orbit Y", true);
|
||||
openspace.navigation.bindJoystickAxis(controller.RightThumbStick[1], "Pan X", true);
|
||||
openspace.navigation.bindJoystickAxis(controller.RightThumbStick[2], "Pan Y", true);
|
||||
openspace.navigation.bindJoystickAxis(controller.L2, "Zoom Out", false, true);
|
||||
openspace.navigation.bindJoystickAxis(controller.R2, "Zoom In", false, true);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.LeftThumbStick[1], "Orbit X");
|
||||
openspace.navigation.bindJoystickAxis(name, controller.LeftThumbStick[2], "Orbit Y", true);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.RightThumbStick[1], "Pan X", true);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.RightThumbStick[2], "Pan Y", true);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.L2, "Zoom Out", false, "TriggerLike");
|
||||
openspace.navigation.bindJoystickAxis(name, controller.R2, "Zoom In", false, "TriggerLike");
|
||||
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.L1,
|
||||
joystickHelper.bindLocalRoll(controller.RightThumbStick[1]),
|
||||
joystickHelper.bindLocalRoll(name, controller.RightThumbStick[1]),
|
||||
"Switch to local roll mode"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.L1,
|
||||
joystickHelper.unbindRoll(controller.RightThumbStick[1]),
|
||||
joystickHelper.unbindRoll(name, controller.RightThumbStick[1]),
|
||||
"Switch back to normal mode",
|
||||
"Release"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.R1,
|
||||
joystickHelper.bindGlobalRoll(controller.RightThumbStick[1]),
|
||||
joystickHelper.bindGlobalRoll(name, controller.RightThumbStick[1]),
|
||||
"Switch to global roll mode"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.R1,
|
||||
joystickHelper.unbindRoll(controller.RightThumbStick[1]),
|
||||
joystickHelper.unbindRoll(name, controller.RightThumbStick[1]),
|
||||
"Switch back to normal mode",
|
||||
"Release"
|
||||
)
|
||||
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.Cross,
|
||||
propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.ZoomFriction'),
|
||||
"Toggle zoom friction"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.Circle,
|
||||
propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.RotationalFriction'),
|
||||
"Toggle rotational friction"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.DPad.Left,
|
||||
propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.RollFriction'),
|
||||
"Toggle roll friction"
|
||||
)
|
||||
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.Square,
|
||||
"openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Aim', '');" ..
|
||||
"openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Anchor', 'Earth');" ..
|
||||
@@ -109,6 +121,7 @@ asset.onInitialize(function()
|
||||
"Switch target to Earth"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.Triangle,
|
||||
"openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Aim', '');" ..
|
||||
"openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Anchor', 'Mars');" ..
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local propertyHelper = asset.require('../property_helper')
|
||||
local joystickHelper = asset.require('./joystick_helper')
|
||||
|
||||
-- Allowed values for the second parameter of bindJoystickAxis:
|
||||
-- Allowed values for the third parameter of bindJoystickAxis:
|
||||
-- "None"
|
||||
-- "Orbit X"
|
||||
-- "Orbit Y"
|
||||
@@ -14,14 +14,15 @@ local joystickHelper = asset.require('./joystick_helper')
|
||||
-- "GlobalRoll Y"
|
||||
-- "Pan X"
|
||||
-- "Pan Y"
|
||||
-- Third parameter determines whether the axis should be inverted
|
||||
-- Fourth parameter determines whether the axis should be normalized from [-1,1] to [0,1]
|
||||
-- Fifth parameters determins if the axis should be "Sticky" or not.
|
||||
-- Fourth parameter determines whether the axis should be inverted
|
||||
-- Fifth parameter determines whether the axis behaves like a joystick or a Trigger.
|
||||
-- Allowed values are "JoystickLike" and "TriggerLike", the first one is the default
|
||||
-- Sixth parameters determins if the axis should be "Sticky" or not.
|
||||
-- The axis values can either go back to 0 when the joystick is released or it can
|
||||
-- stay at the value it was before the joystick was released.
|
||||
-- The latter is called a sticky axis, when the values don't go back to 0.
|
||||
-- This version of the SpaceMouse is NOT Sticky.
|
||||
-- Sixth parameter is the sensitivity for the axis
|
||||
-- Seventh parameter is the sensitivity for the axis
|
||||
|
||||
local SpaceMouse = {
|
||||
Push = {0, 1, 2}, -- left/right, back/forth, up/down
|
||||
@@ -33,23 +34,26 @@ local SpaceMouse = {
|
||||
|
||||
asset.onInitialize(function()
|
||||
local controller = SpaceMouse;
|
||||
local name = "SpaceNavigator";
|
||||
|
||||
openspace.navigation.bindJoystickAxis(controller.Push[1], "Orbit X", false);
|
||||
openspace.navigation.bindJoystickAxis(controller.Push[2], "Orbit Y", false);
|
||||
openspace.navigation.bindJoystickAxis(controller.Twist[1], "Pan X", true);
|
||||
openspace.navigation.bindJoystickAxis(controller.Tilt[2], "Pan Y", false);
|
||||
openspace.navigation.bindJoystickAxis(controller.Push[3], "Zoom", false);
|
||||
openspace.navigation.bindJoystickAxis(controller.Tilt[1], "LocalRoll X", false);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.Push[1], "Orbit X");
|
||||
openspace.navigation.bindJoystickAxis(name, controller.Push[2], "Orbit Y");
|
||||
openspace.navigation.bindJoystickAxis(name, controller.Twist[1], "Pan X", true);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.Tilt[2], "Pan Y");
|
||||
openspace.navigation.bindJoystickAxis(name, controller.Push[3], "Zoom");
|
||||
openspace.navigation.bindJoystickAxis(name, controller.Tilt[1], "LocalRoll X");
|
||||
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.LeftButton,
|
||||
joystickHelper.permaBindLocalRoll(controller.Tilt[1]),
|
||||
joystickHelper.permaBindLocalRoll(name, controller.Tilt[1]),
|
||||
"Switch to local roll mode"
|
||||
)
|
||||
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.RightButton,
|
||||
joystickHelper.permaBindGlobalRoll(controller.Tilt[1]),
|
||||
joystickHelper.permaBindGlobalRoll(name, controller.Tilt[1]),
|
||||
"Switch to global roll mode"
|
||||
)
|
||||
end)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local propertyHelper = asset.require('../property_helper')
|
||||
local joystickHelper = asset.require('./joystick_helper')
|
||||
|
||||
-- Allowed values for the second parameter of bindJoystickAxis:
|
||||
-- Allowed values for the third parameter of bindJoystickAxis:
|
||||
-- "None"
|
||||
-- "Orbit X"
|
||||
-- "Orbit Y"
|
||||
@@ -14,14 +14,15 @@ local joystickHelper = asset.require('./joystick_helper')
|
||||
-- "GlobalRoll Y"
|
||||
-- "Pan X"
|
||||
-- "Pan Y"
|
||||
-- Third parameter determines whether the axis should be inverted
|
||||
-- Fourth parameter determines whether the axis should be normalized from [-1,1] to [0,1]
|
||||
-- Fifth parameters determins if the axis should be "Sticky" or not.
|
||||
-- Fourth parameter determines whether the axis should be inverted
|
||||
-- Fifth parameter determines whether the axis behaves like a joystick or a Trigger.
|
||||
-- Allowed values are "JoystickLike" and "TriggerLike", the first one is the default
|
||||
-- Sixth parameters determins if the axis should be "Sticky" or not.
|
||||
-- The axis values can either go back to 0 when the joystick is released or it can
|
||||
-- stay at the value it was before the joystick was released.
|
||||
-- The latter is called a sticky axis, when the values don't go back to 0.
|
||||
-- This version of the SpaceMouse IS Sticky.
|
||||
-- Sixth parameter is the sensitivity for the axis
|
||||
-- Seventh parameter is the sensitivity for the axis
|
||||
|
||||
local SpaceMouse = {
|
||||
Push = {0, 1, 2}, -- left/right, back/forth, up/down
|
||||
@@ -33,23 +34,26 @@ local SpaceMouse = {
|
||||
|
||||
asset.onInitialize(function()
|
||||
local controller = SpaceMouse;
|
||||
local name = "SpaceNavigator";
|
||||
|
||||
openspace.navigation.bindJoystickAxis(controller.Push[1], "Orbit X", false, false, true, 40.0);
|
||||
openspace.navigation.bindJoystickAxis(controller.Push[2], "Orbit Y", false, false, true, 40.0);
|
||||
openspace.navigation.bindJoystickAxis(controller.Twist[1], "Pan X", true, false, true, 40.0);
|
||||
openspace.navigation.bindJoystickAxis(controller.Tilt[2], "Pan Y", false, false, true, 35.0);
|
||||
openspace.navigation.bindJoystickAxis(controller.Push[3], "Zoom", false, false, true, 40.0);
|
||||
openspace.navigation.bindJoystickAxis(controller.Tilt[1], "LocalRoll X", false, false, true, 35.0);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.Push[1], "Orbit X", false, "JoystickLike", true, 40.0);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.Push[2], "Orbit Y", false, "JoystickLike", true, 40.0);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.Twist[1], "Pan X", true, "JoystickLike", true, 40.0);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.Tilt[2], "Pan Y", false, "JoystickLike", true, 35.0);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.Push[3], "Zoom", false, "JoystickLike", true, 40.0);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.Tilt[1], "LocalRoll X", false, "JoystickLike", true, 35.0);
|
||||
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.LeftButton,
|
||||
joystickHelper.permaBindLocalRoll(controller.Tilt[1]),
|
||||
joystickHelper.permaBindLocalRoll(name, controller.Tilt[1]),
|
||||
"Switch to local roll mode"
|
||||
)
|
||||
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.RightButton,
|
||||
joystickHelper.permaBindGlobalRoll(controller.Tilt[1]),
|
||||
joystickHelper.permaBindGlobalRoll(name, controller.Tilt[1]),
|
||||
"Switch to global roll mode"
|
||||
)
|
||||
end)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local propertyHelper = asset.require('../property_helper')
|
||||
local joystickHelper = asset.require('./joystick_helper')
|
||||
|
||||
-- Allowed values for the second parameter of bindJoystickAxis:
|
||||
-- Allowed values for the third parameter of bindJoystickAxis:
|
||||
-- "None"
|
||||
-- "Orbit X"
|
||||
-- "Orbit Y"
|
||||
@@ -14,13 +14,14 @@ local joystickHelper = asset.require('./joystick_helper')
|
||||
-- "GlobalRoll Y"
|
||||
-- "Pan X"
|
||||
-- "Pan Y"
|
||||
-- Third parameter determines whether the axis should be inverted
|
||||
-- Fourth parameter determines whether the axis should be normalized from [-1,1] to [0,1]
|
||||
-- Fifth parameters determins if the axis should be "Sticky" or not.
|
||||
-- Fourth parameter determines whether the axis should be inverted
|
||||
-- Fifth parameter determines whether the axis behaves like a joystick or a Trigger.
|
||||
-- Allowed values are "JoystickLike" and "TriggerLike", the first one is the default
|
||||
-- Sixth parameters determins if the axis should be "Sticky" or not.
|
||||
-- The axis values can either go back to 0 when the joystick is released or it can
|
||||
-- stay at the value it was before the joystick was released.
|
||||
-- The latter is called a sticky axis, when the values don't go back to 0.
|
||||
-- Sixth parameter is the sensitivity for the axis
|
||||
-- Seventh parameter is the sensitivity for the axis
|
||||
|
||||
local XBoxController = {
|
||||
LeftThumbStick = { 0 , 1 },
|
||||
@@ -47,59 +48,70 @@ local XBoxController = {
|
||||
|
||||
asset.onInitialize(function()
|
||||
local controller = XBoxController;
|
||||
local name = "Xbox Controller";
|
||||
|
||||
openspace.navigation.setAxisDeadZone(controller.LeftThumbStick[1], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(controller.LeftThumbStick[2], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(controller.RightThumbStick[1], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(controller.RightThumbStick[2], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(name, controller.LeftThumbStick[1], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(name, controller.LeftThumbStick[2], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(name, controller.RightThumbStick[1], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(name, controller.RightThumbStick[2], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(name, controller.LeftTrigger, 0.05)
|
||||
openspace.navigation.setAxisDeadZone(name, controller.RightTrigger, 0.05)
|
||||
|
||||
openspace.navigation.bindJoystickAxis(controller.LeftThumbStick[1], "Orbit X");
|
||||
openspace.navigation.bindJoystickAxis(controller.LeftThumbStick[2], "Orbit Y", true);
|
||||
openspace.navigation.bindJoystickAxis(controller.RightThumbStick[1], "Pan X", true);
|
||||
openspace.navigation.bindJoystickAxis(controller.RightThumbStick[2], "Pan Y", true);
|
||||
openspace.navigation.bindJoystickAxis(controller.LeftTrigger, "Zoom Out", false, true);
|
||||
openspace.navigation.bindJoystickAxis(controller.RightTrigger, "Zoom In", false, true);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.LeftThumbStick[1], "Orbit X");
|
||||
openspace.navigation.bindJoystickAxis(name, controller.LeftThumbStick[2], "Orbit Y", true);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.RightThumbStick[1], "Pan X", true);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.RightThumbStick[2], "Pan Y", true);
|
||||
openspace.navigation.bindJoystickAxis(name, controller.LeftTrigger, "Zoom Out", false, "TriggerLike");
|
||||
openspace.navigation.bindJoystickAxis(name, controller.RightTrigger, "Zoom In", false, "TriggerLike");
|
||||
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.LB,
|
||||
joystickHelper.bindLocalRoll(controller.RightThumbStick[1]),
|
||||
joystickHelper.bindLocalRoll(name, controller.RightThumbStick[1]),
|
||||
"Switch to local roll mode"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.LB,
|
||||
joystickHelper.unbindRoll(controller.RightThumbStick[1]),
|
||||
joystickHelper.unbindRoll(name, controller.RightThumbStick[1]),
|
||||
"Switch back to normal mode",
|
||||
"Release"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.RB,
|
||||
joystickHelper.bindGlobalRoll(controller.RightThumbStick[1]),
|
||||
joystickHelper.bindGlobalRoll(name, controller.RightThumbStick[1]),
|
||||
"Switch to global roll mode"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.RB,
|
||||
joystickHelper.unbindRoll(controller.RightThumbStick[1]),
|
||||
joystickHelper.unbindRoll(name, controller.RightThumbStick[1]),
|
||||
"Switch back to normal mode",
|
||||
"Release"
|
||||
)
|
||||
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.A,
|
||||
propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.ZoomFriction'),
|
||||
"Toggle zoom friction"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.B,
|
||||
propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.RotationalFriction'),
|
||||
"Toggle rotational friction"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.DPad.Left,
|
||||
propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.RollFriction'),
|
||||
"Toggle roll friction"
|
||||
)
|
||||
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.X,
|
||||
"openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Aim', '');" ..
|
||||
"openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Anchor', 'Earth');" ..
|
||||
@@ -107,6 +119,7 @@ asset.onInitialize(function()
|
||||
"Switch target to Earth"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
name,
|
||||
controller.Y,
|
||||
"openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Aim', '');" ..
|
||||
"openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Anchor', 'Mars');" ..
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
class InputState;
|
||||
|
||||
class CameraInteractionStates {
|
||||
public:
|
||||
/**
|
||||
@@ -42,8 +40,6 @@ public:
|
||||
CameraInteractionStates(double sensitivity, double velocityScaleFactor);
|
||||
virtual ~CameraInteractionStates() = default;
|
||||
|
||||
virtual void updateStateFromInput(const InputState& inputState, double deltaTime) = 0;
|
||||
|
||||
void setRotationalFriction(double friction);
|
||||
void setHorizontalFriction(double friction);
|
||||
void setVerticalFriction(double friction);
|
||||
|
||||
@@ -49,17 +49,22 @@ public:
|
||||
GlobalRollX,
|
||||
GlobalRollY,
|
||||
PanX,
|
||||
PanY
|
||||
PanY,
|
||||
Property
|
||||
};
|
||||
|
||||
enum class JoystickType {
|
||||
JoystickLike,
|
||||
TriggerLike
|
||||
};
|
||||
|
||||
BooleanType(AxisInvert);
|
||||
BooleanType(AxisNormalize);
|
||||
BooleanType(ButtonCommandRemote);
|
||||
|
||||
struct AxisInformation {
|
||||
AxisType type = AxisType::None;
|
||||
AxisInvert invert = AxisInvert::No;
|
||||
AxisNormalize normalize = AxisNormalize::No;
|
||||
JoystickType joystickType = JoystickType::JoystickLike;
|
||||
|
||||
// The axis values can either go back to 0 when the joystick is released or it can
|
||||
// stay at the value it was before the joystick was released.
|
||||
@@ -70,49 +75,83 @@ public:
|
||||
|
||||
// Every axis can have their own sensitivity
|
||||
double sensitivity = 0.0;
|
||||
|
||||
// The property info if the type is Property
|
||||
std::string propertyUri;
|
||||
float minValue = 0.f;
|
||||
float maxValue = 1.f;
|
||||
bool isRemote = true;
|
||||
};
|
||||
|
||||
JoystickCameraStates(double sensitivity, double velocityScaleFactor);
|
||||
|
||||
void updateStateFromInput(const InputState& inputState, double deltaTime) override;
|
||||
void updateStateFromInput(
|
||||
const JoystickInputStates& joystickInputStates, double deltaTime);
|
||||
|
||||
void setAxisMapping(int axis, AxisType mapping,
|
||||
void setAxisMapping(std::string joystickName, int axis, AxisType mapping,
|
||||
AxisInvert shouldInvert = AxisInvert::No,
|
||||
AxisNormalize shouldNormalize = AxisNormalize::No,
|
||||
JoystickType joystickType = JoystickType::JoystickLike,
|
||||
bool isSticky = false, double sensitivity = 0.0
|
||||
);
|
||||
|
||||
AxisInformation axisMapping(int axis) const;
|
||||
void setAxisMappingProperty(std::string joystickName, int axis,
|
||||
std::string propertyUri, float min = 0.f, float max = 1.f,
|
||||
AxisInvert shouldInvert = AxisInvert::No, bool isRemote = true
|
||||
);
|
||||
|
||||
void setDeadzone(int axis, float deadzone);
|
||||
float deadzone(int axis) const;
|
||||
AxisInformation axisMapping(const std::string& joystickName, int axis) const;
|
||||
|
||||
void setDeadzone(const std::string& joystickName, int axis, float deadzone);
|
||||
float deadzone(const std::string& joystickName, int axis) const;
|
||||
|
||||
void bindButtonCommand(int button, std::string command, JoystickAction action,
|
||||
ButtonCommandRemote remote, std::string documentation);
|
||||
void clearButtonCommand(int button);
|
||||
std::vector<std::string> buttonCommand(int button) const;
|
||||
void bindButtonCommand(const std::string& joystickName, int button,
|
||||
std::string command, JoystickAction action, ButtonCommandRemote remote,
|
||||
std::string documentation);
|
||||
void clearButtonCommand(const std::string& joystickName, int button);
|
||||
std::vector<std::string> buttonCommand(const std::string& joystickName,
|
||||
int button) const;
|
||||
|
||||
private:
|
||||
// We use an array for the axes and a map for the buttons since the axis are going to
|
||||
// be accessed much more often and thus have to be more efficient. And storing a few
|
||||
// extra AxisInformation that are not used will not matter that much; finding an axis
|
||||
// location in a potential map each frame, however, would
|
||||
struct JoystickCameraState {
|
||||
std::string joystickName;
|
||||
|
||||
std::array<AxisInformation, JoystickInputState::MaxAxes> _axisMapping;
|
||||
// We use an array for the axes and a map for the buttons since the axis are going to
|
||||
// be accessed much more often and thus have to be more efficient. And storing a few
|
||||
// extra AxisInformation that are not used will not matter that much; finding an axis
|
||||
// location in a potential map each frame, however, would
|
||||
std::array<AxisInformation, JoystickInputState::MaxAxes> axisMapping;
|
||||
|
||||
// This array is used to store the old axis values from the previous frame,
|
||||
// it is used to calculate the difference in the values in the case of a sticky axis
|
||||
std::array<float, JoystickInputState::MaxAxes> _prevAxisValues;
|
||||
// This array is used to store the old axis values from the previous frame,
|
||||
// it is used to calculate the difference in the values in the case of a sticky axis
|
||||
std::array<float, JoystickInputState::MaxAxes> prevAxisValues;
|
||||
|
||||
struct ButtonInformation {
|
||||
std::string command;
|
||||
JoystickAction action;
|
||||
ButtonCommandRemote synchronization;
|
||||
std::string documentation;
|
||||
struct ButtonInformation {
|
||||
// The script that is run when the button is activated
|
||||
std::string command;
|
||||
|
||||
// When is the button considered activated
|
||||
JoystickAction action;
|
||||
|
||||
// If the script should be syncronised to other remote sessions or not
|
||||
ButtonCommandRemote synchronization;
|
||||
|
||||
// Short documentation on what the script of this button does
|
||||
std::string documentation;
|
||||
};
|
||||
|
||||
std::multimap<int, ButtonInformation> buttonMapping;
|
||||
};
|
||||
|
||||
std::multimap<int, ButtonInformation> _buttonMapping;
|
||||
std::vector<JoystickCameraState> _joystickCameraStates;
|
||||
|
||||
// Find the item in _joystickCameraStates that corresponds to the given joystickName
|
||||
// return a pointer to the item, if not found then return nullptr
|
||||
JoystickCameraState* joystickCameraState(const std::string& joystickName);
|
||||
const JoystickCameraState* joystickCameraState(const std::string& joystickName) const;
|
||||
|
||||
// Ues getJoystickCameraState(name) to find the joystickCameraState that
|
||||
// corresponds to the given joystickName. If not found then add a new item if possible
|
||||
JoystickCameraState* findOrAddJoystickCameraState(const std::string& joystickName);
|
||||
};
|
||||
|
||||
} // namespace openspace::interaction
|
||||
@@ -137,6 +176,7 @@ inline std::string to_string(
|
||||
case T::GlobalRollY: return "GlobalRoll Y";
|
||||
case T::PanX: return "Pan X";
|
||||
case T::PanY: return "Pan Y";
|
||||
case T::Property: return "Property";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
@@ -159,10 +199,35 @@ from_string(std::string_view string)
|
||||
if (string == "GlobalRoll Y") { return T::GlobalRollY; }
|
||||
if (string == "Pan X") { return T::PanX; }
|
||||
if (string == "Pan Y") { return T::PanY; }
|
||||
if (string == "Property") { return T::Property; }
|
||||
|
||||
throw RuntimeError("Unkonwn axis type '" + std::string(string) + "'");
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::string to_string(
|
||||
const openspace::interaction::JoystickCameraStates::JoystickType& value)
|
||||
{
|
||||
using T = openspace::interaction::JoystickCameraStates::JoystickType;
|
||||
switch (value) {
|
||||
case T::JoystickLike: return "JoystickLike";
|
||||
case T::TriggerLike: return "TriggerLike";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr openspace::interaction::JoystickCameraStates::JoystickType
|
||||
from_string(std::string_view string)
|
||||
{
|
||||
using T = openspace::interaction::JoystickCameraStates::JoystickType;
|
||||
|
||||
if (string == "JoystickLike") { return T::JoystickLike; }
|
||||
if (string == "TriggerLike") { return T::TriggerLike; }
|
||||
|
||||
throw RuntimeError("Unkonwn joystick type '" + std::string(string) + "'");
|
||||
}
|
||||
|
||||
} // namespace ghoul
|
||||
|
||||
#endif // __OPENSPACE_CORE___JOYSTICKCAMERASTATES___H__
|
||||
|
||||
@@ -54,10 +54,11 @@ enum class JoystickAction : uint8_t {
|
||||
* The input state of a single joystick.
|
||||
*/
|
||||
struct JoystickInputState {
|
||||
/// These two are just randomly selected numbers that can be increased if needed
|
||||
/// The maximum number of supported axes
|
||||
static constexpr const int MaxAxes = 8;
|
||||
/// The maximum number of supported buttons
|
||||
static constexpr const int MaxButtons = 32;
|
||||
static constexpr const int MaxButtons = 48;
|
||||
|
||||
/// Marks whether this joystick is connected. If this value is \c false, all other
|
||||
/// members of this struct are undefined
|
||||
@@ -72,11 +73,6 @@ struct JoystickInputState {
|
||||
/// \c nAxes values are defined values, the rest are undefined
|
||||
std::array<float, MaxAxes> axes;
|
||||
|
||||
/// The axis values can either go back to 0 when the joystick is released or it can
|
||||
/// stay at the value it was before the joystick was released.
|
||||
/// The latter is called a sticky axis, when the values don't go back to 0.
|
||||
bool isSticky = false;
|
||||
|
||||
/// The number of buttons that this joystick possesses
|
||||
int nButtons = 0;
|
||||
/// The status of each button. Only the first \c nButtons values are defined, the rest
|
||||
@@ -88,6 +84,10 @@ struct JoystickInputState {
|
||||
/// derived from the available GLFW constants
|
||||
constexpr const int MaxJoysticks = 16;
|
||||
struct JoystickInputStates : public std::array<JoystickInputState, MaxJoysticks> {
|
||||
/// The maximum number of joysticks that are supported by this system. This number is
|
||||
/// derived from the available GLFW constants
|
||||
static constexpr const int MaxNumJoysticks = 16;
|
||||
|
||||
/**
|
||||
* This function adds the contributions of all connected joysticks for the provided
|
||||
* \p axis. After adding each joysticks contribution, the result is clamped to [-1,1].
|
||||
@@ -99,7 +99,7 @@ struct JoystickInputStates : public std::array<JoystickInputState, MaxJoysticks>
|
||||
*
|
||||
* \pre \p axis must be 0 or positive
|
||||
*/
|
||||
float axis(int axis) const;
|
||||
float axis(const std::string& joystickName, int axis) const;
|
||||
|
||||
/**
|
||||
* This functions checks whether any connected joystick has its \p button in the
|
||||
@@ -113,7 +113,7 @@ struct JoystickInputStates : public std::array<JoystickInputState, MaxJoysticks>
|
||||
*
|
||||
* \pre \p button must be 0 or positive
|
||||
*/
|
||||
bool button(int button, JoystickAction action) const;
|
||||
bool button(const std::string& joystickName, int button, JoystickAction action) const;
|
||||
};
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
51
include/openspace/interaction/keyboardinputstate.h
Normal file
51
include/openspace/interaction/keyboardinputstate.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_CORE___KEYBOARDINPUTSTATE___H__
|
||||
#define __OPENSPACE_CORE___KEYBOARDINPUTSTATE___H__
|
||||
|
||||
#include <openspace/util/keys.h>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
// This class represents the global input state of interaction devices
|
||||
class KeyboardInputState {
|
||||
public:
|
||||
// Callback functions
|
||||
void keyboardCallback(Key key, KeyModifier modifier, KeyAction action);
|
||||
|
||||
// Accessors
|
||||
const std::vector<std::pair<Key, KeyModifier>>& pressedKeys() const;
|
||||
bool isKeyPressed(std::pair<Key, KeyModifier> keyModPair) const;
|
||||
bool isKeyPressed(Key key) const;
|
||||
|
||||
private:
|
||||
// Input from keyboard
|
||||
std::vector<std::pair<Key, KeyModifier>> _keysDown;
|
||||
};
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
#endif // __OPENSPACE_CORE___KEYBOARDINPUTSTATE___H__
|
||||
@@ -29,11 +29,15 @@
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
class MouseInputState;
|
||||
class KeyboardInputState;
|
||||
|
||||
class MouseCameraStates : public CameraInteractionStates {
|
||||
public:
|
||||
MouseCameraStates(double sensitivity, double velocityScaleFactor);
|
||||
|
||||
void updateStateFromInput(const InputState& inputState, double deltaTime) override;
|
||||
void updateStateFromInput(const MouseInputState& mouseinputState,
|
||||
const KeyboardInputState& keyboardinputState, double deltaTime);
|
||||
|
||||
void setInvertMouseButton(bool value);
|
||||
|
||||
|
||||
@@ -22,52 +22,30 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_CORE___INPUTSTATE___H__
|
||||
#define __OPENSPACE_CORE___INPUTSTATE___H__
|
||||
#ifndef __OPENSPACE_CORE___MOUSEINPUTSTATE___H__
|
||||
#define __OPENSPACE_CORE___MOUSEINPUTSTATE___H__
|
||||
|
||||
#include <openspace/interaction/websocketinputstate.h>
|
||||
#include <openspace/util/keys.h>
|
||||
#include <openspace/util/mouse.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
struct JoystickInputStates;
|
||||
struct WebsocketInputStates;
|
||||
|
||||
// This class represents the global input state of interaction devices
|
||||
class InputState {
|
||||
class MouseInputState {
|
||||
public:
|
||||
// Callback functions
|
||||
void keyboardCallback(Key key, KeyModifier modifier, KeyAction action);
|
||||
void mouseButtonCallback(MouseButton button, MouseAction action);
|
||||
void mousePositionCallback(double mouseX, double mouseY);
|
||||
void mouseScrollWheelCallback(double mouseScrollDelta);
|
||||
|
||||
// Accessors
|
||||
const std::vector<std::pair<Key, KeyModifier>>& pressedKeys() const;
|
||||
bool isKeyPressed(std::pair<Key, KeyModifier> keyModPair) const;
|
||||
bool isKeyPressed(Key key) const;
|
||||
|
||||
const std::vector<MouseButton>& pressedMouseButtons() const;
|
||||
glm::dvec2 mousePosition() const;
|
||||
double mouseScrollDelta() const;
|
||||
bool isMouseButtonPressed(MouseButton mouseButton) const;
|
||||
|
||||
float joystickAxis(int i) const;
|
||||
bool joystickButton(int i) const;
|
||||
|
||||
WebsocketInputStates& websocketInputStates();
|
||||
float websocketAxis(int i) const;
|
||||
bool websocketButton(int i) const;
|
||||
bool hasWebsocketStates() const;
|
||||
void resetWebsockets();
|
||||
|
||||
private:
|
||||
// Input from keyboard
|
||||
std::vector<std::pair<Key, KeyModifier>> _keysDown;
|
||||
|
||||
// Input from mouse
|
||||
std::vector<MouseButton> _mouseButtonsDown;
|
||||
glm::dvec2 _mousePosition = glm::dvec2(0.0);
|
||||
@@ -76,4 +54,4 @@ private:
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
#endif // __OPENSPACE_CORE___INPUTSTATE___H__
|
||||
#endif // __OPENSPACE_CORE___MOUSEINPUTSTATE___H__
|
||||
@@ -33,7 +33,7 @@ class ScriptCameraStates : public CameraInteractionStates {
|
||||
public:
|
||||
ScriptCameraStates();
|
||||
|
||||
void updateStateFromInput(const InputState& inputState, double deltaTime) override;
|
||||
void updateStateFromInput(double deltaTime);
|
||||
|
||||
void addLocalRotation(const glm::dvec2& delta);
|
||||
void addGlobalRotation(const glm::dvec2& delta);
|
||||
|
||||
@@ -65,7 +65,8 @@ public:
|
||||
|
||||
WebsocketCameraStates(double sensitivity, double velocityScaleFactor);
|
||||
|
||||
void updateStateFromInput(const InputState& inputState, double deltaTime) override;
|
||||
void updateStateFromInput(
|
||||
const WebsocketInputStates& websocketInputStates, double deltaTime);
|
||||
|
||||
void setAxisMapping(int axis, AxisType mapping,
|
||||
AxisInvert shouldInvert = AxisInvert::No,
|
||||
|
||||
@@ -26,8 +26,9 @@
|
||||
#define __OPENSPACE_CORE___NAVIGATIONHANDLER___H__
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/interaction/inputstate.h>
|
||||
#include <openspace/interaction/joystickcamerastates.h>
|
||||
#include <openspace/interaction/keyboardinputstate.h>
|
||||
#include <openspace/interaction/mouseinputstate.h>
|
||||
#include <openspace/interaction/websocketcamerastates.h>
|
||||
#include <openspace/navigation/keyframenavigator.h>
|
||||
#include <openspace/navigation/navigationstate.h>
|
||||
@@ -81,7 +82,8 @@ public:
|
||||
// Accessors
|
||||
Camera* camera() const;
|
||||
const SceneGraphNode* anchorNode() const;
|
||||
const InputState& inputState() const;
|
||||
const MouseInputState& mouseInputState() const;
|
||||
const KeyboardInputState& keyboardInputState() const;
|
||||
const OrbitalNavigator& orbitalNavigator() const;
|
||||
OrbitalNavigator& orbitalNavigator();
|
||||
KeyframeNavigator& keyframeNavigator();
|
||||
@@ -96,24 +98,36 @@ public:
|
||||
void mousePositionCallback(double x, double y);
|
||||
void mouseScrollWheelCallback(double pos);
|
||||
|
||||
void setJoystickAxisMapping(int axis, JoystickCameraStates::AxisType mapping,
|
||||
void setJoystickAxisMapping(std::string joystickName,
|
||||
int axis, JoystickCameraStates::AxisType mapping,
|
||||
JoystickCameraStates::AxisInvert shouldInvert =
|
||||
JoystickCameraStates::AxisInvert::No,
|
||||
JoystickCameraStates::AxisNormalize shouldNormalize =
|
||||
JoystickCameraStates::AxisNormalize::No,
|
||||
JoystickCameraStates::JoystickType joystickType =
|
||||
JoystickCameraStates::JoystickType::JoystickLike,
|
||||
bool isSticky = false, double sensitivity = 0.0
|
||||
);
|
||||
|
||||
JoystickCameraStates::AxisInformation joystickAxisMapping(int axis) const;
|
||||
void setJoystickAxisMappingProperty(std::string joystickName,
|
||||
int axis, std::string propertyUri,
|
||||
float min = 0.f, float max = 1.f,
|
||||
JoystickCameraStates::AxisInvert shouldInvert =
|
||||
JoystickCameraStates::AxisInvert::No, bool isRemote = true
|
||||
);
|
||||
|
||||
void setJoystickAxisDeadzone(int axis, float deadzone);
|
||||
float joystickAxisDeadzone(int axis) const;
|
||||
JoystickCameraStates::AxisInformation joystickAxisMapping(
|
||||
const std::string& joystickName, int axis) const;
|
||||
|
||||
void bindJoystickButtonCommand(int button, std::string command, JoystickAction action,
|
||||
void setJoystickAxisDeadzone(const std::string& joystickName, int axis,
|
||||
float deadzone);
|
||||
float joystickAxisDeadzone(const std::string& joystickName, int axis) const;
|
||||
|
||||
void bindJoystickButtonCommand(const std::string& joystickName, int button,
|
||||
std::string command, JoystickAction action,
|
||||
JoystickCameraStates::ButtonCommandRemote remote, std::string documentation);
|
||||
|
||||
void clearJoystickButtonCommand(int button);
|
||||
std::vector<std::string> joystickButtonCommand(int button) const;
|
||||
void clearJoystickButtonCommand(const std::string& joystickName, int button);
|
||||
std::vector<std::string> joystickButtonCommand(const std::string& joystickName,
|
||||
int button) const;
|
||||
|
||||
// Websockets
|
||||
void setWebsocketAxisMapping(int axis, WebsocketCameraStates::AxisType mapping,
|
||||
@@ -144,7 +158,8 @@ private:
|
||||
|
||||
bool _playbackModeEnabled = false;
|
||||
|
||||
InputState _inputState;
|
||||
MouseInputState _mouseInputState;
|
||||
KeyboardInputState _keyboardInputState;
|
||||
Camera* _camera = nullptr;
|
||||
std::function<void()> _playbackEndCallback;
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include <openspace/properties/triggerproperty.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace openspace {
|
||||
@@ -53,13 +52,15 @@ namespace openspace {
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
class InputState;
|
||||
class MouseInputState;
|
||||
class KeyboardInputState;
|
||||
|
||||
class OrbitalNavigator : public properties::PropertyOwner {
|
||||
public:
|
||||
OrbitalNavigator();
|
||||
|
||||
void updateStatesFromInput(const InputState& inputState, double deltaTime);
|
||||
void updateStatesFromInput(const MouseInputState& mouseInputState,
|
||||
const KeyboardInputState& keyboardInputState, double deltaTime);
|
||||
void updateCameraStateFromStates(double deltaTime);
|
||||
void updateCameraScalingFromAnchor(double deltaTime);
|
||||
void resetVelocities();
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include <modules/imgui/include/imgui_include.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/inputstate.h>
|
||||
#include <openspace/interaction/joystickinputstate.h>
|
||||
|
||||
namespace {
|
||||
@@ -86,7 +85,7 @@ void GuiJoystickComponent::render() {
|
||||
ImGui::Text("%s", "Summed contributions");
|
||||
ImGui::Text("%s", "Axes");
|
||||
for (int i = 0; i < JoystickInputState::MaxAxes; ++i) {
|
||||
float f = global::joystickInputStates->axis(i);
|
||||
float f = global::joystickInputStates->axis("", i);
|
||||
ImGui::SliderFloat(
|
||||
std::to_string(i).c_str(),
|
||||
&f,
|
||||
@@ -98,8 +97,8 @@ void GuiJoystickComponent::render() {
|
||||
for (int i = 0; i < JoystickInputState::MaxButtons; ++i) {
|
||||
ImGui::RadioButton(
|
||||
std::to_string(i).c_str(),
|
||||
global::joystickInputStates->button(i, JoystickAction::Press) ||
|
||||
global::joystickInputStates->button(i, JoystickAction::Repeat)
|
||||
global::joystickInputStates->button("", i, JoystickAction::Press) ||
|
||||
global::joystickInputStates->button("", i, JoystickAction::Repeat)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include <openspace/interaction/websocketinputstate.h>
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
struct WebsocketInputStates;
|
||||
struct WebsocketInputState;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <modules/server/include/connection.h>
|
||||
#include <modules/server/include/jsonconverters.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/inputstate.h>
|
||||
#include <openspace/interaction/websocketcamerastates.h>
|
||||
#include <openspace/interaction/websocketinputstate.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
#include <openspace/engine/globalscallbacks.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/interaction/inputstate.h>
|
||||
#include <openspace/interaction/interactionmonitor.h>
|
||||
#include <openspace/interaction/keyboardinputstate.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <fmt/format.h>
|
||||
@@ -462,7 +462,7 @@ CefTouchEvent EventHandler::touchEvent(const TouchInput& input,
|
||||
event.y = windowPos.y;
|
||||
event.type = eventType;
|
||||
const std::vector<std::pair<Key, KeyModifier>>& keyMods =
|
||||
global::navigationHandler->inputState().pressedKeys();
|
||||
global::navigationHandler->keyboardInputState().pressedKeys();
|
||||
for (const std::pair<Key, KeyModifier>& p : keyMods) {
|
||||
const KeyModifier mods = p.second;
|
||||
event.modifiers |= static_cast<uint32_t>(mapToCefModifiers(mods));
|
||||
|
||||
@@ -50,11 +50,12 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/actionmanager_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/camerainteractionstates.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/interactionmonitor.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/inputstate.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/mouseinputstate.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/joystickinputstate.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/joystickcamerastates.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/keybindingmanager.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/keybindingmanager_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/keyboardinputstate.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/mousecamerastates.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/scriptcamerastates.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/externinteraction.cpp
|
||||
@@ -232,13 +233,14 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/delayedvariable.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/delayedvariable.inl
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/camerainteractionstates.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/inputstate.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/mouseinputstate.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/interactionmonitor.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/interpolator.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/interpolator.inl
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/joystickinputstate.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/joystickcamerastates.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/keybindingmanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/keyboardinputstate.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/mousecamerastates.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/externinteraction.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/scriptcamerastates.h
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
#include <openspace/interaction/camerainteractionstates.h>
|
||||
|
||||
#include <openspace/interaction/inputstate.h>
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
CameraInteractionStates::InteractionState::InteractionState(double scaleFactor)
|
||||
|
||||
@@ -25,19 +25,24 @@
|
||||
#include <openspace/interaction/joystickcamerastates.h>
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/inputstate.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/exception.h>
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "JoystickCameraStates";
|
||||
} // namespace
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
JoystickCameraStates::JoystickCameraStates(double sensitivity, double velocityScaleFactor)
|
||||
: CameraInteractionStates(sensitivity, velocityScaleFactor)
|
||||
{}
|
||||
|
||||
void JoystickCameraStates::updateStateFromInput(const InputState& inputState,
|
||||
void JoystickCameraStates::updateStateFromInput(
|
||||
const JoystickInputStates& joystickInputStates,
|
||||
double deltaTime)
|
||||
{
|
||||
std::pair<bool, glm::dvec2> globalRotation = { false, glm::dvec2(0.0) };
|
||||
@@ -46,83 +51,132 @@ void JoystickCameraStates::updateStateFromInput(const InputState& inputState,
|
||||
std::pair<bool, glm::dvec2> globalRoll = { false, glm::dvec2(0.0) };
|
||||
std::pair<bool, glm::dvec2> localRotation = { false, glm::dvec2(0.0) };
|
||||
|
||||
for (int i = 0; i < JoystickInputState::MaxAxes; ++i) {
|
||||
AxisInformation t = _axisMapping[i];
|
||||
if (t.type == AxisType::None) {
|
||||
for (const JoystickInputState& joystickInputState : joystickInputStates) {
|
||||
if (joystickInputState.name.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float rawValue = inputState.joystickAxis(i);
|
||||
float value = rawValue;
|
||||
JoystickCameraState* joystick = joystickCameraState(joystickInputState.name);
|
||||
|
||||
if (t.isSticky) {
|
||||
value = rawValue - _prevAxisValues[i];
|
||||
_prevAxisValues[i] = rawValue;
|
||||
}
|
||||
|
||||
if (std::fabs(value) <= t.deadzone) {
|
||||
if (!joystick) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t.normalize) {
|
||||
value = (value + 1.f) / 2.f;
|
||||
for (int i = 0; i < JoystickInputState::MaxAxes; ++i) {
|
||||
AxisInformation t = joystick->axisMapping[i];
|
||||
if (t.type == AxisType::None) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float rawValue = joystickInputStates.axis(joystickInputState.name, i);
|
||||
float value = rawValue;
|
||||
|
||||
if (t.isSticky) {
|
||||
value = rawValue - joystick->prevAxisValues[i];
|
||||
joystick->prevAxisValues[i] = rawValue;
|
||||
}
|
||||
|
||||
if ((t.joystickType == JoystickType::JoystickLike &&
|
||||
std::abs(value) <= t.deadzone) ||
|
||||
(t.joystickType == JoystickType::TriggerLike && value <= -1.f + t.deadzone))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t.invert) {
|
||||
value *= -1.f;
|
||||
}
|
||||
|
||||
if (t.joystickType == JoystickType::TriggerLike ||
|
||||
t.type == AxisType::Property)
|
||||
{
|
||||
value = (value + 1.f) / 2.f;
|
||||
}
|
||||
|
||||
if (t.type == AxisType::Property) {
|
||||
value = value * (t.maxValue - t.minValue) + t.minValue;
|
||||
}
|
||||
else {
|
||||
if (std::abs(t.sensitivity) > std::numeric_limits<double>::epsilon()) {
|
||||
value = static_cast<float>(value * t.sensitivity * _sensitivity);
|
||||
}
|
||||
else {
|
||||
value = static_cast<float>(value * _sensitivity);
|
||||
}
|
||||
}
|
||||
|
||||
switch (t.type) {
|
||||
case AxisType::None:
|
||||
break;
|
||||
case AxisType::OrbitX:
|
||||
globalRotation.first = true;
|
||||
globalRotation.second.x += value;
|
||||
break;
|
||||
case AxisType::OrbitY:
|
||||
globalRotation.first = true;
|
||||
globalRotation.second.y += value;
|
||||
break;
|
||||
case AxisType::Zoom:
|
||||
case AxisType::ZoomIn:
|
||||
zoom.first = true;
|
||||
zoom.second += value;
|
||||
break;
|
||||
case AxisType::ZoomOut:
|
||||
zoom.first = true;
|
||||
zoom.second -= value;
|
||||
break;
|
||||
case AxisType::LocalRollX:
|
||||
localRoll.first = true;
|
||||
localRoll.second.x += value;
|
||||
break;
|
||||
case AxisType::LocalRollY:
|
||||
localRoll.first = true;
|
||||
localRoll.second.y += value;
|
||||
break;
|
||||
case AxisType::GlobalRollX:
|
||||
globalRoll.first = true;
|
||||
globalRoll.second.x += value;
|
||||
break;
|
||||
case AxisType::GlobalRollY:
|
||||
globalRoll.first = true;
|
||||
globalRoll.second.y += value;
|
||||
break;
|
||||
case AxisType::PanX:
|
||||
localRotation.first = true;
|
||||
localRotation.second.x += value;
|
||||
break;
|
||||
case AxisType::PanY:
|
||||
localRotation.first = true;
|
||||
localRotation.second.y += value;
|
||||
break;
|
||||
case AxisType::Property:
|
||||
std::string script = fmt::format("openspace.setPropertyValue('{}', {});",
|
||||
t.propertyUri, value);
|
||||
|
||||
global::scriptEngine->queueScript(
|
||||
script,
|
||||
scripting::ScriptEngine::RemoteScripting(t.isRemote)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (t.invert) {
|
||||
value *= -1.f;
|
||||
}
|
||||
for (int i = 0; i < JoystickInputState::MaxButtons; ++i) {
|
||||
auto itRange = joystick->buttonMapping.equal_range(i);
|
||||
for (auto it = itRange.first; it != itRange.second; ++it) {
|
||||
bool active = global::joystickInputStates->button(
|
||||
joystickInputState.name,
|
||||
i,
|
||||
it->second.action
|
||||
);
|
||||
|
||||
if (std::abs(t.sensitivity) > std::numeric_limits<double>::epsilon()) {
|
||||
value = static_cast<float>(value * t.sensitivity * _sensitivity);
|
||||
}
|
||||
else {
|
||||
value = static_cast<float>(value * _sensitivity);
|
||||
}
|
||||
|
||||
switch (t.type) {
|
||||
case AxisType::None:
|
||||
break;
|
||||
case AxisType::OrbitX:
|
||||
globalRotation.first = true;
|
||||
globalRotation.second.x = value;
|
||||
break;
|
||||
case AxisType::OrbitY:
|
||||
globalRotation.first = true;
|
||||
globalRotation.second.y = value;
|
||||
break;
|
||||
case AxisType::Zoom:
|
||||
case AxisType::ZoomIn:
|
||||
zoom.first = true;
|
||||
zoom.second += value;
|
||||
break;
|
||||
case AxisType::ZoomOut:
|
||||
zoom.first = true;
|
||||
zoom.second -= value;
|
||||
break;
|
||||
case AxisType::LocalRollX:
|
||||
localRoll.first = true;
|
||||
localRoll.second.x = value;
|
||||
break;
|
||||
case AxisType::LocalRollY:
|
||||
localRoll.first = true;
|
||||
localRoll.second.y = value;
|
||||
break;
|
||||
case AxisType::GlobalRollX:
|
||||
globalRoll.first = true;
|
||||
globalRoll.second.x = value;
|
||||
break;
|
||||
case AxisType::GlobalRollY:
|
||||
globalRoll.first = true;
|
||||
globalRoll.second.y = value;
|
||||
break;
|
||||
case AxisType::PanX:
|
||||
localRotation.first = true;
|
||||
localRotation.second.x = value;
|
||||
break;
|
||||
case AxisType::PanY:
|
||||
localRotation.first = true;
|
||||
localRotation.second.y = value;
|
||||
break;
|
||||
if (active) {
|
||||
global::scriptEngine->queueScript(
|
||||
it->second.command,
|
||||
scripting::ScriptEngine::RemoteScripting(it->second.synchronization)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,72 +214,122 @@ void JoystickCameraStates::updateStateFromInput(const InputState& inputState,
|
||||
else {
|
||||
_localRotationState.velocity.decelerate(deltaTime);
|
||||
}
|
||||
|
||||
for (int i = 0; i < JoystickInputState::MaxButtons; ++i) {
|
||||
auto itRange = _buttonMapping.equal_range(i);
|
||||
for (auto it = itRange.first; it != itRange.second; ++it) {
|
||||
bool active = global::joystickInputStates->button(i, it->second.action);
|
||||
|
||||
if (active) {
|
||||
global::scriptEngine->queueScript(
|
||||
it->second.command,
|
||||
scripting::ScriptEngine::RemoteScripting(it->second.synchronization)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JoystickCameraStates::setAxisMapping(int axis, AxisType mapping,
|
||||
void JoystickCameraStates::setAxisMapping(std::string joystickName,
|
||||
int axis, AxisType mapping,
|
||||
AxisInvert shouldInvert,
|
||||
AxisNormalize shouldNormalize,
|
||||
JoystickType joystickType,
|
||||
bool isSticky,
|
||||
double sensitivity)
|
||||
{
|
||||
ghoul_assert(axis < JoystickInputState::MaxAxes, "axis must be < MaxAxes");
|
||||
|
||||
_axisMapping[axis].type = mapping;
|
||||
_axisMapping[axis].invert = shouldInvert;
|
||||
_axisMapping[axis].normalize = shouldNormalize;
|
||||
_axisMapping[axis].isSticky = isSticky;
|
||||
_axisMapping[axis].sensitivity = sensitivity;
|
||||
|
||||
if (isSticky) {
|
||||
global::joystickInputStates->at(axis).isSticky = true;
|
||||
JoystickCameraState* joystickCameraState = findOrAddJoystickCameraState(joystickName);
|
||||
if (!joystickCameraState) {
|
||||
return;
|
||||
}
|
||||
|
||||
_prevAxisValues[axis] = global::joystickInputStates->axis(axis);
|
||||
joystickCameraState->axisMapping[axis].type = mapping;
|
||||
joystickCameraState->axisMapping[axis].invert = shouldInvert;
|
||||
joystickCameraState->axisMapping[axis].joystickType = joystickType;
|
||||
joystickCameraState->axisMapping[axis].isSticky = isSticky;
|
||||
joystickCameraState->axisMapping[axis].sensitivity = sensitivity;
|
||||
|
||||
joystickCameraState->prevAxisValues[axis] =
|
||||
global::joystickInputStates->axis(joystickName, axis);
|
||||
}
|
||||
|
||||
JoystickCameraStates::AxisInformation JoystickCameraStates::axisMapping(int axis) const {
|
||||
return _axisMapping[axis];
|
||||
void JoystickCameraStates::setAxisMappingProperty(std::string joystickName,
|
||||
int axis,
|
||||
std::string propertyUri,
|
||||
float min, float max,
|
||||
AxisInvert shouldInvert,
|
||||
bool isRemote)
|
||||
{
|
||||
ghoul_assert(axis < JoystickInputState::MaxAxes, "axis must be < MaxAxes");
|
||||
|
||||
JoystickCameraState* joystickCameraState = findOrAddJoystickCameraState(joystickName);
|
||||
if (!joystickCameraState) {
|
||||
return;
|
||||
}
|
||||
|
||||
joystickCameraState->axisMapping[axis].type = AxisType::Property;
|
||||
joystickCameraState->axisMapping[axis].invert = shouldInvert;
|
||||
joystickCameraState->axisMapping[axis].propertyUri = propertyUri;
|
||||
joystickCameraState->axisMapping[axis].minValue = min;
|
||||
joystickCameraState->axisMapping[axis].maxValue = max;
|
||||
joystickCameraState->axisMapping[axis].isRemote = isRemote;
|
||||
|
||||
joystickCameraState->prevAxisValues[axis] =
|
||||
global::joystickInputStates->axis(joystickName, axis);
|
||||
}
|
||||
|
||||
void JoystickCameraStates::setDeadzone(int axis, float deadzone) {
|
||||
_axisMapping[axis].deadzone = deadzone;
|
||||
JoystickCameraStates::AxisInformation JoystickCameraStates::axisMapping(
|
||||
const std::string& joystickName,
|
||||
int axis) const
|
||||
{
|
||||
const JoystickCameraState* joystick = joystickCameraState(joystickName);
|
||||
if (!joystick) {
|
||||
JoystickCameraStates::AxisInformation dummy;
|
||||
return dummy;
|
||||
}
|
||||
|
||||
return joystick->axisMapping[axis];
|
||||
}
|
||||
|
||||
float JoystickCameraStates::deadzone(int axis) const {
|
||||
return _axisMapping[axis].deadzone;
|
||||
void JoystickCameraStates::setDeadzone(const std::string& joystickName, int axis,
|
||||
float deadzone)
|
||||
{
|
||||
JoystickCameraState* joystickCameraState = findOrAddJoystickCameraState(joystickName);
|
||||
if (!joystickCameraState) {
|
||||
return;
|
||||
}
|
||||
|
||||
joystickCameraState->axisMapping[axis].deadzone = deadzone;
|
||||
}
|
||||
|
||||
void JoystickCameraStates::bindButtonCommand(int button, std::string command,
|
||||
float JoystickCameraStates::deadzone(const std::string& joystickName, int axis) const {
|
||||
const JoystickCameraState* joystick = joystickCameraState(joystickName);
|
||||
if (!joystick) {
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
return joystick->axisMapping[axis].deadzone;
|
||||
}
|
||||
|
||||
void JoystickCameraStates::bindButtonCommand(const std::string& joystickName,
|
||||
int button, std::string command,
|
||||
JoystickAction action,
|
||||
ButtonCommandRemote remote,
|
||||
std::string documentation)
|
||||
{
|
||||
_buttonMapping.insert({
|
||||
JoystickCameraState* joystickCameraState = findOrAddJoystickCameraState(joystickName);
|
||||
if (!joystickCameraState) {
|
||||
return;
|
||||
}
|
||||
|
||||
joystickCameraState->buttonMapping.insert({
|
||||
button,
|
||||
{ std::move(command), action, remote, std::move(documentation) }
|
||||
});
|
||||
}
|
||||
|
||||
void JoystickCameraStates::clearButtonCommand(int button) {
|
||||
for (auto it = _buttonMapping.begin(); it != _buttonMapping.end();) {
|
||||
void JoystickCameraStates::clearButtonCommand(const std::string& joystickName,
|
||||
int button)
|
||||
{
|
||||
JoystickCameraState* joystick = joystickCameraState(joystickName);
|
||||
if (!joystick) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it = joystick->buttonMapping.begin();
|
||||
it != joystick->buttonMapping.end(); )
|
||||
{
|
||||
// If the current iterator is the button that we are looking for, delete it
|
||||
// (std::multimap::erase will return the iterator to the next element for us)
|
||||
if (it->first == button) {
|
||||
it = _buttonMapping.erase(it);
|
||||
it = joystick->buttonMapping.erase(it);
|
||||
}
|
||||
else {
|
||||
++it;
|
||||
@@ -233,14 +337,66 @@ void JoystickCameraStates::clearButtonCommand(int button) {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> JoystickCameraStates::buttonCommand(int button) const {
|
||||
std::vector<std::string> JoystickCameraStates::buttonCommand(
|
||||
const std::string& joystickName,
|
||||
int button) const
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
auto itRange = _buttonMapping.equal_range(button);
|
||||
const JoystickCameraState* joystick = joystickCameraState(joystickName);
|
||||
if (!joystick) {
|
||||
return result;
|
||||
}
|
||||
|
||||
auto itRange = joystick->buttonMapping.equal_range(button);
|
||||
for (auto it = itRange.first; it != itRange.second; ++it) {
|
||||
result.push_back(it->second.command);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
JoystickCameraStates::JoystickCameraState* JoystickCameraStates::joystickCameraState(
|
||||
const std::string& joystickName)
|
||||
{
|
||||
for (JoystickCameraState& joystickCameraState : _joystickCameraStates) {
|
||||
if (joystickCameraState.joystickName == joystickName) {
|
||||
return &joystickCameraState;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const JoystickCameraStates::JoystickCameraState*
|
||||
JoystickCameraStates::joystickCameraState(const std::string& joystickName) const
|
||||
{
|
||||
for (const JoystickCameraState& joystickCameraState : _joystickCameraStates) {
|
||||
if (joystickCameraState.joystickName == joystickName) {
|
||||
return &joystickCameraState;
|
||||
}
|
||||
}
|
||||
|
||||
LWARNING(fmt::format("Cannot find JoystickCameraState with name '{}'", joystickName));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JoystickCameraStates::JoystickCameraState*
|
||||
JoystickCameraStates::findOrAddJoystickCameraState(const std::string& joystickName)
|
||||
{
|
||||
JoystickCameraState* joystick = joystickCameraState(joystickName);
|
||||
if (!joystick) {
|
||||
if (_joystickCameraStates.size() < JoystickInputStates::MaxNumJoysticks) {
|
||||
_joystickCameraStates.push_back(JoystickCameraState());
|
||||
joystick = &_joystickCameraStates.back();
|
||||
joystick->joystickName = joystickName;
|
||||
}
|
||||
else {
|
||||
LWARNING(fmt::format("Cannot add more joysticks, only {} joysticks are "
|
||||
"supported", JoystickInputStates::MaxNumJoysticks));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return joystick;
|
||||
}
|
||||
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
@@ -33,38 +33,68 @@
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
float JoystickInputStates::axis(int axis) const {
|
||||
float JoystickInputStates::axis(const std::string& joystickName, int axis) const {
|
||||
ghoul_precondition(axis >= 0, "axis must be 0 or positive");
|
||||
|
||||
float res = std::accumulate(
|
||||
begin(),
|
||||
end(),
|
||||
0.f,
|
||||
[axis](float value, const JoystickInputState& state) {
|
||||
if (state.isConnected) {
|
||||
value += state.axes[axis];
|
||||
if (joystickName.empty()) {
|
||||
float res = std::accumulate(
|
||||
begin(),
|
||||
end(),
|
||||
0.f,
|
||||
[axis](float value, const JoystickInputState& state) {
|
||||
if (state.isConnected) {
|
||||
value += state.axes[axis];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
// If multiple joysticks are connected, we might get values outside the -1,1 range by
|
||||
// summing them up
|
||||
glm::clamp(res, -1.f, 1.f);
|
||||
return res;
|
||||
// If multiple joysticks are connected, we might get values outside the -1,1 range by
|
||||
// summing them up
|
||||
glm::clamp(res, -1.f, 1.f);
|
||||
return res;
|
||||
}
|
||||
|
||||
const JoystickInputState* state = nullptr;
|
||||
for (auto it = begin(); it < end(); ++it) {
|
||||
if (it->name == joystickName) {
|
||||
state = &(*it);
|
||||
}
|
||||
}
|
||||
|
||||
if (!state) {
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
return state->axes[axis];
|
||||
}
|
||||
|
||||
bool JoystickInputStates::button(int button, JoystickAction action) const {
|
||||
bool JoystickInputStates::button(const std::string& joystickName, int button, JoystickAction action) const {
|
||||
ghoul_precondition(button >= 0, "button must be 0 or positive");
|
||||
|
||||
bool res = std::any_of(
|
||||
begin(),
|
||||
end(),
|
||||
[button, action](const JoystickInputState& state) {
|
||||
return state.isConnected ? (state.buttons[button] == action) : false;
|
||||
if (joystickName.empty()) {
|
||||
bool res = std::any_of(
|
||||
begin(),
|
||||
end(),
|
||||
[button, action](const JoystickInputState& state) {
|
||||
return state.isConnected ? (state.buttons[button] == action) : false;
|
||||
}
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
const JoystickInputState* state = nullptr;
|
||||
for (auto it = begin(); it < end(); ++it) {
|
||||
if (it->name == joystickName) {
|
||||
state = &(*it);
|
||||
}
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (!state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return state->isConnected ? (state->buttons[button] == action) : false;
|
||||
}
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
@@ -22,17 +22,15 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/interaction/inputstate.h>
|
||||
#include <openspace/interaction/keyboardinputstate.h>
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/joystickinputstate.h>
|
||||
#include <openspace/interaction/websocketinputstate.h>
|
||||
#include <ghoul/fmt.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
void InputState::keyboardCallback(Key key, KeyModifier modifier, KeyAction action) {
|
||||
void KeyboardInputState::keyboardCallback(Key key, KeyModifier modifier,
|
||||
KeyAction action)
|
||||
{
|
||||
if (action == KeyAction::Press) {
|
||||
_keysDown.emplace_back(key, modifier);
|
||||
}
|
||||
@@ -51,47 +49,15 @@ void InputState::keyboardCallback(Key key, KeyModifier modifier, KeyAction actio
|
||||
}
|
||||
}
|
||||
|
||||
void InputState::mouseButtonCallback(MouseButton button, MouseAction action) {
|
||||
if (action == MouseAction::Press) {
|
||||
_mouseButtonsDown.push_back(button);
|
||||
}
|
||||
else if (action == MouseAction::Release) {
|
||||
_mouseButtonsDown.erase(
|
||||
std::remove(_mouseButtonsDown.begin(), _mouseButtonsDown.end(), button),
|
||||
_mouseButtonsDown.end()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void InputState::mousePositionCallback(double mouseX, double mouseY) {
|
||||
_mousePosition = glm::dvec2(mouseX, mouseY);
|
||||
}
|
||||
|
||||
void InputState::mouseScrollWheelCallback(double mouseScrollDelta) {
|
||||
_mouseScrollDelta = mouseScrollDelta;
|
||||
}
|
||||
|
||||
const std::vector<std::pair<Key, KeyModifier>>& InputState::pressedKeys() const {
|
||||
const std::vector<std::pair<Key, KeyModifier>>& KeyboardInputState::pressedKeys() const {
|
||||
return _keysDown;
|
||||
}
|
||||
|
||||
const std::vector<MouseButton>& InputState::pressedMouseButtons() const {
|
||||
return _mouseButtonsDown;
|
||||
}
|
||||
|
||||
glm::dvec2 InputState::mousePosition() const {
|
||||
return _mousePosition;
|
||||
}
|
||||
|
||||
double InputState::mouseScrollDelta() const {
|
||||
return _mouseScrollDelta;
|
||||
}
|
||||
|
||||
bool InputState::isKeyPressed(std::pair<Key, KeyModifier> keyModPair) const {
|
||||
bool KeyboardInputState::isKeyPressed(std::pair<Key, KeyModifier> keyModPair) const {
|
||||
return std::find(_keysDown.begin(), _keysDown.end(), keyModPair) != _keysDown.end();
|
||||
}
|
||||
|
||||
bool InputState::isKeyPressed(Key key) const {
|
||||
bool KeyboardInputState::isKeyPressed(Key key) const {
|
||||
auto it = std::find_if(
|
||||
_keysDown.begin(),
|
||||
_keysDown.end(),
|
||||
@@ -102,37 +68,4 @@ bool InputState::isKeyPressed(Key key) const {
|
||||
return it != _keysDown.end();
|
||||
}
|
||||
|
||||
bool InputState::isMouseButtonPressed(MouseButton mouseButton) const {
|
||||
auto it = std::find(_mouseButtonsDown.begin(), _mouseButtonsDown.end(), mouseButton);
|
||||
return it != _mouseButtonsDown.end();
|
||||
}
|
||||
|
||||
float InputState::joystickAxis(int i) const {
|
||||
return global::joystickInputStates->axis(i);
|
||||
}
|
||||
|
||||
bool InputState::joystickButton(int i) const {
|
||||
return global::joystickInputStates->button(i, JoystickAction::Press);
|
||||
}
|
||||
|
||||
float InputState::websocketAxis(int i) const {
|
||||
return global::websocketInputStates->axis(i);
|
||||
}
|
||||
|
||||
bool InputState::websocketButton(int i) const {
|
||||
return global::websocketInputStates->button(i, WebsocketAction::Press);
|
||||
}
|
||||
|
||||
void InputState::resetWebsockets() {
|
||||
using K = size_t;
|
||||
using V = WebsocketInputState*;
|
||||
for (const std::pair<const K, V>& p : *global::websocketInputStates) {
|
||||
p.second->isConnected = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool InputState::hasWebsocketStates() const {
|
||||
return !global::websocketInputStates->empty();
|
||||
}
|
||||
|
||||
} // namespace openspace::interaction
|
||||
@@ -24,7 +24,8 @@
|
||||
|
||||
#include <openspace/interaction/mousecamerastates.h>
|
||||
|
||||
#include <openspace/interaction/inputstate.h>
|
||||
#include <openspace/interaction/mouseinputstate.h>
|
||||
#include <openspace/interaction/keyboardinputstate.h>
|
||||
|
||||
namespace {
|
||||
const double SENSITIVITY_ADJUSTMENT_INCREASE = 8.0;
|
||||
@@ -37,7 +38,8 @@ MouseCameraStates::MouseCameraStates(double sensitivity, double velocityScaleFac
|
||||
: CameraInteractionStates(sensitivity, velocityScaleFactor)
|
||||
{}
|
||||
|
||||
void MouseCameraStates::updateStateFromInput(const InputState& inputState,
|
||||
void MouseCameraStates::updateStateFromInput(const MouseInputState& mouseinputState,
|
||||
const KeyboardInputState& keyboardinputState,
|
||||
double deltaTime)
|
||||
{
|
||||
MouseButton primary =
|
||||
@@ -45,17 +47,17 @@ void MouseCameraStates::updateStateFromInput(const InputState& inputState,
|
||||
MouseButton secondary =
|
||||
_isMouseButtonInverted ? MouseButton::Button1 : MouseButton::Button2;
|
||||
|
||||
glm::dvec2 mousePosition = inputState.mousePosition();
|
||||
glm::dvec2 mousePosition = mouseinputState.mousePosition();
|
||||
|
||||
bool primaryPressed = inputState.isMouseButtonPressed(primary);
|
||||
bool secondaryPressed = inputState.isMouseButtonPressed(secondary);
|
||||
bool button3Pressed = inputState.isMouseButtonPressed(MouseButton::Button3);
|
||||
bool keyCtrlPressed = inputState.isKeyPressed(Key::LeftControl) |
|
||||
inputState.isKeyPressed(Key::RightControl);
|
||||
bool keyShiftPressed = inputState.isKeyPressed(Key::LeftShift) |
|
||||
inputState.isKeyPressed(Key::RightShift);
|
||||
bool keyAltPressed = inputState.isKeyPressed(Key::LeftAlt) |
|
||||
inputState.isKeyPressed(Key::RightAlt);
|
||||
bool primaryPressed = mouseinputState.isMouseButtonPressed(primary);
|
||||
bool secondaryPressed = mouseinputState.isMouseButtonPressed(secondary);
|
||||
bool button3Pressed = mouseinputState.isMouseButtonPressed(MouseButton::Button3);
|
||||
bool keyCtrlPressed = keyboardinputState.isKeyPressed(Key::LeftControl) |
|
||||
keyboardinputState.isKeyPressed(Key::RightControl);
|
||||
bool keyShiftPressed = keyboardinputState.isKeyPressed(Key::LeftShift) |
|
||||
keyboardinputState.isKeyPressed(Key::RightShift);
|
||||
bool keyAltPressed = keyboardinputState.isKeyPressed(Key::LeftAlt) |
|
||||
keyboardinputState.isKeyPressed(Key::RightAlt);
|
||||
|
||||
// Update the mouse states
|
||||
if (primaryPressed && !keyShiftPressed && !keyAltPressed) {
|
||||
@@ -94,10 +96,10 @@ void MouseCameraStates::updateStateFromInput(const InputState& inputState,
|
||||
mousePosition;
|
||||
|
||||
double sensitivity = _sensitivity;
|
||||
if (inputState.isKeyPressed(Key::Z)) {
|
||||
if (keyboardinputState.isKeyPressed(Key::Z)) {
|
||||
sensitivity *= SENSITIVITY_ADJUSTMENT_INCREASE;
|
||||
}
|
||||
else if (inputState.isKeyPressed(Key::X)) {
|
||||
else if (keyboardinputState.isKeyPressed(Key::X)) {
|
||||
sensitivity *= SENSITIVITY_ADJUSTMENT_DECREASE;
|
||||
}
|
||||
|
||||
|
||||
68
src/interaction/mouseinputstate.cpp
Normal file
68
src/interaction/mouseinputstate.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/interaction/mouseinputstate.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
void MouseInputState::mouseButtonCallback(MouseButton button, MouseAction action) {
|
||||
if (action == MouseAction::Press) {
|
||||
_mouseButtonsDown.push_back(button);
|
||||
}
|
||||
else if (action == MouseAction::Release) {
|
||||
_mouseButtonsDown.erase(
|
||||
std::remove(_mouseButtonsDown.begin(), _mouseButtonsDown.end(), button),
|
||||
_mouseButtonsDown.end()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void MouseInputState::mousePositionCallback(double mouseX, double mouseY) {
|
||||
_mousePosition = glm::dvec2(mouseX, mouseY);
|
||||
}
|
||||
|
||||
void MouseInputState::mouseScrollWheelCallback(double mouseScrollDelta) {
|
||||
_mouseScrollDelta = mouseScrollDelta;
|
||||
}
|
||||
|
||||
const std::vector<MouseButton>& MouseInputState::pressedMouseButtons() const {
|
||||
return _mouseButtonsDown;
|
||||
}
|
||||
|
||||
glm::dvec2 MouseInputState::mousePosition() const {
|
||||
return _mousePosition;
|
||||
}
|
||||
|
||||
double MouseInputState::mouseScrollDelta() const {
|
||||
return _mouseScrollDelta;
|
||||
}
|
||||
|
||||
bool MouseInputState::isMouseButtonPressed(MouseButton mouseButton) const {
|
||||
auto it = std::find(_mouseButtonsDown.begin(), _mouseButtonsDown.end(), mouseButton);
|
||||
return it != _mouseButtonsDown.end();
|
||||
}
|
||||
|
||||
} // namespace openspace::interaction
|
||||
@@ -24,13 +24,11 @@
|
||||
|
||||
#include <openspace/interaction/scriptcamerastates.h>
|
||||
|
||||
#include <openspace/interaction/inputstate.h>
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
ScriptCameraStates::ScriptCameraStates() : CameraInteractionStates(1.0, 1.0) {}
|
||||
|
||||
void ScriptCameraStates::updateStateFromInput(const InputState&, double deltaTime) {
|
||||
void ScriptCameraStates::updateStateFromInput(double deltaTime) {
|
||||
if (_localRotation != glm::dvec2(0.0)) {
|
||||
_localRotationState.velocity.set(
|
||||
_localRotation * _sensitivity,
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <openspace/interaction/websocketcamerastates.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/interaction/inputstate.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <ghoul/misc/exception.h>
|
||||
#include <ghoul/misc/stringconversion.h>
|
||||
@@ -39,7 +38,8 @@ WebsocketCameraStates::WebsocketCameraStates(double sensitivity,
|
||||
: CameraInteractionStates(sensitivity, velocityScaleFactor)
|
||||
{}
|
||||
|
||||
void WebsocketCameraStates::updateStateFromInput(const InputState& inputState,
|
||||
void WebsocketCameraStates::updateStateFromInput(
|
||||
const WebsocketInputStates& websocketInputStates,
|
||||
double deltaTime)
|
||||
{
|
||||
std::pair<bool, glm::dvec2> globalRotation = { false, glm::dvec2(0.0) };
|
||||
@@ -48,14 +48,14 @@ void WebsocketCameraStates::updateStateFromInput(const InputState& inputState,
|
||||
std::pair<bool, glm::dvec2> globalRoll = { false, glm::dvec2(0.0) };
|
||||
std::pair<bool, glm::dvec2> localRotation = { false, glm::dvec2(0.0) };
|
||||
|
||||
if (inputState.hasWebsocketStates()) {
|
||||
if (!websocketInputStates.empty()) {
|
||||
for (int i = 0; i < WebsocketInputState::MaxAxes; ++i) {
|
||||
AxisInformation t = _axisMapping[i];
|
||||
if (t.type == AxisType::None) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float value = inputState.websocketAxis(i);
|
||||
float value = websocketInputStates.axis(i);
|
||||
bool hasValue = std::fabs(value) > t.deadzone;
|
||||
|
||||
if (!hasValue) {
|
||||
|
||||
@@ -187,7 +187,11 @@ void NavigationHandler::updateCamera(double deltaTime) {
|
||||
JoystickInputState()
|
||||
);
|
||||
}
|
||||
_orbitalNavigator.updateStatesFromInput(_inputState, deltaTime);
|
||||
_orbitalNavigator.updateStatesFromInput(
|
||||
_mouseInputState,
|
||||
_keyboardInputState,
|
||||
deltaTime
|
||||
);
|
||||
_orbitalNavigator.updateCameraStateFromStates(deltaTime);
|
||||
updateCameraTransitions();
|
||||
}
|
||||
@@ -351,25 +355,29 @@ Camera* NavigationHandler::camera() const {
|
||||
return _camera;
|
||||
}
|
||||
|
||||
const InputState& NavigationHandler::inputState() const {
|
||||
return _inputState;
|
||||
const MouseInputState& NavigationHandler::mouseInputState() const {
|
||||
return _mouseInputState;
|
||||
}
|
||||
|
||||
const KeyboardInputState& NavigationHandler::keyboardInputState() const {
|
||||
return _keyboardInputState;
|
||||
}
|
||||
|
||||
void NavigationHandler::mouseButtonCallback(MouseButton button, MouseAction action) {
|
||||
if (!_disableMouseInputs) {
|
||||
_inputState.mouseButtonCallback(button, action);
|
||||
_mouseInputState.mouseButtonCallback(button, action);
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationHandler::mousePositionCallback(double x, double y) {
|
||||
if (!_disableMouseInputs) {
|
||||
_inputState.mousePositionCallback(x, y);
|
||||
_mouseInputState.mousePositionCallback(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationHandler::mouseScrollWheelCallback(double pos) {
|
||||
if (!_disableMouseInputs) {
|
||||
_inputState.mouseScrollWheelCallback(pos);
|
||||
_mouseInputState.mouseScrollWheelCallback(pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,7 +385,7 @@ void NavigationHandler::keyboardCallback(Key key, KeyModifier modifier, KeyActio
|
||||
{
|
||||
// There is no need to disable the keyboard callback based on a property as the vast
|
||||
// majority of input is coming through Lua scripts anyway which are not blocked here
|
||||
_inputState.keyboardCallback(key, modifier, action);
|
||||
_keyboardInputState.keyboardCallback(key, modifier, action);
|
||||
}
|
||||
|
||||
NavigationState NavigationHandler::navigationState() const {
|
||||
@@ -489,23 +497,42 @@ void NavigationHandler::loadNavigationState(const std::string& filepath) {
|
||||
}
|
||||
}
|
||||
|
||||
void NavigationHandler::setJoystickAxisMapping(int axis,
|
||||
void NavigationHandler::setJoystickAxisMapping(std::string joystickName, int axis,
|
||||
JoystickCameraStates::AxisType mapping,
|
||||
JoystickCameraStates::AxisInvert shouldInvert,
|
||||
JoystickCameraStates::AxisNormalize shouldNormalize,
|
||||
JoystickCameraStates::JoystickType joystickType,
|
||||
bool isSticky,
|
||||
double sensitivity)
|
||||
{
|
||||
_orbitalNavigator.joystickStates().setAxisMapping(
|
||||
std::move(joystickName),
|
||||
axis,
|
||||
mapping,
|
||||
shouldInvert,
|
||||
shouldNormalize,
|
||||
joystickType,
|
||||
isSticky,
|
||||
sensitivity
|
||||
);
|
||||
}
|
||||
|
||||
void NavigationHandler::setJoystickAxisMappingProperty(std::string joystickName,
|
||||
int axis,
|
||||
std::string propertyUri,
|
||||
float min, float max,
|
||||
JoystickCameraStates::AxisInvert shouldInvert,
|
||||
bool isRemote)
|
||||
{
|
||||
_orbitalNavigator.joystickStates().setAxisMappingProperty(
|
||||
std::move(joystickName),
|
||||
axis,
|
||||
std::move(propertyUri),
|
||||
min,
|
||||
max,
|
||||
shouldInvert,
|
||||
isRemote
|
||||
);
|
||||
}
|
||||
|
||||
void NavigationHandler::setWebsocketAxisMapping(int axis,
|
||||
WebsocketCameraStates::AxisType mapping,
|
||||
WebsocketCameraStates::AxisInvert shouldInvert,
|
||||
@@ -521,25 +548,31 @@ void NavigationHandler::setWebsocketAxisMapping(int axis,
|
||||
|
||||
|
||||
JoystickCameraStates::AxisInformation
|
||||
NavigationHandler::joystickAxisMapping(int axis) const
|
||||
NavigationHandler::joystickAxisMapping(const std::string& joystickName, int axis) const
|
||||
{
|
||||
return _orbitalNavigator.joystickStates().axisMapping(axis);
|
||||
return _orbitalNavigator.joystickStates().axisMapping(joystickName, axis);
|
||||
}
|
||||
|
||||
void NavigationHandler::setJoystickAxisDeadzone(int axis, float deadzone) {
|
||||
_orbitalNavigator.joystickStates().setDeadzone(axis, deadzone);
|
||||
void NavigationHandler::setJoystickAxisDeadzone(const std::string& joystickName, int axis,
|
||||
float deadzone)
|
||||
{
|
||||
_orbitalNavigator.joystickStates().setDeadzone(joystickName, axis, deadzone);
|
||||
}
|
||||
|
||||
float NavigationHandler::joystickAxisDeadzone(int axis) const {
|
||||
return _orbitalNavigator.joystickStates().deadzone(axis);
|
||||
float NavigationHandler::joystickAxisDeadzone(const std::string& joystickName,
|
||||
int axis) const
|
||||
{
|
||||
return _orbitalNavigator.joystickStates().deadzone(joystickName, axis);
|
||||
}
|
||||
|
||||
void NavigationHandler::bindJoystickButtonCommand(int button, std::string command,
|
||||
void NavigationHandler::bindJoystickButtonCommand(const std::string& joystickName,
|
||||
int button, std::string command,
|
||||
JoystickAction action,
|
||||
JoystickCameraStates::ButtonCommandRemote remote,
|
||||
std::string documentation)
|
||||
{
|
||||
_orbitalNavigator.joystickStates().bindButtonCommand(
|
||||
joystickName,
|
||||
button,
|
||||
std::move(command),
|
||||
action,
|
||||
@@ -548,12 +581,16 @@ void NavigationHandler::bindJoystickButtonCommand(int button, std::string comman
|
||||
);
|
||||
}
|
||||
|
||||
void NavigationHandler::clearJoystickButtonCommand(int button) {
|
||||
_orbitalNavigator.joystickStates().clearButtonCommand(button);
|
||||
void NavigationHandler::clearJoystickButtonCommand(const std::string& joystickName,
|
||||
int button)
|
||||
{
|
||||
_orbitalNavigator.joystickStates().clearButtonCommand(joystickName, button);
|
||||
}
|
||||
|
||||
std::vector<std::string> NavigationHandler::joystickButtonCommand(int button) const {
|
||||
return _orbitalNavigator.joystickStates().buttonCommand(button);
|
||||
std::vector<std::string> NavigationHandler::joystickButtonCommand(
|
||||
const std::string& joystickName, int button) const
|
||||
{
|
||||
return _orbitalNavigator.joystickStates().buttonCommand(joystickName, button);
|
||||
}
|
||||
|
||||
scripting::LuaLibrary NavigationHandler::luaLibrary() {
|
||||
@@ -611,52 +648,79 @@ scripting::LuaLibrary NavigationHandler::luaLibrary() {
|
||||
{
|
||||
"bindJoystickAxis",
|
||||
&luascriptfunctions::bindJoystickAxis,
|
||||
"int, axisType [, isInverted, isNormalized]",
|
||||
"Binds the axis identified by the first argument to be used as the type "
|
||||
"identified by the second argument. If 'isInverted' is 'true', the axis "
|
||||
"value is inverted, if 'isNormalized' is true the axis value is "
|
||||
"normalized from [-1, 1] to [0,1]."
|
||||
"name, axis, axisType [, isInverted, joystickType, isSticky, sensitivity]",
|
||||
"Finds the input joystick with the given 'name' and binds the axis "
|
||||
"identified by the second argument to be used as the type identified by "
|
||||
"the third argument. If 'isInverted' is 'true', the axis value is "
|
||||
"inverted. 'joystickType' is if the joystick behaves more like a "
|
||||
"joystick or a trigger, where the first is the default. If 'isSticky' is "
|
||||
"'true', the value is calculated relative to the previous value. If "
|
||||
"'sensitivity' is given then that value will affect the sensitivity of "
|
||||
"the axis together with the global sensitivity."
|
||||
},
|
||||
{
|
||||
"bindJoystickAxisProperty",
|
||||
&luascriptfunctions::bindJoystickAxisProperty,
|
||||
"name, axis, propertyUri [, min, max, isInverted, isSticky, sensitivity, "
|
||||
"isRemote]",
|
||||
"Finds the input joystick with the given 'name' and binds the axis "
|
||||
"identified by the second argument to be bound to the property "
|
||||
"identified by the third argument. 'min' and 'max' is the minimum and "
|
||||
"the maximum allowed value for the given property and the axis value is "
|
||||
"rescaled from [-1, 1] to [min, max], default is [0, 1]. If 'isInverted' "
|
||||
"is 'true', the axis value is inverted. The last argument determines "
|
||||
"whether the property change is going to be executed locally or "
|
||||
"remotely, where the latter is the default."
|
||||
},
|
||||
{
|
||||
"joystickAxis",
|
||||
&luascriptfunctions::joystickAxis,
|
||||
"int",
|
||||
"Returns the joystick axis information for the passed axis. The "
|
||||
"information that is returned is the current axis binding as a string, "
|
||||
"whether the values are inverted as bool, and whether the value are "
|
||||
"normalized as a bool"
|
||||
"name, axis",
|
||||
"Finds the input joystick with the given 'name' and returns the joystick "
|
||||
"axis information for the passed axis. The information that is returned "
|
||||
"is the current axis binding as a string, whether the values are "
|
||||
"inverted as bool, the joystick type as a string, whether the axis is "
|
||||
"sticky as bool, the sensitivity as number, the property uri bound to "
|
||||
"the axis as string (empty is type is not Property), the min and max "
|
||||
"values for the property as numbers and whether the property change will "
|
||||
"be executed remotly as bool."
|
||||
},
|
||||
{
|
||||
"setAxisDeadZone",
|
||||
&luascriptfunctions::setJoystickAxisDeadzone,
|
||||
"int, float",
|
||||
"Sets the deadzone for a particular joystick axis which means that any "
|
||||
"input less than this value is completely ignored."
|
||||
"name, axis, float",
|
||||
"Finds the input joystick with the given 'name' and sets the deadzone "
|
||||
"for a particular joystick axis, which means that any input less than "
|
||||
"this value is completely ignored."
|
||||
},
|
||||
{
|
||||
"bindJoystickButton",
|
||||
&luascriptfunctions::bindJoystickButton,
|
||||
"int, string [, string, bool]",
|
||||
"Binds a Lua script to be executed when the joystick button identified "
|
||||
"by the first argument is triggered. The third argument determines when "
|
||||
"the script should be executed, this defaults to 'pressed', which means "
|
||||
"that the script is run when the user presses the button. The last "
|
||||
"argument determines whether the command is going to be executable "
|
||||
"locally or remotely. The latter being the default."
|
||||
"name, button, string [, string, string, bool]",
|
||||
"Finds the input joystick with the given 'name' and binds a Lua script "
|
||||
"given by the third argument to be executed when the joystick button "
|
||||
"identified by the second argument is triggered. The fifth argument "
|
||||
"determines when the script should be executed, this defaults to "
|
||||
"'Press', which means that the script is run when the user presses the "
|
||||
"button. The fourth arguemnt is the documentation of the script in the "
|
||||
"third argument. The sixth argument determines whether the command is "
|
||||
"going to be executable locally or remotely, where the latter is the "
|
||||
"default."
|
||||
},
|
||||
{
|
||||
"clearJoystickButton",
|
||||
&luascriptfunctions::clearJoystickButton,
|
||||
"int",
|
||||
"Removes all commands that are currently bound to the button identified "
|
||||
"by the first argument"
|
||||
"name, button",
|
||||
"Finds the input joystick with the given 'name' and removes all commands "
|
||||
"that are currently bound to the button identified by the second argument."
|
||||
},
|
||||
{
|
||||
"joystickButton",
|
||||
&luascriptfunctions::joystickButton,
|
||||
"int",
|
||||
"Returns the script that is currently bound to be executed when the "
|
||||
"provided button is pressed"
|
||||
"name, button",
|
||||
"Finds the input joystick with the given 'name' and returns the script "
|
||||
"that is currently bound to be executed when the provided button is "
|
||||
"pressed."
|
||||
},
|
||||
{
|
||||
"addGlobalRotation",
|
||||
|
||||
@@ -151,68 +151,103 @@ int retargetAim(lua_State* L) {
|
||||
}
|
||||
|
||||
int bindJoystickAxis(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 2, 6 }, "lua::bindJoystickAxis");
|
||||
auto [axis, axisType, shouldInvert, shouldNormalize, isSticky, sensitivity] =
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 3, 7 }, "lua::bindJoystickAxis");
|
||||
auto [joystickName, axis, axisType, shouldInvert, joystickType, isSticky,
|
||||
sensitivity] =
|
||||
ghoul::lua::values<
|
||||
int, std::string, std::optional<bool>, std::optional<bool>,
|
||||
std::optional<bool>, std::optional<double>
|
||||
std::string, int, std::string, std::optional<bool>,
|
||||
std::optional<std::string>, std::optional<bool>, std::optional<double>
|
||||
>(L);
|
||||
shouldInvert = shouldInvert.value_or(false);
|
||||
shouldNormalize = shouldNormalize.value_or(false);
|
||||
isSticky = isSticky.value_or(false);
|
||||
sensitivity = sensitivity.value_or(0.0);
|
||||
joystickType = joystickType.value_or("JoystickLike");
|
||||
|
||||
global::navigationHandler->setJoystickAxisMapping(
|
||||
std::move(joystickName),
|
||||
axis,
|
||||
ghoul::from_string<interaction::JoystickCameraStates::AxisType>(axisType),
|
||||
interaction::JoystickCameraStates::AxisInvert(*shouldInvert),
|
||||
interaction::JoystickCameraStates::AxisNormalize(*shouldNormalize),
|
||||
ghoul::from_string<interaction::JoystickCameraStates::JoystickType>(*joystickType),
|
||||
*isSticky,
|
||||
*sensitivity
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bindJoystickAxisProperty(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 3, 7 }, "lua::bindJoystickAxisProperty");
|
||||
auto [joystickName, axis, propertyUri, min, max, shouldInvert, isRemote] =
|
||||
ghoul::lua::values<
|
||||
std::string, int, std::string, std::optional<float>, std::optional<float>,
|
||||
std::optional<bool>, std::optional<bool>
|
||||
>(L);
|
||||
min = min.value_or(0.f);
|
||||
max = max.value_or(1.f);
|
||||
shouldInvert = shouldInvert.value_or(false);
|
||||
isRemote = isRemote.value_or(true);
|
||||
|
||||
global::navigationHandler->setJoystickAxisMappingProperty(
|
||||
std::move(joystickName),
|
||||
axis,
|
||||
std::move(propertyUri),
|
||||
*min,
|
||||
*max,
|
||||
interaction::JoystickCameraStates::AxisInvert(*shouldInvert),
|
||||
*isRemote
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int joystickAxis(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::joystickAxis");
|
||||
const int axis = ghoul::lua::value<int>(L);
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::joystickAxis");
|
||||
auto [joystickName, axis] = ghoul::lua::values<std::string, int>(L);
|
||||
|
||||
using AI = interaction::JoystickCameraStates::AxisInformation;
|
||||
AI info = global::navigationHandler->joystickAxisMapping(axis);
|
||||
AI info = global::navigationHandler->joystickAxisMapping(joystickName, axis);
|
||||
|
||||
ghoul::lua::push(
|
||||
L,
|
||||
ghoul::to_string(info.type),
|
||||
static_cast<bool>(info.invert),
|
||||
static_cast<bool>(info.normalize),
|
||||
ghoul::to_string(info.joystickType),
|
||||
info.isSticky,
|
||||
info.sensitivity
|
||||
info.sensitivity,
|
||||
info.propertyUri,
|
||||
info.minValue,
|
||||
info.maxValue,
|
||||
info.isRemote
|
||||
);
|
||||
return 5;
|
||||
return 9;
|
||||
}
|
||||
|
||||
int setJoystickAxisDeadzone(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::setJoystickAxisDeadzone");
|
||||
auto [axis, deadzone] = ghoul::lua::values<int, float>(L);
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::setJoystickAxisDeadzone");
|
||||
auto [joystickName, axis, deadzone] = ghoul::lua::values<std::string, int, float>(L);
|
||||
|
||||
global::navigationHandler->setJoystickAxisDeadzone(axis, deadzone);
|
||||
global::navigationHandler->setJoystickAxisDeadzone(joystickName, axis, deadzone);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int joystickAxisDeadzone(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::joystickAxisDeadzone");
|
||||
const int axis = ghoul::lua::value<int>(L);
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::joystickAxisDeadzone");
|
||||
auto [joystickName, axis] = ghoul::lua::values<std::string, int>(L);
|
||||
|
||||
const float deadzone = global::navigationHandler->joystickAxisDeadzone(axis);
|
||||
const float deadzone = global::navigationHandler->joystickAxisDeadzone(joystickName, axis);
|
||||
ghoul::lua::push(L, deadzone);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bindJoystickButton(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 3, 5 }, "lua::bindJoystickButton");
|
||||
auto [button, command, documentation, actionStr, isRemote] =
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 4, 6 }, "lua::bindJoystickButton");
|
||||
auto [joystickName, button, command, documentation, actionStr, isRemote] =
|
||||
ghoul::lua::values<
|
||||
int, std::string, std::string, std::optional<std::string>, std::optional<bool>
|
||||
std::string,
|
||||
int,
|
||||
std::string,
|
||||
std::string,
|
||||
std::optional<std::string>,
|
||||
std::optional<bool>
|
||||
>(L);
|
||||
actionStr = actionStr.value_or("Press");
|
||||
isRemote = isRemote.value_or(true);
|
||||
@@ -221,6 +256,7 @@ int bindJoystickButton(lua_State* L) {
|
||||
ghoul::from_string<interaction::JoystickAction>(*actionStr);
|
||||
|
||||
global::navigationHandler->bindJoystickButtonCommand(
|
||||
joystickName,
|
||||
button,
|
||||
command,
|
||||
action,
|
||||
@@ -231,18 +267,19 @@ int bindJoystickButton(lua_State* L) {
|
||||
}
|
||||
|
||||
int clearJoystickButton(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::clearJoystickButton");
|
||||
const int button = ghoul::lua::value<int>(L);
|
||||
global::navigationHandler->clearJoystickButtonCommand(button);
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::clearJoystickButton");
|
||||
auto [joystickName, button] = ghoul::lua::values<std::string, int>(L);
|
||||
|
||||
global::navigationHandler->clearJoystickButtonCommand(joystickName, button);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int joystickButton(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::joystickButton");
|
||||
const int button = ghoul::lua::value<int>(L);
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::joystickButton");
|
||||
auto [joystickName, button] = ghoul::lua::values<std::string, int>(L);
|
||||
|
||||
const std::vector<std::string>& cmds =
|
||||
global::navigationHandler->joystickButtonCommand(button);
|
||||
global::navigationHandler->joystickButtonCommand(joystickName, button);
|
||||
|
||||
std::string cmd = std::accumulate(
|
||||
cmds.cbegin(),
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/camera/camerapose.h>
|
||||
#include <openspace/interaction/mouseinputstate.h>
|
||||
#include <openspace/interaction/keyboardinputstate.h>
|
||||
#include <openspace/navigation/orbitalnavigator.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
@@ -543,13 +545,14 @@ void OrbitalNavigator::resetVelocities() {
|
||||
}
|
||||
}
|
||||
|
||||
void OrbitalNavigator::updateStatesFromInput(const InputState& inputState,
|
||||
void OrbitalNavigator::updateStatesFromInput(const MouseInputState& mouseInputState,
|
||||
const KeyboardInputState& keyboardInputState,
|
||||
double deltaTime)
|
||||
{
|
||||
_mouseStates.updateStateFromInput(inputState, deltaTime);
|
||||
_joystickStates.updateStateFromInput(inputState, deltaTime);
|
||||
_websocketStates.updateStateFromInput(inputState, deltaTime);
|
||||
_scriptStates.updateStateFromInput(inputState, deltaTime);
|
||||
_mouseStates.updateStateFromInput(mouseInputState, keyboardInputState, deltaTime);
|
||||
_joystickStates.updateStateFromInput(*global::joystickInputStates, deltaTime);
|
||||
_websocketStates.updateStateFromInput(*global::websocketInputStates, deltaTime);
|
||||
_scriptStates.updateStateFromInput(deltaTime);
|
||||
|
||||
bool interactionHappened = _mouseStates.hasNonZeroVelocities() ||
|
||||
_joystickStates.hasNonZeroVelocities() ||
|
||||
|
||||
Reference in New Issue
Block a user