input manager update: analog stick; added controller support to tps characer sample;

This commit is contained in:
turanszkij
2019-05-19 15:05:51 +01:00
parent 27392a3c49
commit 209314c76a
8 changed files with 142 additions and 22 deletions
@@ -646,6 +646,7 @@ Query input devices
- GetPointer() : Vector result
- SetPointer(Vector pos)
- HidePointer(bool visible)
- GetAnalog(int type, opt int playerindex = 0) : Vector result -- read analog data from gamepad. type parameter must be from GAMEPAD_ANALOG values
- GetTouches() : Touch result[]
#### Touch
@@ -704,6 +705,12 @@ Describes a touch contact point
...
- [outer]GAMEPAD_14 : int
#### Gamepad Analog Codes
- [outer]GAMEPAD_ANALOG_THUMBSTICK_L : int
- [outer]GAMEPAD_ANALOG_THUMBSTICK_R : int
- [outer]GAMEPAD_ANALOG_TRIGGER_L : int
- [outer]GAMEPAD_ANALOG_TRIGGER_R : int
### ResourceManager
Stores and manages resources such as textures, sounds and shaders.
- [outer]globalResources : Resource
+12 -4
View File
@@ -774,6 +774,14 @@ void EditorComponent::Update(float dt)
yDif += buttonrotSpeed;
}
const XMFLOAT4 leftStick = wiInputManager::getanalog(GAMEPAD_ANALOG_THUMBSTICK_L, 0);
const XMFLOAT4 rightStick = wiInputManager::getanalog(GAMEPAD_ANALOG_THUMBSTICK_R, 0);
const XMFLOAT4 rightTrigger = wiInputManager::getanalog(GAMEPAD_ANALOG_TRIGGER_R, 0);
const float jostickrotspeed = 0.05f;
xDif += rightStick.x * jostickrotspeed;
yDif += rightStick.y * jostickrotspeed;
xDif *= cameraWnd->rotationspeedSlider->GetValue();
yDif *= cameraWnd->rotationspeedSlider->GetValue();
@@ -783,10 +791,9 @@ void EditorComponent::Update(float dt)
// FPS Camera
const float clampedDT = min(dt, 0.1f); // if dt > 100 millisec, don't allow the camera to jump too far...
const float speed = (wiInputManager::down(VK_SHIFT) ? 10.0f : 1.0f) * cameraWnd->movespeedSlider->GetValue() * clampedDT;
const float speed = ((wiInputManager::down(VK_SHIFT) ? 10.0f : 1.0f) + rightTrigger.x * 10.0f) * cameraWnd->movespeedSlider->GetValue() * clampedDT;
static XMVECTOR move = XMVectorSet(0, 0, 0, 0);
XMVECTOR moveNew = XMVectorSet(0, 0, 0, 0);
XMVECTOR moveNew = XMVectorSet(leftStick.x, 0, leftStick.y, 0);
if (!wiInputManager::down(VK_CONTROL))
{
@@ -797,8 +804,9 @@ void EditorComponent::Update(float dt)
if (wiInputManager::down('S') || wiInputManager::down(GAMEPAD_BUTTON_DOWN, INPUT_TYPE_GAMEPAD)) { moveNew += XMVectorSet(0, 0, -1, 0); }
if (wiInputManager::down('E') || wiInputManager::down(GAMEPAD_BUTTON_2, INPUT_TYPE_GAMEPAD)) { moveNew += XMVectorSet(0, 1, 0, 0); }
if (wiInputManager::down('Q') || wiInputManager::down(GAMEPAD_BUTTON_1, INPUT_TYPE_GAMEPAD)) { moveNew += XMVectorSet(0, -1, 0, 0); }
moveNew = XMVector3Normalize(moveNew) * speed;
moveNew += XMVector3Normalize(moveNew);
}
moveNew *= speed;
move = XMVectorLerp(move, moveNew, 0.18f * clampedDT / 0.0166f); // smooth the movement a bit
float moveLength = XMVectorGetX(XMVector3Length(move));
+54
View File
@@ -6,6 +6,7 @@
#include "wiHelper.h"
#include "wiBackLog.h"
#include <algorithm>
#include <map>
#include <atomic>
#include <thread>
@@ -293,6 +294,59 @@ namespace wiInputManager
#endif
}
inline float deadzone(float x)
{
if ((x) > -0.24f && (x) < 0.24f)
x = 0;
if (x < -1.0f)
x = -1.0f;
if (x > 1.0f)
x = 1.0f;
return x;
}
XMFLOAT4 getanalog(GAMEPAD_ANALOG analog, short playerindex)
{
if (playerindex < (int)controllers.size())
{
const Controller& controller = controllers[playerindex];
if (xinput != nullptr && controller.deviceType == Controller::XINPUT)
{
const auto& state = xinput->controllers[controller.deviceIndex].state.Gamepad;
switch (analog)
{
case GAMEPAD_ANALOG_THUMBSTICK_L: return XMFLOAT4(deadzone((float)state.sThumbLX / 32767.0f), deadzone((float)state.sThumbLY / 32767.0f), 0, 0);
case GAMEPAD_ANALOG_THUMBSTICK_R: return XMFLOAT4(deadzone((float)state.sThumbRX / 32767.0f), deadzone((float)state.sThumbRY / 32767.0f), 0, 0);
case GAMEPAD_ANALOG_TRIGGER_L: return XMFLOAT4((float)state.bLeftTrigger / 255.0f, 0, 0, 0);
case GAMEPAD_ANALOG_TRIGGER_R: return XMFLOAT4((float)state.bRightTrigger / 255.0f, 0, 0, 0);
default:
break;
}
}
#ifndef WINSTORE_SUPPORT
if (dinput != nullptr && controller.deviceType == Controller::DIRECTINPUT)
{
const auto& state = dinput->joyState[controller.deviceIndex];
switch (analog)
{
case GAMEPAD_ANALOG_THUMBSTICK_L: return XMFLOAT4(deadzone((float)state.lX / 1000.0f), deadzone(-(float)state.lY / 1000.0f), 0, 0);
case GAMEPAD_ANALOG_THUMBSTICK_R: return XMFLOAT4(deadzone((float)state.lZ / 1000.0f), deadzone((float)state.lRz / 1000.0f), 0, 0);
case GAMEPAD_ANALOG_TRIGGER_L: return XMFLOAT4((float)state.lRx / 1000.0f * 0.5f + 0.5f, 0, 0, 0);
case GAMEPAD_ANALOG_TRIGGER_R: return XMFLOAT4((float)state.lRy / 1000.0f * 0.5f + 0.5f, 0, 0, 0);
default:
break;
}
}
#endif
}
return XMFLOAT4(0, 0, 0, 0);
}
void AddTouch(const Touch& touch)
{
+9
View File
@@ -29,6 +29,13 @@ enum GAMEPAD_BUTTON
GAMEPAD_BUTTON_13,
GAMEPAD_BUTTON_14,
};
enum GAMEPAD_ANALOG
{
GAMEPAD_ANALOG_THUMBSTICK_L,
GAMEPAD_ANALOG_THUMBSTICK_R,
GAMEPAD_ANALOG_TRIGGER_L,
GAMEPAD_ANALOG_TRIGGER_R,
};
namespace wiInputManager
{
@@ -50,6 +57,8 @@ namespace wiInputManager
void setpointer(const XMFLOAT4& props);
// hide pointer
void hidepointer(bool value);
// read analog input from controllers, like thumbsticks or triggers
XMFLOAT4 getanalog(GAMEPAD_ANALOG analog, short playerIndex = 0);
struct Touch
{
+28
View File
@@ -10,6 +10,7 @@ Luna<wiInputManager_BindLua>::FunctionType wiInputManager_BindLua::methods[] = {
lunamethod(wiInputManager_BindLua, GetPointer),
lunamethod(wiInputManager_BindLua, SetPointer),
lunamethod(wiInputManager_BindLua, HidePointer),
lunamethod(wiInputManager_BindLua, GetAnalog),
lunamethod(wiInputManager_BindLua, GetTouches),
{ NULL, NULL }
};
@@ -131,6 +132,27 @@ int wiInputManager_BindLua::HidePointer(lua_State* L)
wiLua::SError(L, "HidePointer(bool value) not enough arguments!");
return 0;
}
int wiInputManager_BindLua::GetAnalog(lua_State* L)
{
XMFLOAT4 result = XMFLOAT4(0, 0, 0, 0);
int argc = wiLua::SGetArgCount(L);
if (argc > 0)
{
GAMEPAD_ANALOG type = (GAMEPAD_ANALOG)wiLua::SGetInt(L, 1);
short playerindex = 0;
if (argc > 1)
{
playerindex = (short)wiLua::SGetInt(L, 2);
}
result = wiInputManager::getanalog(type, playerindex);
}
else
wiLua::SError(L, "GetAnalog(int type, opt int playerindex = 0) not enough arguments!");
Luna<Vector_BindLua>::push(L, new Vector_BindLua(XMLoadFloat4(&result)));
return 1;
}
int wiInputManager_BindLua::GetTouches(lua_State* L)
{
auto& touches = wiInputManager::getTouches();
@@ -202,6 +224,12 @@ void wiInputManager_BindLua::Bind()
wiLua::GetGlobal()->RunText("GAMEPAD_BUTTON_13 = 16");
wiLua::GetGlobal()->RunText("GAMEPAD_BUTTON_14 = 17");
//Analog
wiLua::GetGlobal()->RunText("GAMEPAD_ANALOG_THUMBSTICK_L = 0");
wiLua::GetGlobal()->RunText("GAMEPAD_ANALOG_THUMBSTICK_R = 1");
wiLua::GetGlobal()->RunText("GAMEPAD_ANALOG_TRIGGER_L = 2");
wiLua::GetGlobal()->RunText("GAMEPAD_ANALOG_TRIGGER_R = 3");
//Touch
wiLua::GetGlobal()->RunText("TOUCHSTATE_PRESSED = 0");
wiLua::GetGlobal()->RunText("TOUCHSTATE_RELEASED = 1");
+1
View File
@@ -19,6 +19,7 @@ public:
int GetPointer(lua_State* L);
int SetPointer(lua_State* L);
int HidePointer(lua_State* L);
int GetAnalog(lua_State* L);
int GetTouches(lua_State* L);
static void Bind();
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wiVersion
// minor features, major updates
const int minor = 26;
// minor bug fixes, alterations, refactors, updates
const int revision = 29;
const int revision = 30;
long GetVersion()
+30 -17
View File
@@ -2,11 +2,11 @@
-- This script will load a simple scene with a character that can be controlled
--
-- CONTROLS:
-- WASD: walk
-- SHIFT: speed
-- SPACE: Jump
-- Right Mouse Button: rotate camera
-- Scoll middle mouse: adjust camera distance
-- WASD/left thumbstick: walk
-- SHIFT/right shoulder button: speed
-- SPACE/gamepad X/gamepad button 2: Jump
-- Right Mouse Button/Right thumbstick: rotate camera
-- Scoll middle mouse/Left-Right triggers: adjust camera distance
-- ESCAPE key: quit
-- ENTER: reload script
@@ -110,9 +110,12 @@ Character = {
if(input.Down(VK_DOWN) or input.Down(string.byte('S'))) then
lookDir = lookDir:Add( Vector(0,0,-1) )
end
local analog = input.GetAnalog(GAMEPAD_ANALOG_THUMBSTICK_L)
lookDir = vector.Add(lookDir, Vector(analog.GetX(), 0, analog.GetY()))
if(lookDir:Length()>0) then
if(input.Down(VK_LSHIFT)) then
if(input.Down(VK_LSHIFT) or input.Down(GAMEPAD_BUTTON_6, INPUT_TYPE_GAMEPAD)) then
self:MoveDirection(lookDir,self.moveSpeed*2)
else
self:MoveDirection(lookDir,self.moveSpeed)
@@ -121,19 +124,22 @@ Character = {
end
if( input.Press(string.byte('J')) or input.Press(VK_SPACE) ) then
if( input.Press(string.byte('J')) or input.Press(VK_SPACE) or input.Press(GAMEPAD_BUTTON_2, INPUT_TYPE_GAMEPAD) ) then
self:Jump(0.6)
end
-- Camera target control:
-- read from gamepad analog stick:
local diff = input.GetAnalog(GAMEPAD_ANALOG_THUMBSTICK_R)
diff = vector.Multiply(diff, getDeltaTime() * 4)
-- mouse control
-- read from mouse:
if(input.Down(VK_RBUTTON)) then
local mousePosNew = input.GetPointer()
local mouseDif = vector.Subtract(mousePosNew,self.savedPointerPos)
mouseDif = mouseDif:Multiply(getDeltaTime() * 0.3)
local target_transform = scene.Component_GetTransform(self.target)
target_transform.Rotate(Vector(mouseDif.GetY(),mouseDif.GetX()))
self.face.SetY(0)
self.face=self.face:Normalize()
diff = vector.Add(diff, mouseDif)
input.SetPointer(self.savedPointerPos)
input.HidePointer(true)
else
@@ -141,6 +147,11 @@ Character = {
input.HidePointer(false)
end
local target_transform = scene.Component_GetTransform(self.target)
target_transform.Rotate(Vector(diff.GetY(),diff.GetX()))
self.face.SetY(0)
self.face=self.face:Normalize()
end,
Update = function(self)
@@ -238,9 +249,11 @@ ThirdPersonCamera = {
Update = function(self)
if(self.character ~= nil) then
-- Mouse scroll will move the camera distance:
local mouse_scroll = input.GetPointer().GetZ() -- pointer.z is the mouse wheel delta this frame
self.rest_distance_new = math.max(self.rest_distance_new - mouse_scroll, 2) -- do not allow too close using max
-- Mouse scroll or gamepad triggers will move the camera distance:
local scroll = input.GetPointer().GetZ() -- pointer.z is the mouse wheel delta this frame
scroll = scroll + input.GetAnalog(GAMEPAD_ANALOG_TRIGGER_R).GetX()
scroll = scroll - input.GetAnalog(GAMEPAD_ANALOG_TRIGGER_L).GetX()
self.rest_distance_new = math.max(self.rest_distance_new - scroll, 2) -- do not allow too close using max
self.rest_distance = math.lerp(self.rest_distance, self.rest_distance_new, 0.1) -- lerp will smooth out the zooming
-- We update the scene so that character's target_transform will be using up to date values
@@ -336,8 +349,8 @@ runProcess(function()
path.SetLightShaftsEnabled(true)
main.SetActivePath(path)
local font = Font("This script is showcasing how to perform scene collision with raycasts for character and camera.\nControls:\n#####################\n\nWASD/arrows: walk\nSHIFT: movement speed\nSPACE: Jump\nRight Mouse Button: rotate camera\nScoll middle mouse: adjust camera distance\nESCAPE key: quit\nR: reload script");
font.SetSize(20)
local font = Font("This script is showcasing how to perform scene collision with raycasts for character and camera.\nControls:\n#####################\n\nWASD/arrows/left analog stick: walk\nSHIFT/right shoulder button: movement speed\nSPACE/gamepad X/gamepad button 2: Jump\nRight Mouse Button/Right thumbstick: rotate camera\nScoll middle mouse/Left-Right triggers: adjust camera distance\nESCAPE key: quit\nR: reload script");
font.SetSize(24)
font.SetPos(Vector(10, GetScreenHeight() - 10))
font.SetAlign(WIFALIGN_LEFT, WIFALIGN_BOTTOM)
font.SetColor(0xFFADA3FF)