input manager update: analog stick; added controller support to tps characer sample;
This commit is contained in:
@@ -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
@@ -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));
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user