Raw Input and some ImGuiExtension changes

This commit is contained in:
Simon Lübeß
2022-11-26 15:24:33 +01:00
parent 8f22cbb8bc
commit d47ac23e1b
9 changed files with 408 additions and 87 deletions
+2
View File
@@ -245,6 +245,8 @@ namespace GlitchyEditor
private bool OnImGuiRender(ImGuiRenderEvent event) private bool OnImGuiRender(ImGuiRenderEvent event)
{ {
Input.ImGuiDebugDraw();
//viewer.ViewTexture(Renderer.[Friend]_gBuffer.Target); //viewer.ViewTexture(Renderer.[Friend]_gBuffer.Target);
ImGui.Viewport* viewport = ImGui.GetMainViewport(); ImGui.Viewport* viewport = ImGui.GetMainViewport();
+2
View File
@@ -55,6 +55,8 @@ namespace GlitchyEngine
_window = new Window(.Default); _window = new Window(.Default);
_window.EventCallback = new => OnEvent; _window.EventCallback = new => OnEvent;
Input.Init();
_rendererApi = new RendererAPI(); _rendererApi = new RendererAPI();
_rendererApi.Context = _window.Context; _rendererApi.Context = _window.Context;
+27
View File
@@ -29,6 +29,33 @@ namespace GlitchyEngine.Events
} }
} }
public class RawMouseMovedEvent : Event, IEvent
{
private int32 _mouseX, _mouseY;
public override EventType EventType => .MouseMoved;
public override StringView Name => "RawMouseMoved";
public override EventCategory Category => .Input | .Mouse;
public static EventType StaticType => .MouseMoved;
public int32 PositionX => _mouseX;
public int32 PositionY => _mouseY;
public this(int32 x, int32 y)
{
_mouseX = x;
_mouseY = y;
}
public override void ToString(String strBuffer)
{
strBuffer.AppendF("RawMouseMovedEvent: Position: ({}, {})", _mouseX, _mouseY);
}
}
public class MouseScrolledEvent : Event, IEvent public class MouseScrolledEvent : Event, IEvent
{ {
private int32 _xOffset, _yOffset; private int32 _xOffset, _yOffset;
+66 -13
View File
@@ -3,8 +3,18 @@ using GlitchyEngine.Renderer;
using System; using System;
using GlitchyEngine; using GlitchyEngine;
namespace GlitchyEngine.Math
{
extension ColorRGBA
{
internal uint32 ImGuiU32 => ImGui.ImGui.ColorConvertFloat4ToU32((.)(Vector4)this);
}
}
namespace ImGui namespace ImGui
{ {
using internal GlitchyEngine.Math;
extension ImGui extension ImGui
{ {
extension Vec2 extension Vec2
@@ -19,6 +29,30 @@ namespace ImGui
public static explicit operator Vec4(Vector4 v) => .(v.X, v.Y, v.Z, v.W); public static explicit operator Vec4(Vector4 v) => .(v.X, v.Y, v.Z, v.W);
} }
/*public static bool IsItemJustDeactivated()
{
return IsItemDeactivatedAfterEdit();
}
public static bool IsItemActiveLastFrame()
{
Context* g = GetCurrentContext();
if (g.ActiveIdPreviousFrame != 0)
return g.ActiveIdPreviousFrame == g.CurrentWindow.DC.LastItemId;
return false;
}
public static bool IsItemJustActivated()
{
return IsItemActive() && !IsItemActiveLastFrame();
}
public static bool IsItemEditing()
{
return IsItemActive();
}*/
// TODO: Color-functions // TODO: Color-functions
public static bool ColorEdit3(char* label, ref ColorRGB col, ColorEditFlags flags = (ColorEditFlags) 0) => ColorEdit3Impl(label, *(float[3]*)&col, flags); public static bool ColorEdit3(char* label, ref ColorRGB col, ColorEditFlags flags = (ColorEditFlags) 0) => ColorEdit3Impl(label, *(float[3]*)&col, flags);
public static bool ColorEdit3(char* label, ref ColorRGBA col, ColorEditFlags flags = (ColorEditFlags) 0) => ColorEdit3Impl(label, *(float[3]*)&col, flags); public static bool ColorEdit3(char* label, ref ColorRGBA col, ColorEditFlags flags = (ColorEditFlags) 0) => ColorEdit3Impl(label, *(float[3]*)&col, flags);
@@ -89,28 +123,27 @@ namespace ImGui
return EditVector<4>(label, ref *(float[4]*)&value, (float[4])resetValues, dragSpeed, columnWidth, (float[4])minValue, (float[4])maxValue); return EditVector<4>(label, ref *(float[4]*)&value, (float[4])resetValues, dragSpeed, columnWidth, (float[4])minValue, (float[4])maxValue);
} }
static (Color Default, Color Hovered, Color Active)[?] VectorButtonColors = .( static (ColorRGBA Default, ColorRGBA Hovered, ColorRGBA Active)[?] VectorButtonColors = .(
(Color(230, 25, 45), Color(150, 25, 45), Color(230, 90, 90)), (.(230, 25, 45), .(150, 25, 45), .(230, 90, 90)),
(Color(50, 190, 15), Color(50, 120, 15), Color(116, 190, 99)), (.(50, 190, 15), .(50, 120, 15), .(116, 190, 99)),
(Color(55, 55, 230), Color(55, 55, 150), Color(90, 90, 230)), (.(55, 55, 230), .(55, 55, 150), .(90, 90, 230)),
(Color(230, 25, 45), Color(230, 25, 45), Color(230, 25, 45))); (.(230, 25, 45), .(230, 25, 45), .(230, 25, 45)));
public static bool EditVector<NumComponents>(StringView label, ref float[NumComponents] value, float[NumComponents] resetValues = .(), float dragSpeed = 0.1f, float columnWidth = 100f, float[NumComponents] minValue = .(), float[NumComponents] maxValue = .()) where NumComponents : const int32 public static bool EditVector<NumComponents>(StringView label, ref float[NumComponents] value, float[NumComponents] resetValues = .(), float dragSpeed = 0.1f, float columnWidth = 100f, float[NumComponents] minValue = .(), float[NumComponents] maxValue = .()) where NumComponents : const int32
{ {
const String[?] componentNames = .("X", "Y", "Z", "W"); const String[?] componentNames = .("X", "Y", "Z", "W");
const String[?] componentIds = .("##X", "##Y", "##Z", "##W"); const String[?] componentIds = .("##X", "##Y", "##Z", "##W");
/*(Color Default, Color Hovered, Color Active)[?] VectorButtonColors = .( static int mouseLockId = 0;
(Color(230, 25, 45), Color(150, 25, 45), Color(230, 90, 90)),
(Color(50, 190, 15), Color(50, 120, 15), Color(116, 190, 99)),
(Color(55, 55, 230), Color(55, 55, 150), Color(90, 90, 230)),
(Color(230, 25, 45), Color(230, 25, 45), Color(230, 25, 45)));*/
bool changed = false; bool changed = false;
bool deactivated = false;
PushID(label); PushID(label);
defer PopID(); defer PopID();
int currentId = ImGui.GetID("");
Columns(2); Columns(2);
defer Columns(1); defer Columns(1);
SetColumnWidth(0, columnWidth); SetColumnWidth(0, columnWidth);
@@ -133,9 +166,9 @@ namespace ImGui
SameLine(); SameLine();
} }
PushStyleColor(.Button, VectorButtonColors[i].Default.Value); PushStyleColor(.Button, VectorButtonColors[i].Default.ImGuiU32);
PushStyleColor(.ButtonHovered, VectorButtonColors[i].Hovered.Value); PushStyleColor(.ButtonHovered, VectorButtonColors[i].Hovered.ImGuiU32);
PushStyleColor(.ButtonActive, VectorButtonColors[i].Active.Value); PushStyleColor(.ButtonActive, VectorButtonColors[i].Active.ImGuiU32);
if (Button(componentNames[i], buttonSize)) if (Button(componentNames[i], buttonSize))
{ {
@@ -146,14 +179,34 @@ namespace ImGui
SameLine(); SameLine();
if (DragFloat(componentIds[i], &value[i], dragSpeed, minValue[i], maxValue[i])) if (DragFloat(componentIds[i], &value[i], dragSpeed, minValue[i], maxValue[i]))
{
changed = true; changed = true;
/*if (mouseLockId != currentId)
{
mouseLockId = currentId;
Mouse.LockCurrentPosition(mouseLockId);
}*/
}
/*if (IsItemDeactivatedAfterEdit())
{
deactivated = true;
}*/
PopItemWidth(); PopItemWidth();
PopStyleColor(3); PopStyleColor(3);
} }
PopStyleVar(); PopStyleVar();
/*if (mouseLockId == currentId && deactivated)
{
Mouse.UnlockPosition(mouseLockId);
mouseLockId = 0;
}*/
return changed; return changed;
} }
+140 -10
View File
@@ -1,6 +1,8 @@
using System; using System;
using GlitchyEngine.Events; using GlitchyEngine.Events;
using GlitchyEngine.Math; using GlitchyEngine.Math;
using System.Collections;
using ImGui;
namespace GlitchyEngine namespace GlitchyEngine
{ {
@@ -25,25 +27,153 @@ namespace GlitchyEngine
*/ */
public static extern bool IsKeyReleasing(Key keycode); public static extern bool IsKeyReleasing(Key keycode);
public static extern bool IsMouseButtonPressed(MouseButton button);
public static extern bool IsMouseButtonReleased(MouseButton button);
public static extern Int2 GetMousePosition();
public static extern int32 GetMouseX();
public static extern int32 GetMouseY();
// TODO: Should Input be able to set mousepos? // TODO: Should Input be able to set mousepos?
public static extern void SetMousePosition(Int2 pos); public static extern void SetMousePosition(Int2 pos);
public static extern bool IsMouseButtonPressed(MouseButton button);
public static extern bool IsMouseButtonReleased(MouseButton button);
public static extern bool IsMouseButtonPressing(MouseButton button);
public static extern bool IsMouseButtonReleasing(MouseButton button);
public static extern Int2 GetMousePosition();
public static extern Int2 GetMouseMovement();
public static extern Int2 GetRawMouseMovement();
public static extern int32 GetMouseX();
public static extern int32 GetMouseY();
public static extern bool WasMouseButtonPressed(MouseButton button); public static extern bool WasMouseButtonPressed(MouseButton button);
// public static extern bool WasMouseButtonPressing(MouseButton button);
public static extern bool WasMouseButtonReleased(MouseButton button); public static extern bool WasMouseButtonReleased(MouseButton button);
//public static extern bool WasMouseButtonReleasing(MouseButton button);
public static extern Int2 GetLastMousePosition(); public static extern Int2 GetLastMousePosition();
public static extern Int2 GetLastMouseMovement();
public static extern Int2 GetLastRawMouseMovement();
public static extern int32 GetLastMouseX(); public static extern int32 GetLastMouseX();
public static extern int32 GetLastMouseY(); public static extern int32 GetLastMouseY();
public static extern bool IsMouseButtonPressing(MouseButton button); public static extern void Init();
public static extern bool IsMouseButtonReleasing(MouseButton button);
public static extern Int2 GetMouseMovement();
public static extern void NewFrame(); public static void NewFrame()
{
[Inline]
Impl_NewFrame();
Mouse.NewFrame();
[Inline]
Impl_EndFrame();
}
public static extern void Impl_NewFrame();
public static extern void Impl_EndFrame();
public static void ImGuiDebugDraw()
{
if (ImGui.Begin("Input"))
{
ImGui.TextUnformatted("Last Mouse state");
ImGui.Columns(2);
ImGui.TextUnformatted("Position");
ImGui.NextColumn();
ImGui.Text($"{GetLastMousePosition()}");
ImGui.NextColumn();
ImGui.TextUnformatted("Movement");
ImGui.NextColumn();
ImGui.Text($"{GetLastMouseMovement()}");
ImGui.NextColumn();
ImGui.TextUnformatted("RawMovement");
ImGui.NextColumn();
ImGui.Text($"{GetLastRawMouseMovement()}");
ImGui.NextColumn();
ImGui.Columns(1);
ImGui.Separator();
ImGui.TextUnformatted("Current Mouse state");
ImGui.Columns(2);
ImGui.TextUnformatted("Position");
ImGui.NextColumn();
ImGui.Text($"{GetMousePosition()}");
ImGui.NextColumn();
ImGui.TextUnformatted("Movement");
ImGui.NextColumn();
ImGui.Text($"{GetMouseMovement()}");
ImGui.NextColumn();
ImGui.TextUnformatted("RawMovement");
ImGui.NextColumn();
ImGui.Text($"{GetRawMouseMovement()}");
ImGui.NextColumn();
ImGui.Columns(1);
}
ImGui.End();
}
}
public static class Mouse
{
private static append List<(Int2 Position, int Hash)> _lockPositions = .();
public static void LockCurrentPosition(int hash)
{
LockPosition(Input.GetMousePosition(), hash);
}
public static void LockPosition(Int2 pos, int hash)
{
for (var entry in _lockPositions)
{
if (entry.Hash == hash)
{
entry.Position = pos;
break;
}
}
_lockPositions.Add((pos, hash));
}
public static void UnlockPosition(int hash)
{
for (var entry in _lockPositions)
{
if (entry.Hash == hash)
{
@entry.Remove();
break;
}
}
//Log.EngineLogger.AssertDebug(false, "No mouse lock position with hash found.");
}
public static Int2? LockedPosition;
public static void NewFrame()
{
Log.EngineLogger.Info($"{Input.GetMousePosition()}");
if (_lockPositions.Count > 0)
{
var position = _lockPositions.Back.Position;
LockedPosition = position;
Input.SetMousePosition(position);
}
else
{
LockedPosition = null;
}
}
} }
} }
+9
View File
@@ -185,6 +185,15 @@ namespace GlitchyEngine.Math
A = a; A = a;
} }
/// Creates a new instance of ColorRGBA with the specified values.
public this(uint8 r, uint8 g, uint8 b, uint8 a = 255)
{
R = r / 255f;
G = g / 255f;
B = b / 255f;
A = a / 255f;
}
/// Creates a new instance of ColorRGBA with the specified values. /// Creates a new instance of ColorRGBA with the specified values.
public this(ColorRGB color, float a = 1.0f) public this(ColorRGB color, float a = 1.0f)
{ {
@@ -0,0 +1,9 @@
namespace GlitchyEngine.Physics;
struct PhysicsMaterial2D
{
public float Density = 1.0f;
public float Friction = 0.5f;
public float Restitution = 0.0f;
public float RestitutionThreshold = 0.5f;
}
@@ -1,11 +1,14 @@
#if BF_PLATFORM_WINDOWS #if BF_PLATFORM_WINDOWS
using System;
using GlitchyEngine.Events;
using DirectX.Windows.VirtualKeyCodes;
using DirectX.Windows; using DirectX.Windows;
using GlitchyEngine.Math; using DirectX.Windows.Winuser;
using DirectX.Windows.Winuser.RawInput;
using DirectX.Windows.VirtualKeyCodes;
using System;
using System.Interop; using System.Interop;
using GlitchyEngine.Events;
using GlitchyEngine.Math;
using static System.Windows; using static System.Windows;
namespace GlitchyEngine namespace GlitchyEngine
@@ -13,12 +16,43 @@ namespace GlitchyEngine
/// Windows (WinApi) specific implementation of the Input-class /// Windows (WinApi) specific implementation of the Input-class
extension Input extension Input
{ {
//[CLink, CallingConvention(.Stdcall)]
//static extern int16 GetKeyState(int32 keycode);
[CLink, CallingConvention(.Stdcall)]
static extern IntBool GetCursorPos(out Int2 p);
[CLink, CallingConvention(.Stdcall)]
static extern IntBool SetCursorPos(c_int x, c_int y);
[CLink, CallingConvention(.Stdcall)]
static extern IntBool ScreenToClient(HWnd hWnd, ref Int2 p);
[CLink, CallingConvention(.Stdcall)]
static extern IntBool ClientToScreen(HWnd hWnd, ref Int2 p);
[Import("user32.lib"), CLink]
public static extern IntBool RegisterRawInputDevices(RAWINPUTDEVICE* pRawInputDevices, uint32 uiNumDevices, uint32 cbSize);
public static void RegisterRIDs()
{
RAWINPUTDEVICE rid;
rid.UsagePage = 0x01;
rid.Usage = 0x02;
rid.Flags = 0;
rid.Target = 0;
if(RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)) == 0)
{
Log.EngineLogger.Error("Failed to register raw input devices: {0}", GetLastError());
Log.EngineLogger.AssertDebug(false, "Failed to register raw input device.");
}
}
/// Represents the state of the input devices on the windows platform (WinApi that is). /// Represents the state of the input devices on the windows platform (WinApi that is).
struct WindowsInputState struct WindowsInputState
{ {
public int8[256] KeyStates; public int8[256] KeyStates;
public Int2 CursorPosition; public Int2 CursorPosition;
public Int2 CursorPositionDifference; public Int2 CursorPositionDifference;
public Int2 RawCursorMovement;
} }
static WindowsInputState[2] IputStates; static WindowsInputState[2] IputStates;
@@ -119,8 +153,16 @@ namespace GlitchyEngine
return state >= 0; return state >= 0;
} }
public override static bool IsMouseButtonPressing(MouseButton button) => IsMouseButtonPressed(button) && WasMouseButtonReleased(button);
public override static bool IsMouseButtonReleasing(MouseButton button) => IsMouseButtonReleased(button) && WasMouseButtonPressed(button);
public override static Int2 GetMousePosition() => CurrentState.CursorPosition; public override static Int2 GetMousePosition() => CurrentState.CursorPosition;
public override static Int2 GetMouseMovement() => CurrentState.CursorPositionDifference;
public override static Int2 GetRawMouseMovement() => CurrentState.RawCursorMovement;
public override static int32 GetMouseX() => CurrentState.CursorPosition.X; public override static int32 GetMouseX() => CurrentState.CursorPosition.X;
public override static int32 GetMouseY() => CurrentState.CursorPosition.Y; public override static int32 GetMouseY() => CurrentState.CursorPosition.Y;
@@ -142,32 +184,37 @@ namespace GlitchyEngine
public override static Int2 GetLastMousePosition() => LastState.CursorPosition; public override static Int2 GetLastMousePosition() => LastState.CursorPosition;
public override static Int2 GetLastMouseMovement() => LastState.CursorPositionDifference;
public override static Int2 GetLastRawMouseMovement() => LastState.RawCursorMovement;
public override static int32 GetLastMouseX() => LastState.CursorPosition.X; public override static int32 GetLastMouseX() => LastState.CursorPosition.X;
public override static int32 GetLastMouseY() => LastState.CursorPosition.Y; public override static int32 GetLastMouseY() => LastState.CursorPosition.Y;
// public override static void SetMousePosition(Int2 pos)
// Mouse state transition
//
public override static bool IsMouseButtonPressing(MouseButton button) => IsMouseButtonPressed(button) && WasMouseButtonReleased(button);
public override static bool IsMouseButtonReleasing(MouseButton button) => IsMouseButtonReleased(button) && WasMouseButtonPressed(button);
public override static Int2 GetMouseMovement() => CurrentState.CursorPositionDifference;
public override static void SetMousePosition(Int2 pos) => SetCursorPos(pos.X, pos.Y);
//[CLink, CallingConvention(.Stdcall)]
//static extern int16 GetKeyState(int32 keycode);
[CLink, CallingConvention(.Stdcall)]
static extern IntBool GetCursorPos(out Int2 p);
[CLink, CallingConvention(.Stdcall)]
static extern IntBool SetCursorPos(c_int x, c_int y);
[CLink, CallingConvention(.Stdcall)]
static extern IntBool ScreenToClient(HWnd hWnd, ref Int2 p);
public override static void NewFrame()
{ {
HWnd windowHandle = (HWnd)(int)Application.Get().Window.NativeWindow;
var pos;
// TODO: can fail
ClientToScreen(windowHandle, ref pos);
SetCursorPos(pos.X, pos.Y);
}
public override static void Init()
{
RegisterRIDs();
}
//public override
public override static void Impl_NewFrame()
{
Window window = Application.Get().Window;
Debug.Profiler.ProfileFunction!(); Debug.Profiler.ProfileFunction!();
Swap!(CurrentState, LastState); Swap!(CurrentState, LastState);
@@ -182,7 +229,7 @@ namespace GlitchyEngine
// Get the current mouse position // Get the current mouse position
if (GetCursorPos(out CurrentState.CursorPosition) != 0) if (GetCursorPos(out CurrentState.CursorPosition) != 0)
{ {
HWnd windowHandle = (HWnd)(int)Application.Get().Window.NativeWindow; HWnd windowHandle = (HWnd)(int)window.NativeWindow;
if (ScreenToClient(windowHandle, ref CurrentState.CursorPosition) == 0) if (ScreenToClient(windowHandle, ref CurrentState.CursorPosition) == 0)
{ {
DirectX.Common.HResult errorCode = (.)GetLastError(); DirectX.Common.HResult errorCode = (.)GetLastError();
@@ -195,9 +242,26 @@ namespace GlitchyEngine
Log.EngineLogger.Error($"Failed to get mouse position. Message({(int32)errorCode}){errorCode}:"); Log.EngineLogger.Error($"Failed to get mouse position. Message({(int32)errorCode}){errorCode}:");
} }
CurrentState.RawCursorMovement = window.[Friend]_rawMouseMovementAccumulator;
if (Mouse.LockedPosition == null)
{
// Calculate cursor movement // Calculate cursor movement
CurrentState.CursorPositionDifference = CurrentState.CursorPosition - LastState.CursorPosition; CurrentState.CursorPositionDifference = CurrentState.CursorPosition - LastState.CursorPosition;
} }
else
{
// Calculate cursor movement
CurrentState.CursorPositionDifference = CurrentState.CursorPosition - Mouse.LockedPosition.Value;
CurrentState.CursorPosition = Mouse.LockedPosition.Value;
}
}
public override static void Impl_EndFrame()
{
Application.Get().Window.[Friend]_rawMouseMovementAccumulator = .Zero;
}
} }
} }
@@ -10,6 +10,7 @@ using GlitchyEngine.Events;
using System.Diagnostics; using System.Diagnostics;
using GlitchyEngine.Math; using GlitchyEngine.Math;
using GlitchyEngine.Renderer; using GlitchyEngine.Renderer;
using DirectX.Windows.Winuser.RawInput;
using static System.Windows; using static System.Windows;
using internal GlitchyEngine; using internal GlitchyEngine;
@@ -262,6 +263,8 @@ namespace GlitchyEngine
return .Ok; return .Ok;
} }
internal Int2 _rawMouseMovementAccumulator;
private static LRESULT MessageHandler(HWND hwnd, uint32 uMsg, WPARAM wParam, LPARAM lParam) private static LRESULT MessageHandler(HWND hwnd, uint32 uMsg, WPARAM wParam, LPARAM lParam)
{ {
void* windowPtr = (void*)GetWindowLongPtrW(hwnd, GWL_USERDATA); void* windowPtr = (void*)GetWindowLongPtrW(hwnd, GWL_USERDATA);
@@ -458,6 +461,28 @@ namespace GlitchyEngine
var event = scope MouseMovedEvent(x, y); var event = scope MouseMovedEvent(x, y);
window._eventCallback(event); window._eventCallback(event);
} }
case WM_INPUT:
{
uint32 dataSize = ?;
GetRawInputData((.)lParam, RID_INPUT, null, &dataSize, sizeof(RAWINPUTHEADER));
if (dataSize > 0)
{
uint8[] rawData = scope .[dataSize];
if (GetRawInputData((.)lParam, RID_INPUT, rawData.CArray(), &dataSize, sizeof(RAWINPUTHEADER)) == dataSize)
{
RAWINPUT* raw = (.)rawData.CArray();
if (raw.Header.Type == RIM_TYPEMOUSE)
{
var event = scope MouseMovedEvent(raw.Data.Mouse.lLastX, raw.Data.Mouse.lLastY);
window._eventCallback(event);
// We accumulate the raw movements an collect them once each frame in WindowsInput.Impl_NewFrame()
window._rawMouseMovementAccumulator += Int2(raw.Data.Mouse.lLastX, raw.Data.Mouse.lLastY);
}
}
}
}
// Todo: DirectInput // Todo: DirectInput