diff --git a/include/vsg/all.h b/include/vsg/all.h index 522be1a4e..989cf6a31 100644 --- a/include/vsg/all.h +++ b/include/vsg/all.h @@ -163,6 +163,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include #include #include #include diff --git a/include/vsg/app/Trackball.h b/include/vsg/app/Trackball.h index d17842f97..841ce8faf 100644 --- a/include/vsg/app/Trackball.h +++ b/include/vsg/app/Trackball.h @@ -15,8 +15,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include -#include -#include +#include #include #include #include @@ -37,6 +36,9 @@ namespace vsg dvec3 tbc(PointerEvent& event); void apply(KeyPressEvent& keyPress) override; + void apply(KeyReleaseEvent& keyRelease) override; + void apply(FocusInEvent& focusIn) override; + void apply(FocusOutEvent& focusOut) override; void apply(ButtonPressEvent& buttonPress) override; void apply(ButtonReleaseEvent& buttonRelease) override; void apply(MoveEvent& moveEvent) override; @@ -81,6 +83,42 @@ namespace vsg /// container that maps key symbol bindings with the Viewpoint that should move the LookAt to when pressed. std::map keyViewpointMap; + /// Key that turns the view left around the eye points + KeySymbol turnLeftKey = KEY_a; + + /// Key that turns the view right around the eye points + KeySymbol turnRightKey = KEY_d; + + /// Key that pitches up the view around the eye point + KeySymbol pitchUpKey = KEY_w; + + /// Key that pitches down the view around the eye point + KeySymbol pitchDownKey = KEY_s; + + /// Key that rools the view anti-clockwise/left + KeySymbol rollLeftKey = KEY_q; + + /// Key that rolls the view clockwise/right + KeySymbol rollRightKey = KEY_e; + + /// Key that moves the view forward + KeySymbol moveForwardKey = KEY_o; + + /// Key that moves the view backwards + KeySymbol moveBackwardKey = KEY_i; + + /// Key that moves the view left + KeySymbol moveLeftKey = KEY_Left; + + /// Key that moves the view right + KeySymbol moveRightKey = KEY_Right; + + /// Key that moves the view upward + KeySymbol moveUpKey = KEY_Up; + + /// Key that moves the view downard + KeySymbol moveDownKey = KEY_Down; + /// Button mask value used to enable panning of the view, defaults to left mouse button ButtonMask rotateButtonMask = BUTTON_MASK_1; @@ -104,7 +142,8 @@ namespace vsg ref_ptr _lookAt; ref_ptr _ellipsoidModel; - bool _hasFocus = false; + bool _hasKeyboardFocus = false; + bool _hasPointerFocus = false; bool _lastPointerEventWithinRenderArea = false; enum UpdateMode @@ -131,6 +170,8 @@ namespace vsg ref_ptr _endLookAt; std::map> _previousTouches; + ref_ptr _keyboard; + double _animationDuration = 0.0; }; VSG_type_name(vsg::Trackball); diff --git a/include/vsg/app/WindowResizeHandler.h b/include/vsg/app/WindowResizeHandler.h index cee73928c..8e4aa6147 100644 --- a/include/vsg/app/WindowResizeHandler.h +++ b/include/vsg/app/WindowResizeHandler.h @@ -26,7 +26,6 @@ namespace vsg class VSG_DECLSPEC UpdateGraphicsPipelines : public vsg::Inherit { public: - UpdateGraphicsPipelines(); vsg::ref_ptr context; diff --git a/include/vsg/core/ConstVisitor.h b/include/vsg/core/ConstVisitor.h index 3ceb633b2..13568b8fd 100644 --- a/include/vsg/core/ConstVisitor.h +++ b/include/vsg/core/ConstVisitor.h @@ -109,6 +109,8 @@ namespace vsg class ExposeWindowEvent; class ConfigureWindowEvent; class CloseWindowEvent; + class FocusInEvent; + class FocusOutEvent; class KeyEvent; class KeyPressEvent; class KeyReleaseEvent; @@ -356,6 +358,8 @@ namespace vsg virtual void apply(const ExposeWindowEvent&); virtual void apply(const ConfigureWindowEvent&); virtual void apply(const CloseWindowEvent&); + virtual void apply(const FocusInEvent&); + virtual void apply(const FocusOutEvent&); virtual void apply(const KeyEvent&); virtual void apply(const KeyPressEvent&); virtual void apply(const KeyReleaseEvent&); diff --git a/include/vsg/core/Visitor.h b/include/vsg/core/Visitor.h index b06e1d129..d30addf03 100644 --- a/include/vsg/core/Visitor.h +++ b/include/vsg/core/Visitor.h @@ -109,6 +109,8 @@ namespace vsg class ExposeWindowEvent; class ConfigureWindowEvent; class CloseWindowEvent; + class FocusInEvent; + class FocusOutEvent; class KeyEvent; class KeyPressEvent; class KeyReleaseEvent; @@ -356,6 +358,8 @@ namespace vsg virtual void apply(ExposeWindowEvent&); virtual void apply(ConfigureWindowEvent&); virtual void apply(CloseWindowEvent&); + virtual void apply(FocusInEvent&); + virtual void apply(FocusOutEvent&); virtual void apply(KeyEvent&); virtual void apply(KeyPressEvent&); virtual void apply(KeyReleaseEvent&); diff --git a/include/vsg/maths/plane.h b/include/vsg/maths/plane.h index 3c1003d8c..85d1ebcfc 100644 --- a/include/vsg/maths/plane.h +++ b/include/vsg/maths/plane.h @@ -102,6 +102,8 @@ namespace vsg bool valid() const { return n.x != 0.0 && n.y != 0.0 && n.z != 0.0; } + explicit operator bool() const noexcept { return valid(); } + T* data() { return value; } const T* data() const { return value; } }; diff --git a/include/vsg/maths/quat.h b/include/vsg/maths/quat.h index a49374636..d03e90401 100644 --- a/include/vsg/maths/quat.h +++ b/include/vsg/maths/quat.h @@ -141,6 +141,8 @@ namespace vsg z = axis.z * sinhalfangle * inversenorm; w = coshalfangle; } + + explicit operator bool() const noexcept { return value[0] != 0.0 || value[1] != 0.0 || value[2] != 0.0 || value[3] != 0.0; } }; using quat = t_quat; /// float quaternion diff --git a/include/vsg/maths/vec2.h b/include/vsg/maths/vec2.h index 1b62507dc..f57d71740 100644 --- a/include/vsg/maths/vec2.h +++ b/include/vsg/maths/vec2.h @@ -130,6 +130,8 @@ namespace vsg } return *this; } + + explicit operator bool() const noexcept { return value[0] != 0.0 || value[1] != 0.0; } }; using vec2 = t_vec2; // float 2D vector diff --git a/include/vsg/maths/vec3.h b/include/vsg/maths/vec3.h index 040910cfa..40cf7752b 100644 --- a/include/vsg/maths/vec3.h +++ b/include/vsg/maths/vec3.h @@ -140,6 +140,8 @@ namespace vsg } return *this; } + + explicit operator bool() const noexcept { return value[0] != 0.0 || value[1] != 0.0 || value[2] != 0.0; } }; using vec3 = t_vec3; // float 3D vector diff --git a/include/vsg/maths/vec4.h b/include/vsg/maths/vec4.h index 28f69f3e0..72473012a 100644 --- a/include/vsg/maths/vec4.h +++ b/include/vsg/maths/vec4.h @@ -154,6 +154,8 @@ namespace vsg } return *this; } + + explicit operator bool() const noexcept { return value[0] != 0.0 || value[1] != 0.0 || value[2] != 0.0 || value[3] != 0.0; } }; using vec4 = t_vec4; // float 4D vector diff --git a/include/vsg/ui/Keyboard.h b/include/vsg/ui/Keyboard.h new file mode 100644 index 000000000..18e7bfbf5 --- /dev/null +++ b/include/vsg/ui/Keyboard.h @@ -0,0 +1,49 @@ +#pragma once + +/* + +Copyright(c) 2023 Robert Osfield + +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 +#include + +namespace vsg +{ + + /// Keyboard tracks keyboard events to maintain the key pressed state and how long the key has been hel for + class VSG_DECLSPEC Keyboard : public Inherit + { + public: + void apply(KeyPressEvent& keyPress) override; + void apply(KeyReleaseEvent& keyRelease) override; + void apply(FocusInEvent& focusIn) override; + void apply(FocusOutEvent& focusOut) override; + + struct KeyHistory + { + vsg::time_point timeOfFirstKeyPress = {}; + vsg::time_point timeOfLastKeyPress = {}; + vsg::time_point timeOfKeyRelease = {}; + bool handled = false; + }; + + std::map keyState; + + /// return true if key is currently pressed + bool pressed(KeySymbol key, bool ignore_handled_keys = true); + + /// return a pair of times, the first is the time, in seconds, since the key was first pressed and the second is the time, in secnds, since it was released. + /// if the key hasn't been pressed then then first value will be < 0.0, if the key is still pressed then the second value will be 0.0. + std::pair times(KeySymbol key, bool ignore_handled_keys = true); + }; + VSG_type_name(vsg::Keyboard); + +} // namespace vsg diff --git a/include/vsg/ui/WindowEvent.h b/include/vsg/ui/WindowEvent.h index 32c908020..62f3a46f5 100644 --- a/include/vsg/ui/WindowEvent.h +++ b/include/vsg/ui/WindowEvent.h @@ -93,4 +93,26 @@ namespace vsg }; VSG_type_name(vsg::CloseWindowEvent); + /// FocusInEvent represents a window aquiring focus event. + class FocusInEvent : public Inherit + { + public: + FocusInEvent() {} + + FocusInEvent(Window* in_window, time_point in_time) : + Inherit(in_window, in_time) {} + }; + VSG_type_name(vsg::FocusInEvent); + + /// FocusOutEvent represents a window loosing focus event. + class FocusOutEvent : public Inherit + { + public: + FocusOutEvent() {} + + FocusOutEvent(Window* in_window, time_point in_time) : + Inherit(in_window, in_time) {} + }; + VSG_type_name(vsg::FocusOutEvent); + } // namespace vsg diff --git a/src/vsg/CMakeLists.txt b/src/vsg/CMakeLists.txt index 4154312f1..3d9625e4d 100644 --- a/src/vsg/CMakeLists.txt +++ b/src/vsg/CMakeLists.txt @@ -192,6 +192,7 @@ set(SOURCES ui/ShiftEventTime.cpp ui/PlayEvents.cpp ui/PrintEvents.cpp + ui/Keyboard.cpp vk/CommandBuffer.cpp vk/CommandPool.cpp diff --git a/src/vsg/app/CompileTraversal.cpp b/src/vsg/app/CompileTraversal.cpp index 717255aec..698c0bcee 100644 --- a/src/vsg/app/CompileTraversal.cpp +++ b/src/vsg/app/CompileTraversal.cpp @@ -310,7 +310,7 @@ void CompileTraversal::apply(View& view) { // if context is associated with a view make sure we only apply it if it matches with view, oherwsie we skip this context auto context_view = context->view.ref_ptr(); - if (context_view && context_view.get()!=&view) continue; + if (context_view && context_view.get() != &view) continue; context->viewID = view.viewID; context->viewDependentState = view.viewDependentState.get(); diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index 5f16a5543..362434082 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -15,13 +15,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include +#include using namespace vsg; Trackball::Trackball(ref_ptr camera, ref_ptr ellipsoidModel) : _camera(camera), _lookAt(camera->viewMatrix.cast()), - _ellipsoidModel(ellipsoidModel) + _ellipsoidModel(ellipsoidModel), + _keyboard(Keyboard::create()) { if (!_lookAt) { @@ -127,7 +129,9 @@ dvec3 Trackball::tbc(PointerEvent& event) void Trackball::apply(KeyPressEvent& keyPress) { - if (keyPress.handled || !eventRelevant(keyPress) || !_lastPointerEventWithinRenderArea) return; + if (_keyboard) keyPress.accept(*_keyboard); + + if (!_hasKeyboardFocus || keyPress.handled || !eventRelevant(keyPress)) return; if (auto itr = keyViewpointMap.find(keyPress.keyBase); itr != keyViewpointMap.end()) { @@ -139,12 +143,31 @@ void Trackball::apply(KeyPressEvent& keyPress) } } +void Trackball::apply(KeyReleaseEvent& keyRelease) +{ + if (_keyboard) keyRelease.accept(*_keyboard); +} + +void Trackball::apply(FocusInEvent& focusIn) +{ + if (_keyboard) focusIn.accept(*_keyboard); +} + +void Trackball::apply(FocusOutEvent& focusOut) +{ + if (_keyboard) focusOut.accept(*_keyboard); +} + void Trackball::apply(ButtonPressEvent& buttonPress) { - if (buttonPress.handled || !eventRelevant(buttonPress)) return; + if (buttonPress.handled || !eventRelevant(buttonPress)) + { + _hasKeyboardFocus = false; + return; + } - _hasFocus = withinRenderArea(buttonPress); - _lastPointerEventWithinRenderArea = _hasFocus; + _hasPointerFocus = _hasKeyboardFocus = withinRenderArea(buttonPress); + _lastPointerEventWithinRenderArea = _hasPointerFocus; if (buttonPress.mask & rotateButtonMask) _updateMode = ROTATE; @@ -155,7 +178,7 @@ void Trackball::apply(ButtonPressEvent& buttonPress) else _updateMode = INACTIVE; - if (_hasFocus) buttonPress.handled = true; + if (_hasPointerFocus) buttonPress.handled = true; _zoomPreviousRatio = 0.0; _pan.set(0.0, 0.0); @@ -173,7 +196,7 @@ void Trackball::apply(ButtonReleaseEvent& buttonRelease) if (supportsThrow) _thrown = _previousPointerEvent && (buttonRelease.time == _previousPointerEvent->time); _lastPointerEventWithinRenderArea = withinRenderArea(buttonRelease); - _hasFocus = false; + _hasPointerFocus = false; _previousPointerEvent = &buttonRelease; } @@ -184,7 +207,7 @@ void Trackball::apply(MoveEvent& moveEvent) _lastPointerEventWithinRenderArea = withinRenderArea(moveEvent); - if (moveEvent.handled || !_hasFocus) return; + if (moveEvent.handled || !_hasPointerFocus) return; dvec2 new_ndc = ndc(moveEvent); dvec3 new_tbc = tbc(moveEvent); @@ -375,6 +398,69 @@ void Trackball::apply(TouchMoveEvent& touchMove) void Trackball::apply(FrameEvent& frame) { + // std::cout<<"Trackball::apply(FrameEvent&) frameCount = "<frameCount< duration) -> double { + if (duration.first <= 0.0) return 0.0; + double speed = duration.first >= 1.0 ? 1.0 : duration.first; + + if (duration.second > 0.0) + { + // key has been released so slow down + speed -= duration.second; + return speed > 0.0 ? speed : 0.0; + } + else + { + // key still pressed so return speed based on duration of press + return speed; + } + }; + + double speed = 0.0; + vsg::dvec3 move(0.0, 0.0, 0.0); + if ((speed = times2speed(_keyboard->times(moveLeftKey))) != 0.0) move.x += -speed; + if ((speed = times2speed(_keyboard->times(moveRightKey))) != 0.0) move.x += speed; + if ((speed = times2speed(_keyboard->times(moveUpKey))) != 0.0) move.y += speed; + if ((speed = times2speed(_keyboard->times(moveDownKey))) != 0.0) move.y += -speed; + if ((speed = times2speed(_keyboard->times(moveForwardKey))) != 0.0) move.z += speed; + if ((speed = times2speed(_keyboard->times(moveBackwardKey))) != 0.0) move.z += -speed; + + vsg::dvec3 rot(0.0, 0.0, 0.0); + if ((speed = times2speed(_keyboard->times(turnLeftKey))) != 0.0) rot.x += speed; + if ((speed = times2speed(_keyboard->times(turnRightKey))) != 0.0) rot.x -= speed; + if ((speed = times2speed(_keyboard->times(pitchUpKey))) != 0.0) rot.y += speed; + if ((speed = times2speed(_keyboard->times(pitchDownKey))) != 0.0) rot.y -= speed; + if ((speed = times2speed(_keyboard->times(rollLeftKey))) != 0.0) rot.z -= speed; + if ((speed = times2speed(_keyboard->times(rollRightKey))) != 0.0) rot.z += speed; + + if (rot || move) + { + double scale = std::chrono::duration(frame.time - _previousTime).count(); + double scaleTranslation = scale * 0.2 * length(_lookAt->center - _lookAt->eye); + double scaleRotation = scale * 0.5; + + dvec3 upVector = _lookAt->up; + dvec3 lookVector = vsg::normalize(_lookAt->center - _lookAt->eye); + dvec3 sideVector = vsg::normalize(vsg::cross(lookVector, upVector)); + + dvec3 delta = sideVector * (scaleTranslation * move.x) + upVector * (scaleTranslation * move.y) + lookVector * (scaleTranslation * move.z); + dmat4 matrix = vsg::translate(_lookAt->eye + delta) * + vsg::rotate(rot.x * scaleRotation, upVector) * + vsg::rotate(rot.y * scaleRotation, sideVector) * + vsg::rotate(rot.z * scaleRotation, lookVector) * + vsg::translate(-_lookAt->eye); + + _lookAt->up = normalize(matrix * (_lookAt->eye + _lookAt->up) - matrix * _lookAt->eye); + _lookAt->center = matrix * _lookAt->center; + _lookAt->eye = matrix * _lookAt->eye; + + clampToGlobe(); + _thrown = false; + } + } + if (_endLookAt) { double timeSinceOfAnimation = std::chrono::duration(frame.time - _startTime).count(); diff --git a/src/vsg/core/ConstVisitor.cpp b/src/vsg/core/ConstVisitor.cpp index ac19df6e2..e94a2e477 100644 --- a/src/vsg/core/ConstVisitor.cpp +++ b/src/vsg/core/ConstVisitor.cpp @@ -837,6 +837,14 @@ void ConstVisitor::apply(const CloseWindowEvent& event) { apply(static_cast(event)); } +void ConstVisitor::apply(const FocusInEvent& event) +{ + apply(static_cast(event)); +} +void ConstVisitor::apply(const FocusOutEvent& event) +{ + apply(static_cast(event)); +} void ConstVisitor::apply(const KeyEvent& event) { apply(static_cast(event)); diff --git a/src/vsg/core/Visitor.cpp b/src/vsg/core/Visitor.cpp index ebd926ba1..e11f27343 100644 --- a/src/vsg/core/Visitor.cpp +++ b/src/vsg/core/Visitor.cpp @@ -837,6 +837,14 @@ void Visitor::apply(CloseWindowEvent& event) { apply(static_cast(event)); } +void Visitor::apply(FocusInEvent& event) +{ + apply(static_cast(event)); +} +void Visitor::apply(FocusOutEvent& event) +{ + apply(static_cast(event)); +} void Visitor::apply(KeyEvent& event) { apply(static_cast(event)); diff --git a/src/vsg/platform/win32/Win32_Window.cpp b/src/vsg/platform/win32/Win32_Window.cpp index 55b20fc1d..47fa33876 100644 --- a/src/vsg/platform/win32/Win32_Window.cpp +++ b/src/vsg/platform/win32/Win32_Window.cpp @@ -631,6 +631,16 @@ LRESULT Win32_Window::handleWin32Messages(UINT msg, WPARAM wParam, LPARAM lParam break; } + case WM_SETFOCUS: { + vsg::clock::time_point event_time = vsg::clock::now(); + bufferedEvents.emplace_back(vsg::FocusInEvent::create(this, event_time)); + break; + } + case WM_KILLFOCUS: { + vsg::clock::time_point event_time = vsg::clock::now(); + bufferedEvents.emplace_back(vsg::FocusOutEvent::create(this, event_time)); + break; + } default: break; } diff --git a/src/vsg/platform/xcb/Xcb_Window.cpp b/src/vsg/platform/xcb/Xcb_Window.cpp index 494240c69..879474389 100644 --- a/src/vsg/platform/xcb/Xcb_Window.cpp +++ b/src/vsg/platform/xcb/Xcb_Window.cpp @@ -611,11 +611,13 @@ bool Xcb_Window::pollEvents(UIEvents& events) break; } case (XCB_FOCUS_IN): { - //debug("xcb_focus_in_event_t"); + vsg::clock::time_point event_time = vsg::clock::now(); + bufferedEvents.emplace_back(vsg::FocusInEvent::create(this, event_time)); break; } case (XCB_FOCUS_OUT): { - //debug("xcb_focus_out_event_t"); + vsg::clock::time_point event_time = vsg::clock::now(); + bufferedEvents.emplace_back(vsg::FocusOutEvent::create(this, event_time)); break; } case (XCB_ENTER_NOTIFY): { diff --git a/src/vsg/ui/Keyboard.cpp b/src/vsg/ui/Keyboard.cpp new file mode 100644 index 000000000..19d8399c7 --- /dev/null +++ b/src/vsg/ui/Keyboard.cpp @@ -0,0 +1,110 @@ +/* + +Copyright(c) 2023 Robert Osfield + +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 +#include +#include + +using namespace vsg; + +void Keyboard::apply(KeyPressEvent& keyPress) +{ + //std::cout<<"Keyboard::apply(KeyReleaseEvent& keyRelease)"<second; + keyHistory.handled = keyPress.handled; + if (keyHistory.timeOfKeyRelease == keyPress.time) + { + keyHistory.timeOfKeyRelease = keyHistory.timeOfFirstKeyPress; + keyHistory.timeOfLastKeyPress = keyPress.time; + //std::cout<<"key repeated "<(keyPress.time - keyHistory.timeOfFirstKeyPress).count()<<"ms"<(keyPress.time - keyHistory.timeOfFirstKeyPress).count()<<"ms"<(keyPress.time - keyHistory.timeOfFirstKeyPress).count()<<"ms"<second; + keyHistory.handled = keyRelease.handled; + keyHistory.timeOfKeyRelease = keyRelease.time; + //std::cout<<"key provisionally released "<(keyRelease.time - keyHistory.timeOfFirstKeyPress).count()<<"ms"<second; + if (keyHistory.timeOfKeyRelease != keyHistory.timeOfFirstKeyPress) + { + return false; + } + + if (ignore_handled_keys && keyHistory.handled) return false; + + return true; +} + +std::pair Keyboard::times(KeySymbol key, bool ignore_handled_keys) +{ + auto itr = keyState.find(key); + if (itr == keyState.end()) return {-1.0, -1.0}; + + auto currentTime = clock::now(); + + auto& keyHistory = itr->second; + if (keyHistory.timeOfKeyRelease != keyHistory.timeOfFirstKeyPress) + { + return {std::chrono::duration(currentTime - keyHistory.timeOfFirstKeyPress).count(), + std::chrono::duration(currentTime - keyHistory.timeOfLastKeyPress).count()}; + } + + if (ignore_handled_keys && keyHistory.handled) return {-1.0, -1.0}; + + return {std::chrono::duration(currentTime - keyHistory.timeOfFirstKeyPress).count(), 0.0}; +} diff --git a/src/vsg/vk/RenderPass.cpp b/src/vsg/vk/RenderPass.cpp index b6a2b81a8..8d233d566 100644 --- a/src/vsg/vk/RenderPass.cpp +++ b/src/vsg/vk/RenderPass.cpp @@ -12,8 +12,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include -#include #include +#include #include #include