From 2f2b04e36139f8f1089f604c3d9b05f571a3154f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 5 May 2023 11:37:22 +0100 Subject: [PATCH 01/35] Initial support for movement controlled by keys --- src/vsg/app/Trackball.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index 5b185b4f1d..07b153e97d 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -137,6 +137,42 @@ void Trackball::apply(KeyPressEvent& keyPress) keyPress.handled = true; } + else + { + vsg::dvec2 delta(0.0, 0.0); + if (keyPress.keyBase == KEY_Left) delta.x = -1.0; + else if (keyPress.keyBase == KEY_Right) delta.x = 1.0; + else if (keyPress.keyBase == KEY_Up) delta.y = 1.0; + else if (keyPress.keyBase == KEY_Down) delta.y = -1.0; + + if (delta.x != 0.0 || delta.y != 0.0) + { + double scale = 0.05; + if ((keyPress.keyModifier & MODKEY_Shift) != 0) scale *= 0.2; + + if ((keyPress.keyModifier & MODKEY_Alt) != 0) + { + dvec3 lookVector = _lookAt->center - _lookAt->eye; + dmat4 matrix = vsg::translate(lookVector * (scale * delta.y * 0.1)); + + info("need to implement left/right and move forward/right = ", matrix); + + _lookAt->up = normalize(matrix * (_lookAt->eye + _lookAt->up) - matrix * _lookAt->eye); + _lookAt->center = matrix * _lookAt->center; + _lookAt->eye = matrix * _lookAt->eye; + + clampToGlobe(); + } + else if ((keyPress.keyModifier & MODKEY_Control) != 0) + { + info("need to implement rotate"); + } + else + { + pan( dvec2(-delta.x, delta.y) * scale); + } + } + } } void Trackball::apply(ButtonPressEvent& buttonPress) From 22f90878e1b55f8b6358c2cb5342867033680079 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 8 May 2023 09:45:03 +0100 Subject: [PATCH 02/35] Fixed cppecheck reported issue --- cmake/cppcheck-suppression-list.txt | 1 + src/vsg/io/Path.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/cppcheck-suppression-list.txt b/cmake/cppcheck-suppression-list.txt index 35fcbf828e..643fefb601 100644 --- a/cmake/cppcheck-suppression-list.txt +++ b/cmake/cppcheck-suppression-list.txt @@ -134,6 +134,7 @@ returnTempReference:*/include/vsg/core/Inherit.h // suppress inappropriate warning of variableScope variableScope:*/include/vsg/utils/SharedObjects.h variableScope:*/src/vsg/utils/SharedObjects.cpp +variableScope:*/src/vsg/app/CompileManager.cpp // suppress really stupid warning of pointerLessThanZero pointerLessThanZero:*/src/vsg/app/Viewer.cpp diff --git a/src/vsg/io/Path.cpp b/src/vsg/io/Path.cpp index 34327fb55e..6215dc271f 100644 --- a/src/vsg/io/Path.cpp +++ b/src/vsg/io/Path.cpp @@ -221,7 +221,7 @@ Path Path::lexically_normal() const prev_itr = itr; --prev_itr; } - else if (itr != path_segments.end()) + else { prev_itr = itr; ++itr; From bd2586d5448432994247a47ea104099482b2f37d Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Mon, 8 May 2023 11:22:04 +0200 Subject: [PATCH 03/35] Improve documentation of plane-matrix multiplication --- include/vsg/maths/mat4.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/vsg/maths/mat4.h b/include/vsg/maths/mat4.h index 0644b00675..200395acc5 100644 --- a/include/vsg/maths/mat4.h +++ b/include/vsg/maths/mat4.h @@ -198,8 +198,9 @@ namespace vsg lhs[0] * rhs[3][0] + lhs[1] * rhs[3][1] + lhs[2] * rhs[3][2] + lhs[3] * rhs[3][3]); } - /* Left multiplication of a plane and a matrix. This can be used directly to transform a plane - from a coordinate system's local coordinates to world coordinates. */ + /* Left multiplication of a plane and a matrix. If the matrix is the inverse of the + local-to-world transform i.e., the world-to-local transform, then this can be used directly + to transform a plane from a coordinate system's local coordinates to world coordinates. */ template t_plane operator*(const t_plane& lhs, const t_mat4& rhs) { From 9cb5372e23773884e7ced06b3bb0190b9e99dae6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 9 May 2023 14:45:26 +0100 Subject: [PATCH 04/35] Adopted std::map<> for speedig up deletion --- include/vsg/core/Allocator.h | 7 ++++- src/vsg/core/Allocator.cpp | 52 ++++++++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/include/vsg/core/Allocator.h b/include/vsg/core/Allocator.h index e502d1883d..639e632d27 100644 --- a/include/vsg/core/Allocator.h +++ b/include/vsg/core/Allocator.h @@ -93,13 +93,15 @@ namespace vsg Allocator* parent = nullptr; std::string name; size_t blockSize = 0; - std::list> memoryBlocks; + std::map> memoryBlocks; + MemoryBlock* latestMemoryBlock = nullptr; MemoryBlocks(Allocator* in_parent, const std::string& in_name, size_t in_blockSize); virtual ~MemoryBlocks(); void* allocate(std::size_t size); bool deallocate(void* ptr, std::size_t size); + size_t deleteEmptyMemoryBlocks(); size_t totalAvailableSize() const; size_t totalReservedSize() const; @@ -114,6 +116,9 @@ namespace vsg mutable std::mutex mutex; + double allocationTime = 0.0; + double deallocationTime = 0.0; + protected: // if you are assigning a custom allocator you must retain the old allocator to manage the memory it allocated and needs to delete std::unique_ptr nestedAllocator; diff --git a/src/vsg/core/Allocator.cpp b/src/vsg/core/Allocator.cpp index f30c623fd0..9b3a0a9dae 100644 --- a/src/vsg/core/Allocator.cpp +++ b/src/vsg/core/Allocator.cpp @@ -80,7 +80,7 @@ void Allocator::report(std::ostream& out) const if (memoryBlocks) { out << memoryBlocks->name << " " << memoryBlocks->memoryBlocks.size() << " blocks"; - for (const auto& memoryBlock : memoryBlocks->memoryBlocks) + for (const auto& [ptr, memoryBlock] : memoryBlocks->memoryBlocks) { const auto& memorySlots = memoryBlock->memorySlots; out << " [used = " << memorySlots.totalReservedSize() << ", avail = " << memorySlots.maximumAvailableSpace() << "]"; @@ -272,7 +272,7 @@ void Allocator::setMemoryTracking(int mt) { if (amb) { - for (auto& mb : amb->memoryBlocks) + for (auto& [ptr, mb] : amb->memoryBlocks) { mb->memorySlots.memoryTracking = mt; } @@ -371,20 +371,31 @@ Allocator::MemoryBlocks::~MemoryBlocks() void* Allocator::MemoryBlocks::allocate(std::size_t size) { + if (latestMemoryBlock) + { + auto ptr = latestMemoryBlock->allocate(size); + if (ptr) return ptr; + } + // search existing blocks from last to first for space for the required memory allocation. for (auto itr = memoryBlocks.rbegin(); itr != memoryBlocks.rend(); ++itr) { - auto& block = *itr; - auto ptr = block->allocate(size); - if (ptr) return ptr; + auto& block = itr->second; + if (block.get() != latestMemoryBlock) + { + auto ptr = block->allocate(size); + if (ptr) return ptr; + } } size_t new_blockSize = std::max(size, blockSize); std::unique_ptr block(new MemoryBlock(new_blockSize, parent->memoryTracking, parent->memoryBlocksAllocatorType)); + latestMemoryBlock = block.get(); + auto ptr = block->allocate(size); - memoryBlocks.push_back(std::move(block)); + memoryBlocks[block->memory] = std::move(block); if (parent->memoryTracking & MEMORY_TRACKING_REPORT_ACTIONS) { @@ -396,8 +407,26 @@ void* Allocator::MemoryBlocks::allocate(std::size_t size) bool Allocator::MemoryBlocks::deallocate(void* ptr, std::size_t size) { - for (auto& block : memoryBlocks) + if (memoryBlocks.empty()) return false; + + auto itr = memoryBlocks.upper_bound(ptr); + if (itr != memoryBlocks.end()) + { + if (itr != memoryBlocks.begin()) + { + --itr; + auto& block = itr->second; + if (block->deallocate(ptr, size)) return true; + } + else + { + auto& block = itr->second; + if (block->deallocate(ptr, size)) return true; + } + } + else { + auto& block = memoryBlocks.rbegin()->second; if (block->deallocate(ptr, size)) return true; } @@ -419,13 +448,14 @@ size_t Allocator::MemoryBlocks::deleteEmptyMemoryBlocks() auto itr = memoryBlocks.begin(); while (itr != memoryBlocks.end()) { - auto& block = *itr; + auto& block = itr->second; if (block->memorySlots.empty()) { if (parent->memoryTracking & MEMORY_TRACKING_REPORT_ACTIONS) { info(" MemoryBlocks:deleteEmptyMemoryBlocks() MemoryBlocks.name = ", name, ", removing MemoryBlock", block.get()); } + if (block.get() == latestMemoryBlock) latestMemoryBlock = nullptr; memoryDeleted += block->memorySlots.totalMemorySize(); itr = memoryBlocks.erase(itr); } @@ -440,7 +470,7 @@ size_t Allocator::MemoryBlocks::deleteEmptyMemoryBlocks() size_t Allocator::MemoryBlocks::totalAvailableSize() const { size_t size = 0; - for (auto& block : memoryBlocks) + for (auto& [ptr, block] : memoryBlocks) { size += block->memorySlots.totalAvailableSize(); } @@ -450,7 +480,7 @@ size_t Allocator::MemoryBlocks::totalAvailableSize() const size_t Allocator::MemoryBlocks::totalReservedSize() const { size_t size = 0; - for (auto& block : memoryBlocks) + for (auto& [ptr, block] : memoryBlocks) { size += block->memorySlots.totalReservedSize(); } @@ -460,7 +490,7 @@ size_t Allocator::MemoryBlocks::totalReservedSize() const size_t Allocator::MemoryBlocks::totalMemorySize() const { size_t size = 0; - for (auto& block : memoryBlocks) + for (auto& [ptr, block] : memoryBlocks) { size += block->memorySlots.totalMemorySize(); } From e7c7c82014bec13632949b2d3da2be24c98ab7ae Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 10 May 2023 10:53:11 +0100 Subject: [PATCH 05/35] Fixed cppcheck reported issue --- include/vsg/core/Allocator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/vsg/core/Allocator.h b/include/vsg/core/Allocator.h index 639e632d27..3768038387 100644 --- a/include/vsg/core/Allocator.h +++ b/include/vsg/core/Allocator.h @@ -140,7 +140,7 @@ namespace vsg allocator_affinity_nodes() = default; template - constexpr allocator_affinity_nodes(const allocator_affinity_nodes&) noexcept {} + explicit constexpr allocator_affinity_nodes(const allocator_affinity_nodes&) noexcept {} value_type* allocate(std::size_t n) { From 3bfc0c8f153b028a26a0debdc6e01ada2c6ab5ab Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 12 May 2023 08:05:00 +0100 Subject: [PATCH 06/35] Added setting of the overrideMask to make sure the UpdateGraphicsPipeline and WindowResizeHandler work on scene graphs with vsg::Switch nodes --- include/vsg/app/WindowResizeHandler.h | 3 +++ src/vsg/app/WindowResizeHandler.cpp | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/include/vsg/app/WindowResizeHandler.h b/include/vsg/app/WindowResizeHandler.h index 69db105ab6..cee73928c7 100644 --- a/include/vsg/app/WindowResizeHandler.h +++ b/include/vsg/app/WindowResizeHandler.h @@ -26,6 +26,9 @@ namespace vsg class VSG_DECLSPEC UpdateGraphicsPipelines : public vsg::Inherit { public: + + UpdateGraphicsPipelines(); + vsg::ref_ptr context; std::set> visited; diff --git a/src/vsg/app/WindowResizeHandler.cpp b/src/vsg/app/WindowResizeHandler.cpp index ee657fb520..9004ad959f 100644 --- a/src/vsg/app/WindowResizeHandler.cpp +++ b/src/vsg/app/WindowResizeHandler.cpp @@ -20,6 +20,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI using namespace vsg; +UpdateGraphicsPipelines::UpdateGraphicsPipelines() +{ + overrideMask = MASK_ALL; +} + bool UpdateGraphicsPipelines::visit(const Object* object, uint32_t index) { decltype(visited)::value_type objectIndex(object, index); @@ -74,6 +79,7 @@ void UpdateGraphicsPipelines::apply(vsg::View& view) // WindowResizeHandler::WindowResizeHandler() { + overrideMask = MASK_ALL; } void WindowResizeHandler::scale_rect(VkRect2D& rect) From e775af7f08a1890ef7b5ba402474dce687790835 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 12 May 2023 15:35:27 +0100 Subject: [PATCH 07/35] Added check to make sure context is only used if it matches the view being traversed --- src/vsg/app/CompileTraversal.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vsg/app/CompileTraversal.cpp b/src/vsg/app/CompileTraversal.cpp index de0636f199..6833803a12 100644 --- a/src/vsg/app/CompileTraversal.cpp +++ b/src/vsg/app/CompileTraversal.cpp @@ -308,6 +308,10 @@ void CompileTraversal::apply(View& view) { for (auto& context : contexts) { + // 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; + context->viewID = view.viewID; context->viewDependentState = view.viewDependentState.get(); if (view.viewDependentState) view.viewDependentState->compile(*context); From 6be18aa5abae62195f7d8522d743b3264a3c65c8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 12 May 2023 16:26:10 +0100 Subject: [PATCH 08/35] Implemented turn left/right. --- src/vsg/app/Trackball.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index 07b153e97d..4452a87856 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -153,9 +153,10 @@ void Trackball::apply(KeyPressEvent& keyPress) if ((keyPress.keyModifier & MODKEY_Alt) != 0) { dvec3 lookVector = _lookAt->center - _lookAt->eye; - dmat4 matrix = vsg::translate(lookVector * (scale * delta.y * 0.1)); - - info("need to implement left/right and move forward/right = ", matrix); + dmat4 matrix = vsg::translate(lookVector * (scale * delta.y * 0.1)) * + vsg::translate(_lookAt->eye) * + vsg::rotate(-delta.x * scale, _lookAt->up) * + vsg::translate(-_lookAt->eye); _lookAt->up = normalize(matrix * (_lookAt->eye + _lookAt->up) - matrix * _lookAt->eye); _lookAt->center = matrix * _lookAt->center; From e70e5574bd3fe5c70993596152f0637f23ed96ac Mon Sep 17 00:00:00 2001 From: siystar Date: Sat, 13 May 2023 08:02:53 +0200 Subject: [PATCH 09/35] [FIXED] vkCreateRenderPass2KHR support Fixed vsg::RenderPass to support VK_KHR_create_renderpass2 for Vulkan versions less than 1.2. Fixed Vulkan 1.2 check to include the physicalDevice's apiVersion. --- include/vsg/vk/Device.h | 5 +++++ include/vsg/vk/PhysicalDevice.h | 3 +++ src/vsg/vk/Device.cpp | 17 +++++++++-------- src/vsg/vk/Extensions.cpp | 5 ++++- src/vsg/vk/PhysicalDevice.cpp | 11 +++++++++++ src/vsg/vk/RenderPass.cpp | 11 ++++++----- 6 files changed, 38 insertions(+), 14 deletions(-) diff --git a/include/vsg/vk/Device.h b/include/vsg/vk/Device.h index d2d9464fdd..16064bdc02 100644 --- a/include/vsg/vk/Device.h +++ b/include/vsg/vk/Device.h @@ -58,6 +58,8 @@ namespace vsg const Extensions* getExtensions() const { return _extensions.get(); } /// get the address of specified function using vkGetDeviceProcAddr + /// for core commands beyond the apiVersion specified in vsg::Instance creation, vkGetDeviceProcAddr may return a non-nullptr function pointer, though the function pointer must not be called. + /// for extension commands, vkGetDeviceProcAddr will always return nullptr if the extension is not enabled in vsg::Device creation. template bool getProcAddr(T& procAddress, const char* pName, const char* pNameFallback = nullptr) const { @@ -68,6 +70,9 @@ namespace vsg return (procAddress); } + /// device-level core functionality can be used if both VkInstance and VkPhysicalDevice support the Vulkan version that provides it. + bool supportsApiVersion(uint32_t version) const; + protected: virtual ~Device(); diff --git a/include/vsg/vk/PhysicalDevice.h b/include/vsg/vk/PhysicalDevice.h index 91af8d6ab1..1dbef8b055 100644 --- a/include/vsg/vk/PhysicalDevice.h +++ b/include/vsg/vk/PhysicalDevice.h @@ -75,6 +75,9 @@ namespace vsg /// Call vkEnumerateDeviceExtensionProperties to enumerate extension properties. std::vector enumerateDeviceExtensionProperties(const char* pLayerName = nullptr); + /// return true if the extension is supported by physicalDevice + bool supportsDeviceExtension(const char* extensionName); + protected: // use Instance::getDevice(..) to create PhysicalDevice PhysicalDevice(Instance* instance, VkPhysicalDevice device); diff --git a/src/vsg/vk/Device.cpp b/src/vsg/vk/Device.cpp index a152930f01..38621afac7 100644 --- a/src/vsg/vk/Device.cpp +++ b/src/vsg/vk/Device.cpp @@ -18,6 +18,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include +#include +#include #include using namespace vsg; @@ -110,14 +112,8 @@ Device::Device(PhysicalDevice* physicalDevice, const QueueSettings& queueSetting #if defined(__APPLE__) // MacOS requires "VK_KHR_portability_subset" to be a requested extension if the PhysicalDevice supported it. - auto extensionProperties = _physicalDevice->enumerateDeviceExtensionProperties(); - for (auto& extensionProperty : extensionProperties) - { - if (std::strncmp(extensionProperty.extensionName, VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME, VK_MAX_EXTENSION_NAME_SIZE) == 0) - { - deviceExtensions.push_back(extensionProperty.extensionName); - } - } + if (_physicalDevice->supportsDeviceExtension(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) + deviceExtensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); #endif VkDeviceCreateInfo createInfo = {}; @@ -192,3 +188,8 @@ ref_ptr Device::getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex) return {}; } + +bool Device::supportsApiVersion(uint32_t version) const +{ + return getInstance()->apiVersion >= version && _physicalDevice->getProperties().apiVersion >= version; +} diff --git a/src/vsg/vk/Extensions.cpp b/src/vsg/vk/Extensions.cpp index 3ab7ea2893..de9cf88ffa 100644 --- a/src/vsg/vk/Extensions.cpp +++ b/src/vsg/vk/Extensions.cpp @@ -47,7 +47,10 @@ Extensions::Extensions(Device* device) device->getProcAddr(vkResetQueryPool, "vkResetQueryPool", "vkResetQueryPoolEXT"); // VK_KHR_create_renderpass2 - device->getProcAddr(vkCreateRenderPass2, "vkCreateRenderPass2", "vkCreateRenderPass2KHR"); + if (device->supportsApiVersion(VK_API_VERSION_1_2)) + device->getProcAddr(vkCreateRenderPass2, "vkCreateRenderPass2"); + else if (device->getPhysicalDevice()->supportsDeviceExtension(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) + device->getProcAddr(vkCreateRenderPass2, "vkCreateRenderPass2KHR"); // VK_KHR_ray_tracing device->getProcAddr(vkCreateAccelerationStructureKHR, "vkCreateAccelerationStructureKHR"); diff --git a/src/vsg/vk/PhysicalDevice.cpp b/src/vsg/vk/PhysicalDevice.cpp index 24a32b11ce..6e9b604f2b 100644 --- a/src/vsg/vk/PhysicalDevice.cpp +++ b/src/vsg/vk/PhysicalDevice.cpp @@ -103,3 +103,14 @@ std::vector PhysicalDevice::enumerateDeviceExtensionPrope vkEnumerateDeviceExtensionProperties(_device, pLayerName, &propertyCount, extensionProperties.data()); return extensionProperties; } + +bool PhysicalDevice::supportsDeviceExtension(const char* extensionName) +{ + auto extensionProperties = enumerateDeviceExtensionProperties(); + for (auto& extensionProperty : extensionProperties) + { + if (std::strncmp(extensionProperty.extensionName, extensionName, VK_MAX_EXTENSION_NAME_SIZE) == 0) + return true; + } + return false; +} diff --git a/src/vsg/vk/RenderPass.cpp b/src/vsg/vk/RenderPass.cpp index 463e9bbe4d..d0fa662026 100644 --- a/src/vsg/vk/RenderPass.cpp +++ b/src/vsg/vk/RenderPass.cpp @@ -13,6 +13,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include #include #include @@ -39,13 +40,11 @@ RenderPass::RenderPass(Device* in_device, const Attachments& in_attachments, con maxSamples(computeMaxSamples(in_attachments)) { auto scratchMemory = ScratchMemory::create(1024); - - // vkCreateRenderPass2 is only supported in Vulkan 1.2 and later. - bool useRenderPass2 = device->getInstance()->apiVersion >= VK_API_VERSION_1_2; + // vkCreateRenderPass2 is supported with the VK_KHR_create_renderpass2 device extension, or in Vulkan core 1.2 and later auto extensions = device->getExtensions(); - if (useRenderPass2 && extensions->vkCreateRenderPass2) + if (extensions->vkCreateRenderPass2) { - // Vulkan 1.2 vkCreateRenderPass2 code path + // vkCreateRenderPass2 code path auto copyAttachmentDescriptions = [&scratchMemory](const Attachments& attachmentDescriptions) -> VkAttachmentDescription2* { if (attachmentDescriptions.empty()) return nullptr; @@ -211,6 +210,8 @@ RenderPass::RenderPass(Device* in_device, const Attachments& in_attachments, con for (size_t i = 0; i < subpassDescriptions.size(); ++i) { auto& src = subpassDescriptions[i]; + if (!src.depthStencilResolveAttachments.empty()) + vsg::warn("vsg::RenderPass::create(...): Subpass includes depthStencilResolveAttachments but vkCreateRenderPass2 is not enabled. Set WindowTraits::vulkanVersion to at least VK_API_VERSION_1_2 or add VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME to WindowTraits::deviceExtensionNames."); auto& dst = vk_subpassDescription[i]; dst.flags = src.flags; dst.pipelineBindPoint = src.pipelineBindPoint; From 8b139067d33ca61dc0f5523cdebf8b3ab8745a3c Mon Sep 17 00:00:00 2001 From: siystar Date: Sat, 13 May 2023 08:02:59 +0200 Subject: [PATCH 10/35] [ADDED] renderPass to RenderGraph Added renderPass member to RenderGraph to support different renderPasses operating on the same framebuffer or window. --- include/vsg/app/RenderGraph.h | 5 ++++- src/vsg/app/RenderGraph.cpp | 26 ++++++++++++++++---------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/include/vsg/app/RenderGraph.h b/include/vsg/app/RenderGraph.h index 3820d1bd4c..8e32436e7f 100644 --- a/include/vsg/app/RenderGraph.h +++ b/include/vsg/app/RenderGraph.h @@ -41,7 +41,7 @@ namespace vsg ref_ptr framebuffer; ref_ptr window; - /// RenderPass to use passed to the vkCmdBeginRenderPass, either obtained from which of the framebuffer or window are active + /// RenderPass to use passed to the vkCmdBeginRenderPass, if renderPass is set it takes precedence, if not then either obtained from which of the framebuffer or window are active RenderPass* getRenderPass(); /// Get the Exten2D of the attached Framebuffer or Window. @@ -50,6 +50,9 @@ namespace vsg /// ReandingArea settings for VkRenderPassBeginInfo.renderArea passed to the vkCmdBeginRenderPass, usually maps the ViewportState's scissor VkRect2D renderArea; + /// RenderPass to use passed to the vkCmdBeginRenderPass in place of the framebuffer's or window's renderPass. renderPass must be compatible with the render pass used to create the window or framebuffer. + ref_ptr renderPass; + /// Buffer clearing settings for vkRrenderPassInfo.clearValueCount & vkRenderPassInfo.pClearValues passed to the vkCmdBeginRenderPass using ClearValues = std::vector; ClearValues clearValues; // initialize window colour and depth/stencil diff --git a/src/vsg/app/RenderGraph.cpp b/src/vsg/app/RenderGraph.cpp index 0d94d59610..b7ab4bdc3d 100644 --- a/src/vsg/app/RenderGraph.cpp +++ b/src/vsg/app/RenderGraph.cpp @@ -54,7 +54,11 @@ RenderGraph::RenderGraph(ref_ptr in_window, ref_ptr in_view) : RenderPass* RenderGraph::getRenderPass() { - if (framebuffer) + if (renderPass) + { + return renderPass; + } + else if (framebuffer) { return framebuffer->getRenderPass(); } @@ -67,10 +71,10 @@ RenderPass* RenderGraph::getRenderPass() void RenderGraph::setClearValues(VkClearColorValue clearColor, VkClearDepthStencilValue clearDepthStencil) { - auto renderPass = getRenderPass(); - if (!renderPass) return; + auto activeRenderPass = getRenderPass(); + if (!activeRenderPass) return; - auto& attachments = renderPass->attachments; + auto& attachments = activeRenderPass->attachments; clearValues.resize(attachments.size()); for (size_t i = 0; i < attachments.size(); ++i) { @@ -124,6 +128,8 @@ void RenderGraph::accept(RecordTraversal& recordTraversal) const renderPassInfo.renderPass = *(window->getRenderPass()); renderPassInfo.framebuffer = *(window->framebuffer(imageIndex)); } + if (renderPass) + renderPassInfo.renderPass = *(renderPass); renderPassInfo.renderArea = renderArea; @@ -149,25 +155,25 @@ void RenderGraph::resized() if (!windowResizeHandler) return; if (!window && !framebuffer) return; - auto renderPass = getRenderPass(); - if (!renderPass) return; + auto activeRenderPass = getRenderPass(); + if (!activeRenderPass) return; - auto device = renderPass->device; + auto device = activeRenderPass->device; if (!windowResizeHandler->context) windowResizeHandler->context = vsg::Context::create(device); auto extent = getExtent(); windowResizeHandler->context->commandPool = nullptr; - windowResizeHandler->context->renderPass = renderPass; + windowResizeHandler->context->renderPass = activeRenderPass; windowResizeHandler->renderArea = renderArea; windowResizeHandler->previous_extent = previous_extent; windowResizeHandler->new_extent = extent; windowResizeHandler->visited.clear(); - if (renderPass->maxSamples != VK_SAMPLE_COUNT_1_BIT) + if (activeRenderPass->maxSamples != VK_SAMPLE_COUNT_1_BIT) { - windowResizeHandler->context->overridePipelineStates.emplace_back(vsg::MultisampleState::create(renderPass->maxSamples)); + windowResizeHandler->context->overridePipelineStates.emplace_back(vsg::MultisampleState::create(activeRenderPass->maxSamples)); } // make sure the device is idle before we recreate any Vulkan objects From eeee9a4aec4d96d54dd356c020bdcd8368e0b8a2 Mon Sep 17 00:00:00 2001 From: siystar Date: Sat, 13 May 2023 08:03:05 +0200 Subject: [PATCH 11/35] [FIXED] depthResolveAttachment to use LOAD_OP_DONT_CARE --- src/vsg/vk/RenderPass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vsg/vk/RenderPass.cpp b/src/vsg/vk/RenderPass.cpp index 463e9bbe4d..963228792e 100644 --- a/src/vsg/vk/RenderPass.cpp +++ b/src/vsg/vk/RenderPass.cpp @@ -400,7 +400,7 @@ ref_ptr vsg::createMultisampledRenderPass(Device* device, VkFormat i AttachmentDescription depthResolveAttachment = {}; depthResolveAttachment.format = depthFormat; depthResolveAttachment.samples = VK_SAMPLE_COUNT_1_BIT; - depthResolveAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + depthResolveAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; depthResolveAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; depthResolveAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; depthResolveAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; From 149ea0f5c78615b2d3c4afadbfde09093ed9ad32 Mon Sep 17 00:00:00 2001 From: siystar Date: Sat, 13 May 2023 08:03:11 +0200 Subject: [PATCH 12/35] [FIXED] -Wunused-but-set-variable warnings --- src/vsg/app/Viewer.cpp | 6 +----- src/vsg/io/DatabasePager.cpp | 2 -- src/vsg/state/BufferInfo.cpp | 10 ---------- 3 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/vsg/app/Viewer.cpp b/src/vsg/app/Viewer.cpp index 6a2596773b..0ac06eadf3 100644 --- a/src/vsg/app/Viewer.cpp +++ b/src/vsg/app/Viewer.cpp @@ -465,17 +465,13 @@ void Viewer::setupThreading() stopThreading(); - // check how valid tasks and command graphs there are. + // check how many valid tasks there are. uint32_t numValidTasks = 0; - size_t numCommandGraphs = 0; - size_t numEarlyTransferTasks = 0; for (auto& task : recordAndSubmitTasks) { if (!task->commandGraphs.empty()) { ++numValidTasks; - numCommandGraphs += task->commandGraphs.size(); - if (task->earlyTransferTask) ++numEarlyTransferTasks; } } diff --git a/src/vsg/io/DatabasePager.cpp b/src/vsg/io/DatabasePager.cpp index 8090eb0367..41b55ea10a 100644 --- a/src/vsg/io/DatabasePager.cpp +++ b/src/vsg/io/DatabasePager.cpp @@ -251,7 +251,6 @@ void DatabasePager::updateSceneGraph(FrameStamp* frameStamp, CompileResult& cr) } auto& activeList = pagedLODContainer->activeList; - uint32_t switchedCount = 0; for (uint32_t index = activeList.head; index != 0;) { auto& element = elements[index]; @@ -260,7 +259,6 @@ void DatabasePager::updateSceneGraph(FrameStamp* frameStamp, CompileResult& cr) if (!element.plod->highResActive(frameCount)) { // debug(" active to inactive ", index); - ++switchedCount; pagedLODContainer->inactive(element.plod.get()); } } diff --git a/src/vsg/state/BufferInfo.cpp b/src/vsg/state/BufferInfo.cpp index cbd9e016f6..b0d2309132 100644 --- a/src/vsg/state/BufferInfo.cpp +++ b/src/vsg/state/BufferInfo.cpp @@ -163,9 +163,7 @@ bool vsg::createBufferAndTransferData(Context& context, const BufferInfoList& bu auto deviceID = context.deviceID; ref_ptr deviceBufferInfo; - size_t numBuffersAssigned = 0; size_t numBuffersRequired = 0; - size_t numNoData = 0; bool containsMultipleParents = false; for (auto& bufferInfo : bufferInfoList) { @@ -175,14 +173,6 @@ bool vsg::createBufferAndTransferData(Context& context, const BufferInfoList& bu { ++numBuffersRequired; } - else - { - ++numBuffersAssigned; - } - } - else - { - ++numNoData; } if (bufferInfo->parent) From 4cc75f362cbdb8b6dd088bea7249cbdc29525da3 Mon Sep 17 00:00:00 2001 From: siystar Date: Sat, 13 May 2023 09:56:48 +0200 Subject: [PATCH 13/35] [FIXED] accidentally added includes --- src/vsg/vk/Device.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vsg/vk/Device.cpp b/src/vsg/vk/Device.cpp index 38621afac7..373cdc6a52 100644 --- a/src/vsg/vk/Device.cpp +++ b/src/vsg/vk/Device.cpp @@ -18,8 +18,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include -#include -#include #include using namespace vsg; From a043ecc4fb43f11031e92de0d7c811c29308fc50 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 13 May 2023 13:03:30 +0100 Subject: [PATCH 14/35] Experiment with tracking holding keyboard keys --- include/vsg/app/Trackball.h | 9 +++++ src/vsg/app/Trackball.cpp | 55 +++++++++++++++++++++++++++++ src/vsg/platform/xcb/Xcb_Window.cpp | 4 +-- 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/include/vsg/app/Trackball.h b/include/vsg/app/Trackball.h index d17842f975..dc49a58096 100644 --- a/include/vsg/app/Trackball.h +++ b/include/vsg/app/Trackball.h @@ -37,6 +37,7 @@ namespace vsg dvec3 tbc(PointerEvent& event); void apply(KeyPressEvent& keyPress) override; + void apply(KeyReleaseEvent& keyRelease) override; void apply(ButtonPressEvent& buttonPress) override; void apply(ButtonReleaseEvent& buttonRelease) override; void apply(MoveEvent& moveEvent) override; @@ -99,6 +100,14 @@ namespace vsg /// Toggle on/off whether the view should continue moving when the mouse buttons are released while the mouse is in motion. bool supportsThrow = true; + struct KeyHistory + { + vsg::time_point timeOfKeyPress = {}; + vsg::time_point timeOfKeyRelease = {}; + }; + + std::map keyState; + protected: ref_ptr _camera; ref_ptr _lookAt; diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index 4452a87856..8ba2280e93 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -125,10 +125,36 @@ dvec3 Trackball::tbc(PointerEvent& event) } } +#include + void Trackball::apply(KeyPressEvent& keyPress) { if (keyPress.handled || !eventRelevant(keyPress) || !_lastPointerEventWithinRenderArea) return; + auto keyState_itr = keyState.find(keyPress.keyBase); + if (keyState_itr != keyState.end()) + { + auto& keyHistory = keyState_itr->second; + if (keyHistory.timeOfKeyRelease == keyPress.time) + { + keyHistory.timeOfKeyRelease = keyHistory.timeOfKeyPress; + std::cout<<"key repeated "<(keyPress.time - keyHistory.timeOfKeyPress).count()<<"ms"<(keyPress.time - keyHistory.timeOfKeyPress).count()<<"ms"<(keyPress.time - keyHistory.timeOfKeyPress).count()<<"ms"<second; + keyHistory.timeOfKeyRelease = keyRelease.time; + std::cout<<"key provisionally released "<(keyRelease.time - keyHistory.timeOfKeyPress).count()<<"ms"<second; + if (keyHistory.timeOfKeyRelease != keyHistory.timeOfKeyPress) + { + std::cout<<"Trackball::apply(FrameEvent&) key = "<first<<" released "<(frame.time - _startTime).count(); diff --git a/src/vsg/platform/xcb/Xcb_Window.cpp b/src/vsg/platform/xcb/Xcb_Window.cpp index 494240c691..48e2568d4f 100644 --- a/src/vsg/platform/xcb/Xcb_Window.cpp +++ b/src/vsg/platform/xcb/Xcb_Window.cpp @@ -611,11 +611,11 @@ bool Xcb_Window::pollEvents(UIEvents& events) break; } case (XCB_FOCUS_IN): { - //debug("xcb_focus_in_event_t"); + info("xcb_focus_in_event_t"); break; } case (XCB_FOCUS_OUT): { - //debug("xcb_focus_out_event_t"); + info("xcb_focus_out_event_t"); break; } case (XCB_ENTER_NOTIFY): { From 3a85183a618525b6b0e44389fba18d8e6263a326 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 13 May 2023 13:11:35 +0100 Subject: [PATCH 15/35] Refacrtord to avoid access of resources that are unneccessary. --- src/vsg/app/CompileTraversal.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vsg/app/CompileTraversal.cpp b/src/vsg/app/CompileTraversal.cpp index 6833803a12..717255aec3 100644 --- a/src/vsg/app/CompileTraversal.cpp +++ b/src/vsg/app/CompileTraversal.cpp @@ -233,7 +233,7 @@ void CompileTraversal::apply(Geometry& geometry) void CompileTraversal::apply(CommandGraph& commandGraph) { auto traverseRenderedSubgraph = [&](vsg::RenderPass* renderpass, VkExtent2D renderArea) { - uint32_t samples = renderpass->maxSamples; + auto samples = renderpass->maxSamples; for (auto& context : contexts) { @@ -247,7 +247,7 @@ void CompileTraversal::apply(CommandGraph& commandGraph) if (samples != VK_SAMPLE_COUNT_1_BIT) { - mergeGraphicsPipelineStates(context->overridePipelineStates, MultisampleState::create(commandGraph.window->framebufferSamples())); + mergeGraphicsPipelineStates(context->overridePipelineStates, MultisampleState::create(samples)); } commandGraph.traverse(*this); From 634a10cdba8478e64383858f702054952b890196 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 14 May 2023 15:51:37 +0100 Subject: [PATCH 16/35] Moved the renderPassInfo.renderPass assignment to avoid setting it multiple times. --- src/vsg/app/RenderGraph.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vsg/app/RenderGraph.cpp b/src/vsg/app/RenderGraph.cpp index b7ab4bdc3d..59b24902f2 100644 --- a/src/vsg/app/RenderGraph.cpp +++ b/src/vsg/app/RenderGraph.cpp @@ -117,7 +117,7 @@ void RenderGraph::accept(RecordTraversal& recordTraversal) const if (framebuffer) { - renderPassInfo.renderPass = *(framebuffer->getRenderPass()); + renderPassInfo.renderPass = renderPass ? *(renderPass) : *(framebuffer->getRenderPass()); renderPassInfo.framebuffer = *(framebuffer); } else @@ -125,11 +125,9 @@ void RenderGraph::accept(RecordTraversal& recordTraversal) const size_t imageIndex = window->imageIndex(); if (imageIndex >= window->numFrames()) return; - renderPassInfo.renderPass = *(window->getRenderPass()); + renderPassInfo.renderPass = renderPass ? *(renderPass) : *(window->getRenderPass()); renderPassInfo.framebuffer = *(window->framebuffer(imageIndex)); } - if (renderPass) - renderPassInfo.renderPass = *(renderPass); renderPassInfo.renderArea = renderArea; From 06d78b5ebfb88d85b55ca2a015ca916434f80604 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 14 May 2023 19:27:11 +0100 Subject: [PATCH 17/35] Added experimental update of camera position using key controls. --- include/vsg/app/Trackball.h | 3 +- src/vsg/app/Trackball.cpp | 80 ++++++++++++++++++++++++++++++++----- 2 files changed, 72 insertions(+), 11 deletions(-) diff --git a/include/vsg/app/Trackball.h b/include/vsg/app/Trackball.h index dc49a58096..ca21d8c912 100644 --- a/include/vsg/app/Trackball.h +++ b/include/vsg/app/Trackball.h @@ -102,7 +102,8 @@ namespace vsg struct KeyHistory { - vsg::time_point timeOfKeyPress = {}; + vsg::time_point timeOfFirstKeyPress = {}; + vsg::time_point timeOfLastKeyPress = {}; vsg::time_point timeOfKeyRelease = {}; }; diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index 8ba2280e93..d51df98171 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -137,22 +137,25 @@ void Trackball::apply(KeyPressEvent& keyPress) auto& keyHistory = keyState_itr->second; if (keyHistory.timeOfKeyRelease == keyPress.time) { - keyHistory.timeOfKeyRelease = keyHistory.timeOfKeyPress; - std::cout<<"key repeated "<(keyPress.time - keyHistory.timeOfKeyPress).count()<<"ms"<(keyPress.time - keyHistory.timeOfFirstKeyPress).count()<<"ms"<(keyPress.time - keyHistory.timeOfKeyPress).count()<<"ms"<(keyPress.time - keyHistory.timeOfFirstKeyPress).count()<<"ms"<(keyPress.time - keyHistory.timeOfKeyPress).count()<<"ms"<(keyPress.time - keyHistory.timeOfFirstKeyPress).count()<<"ms"<second; keyHistory.timeOfKeyRelease = keyRelease.time; - std::cout<<"key provisionally released "<(keyRelease.time - keyHistory.timeOfKeyPress).count()<<"ms"<(keyRelease.time - keyHistory.timeOfFirstKeyPress).count()<<"ms"<(frame.time - keyHistory.timeOfLastKeyPress).count(); + if (timeSinceLastRepeat > 1.0) + { + //std::cout<<" Trackball::apply(FrameEvent&) key = "<first<<" time out!!!!! timeSinceLastRepeat = "<(frame.time - keyHistory.timeOfFirstKeyPress).count(); + // std::cout<<" Trackball::apply(FrameEvent&) key = "<first<<" held down "<first; + + vsg::dvec2 delta(0.0, 0.0); + if (key == KEY_Left) delta.x = -1.0; + else if (key == KEY_Right) delta.x = 1.0; + else if (key == KEY_Up) delta.y = 1.0; + else if (key == KEY_Down) delta.y = -1.0; + + double scale = std::chrono::duration(frame.time - _previousTime).count(); + if (delta.x != 0.0 || delta.y != 0.0) + { + pan( dvec2(-delta.x, delta.y) * scale); + } + + delta.set(0.0, 0.0); + if (key == 'w') delta.y = 1.0; + else if (key == 's') delta.y = -1.0; + else if (key == 'a') delta.x = -1.0; + else if (key == 'd') delta.x = 1.0; + + if (delta.x != 0.0 || delta.y != 0.0) + { + dvec3 lookVector = _lookAt->center - _lookAt->eye; + dmat4 matrix = vsg::translate(lookVector * (scale * delta.y * 0.2)) * + vsg::translate(_lookAt->eye) * + vsg::rotate(-delta.x * scale * 0.25, _lookAt->up) * + 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(); + } + ++itr; } } From eecadeed8650a9b4519b15c0ef850597c76a37c9 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 15 May 2023 10:48:54 +0100 Subject: [PATCH 18/35] Moved keyboard state tracking into decidated Keyboard class --- include/vsg/app/Trackball.h | 35 ++++-- src/vsg/app/Trackball.cpp | 244 ++++++++++++++++-------------------- 2 files changed, 133 insertions(+), 146 deletions(-) diff --git a/include/vsg/app/Trackball.h b/include/vsg/app/Trackball.h index ca21d8c912..08c6bd2cd5 100644 --- a/include/vsg/app/Trackball.h +++ b/include/vsg/app/Trackball.h @@ -24,6 +24,30 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI 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; + + struct KeyHistory + { + vsg::time_point timeOfFirstKeyPress = {}; + vsg::time_point timeOfLastKeyPress = {}; + vsg::time_point timeOfKeyRelease = {}; + }; + + std::map keyState; + + /// return true if key is currently pressed + bool pressed(KeySymbol key); + + /// return the length of time key has been pressed, return -1.0 for key is not currently pressed + double time_pressed(KeySymbol key); + }; + /// Trackball is an event handler that provides mouse and touch controlled 3d trackball camera view manipulation. class VSG_DECLSPEC Trackball : public Inherit { @@ -100,15 +124,6 @@ namespace vsg /// Toggle on/off whether the view should continue moving when the mouse buttons are released while the mouse is in motion. bool supportsThrow = true; - struct KeyHistory - { - vsg::time_point timeOfFirstKeyPress = {}; - vsg::time_point timeOfLastKeyPress = {}; - vsg::time_point timeOfKeyRelease = {}; - }; - - std::map keyState; - protected: ref_ptr _camera; ref_ptr _lookAt; @@ -141,6 +156,8 @@ namespace vsg ref_ptr _endLookAt; std::map> _previousTouches; + ref_ptr _keyboard; + double _animationDuration = 0.0; }; VSG_type_name(vsg::Trackball); diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index d51df98171..841e40583b 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -15,13 +15,90 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include +#include using namespace vsg; +void Keyboard::apply(KeyPressEvent& keyPress) +{ + //std::cout<<"Keyboard::apply(KeyReleaseEvent& keyRelease)"<second; + 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.timeOfKeyRelease = keyRelease.time; + //std::cout<<"key provisionally released "<(keyRelease.time - keyHistory.timeOfFirstKeyPress).count()<<"ms"<second; + if (keyHistory.timeOfKeyRelease != keyHistory.timeOfFirstKeyPress) + { + keyState.erase(itr); + return false; + } + + return true; +} + +double Keyboard::time_pressed(KeySymbol key) +{ + auto itr = keyState.find(key); + if (itr == keyState.end()) return -1.0; + + auto& keyHistory = itr->second; + if (keyHistory.timeOfKeyRelease != keyHistory.timeOfFirstKeyPress) + { + keyState.erase(itr); + return -1.0; + } + + return std::chrono::duration(clock::now() - keyHistory.timeOfFirstKeyPress).count(); +} + Trackball::Trackball(ref_ptr camera, ref_ptr ellipsoidModel) : _camera(camera), _lookAt(camera->viewMatrix.cast()), - _ellipsoidModel(ellipsoidModel) + _ellipsoidModel(ellipsoidModel), + _keyboard(Keyboard::create()) { if (!_lookAt) { @@ -125,38 +202,11 @@ dvec3 Trackball::tbc(PointerEvent& event) } } -#include - void Trackball::apply(KeyPressEvent& keyPress) { - if (keyPress.handled || !eventRelevant(keyPress) || !_lastPointerEventWithinRenderArea) return; + if (_keyboard) keyPress.accept(*_keyboard); - auto keyState_itr = keyState.find(keyPress.keyBase); - if (keyState_itr != keyState.end()) - { - auto& keyHistory = keyState_itr->second; - 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"<center - _lookAt->eye; - dmat4 matrix = vsg::translate(lookVector * (scale * delta.y * 0.1)) * - vsg::translate(_lookAt->eye) * - vsg::rotate(-delta.x * scale, _lookAt->up) * - 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(); - } - else if ((keyPress.keyModifier & MODKEY_Control) != 0) - { - info("need to implement rotate"); - } - else - { - pan( dvec2(-delta.x, delta.y) * scale); - } - } - } -#endif } void Trackball::apply(KeyReleaseEvent& keyRelease) { - if (keyRelease.handled || !eventRelevant(keyRelease) || !_lastPointerEventWithinRenderArea) return; - - auto keyState_itr = keyState.find(keyRelease.keyBase); - if (keyState_itr != keyState.end()) - { - auto& keyHistory = keyState_itr->second; - keyHistory.timeOfKeyRelease = keyRelease.time; - // std::cout<<"key provisionally released "<(keyRelease.time - keyHistory.timeOfFirstKeyPress).count()<<"ms"<(frame.time - keyHistory.timeOfFirstKeyPress).count(); - // std::cout<<" Trackball::apply(FrameEvent&) key = "<first<<" held down "<first; - vsg::dvec2 delta(0.0, 0.0); - if (key == KEY_Left) delta.x = -1.0; - else if (key == KEY_Right) delta.x = 1.0; - else if (key == KEY_Up) delta.y = 1.0; - else if (key == KEY_Down) delta.y = -1.0; - - double scale = std::chrono::duration(frame.time - _previousTime).count(); - if (delta.x != 0.0 || delta.y != 0.0) - { - pan( dvec2(-delta.x, delta.y) * scale); - } - - delta.set(0.0, 0.0); - if (key == 'w') delta.y = 1.0; - else if (key == 's') delta.y = -1.0; - else if (key == 'a') delta.x = -1.0; - else if (key == 'd') delta.x = 1.0; - - if (delta.x != 0.0 || delta.y != 0.0) - { - dvec3 lookVector = _lookAt->center - _lookAt->eye; - dmat4 matrix = vsg::translate(lookVector * (scale * delta.y * 0.2)) * - vsg::translate(_lookAt->eye) * - vsg::rotate(-delta.x * scale * 0.25, _lookAt->up) * - vsg::translate(-_lookAt->eye); + delta.set(0.0, 0.0); + if (_keyboard->pressed(KEY_w)) delta.y = 1.0; + if (_keyboard->pressed(KEY_s)) delta.y = -1.0; + if (_keyboard->pressed(KEY_a)) delta.x = -1.0; + if (_keyboard->pressed(KEY_d)) delta.x = 1.0; - _lookAt->up = normalize(matrix * (_lookAt->eye + _lookAt->up) - matrix * _lookAt->eye); - _lookAt->center = matrix * _lookAt->center; - _lookAt->eye = matrix * _lookAt->eye; + if (delta.x != 0.0 || delta.y != 0.0) + { + dvec3 lookVector = _lookAt->center - _lookAt->eye; + dmat4 matrix = vsg::translate(lookVector * (scale * delta.y * 0.2)) * + vsg::translate(_lookAt->eye) * + vsg::rotate(-delta.x * scale * 0.25, _lookAt->up) * + vsg::translate(-_lookAt->eye); - clampToGlobe(); - } + _lookAt->up = normalize(matrix * (_lookAt->eye + _lookAt->up) - matrix * _lookAt->eye); + _lookAt->center = matrix * _lookAt->center; + _lookAt->eye = matrix * _lookAt->eye; - ++itr; + clampToGlobe(); } + } if (_endLookAt) From e5dfd876a7e1cad039ce95c40aa3651f34aa46e0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 15 May 2023 12:48:39 +0100 Subject: [PATCH 19/35] Improved support for handling keyboard focus --- include/vsg/app/Trackball.h | 8 +++++--- src/vsg/app/Trackball.cpp | 36 ++++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/include/vsg/app/Trackball.h b/include/vsg/app/Trackball.h index 08c6bd2cd5..38e3bf1cfc 100644 --- a/include/vsg/app/Trackball.h +++ b/include/vsg/app/Trackball.h @@ -37,15 +37,16 @@ namespace vsg 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 pressed(KeySymbol key, bool ignore_handled_keys = true); /// return the length of time key has been pressed, return -1.0 for key is not currently pressed - double time_pressed(KeySymbol key); + double time_pressed(KeySymbol key, bool ignore_handled_keys = true); }; /// Trackball is an event handler that provides mouse and touch controlled 3d trackball camera view manipulation. @@ -129,7 +130,8 @@ namespace vsg ref_ptr _lookAt; ref_ptr _ellipsoidModel; - bool _hasFocus = false; + bool _hasKeyboardFocus = false; + bool _hasPointerFocus = false; bool _lastPointerEventWithinRenderArea = false; enum UpdateMode diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index 841e40583b..71198fced5 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -27,6 +27,7 @@ void Keyboard::apply(KeyPressEvent& keyPress) if (keyState_itr != keyState.end()) { auto& keyHistory = keyState_itr->second; + keyHistory.handled = keyPress.handled; if (keyHistory.timeOfKeyRelease == keyPress.time) { keyHistory.timeOfKeyRelease = keyHistory.timeOfFirstKeyPress; @@ -44,6 +45,7 @@ void Keyboard::apply(KeyPressEvent& keyPress) else { auto& keyHistory = keyState[keyPress.keyBase]; + keyHistory.handled = keyPress.handled; keyHistory.timeOfFirstKeyPress = keyPress.time; keyHistory.timeOfLastKeyPress = keyPress.time; keyHistory.timeOfKeyRelease = keyPress.time; @@ -59,12 +61,13 @@ void Keyboard::apply(KeyReleaseEvent& keyRelease) if (keyState_itr != keyState.end()) { auto& keyHistory = keyState_itr->second; + keyHistory.handled = keyRelease.handled; keyHistory.timeOfKeyRelease = keyRelease.time; //std::cout<<"key provisionally released "<(keyRelease.time - keyHistory.timeOfFirstKeyPress).count()<<"ms"<(clock::now() - keyHistory.timeOfFirstKeyPress).count(); } @@ -206,7 +213,7 @@ void Trackball::apply(KeyPressEvent& keyPress) { if (_keyboard) keyPress.accept(*_keyboard); - if (keyPress.handled || !eventRelevant(keyPress) || !_lastPointerEventWithinRenderArea) return; + if (!_hasKeyboardFocus || keyPress.handled || !eventRelevant(keyPress)) return; if (auto itr = keyViewpointMap.find(keyPress.keyBase); itr != keyViewpointMap.end()) { @@ -225,10 +232,14 @@ void Trackball::apply(KeyReleaseEvent& keyRelease) 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; @@ -239,7 +250,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); @@ -257,7 +268,7 @@ void Trackball::apply(ButtonReleaseEvent& buttonRelease) if (supportsThrow) _thrown = _previousPointerEvent && (buttonRelease.time == _previousPointerEvent->time); _lastPointerEventWithinRenderArea = withinRenderArea(buttonRelease); - _hasFocus = false; + _hasPointerFocus = false; _previousPointerEvent = &buttonRelease; } @@ -268,7 +279,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); @@ -460,7 +471,7 @@ void Trackball::apply(TouchMoveEvent& touchMove) void Trackball::apply(FrameEvent& frame) { // std::cout<<"Trackball::apply(FrameEvent&) frameCount = "<frameCount<pressed(KEY_Left)) delta.x = -1.0; @@ -472,6 +483,7 @@ void Trackball::apply(FrameEvent& frame) if (delta.x != 0.0 || delta.y != 0.0) { pan( dvec2(-delta.x, delta.y) * scale); + _thrown = false; } delta.set(0.0, 0.0); @@ -485,7 +497,7 @@ void Trackball::apply(FrameEvent& frame) dvec3 lookVector = _lookAt->center - _lookAt->eye; dmat4 matrix = vsg::translate(lookVector * (scale * delta.y * 0.2)) * vsg::translate(_lookAt->eye) * - vsg::rotate(-delta.x * scale * 0.25, _lookAt->up) * + vsg::rotate(-delta.x * scale * 0.5, _lookAt->up) * vsg::translate(-_lookAt->eye); _lookAt->up = normalize(matrix * (_lookAt->eye + _lookAt->up) - matrix * _lookAt->eye); @@ -493,8 +505,8 @@ void Trackball::apply(FrameEvent& frame) _lookAt->eye = matrix * _lookAt->eye; clampToGlobe(); + _thrown = false; } - } if (_endLookAt) From 30b5535cfd39ed4b302dcf7c2cf016b75c341c2e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 15 May 2023 14:01:01 +0100 Subject: [PATCH 20/35] Added look up/down and forwrd/back support with 'w', 's', 'i' and 'o' keys respectively. --- src/vsg/app/Trackball.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index 71198fced5..84cc78713d 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -473,7 +473,7 @@ void Trackball::apply(FrameEvent& frame) // std::cout<<"Trackball::apply(FrameEvent&) frameCount = "<frameCount<pressed(KEY_Left)) delta.x = -1.0; if (_keyboard->pressed(KEY_Right)) delta.x = 1.0; if (_keyboard->pressed(KEY_Up)) delta.y = 1.0; @@ -486,18 +486,22 @@ void Trackball::apply(FrameEvent& frame) _thrown = false; } - delta.set(0.0, 0.0); + delta.set(0.0, 0.0, 0.0); if (_keyboard->pressed(KEY_w)) delta.y = 1.0; if (_keyboard->pressed(KEY_s)) delta.y = -1.0; if (_keyboard->pressed(KEY_a)) delta.x = -1.0; if (_keyboard->pressed(KEY_d)) delta.x = 1.0; + if (_keyboard->pressed(KEY_o)) delta.z = 1.0; + if (_keyboard->pressed(KEY_i)) delta.z = -1.0; - if (delta.x != 0.0 || delta.y != 0.0) + if (delta.x != 0.0 || delta.y != 0.0 || delta.z != 0.0) { dvec3 lookVector = _lookAt->center - _lookAt->eye; - dmat4 matrix = vsg::translate(lookVector * (scale * delta.y * 0.2)) * + dvec3 sideVector = vsg::normalize(vsg::cross(_lookAt->up, lookVector)); + dmat4 matrix = vsg::translate(lookVector * (scale * delta.z * 0.2)) * vsg::translate(_lookAt->eye) * vsg::rotate(-delta.x * scale * 0.5, _lookAt->up) * + vsg::rotate(-delta.y * scale * 0.5, sideVector) * vsg::translate(-_lookAt->eye); _lookAt->up = normalize(matrix * (_lookAt->eye + _lookAt->up) - matrix * _lookAt->eye); From 364a7980db4ba050e537b728da30d2c76322fb6e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 May 2023 12:24:05 +0100 Subject: [PATCH 21/35] Test build of WM_SETFOCUS & WM_KILLFOCUS --- src/vsg/platform/win32/Win32_Window.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vsg/platform/win32/Win32_Window.cpp b/src/vsg/platform/win32/Win32_Window.cpp index 45ec47fe81..2d6322e92f 100644 --- a/src/vsg/platform/win32/Win32_Window.cpp +++ b/src/vsg/platform/win32/Win32_Window.cpp @@ -631,6 +631,12 @@ LRESULT Win32_Window::handleWin32Messages(UINT msg, WPARAM wParam, LPARAM lParam break; } + case WM_SETFOCUS : + info("win32_focus_in_event"); + break; + case WM_KILLFOCUS : + info("win32_focus_out_event"); + break; default: break; } From 907e247d152728fb76bc679ed5170cc3d34a1105 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 May 2023 13:01:41 +0100 Subject: [PATCH 22/35] Added FocusInEvent and FocusOutEvent for tracking when a window gain/looses keyboard focus --- include/vsg/core/ConstVisitor.h | 4 ++++ include/vsg/core/Visitor.h | 4 ++++ include/vsg/ui/WindowEvent.h | 22 ++++++++++++++++++++++ src/vsg/core/ConstVisitor.cpp | 8 ++++++++ src/vsg/core/Visitor.cpp | 8 ++++++++ 5 files changed, 46 insertions(+) diff --git a/include/vsg/core/ConstVisitor.h b/include/vsg/core/ConstVisitor.h index 3ceb633b26..13568b8fd5 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 b06e1d129d..d30addf03a 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/ui/WindowEvent.h b/include/vsg/ui/WindowEvent.h index 32c908020c..62f3a46f5b 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/core/ConstVisitor.cpp b/src/vsg/core/ConstVisitor.cpp index ac19df6e2f..e94a2e4774 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 ebd926ba1a..e11f273431 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)); From 5f7b64f42e50575430e74a6f2e3711f756d9052e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 May 2023 13:02:55 +0100 Subject: [PATCH 23/35] Added FocusInEvent/FocusOutEvent suppprt to Xcb_Window and Win32_Window. --- src/vsg/platform/win32/Win32_Window.cpp | 6 ++++-- src/vsg/platform/xcb/Xcb_Window.cpp | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/vsg/platform/win32/Win32_Window.cpp b/src/vsg/platform/win32/Win32_Window.cpp index 2d6322e92f..9078b48ec0 100644 --- a/src/vsg/platform/win32/Win32_Window.cpp +++ b/src/vsg/platform/win32/Win32_Window.cpp @@ -632,10 +632,12 @@ LRESULT Win32_Window::handleWin32Messages(UINT msg, WPARAM wParam, LPARAM lParam break; } case WM_SETFOCUS : - info("win32_focus_in_event"); + vsg::clock::time_point event_time = vsg::clock::now(); + bufferedEvents.emplace_back(vsg::FocusInEvent::create(this, event_time)); break; case WM_KILLFOCUS : - info("win32_focus_out_event"); + 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 48e2568d4f..8794743895 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): { - info("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): { - info("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): { From d7755f1733a067a16ba680c0276135958f6600f1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 May 2023 13:03:38 +0100 Subject: [PATCH 24/35] Added use of FocusInEvent/FocusOutEvent to Trackball --- include/vsg/app/Trackball.h | 4 ++++ src/vsg/app/Trackball.cpp | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/include/vsg/app/Trackball.h b/include/vsg/app/Trackball.h index 38e3bf1cfc..b71375c468 100644 --- a/include/vsg/app/Trackball.h +++ b/include/vsg/app/Trackball.h @@ -31,6 +31,8 @@ namespace vsg void apply(KeyPressEvent& keyPress) override; void apply(KeyReleaseEvent& keyRelease) override; + void apply(FocusInEvent& focusIn) override; + void apply(FocusOutEvent& focusOut) override; struct KeyHistory { @@ -63,6 +65,8 @@ namespace vsg 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; diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index 84cc78713d..eaa15f0e7f 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -67,6 +67,16 @@ void Keyboard::apply(KeyReleaseEvent& keyRelease) } } +void Keyboard::apply(FocusInEvent&) +{ +} + +void Keyboard::apply(FocusOutEvent& focusOut) +{ + focusOut.handled = true; + keyState.clear(); +} + bool Keyboard::pressed(KeySymbol key, bool ignore_handled_keys) { auto itr = keyState.find(key); @@ -230,6 +240,16 @@ 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)) From e21f72604f17eadec7f068034f943b5188ec3625 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 May 2023 13:16:48 +0100 Subject: [PATCH 25/35] Moved Keyboard class into into own header --- include/vsg/all.h | 1 + include/vsg/app/Trackball.h | 30 +--------- include/vsg/ui/Keyboard.h | 49 ++++++++++++++++ src/vsg/CMakeLists.txt | 1 + src/vsg/app/Trackball.cpp | 92 ------------------------------ src/vsg/ui/Keyboard.cpp | 109 ++++++++++++++++++++++++++++++++++++ 6 files changed, 161 insertions(+), 121 deletions(-) create mode 100644 include/vsg/ui/Keyboard.h create mode 100644 src/vsg/ui/Keyboard.cpp diff --git a/include/vsg/all.h b/include/vsg/all.h index 522be1a4e3..989cf6a31f 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 b71375c468..1957855950 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 @@ -24,33 +23,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI 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 the length of time key has been pressed, return -1.0 for key is not currently pressed - double time_pressed(KeySymbol key, bool ignore_handled_keys = true); - }; - /// Trackball is an event handler that provides mouse and touch controlled 3d trackball camera view manipulation. class VSG_DECLSPEC Trackball : public Inherit { diff --git a/include/vsg/ui/Keyboard.h b/include/vsg/ui/Keyboard.h new file mode 100644 index 0000000000..34ac954eec --- /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 the length of time key has been pressed, return -1.0 for key is not currently pressed + double time_pressed(KeySymbol key, bool ignore_handled_keys = true); + }; + VSG_type_name(vsg::Keyboard); + +} // namespace vsg diff --git a/src/vsg/CMakeLists.txt b/src/vsg/CMakeLists.txt index 4154312f1d..3d9625e4d3 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/Trackball.cpp b/src/vsg/app/Trackball.cpp index eaa15f0e7f..5549cd0a37 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -19,98 +19,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI 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) - { - keyState.erase(itr); - return false; - } - - if (ignore_handled_keys && keyHistory.handled) return false; - - return true; -} - -double Keyboard::time_pressed(KeySymbol key, bool ignore_handled_keys) -{ - auto itr = keyState.find(key); - if (itr == keyState.end()) return -1.0; - - auto& keyHistory = itr->second; - if (keyHistory.timeOfKeyRelease != keyHistory.timeOfFirstKeyPress) - { - keyState.erase(itr); - return -1.0; - } - - if (ignore_handled_keys && keyHistory.handled) return -1.0; - - return std::chrono::duration(clock::now() - keyHistory.timeOfFirstKeyPress).count(); -} - Trackball::Trackball(ref_ptr camera, ref_ptr ellipsoidModel) : _camera(camera), _lookAt(camera->viewMatrix.cast()), diff --git a/src/vsg/ui/Keyboard.cpp b/src/vsg/ui/Keyboard.cpp new file mode 100644 index 0000000000..4cf0dfcee1 --- /dev/null +++ b/src/vsg/ui/Keyboard.cpp @@ -0,0 +1,109 @@ +/* + +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) + { + keyState.erase(itr); + return false; + } + + if (ignore_handled_keys && keyHistory.handled) return false; + + return true; +} + +double Keyboard::time_pressed(KeySymbol key, bool ignore_handled_keys) +{ + auto itr = keyState.find(key); + if (itr == keyState.end()) return -1.0; + + auto& keyHistory = itr->second; + if (keyHistory.timeOfKeyRelease != keyHistory.timeOfFirstKeyPress) + { + keyState.erase(itr); + return -1.0; + } + + if (ignore_handled_keys && keyHistory.handled) return -1.0; + + return std::chrono::duration(clock::now() - keyHistory.timeOfFirstKeyPress).count(); +} From cdf26b81e8d5f8c7dc1ce602c2f80bb99470aa1c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 May 2023 13:17:23 +0100 Subject: [PATCH 26/35] Ran clang-format --- include/vsg/app/WindowResizeHandler.h | 1 - include/vsg/ui/Keyboard.h | 1 - src/vsg/app/CompileTraversal.cpp | 2 +- src/vsg/app/Trackball.cpp | 10 +++++----- src/vsg/platform/win32/Win32_Window.cpp | 4 ++-- src/vsg/ui/Keyboard.cpp | 2 +- src/vsg/vk/RenderPass.cpp | 2 +- 7 files changed, 10 insertions(+), 12 deletions(-) diff --git a/include/vsg/app/WindowResizeHandler.h b/include/vsg/app/WindowResizeHandler.h index cee73928c7..8e4aa6147b 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/ui/Keyboard.h b/include/vsg/ui/Keyboard.h index 34ac954eec..2c30df1e87 100644 --- a/include/vsg/ui/Keyboard.h +++ b/include/vsg/ui/Keyboard.h @@ -22,7 +22,6 @@ namespace vsg class VSG_DECLSPEC Keyboard : public Inherit { public: - void apply(KeyPressEvent& keyPress) override; void apply(KeyReleaseEvent& keyRelease) override; void apply(FocusInEvent& focusIn) override; diff --git a/src/vsg/app/CompileTraversal.cpp b/src/vsg/app/CompileTraversal.cpp index 717255aec3..698c0bcee1 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 5549cd0a37..de25518db1 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -410,7 +410,7 @@ void Trackball::apply(FrameEvent& frame) double scale = std::chrono::duration(frame.time - _previousTime).count(); if (delta.x != 0.0 || delta.y != 0.0) { - pan( dvec2(-delta.x, delta.y) * scale); + pan(dvec2(-delta.x, delta.y) * scale); _thrown = false; } @@ -427,10 +427,10 @@ void Trackball::apply(FrameEvent& frame) dvec3 lookVector = _lookAt->center - _lookAt->eye; dvec3 sideVector = vsg::normalize(vsg::cross(_lookAt->up, lookVector)); dmat4 matrix = vsg::translate(lookVector * (scale * delta.z * 0.2)) * - vsg::translate(_lookAt->eye) * - vsg::rotate(-delta.x * scale * 0.5, _lookAt->up) * - vsg::rotate(-delta.y * scale * 0.5, sideVector) * - vsg::translate(-_lookAt->eye); + vsg::translate(_lookAt->eye) * + vsg::rotate(-delta.x * scale * 0.5, _lookAt->up) * + vsg::rotate(-delta.y * scale * 0.5, sideVector) * + vsg::translate(-_lookAt->eye); _lookAt->up = normalize(matrix * (_lookAt->eye + _lookAt->up) - matrix * _lookAt->eye); _lookAt->center = matrix * _lookAt->center; diff --git a/src/vsg/platform/win32/Win32_Window.cpp b/src/vsg/platform/win32/Win32_Window.cpp index 9078b48ec0..d571dce37e 100644 --- a/src/vsg/platform/win32/Win32_Window.cpp +++ b/src/vsg/platform/win32/Win32_Window.cpp @@ -631,11 +631,11 @@ LRESULT Win32_Window::handleWin32Messages(UINT msg, WPARAM wParam, LPARAM lParam break; } - case WM_SETFOCUS : + 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 : + case WM_KILLFOCUS: vsg::clock::time_point event_time = vsg::clock::now(); bufferedEvents.emplace_back(vsg::FocusOutEvent::create(this, event_time)); break; diff --git a/src/vsg/ui/Keyboard.cpp b/src/vsg/ui/Keyboard.cpp index 4cf0dfcee1..bcddfc483a 100644 --- a/src/vsg/ui/Keyboard.cpp +++ b/src/vsg/ui/Keyboard.cpp @@ -10,9 +10,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI */ -#include #include #include +#include using namespace vsg; diff --git a/src/vsg/vk/RenderPass.cpp b/src/vsg/vk/RenderPass.cpp index b6a2b81a86..8d233d566e 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 From 788225a7665801221d7fefb5952be7c8760b45e8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 May 2023 13:22:09 +0100 Subject: [PATCH 27/35] Added { } to fix build --- src/vsg/platform/win32/Win32_Window.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vsg/platform/win32/Win32_Window.cpp b/src/vsg/platform/win32/Win32_Window.cpp index d571dce37e..271c57dffc 100644 --- a/src/vsg/platform/win32/Win32_Window.cpp +++ b/src/vsg/platform/win32/Win32_Window.cpp @@ -631,14 +631,16 @@ LRESULT Win32_Window::handleWin32Messages(UINT msg, WPARAM wParam, LPARAM lParam break; } - case WM_SETFOCUS: + 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: + } + case WM_KILLFOCUS: { vsg::clock::time_point event_time = vsg::clock::now(); bufferedEvents.emplace_back(vsg::FocusOutEvent::create(this, event_time)); break; + } default: break; } From 20f7b545deed335bcfeeb53e410987432e67db1c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 May 2023 15:14:11 +0100 Subject: [PATCH 28/35] Added user controllable keys for controlling motion --- include/vsg/app/Trackball.h | 30 ++++++++++++++++++++++++++++++ src/vsg/app/Trackball.cpp | 20 ++++++++++---------- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/include/vsg/app/Trackball.h b/include/vsg/app/Trackball.h index 1957855950..09cac5c038 100644 --- a/include/vsg/app/Trackball.h +++ b/include/vsg/app/Trackball.h @@ -83,6 +83,36 @@ 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 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; diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index de25518db1..acaf6f0792 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -402,10 +402,10 @@ void Trackball::apply(FrameEvent& frame) if (_hasKeyboardFocus && _keyboard) { vsg::dvec3 delta(0.0, 0.0, 0.0); - if (_keyboard->pressed(KEY_Left)) delta.x = -1.0; - if (_keyboard->pressed(KEY_Right)) delta.x = 1.0; - if (_keyboard->pressed(KEY_Up)) delta.y = 1.0; - if (_keyboard->pressed(KEY_Down)) delta.y = -1.0; + if (_keyboard->pressed(moveLeftKey)) delta.x = -1.0; + if (_keyboard->pressed(moveRightKey)) delta.x = 1.0; + if (_keyboard->pressed(moveUpKey)) delta.y = 1.0; + if (_keyboard->pressed(moveDownKey)) delta.y = -1.0; double scale = std::chrono::duration(frame.time - _previousTime).count(); if (delta.x != 0.0 || delta.y != 0.0) @@ -415,12 +415,12 @@ void Trackball::apply(FrameEvent& frame) } delta.set(0.0, 0.0, 0.0); - if (_keyboard->pressed(KEY_w)) delta.y = 1.0; - if (_keyboard->pressed(KEY_s)) delta.y = -1.0; - if (_keyboard->pressed(KEY_a)) delta.x = -1.0; - if (_keyboard->pressed(KEY_d)) delta.x = 1.0; - if (_keyboard->pressed(KEY_o)) delta.z = 1.0; - if (_keyboard->pressed(KEY_i)) delta.z = -1.0; + if (_keyboard->pressed(pitchUpKey)) delta.y = 1.0; + if (_keyboard->pressed(pitchDownKey)) delta.y = -1.0; + if (_keyboard->pressed(turnLeftKey)) delta.x = -1.0; + if (_keyboard->pressed(turnRightKey)) delta.x = 1.0; + if (_keyboard->pressed(moveForwardKey)) delta.z = 1.0; + if (_keyboard->pressed(moveBackwardKey)) delta.z = -1.0; if (delta.x != 0.0 || delta.y != 0.0 || delta.z != 0.0) { From 16a17510f17435e1a64c63ed31e7169fd6dbea3d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 May 2023 18:15:14 +0100 Subject: [PATCH 29/35] Resutrctured the keyboard movement implementation --- src/vsg/app/Trackball.cpp | 56 +++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index acaf6f0792..80eca76e59 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -401,35 +401,35 @@ void Trackball::apply(FrameEvent& frame) // std::cout<<"Trackball::apply(FrameEvent&) frameCount = "<frameCount<pressed(moveLeftKey)) delta.x = -1.0; - if (_keyboard->pressed(moveRightKey)) delta.x = 1.0; - if (_keyboard->pressed(moveUpKey)) delta.y = 1.0; - if (_keyboard->pressed(moveDownKey)) delta.y = -1.0; - - double scale = std::chrono::duration(frame.time - _previousTime).count(); - if (delta.x != 0.0 || delta.y != 0.0) + bool update = false; + vsg::dvec3 move(0.0, 0.0, 0.0); + if (_keyboard->pressed(moveLeftKey)) { move.x = -1.0; update = true; } + if (_keyboard->pressed(moveRightKey)) { move.x = 1.0; update = true; } + if (_keyboard->pressed(moveUpKey)) { move.y = 1.0; update = true; } + if (_keyboard->pressed(moveDownKey)) { move.y = -1.0; update = true; } + if (_keyboard->pressed(moveForwardKey)) { move.z = 1.0; update = true; } + if (_keyboard->pressed(moveBackwardKey)) { move.z = -1.0; update = true; } + + vsg::dvec2 rot(0.0, 0.0); + if (_keyboard->pressed(pitchUpKey)) { rot.y = 1.0; update = true; } + if (_keyboard->pressed(pitchDownKey)) { rot.y = -1.0; update = true; } + if (_keyboard->pressed(turnLeftKey)) { rot.x = -1.0; update = true; } + if (_keyboard->pressed(turnRightKey)) { rot.x = 1.0; update = true; } + + if (update) { - pan(dvec2(-delta.x, delta.y) * scale); - _thrown = false; - } - - delta.set(0.0, 0.0, 0.0); - if (_keyboard->pressed(pitchUpKey)) delta.y = 1.0; - if (_keyboard->pressed(pitchDownKey)) delta.y = -1.0; - if (_keyboard->pressed(turnLeftKey)) delta.x = -1.0; - if (_keyboard->pressed(turnRightKey)) delta.x = 1.0; - if (_keyboard->pressed(moveForwardKey)) delta.z = 1.0; - if (_keyboard->pressed(moveBackwardKey)) delta.z = -1.0; - - if (delta.x != 0.0 || delta.y != 0.0 || delta.z != 0.0) - { - dvec3 lookVector = _lookAt->center - _lookAt->eye; - dvec3 sideVector = vsg::normalize(vsg::cross(_lookAt->up, lookVector)); - dmat4 matrix = vsg::translate(lookVector * (scale * delta.z * 0.2)) * - vsg::translate(_lookAt->eye) * - vsg::rotate(-delta.x * scale * 0.5, _lookAt->up) * - vsg::rotate(-delta.y * scale * 0.5, sideVector) * + 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::translate(-_lookAt->eye); _lookAt->up = normalize(matrix * (_lookAt->eye + _lookAt->up) - matrix * _lookAt->eye); From ecd23ae63c0dae02aa4d35a9dbf0147bd5da6ae8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 May 2023 09:52:43 +0100 Subject: [PATCH 30/35] Ran clang-format --- src/vsg/app/Trackball.cpp | 62 ++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index 80eca76e59..5c8506fe84 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -403,23 +403,63 @@ void Trackball::apply(FrameEvent& frame) { bool update = false; vsg::dvec3 move(0.0, 0.0, 0.0); - if (_keyboard->pressed(moveLeftKey)) { move.x = -1.0; update = true; } - if (_keyboard->pressed(moveRightKey)) { move.x = 1.0; update = true; } - if (_keyboard->pressed(moveUpKey)) { move.y = 1.0; update = true; } - if (_keyboard->pressed(moveDownKey)) { move.y = -1.0; update = true; } - if (_keyboard->pressed(moveForwardKey)) { move.z = 1.0; update = true; } - if (_keyboard->pressed(moveBackwardKey)) { move.z = -1.0; update = true; } + if (_keyboard->pressed(moveLeftKey)) + { + move.x = -1.0; + update = true; + } + if (_keyboard->pressed(moveRightKey)) + { + move.x = 1.0; + update = true; + } + if (_keyboard->pressed(moveUpKey)) + { + move.y = 1.0; + update = true; + } + if (_keyboard->pressed(moveDownKey)) + { + move.y = -1.0; + update = true; + } + if (_keyboard->pressed(moveForwardKey)) + { + move.z = 1.0; + update = true; + } + if (_keyboard->pressed(moveBackwardKey)) + { + move.z = -1.0; + update = true; + } vsg::dvec2 rot(0.0, 0.0); - if (_keyboard->pressed(pitchUpKey)) { rot.y = 1.0; update = true; } - if (_keyboard->pressed(pitchDownKey)) { rot.y = -1.0; update = true; } - if (_keyboard->pressed(turnLeftKey)) { rot.x = -1.0; update = true; } - if (_keyboard->pressed(turnRightKey)) { rot.x = 1.0; update = true; } + if (_keyboard->pressed(pitchUpKey)) + { + rot.y = 1.0; + update = true; + } + if (_keyboard->pressed(pitchDownKey)) + { + rot.y = -1.0; + update = true; + } + if (_keyboard->pressed(turnLeftKey)) + { + rot.x = -1.0; + update = true; + } + if (_keyboard->pressed(turnRightKey)) + { + rot.x = 1.0; + update = true; + } if (update) { double scale = std::chrono::duration(frame.time - _previousTime).count(); - double scaleTranslation = scale * 0.2 * length(_lookAt->center - _lookAt->eye) ; + double scaleTranslation = scale * 0.2 * length(_lookAt->center - _lookAt->eye); double scaleRotation = scale * 0.5; dvec3 upVector = _lookAt->up; From 68fe63662cfb0beb05851bce85aa5e9a51b53f86 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 May 2023 11:56:43 +0100 Subject: [PATCH 31/35] Added bool method to vec/plane/quat class to make it easier to test if they are non zero --- include/vsg/maths/plane.h | 2 ++ include/vsg/maths/quat.h | 2 ++ include/vsg/maths/vec2.h | 2 ++ include/vsg/maths/vec3.h | 2 ++ include/vsg/maths/vec4.h | 2 ++ 5 files changed, 10 insertions(+) diff --git a/include/vsg/maths/plane.h b/include/vsg/maths/plane.h index 3c1003d8cd..85d1ebcfc2 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 a493746361..d03e904012 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 1b62507dc4..f57d717400 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 040910cfa7..40cf7752b9 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 28f69f3e0d..72473012ac 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 From b30c90dc51de01c742a4ef894e3a7c49bddb173f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 May 2023 11:58:55 +0100 Subject: [PATCH 32/35] Added inertial effect to Trackball keyboard controls. --- include/vsg/ui/Keyboard.h | 5 ++- src/vsg/app/Trackball.cpp | 82 ++++++++++++++------------------------- src/vsg/ui/Keyboard.cpp | 16 ++++---- 3 files changed, 42 insertions(+), 61 deletions(-) diff --git a/include/vsg/ui/Keyboard.h b/include/vsg/ui/Keyboard.h index 2c30df1e87..18e7bfbf5d 100644 --- a/include/vsg/ui/Keyboard.h +++ b/include/vsg/ui/Keyboard.h @@ -40,8 +40,9 @@ namespace vsg /// return true if key is currently pressed bool pressed(KeySymbol key, bool ignore_handled_keys = true); - /// return the length of time key has been pressed, return -1.0 for key is not currently pressed - double time_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); diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index 5c8506fe84..e75d33526e 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -401,62 +401,40 @@ void Trackball::apply(FrameEvent& frame) // std::cout<<"Trackball::apply(FrameEvent&) frameCount = "<frameCount<pressed(moveLeftKey)) - { - move.x = -1.0; - update = true; - } - if (_keyboard->pressed(moveRightKey)) - { - move.x = 1.0; - update = true; - } - if (_keyboard->pressed(moveUpKey)) - { - move.y = 1.0; - update = true; - } - if (_keyboard->pressed(moveDownKey)) + auto times2speed = [](std::pair duration) -> double { - move.y = -1.0; - update = true; - } - if (_keyboard->pressed(moveForwardKey)) - { - move.z = 1.0; - update = true; - } - if (_keyboard->pressed(moveBackwardKey)) - { - move.z = -1.0; - update = true; - } + 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::dvec2 rot(0.0, 0.0); - if (_keyboard->pressed(pitchUpKey)) - { - rot.y = 1.0; - update = true; - } - if (_keyboard->pressed(pitchDownKey)) - { - rot.y = -1.0; - update = true; - } - if (_keyboard->pressed(turnLeftKey)) - { - rot.x = -1.0; - update = true; - } - if (_keyboard->pressed(turnRightKey)) - { - rot.x = 1.0; - update = true; - } + 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(turnLeftKey))) != 0.0) rot.x += -speed; + if ((speed = times2speed(_keyboard->times(turnRightKey))) != 0.0) rot.x += speed; - if (update) + if (rot || move) { double scale = std::chrono::duration(frame.time - _previousTime).count(); double scaleTranslation = scale * 0.2 * length(_lookAt->center - _lookAt->eye); diff --git a/src/vsg/ui/Keyboard.cpp b/src/vsg/ui/Keyboard.cpp index bcddfc483a..474d37675e 100644 --- a/src/vsg/ui/Keyboard.cpp +++ b/src/vsg/ui/Keyboard.cpp @@ -82,7 +82,6 @@ bool Keyboard::pressed(KeySymbol key, bool ignore_handled_keys) auto& keyHistory = itr->second; if (keyHistory.timeOfKeyRelease != keyHistory.timeOfFirstKeyPress) { - keyState.erase(itr); return false; } @@ -91,19 +90,22 @@ bool Keyboard::pressed(KeySymbol key, bool ignore_handled_keys) return true; } -double Keyboard::time_pressed(KeySymbol key, bool ignore_handled_keys) + +std::pair Keyboard::times(KeySymbol key, bool ignore_handled_keys) { auto itr = keyState.find(key); - if (itr == keyState.end()) return -1.0; + if (itr == keyState.end()) return {-1.0, -1.0}; + + auto currentTime = clock::now(); auto& keyHistory = itr->second; if (keyHistory.timeOfKeyRelease != keyHistory.timeOfFirstKeyPress) { - keyState.erase(itr); - return -1.0; + return {std::chrono::duration(currentTime - keyHistory.timeOfFirstKeyPress).count(), + std::chrono::duration(currentTime - keyHistory.timeOfLastKeyPress).count()}; } - if (ignore_handled_keys && keyHistory.handled) return -1.0; + if (ignore_handled_keys && keyHistory.handled) return {-1.0, -1.0}; - return std::chrono::duration(clock::now() - keyHistory.timeOfFirstKeyPress).count(); + return {std::chrono::duration(currentTime - keyHistory.timeOfFirstKeyPress).count(), 0.0}; } From f08409d8e287eab976c5029bbde8e115486d1b8b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 May 2023 12:24:20 +0100 Subject: [PATCH 33/35] Added roll with q and e keys --- include/vsg/app/Trackball.h | 6 ++++++ src/vsg/app/Trackball.cpp | 17 ++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/include/vsg/app/Trackball.h b/include/vsg/app/Trackball.h index 09cac5c038..841ce8fafd 100644 --- a/include/vsg/app/Trackball.h +++ b/include/vsg/app/Trackball.h @@ -95,6 +95,12 @@ namespace vsg /// 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; diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index e75d33526e..d0decb3ea0 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -428,11 +428,13 @@ void Trackball::apply(FrameEvent& frame) if ((speed = times2speed(_keyboard->times(moveForwardKey))) != 0.0) move.z += speed; if ((speed = times2speed(_keyboard->times(moveBackwardKey))) != 0.0) move.z += -speed; - vsg::dvec2 rot(0.0, 0.0); - 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(turnLeftKey))) != 0.0) rot.x += -speed; - if ((speed = times2speed(_keyboard->times(turnRightKey))) != 0.0) rot.x += 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) { @@ -446,8 +448,9 @@ void Trackball::apply(FrameEvent& frame) 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.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); From 8b4dee7bbc9852f293c202f08a9d93548aa98f98 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 May 2023 12:41:15 +0100 Subject: [PATCH 34/35] Ran clang-format --- src/vsg/app/Trackball.cpp | 7 +++---- src/vsg/ui/Keyboard.cpp | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index d0decb3ea0..4ca4cfbb2d 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -401,16 +401,15 @@ void Trackball::apply(FrameEvent& frame) // std::cout<<"Trackball::apply(FrameEvent&) frameCount = "<frameCount< duration) -> double - { - if (duration.first<=0.0) return 0.0; + auto times2speed = [](std::pair 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 ; + return speed > 0.0 ? speed : 0.0; } else { diff --git a/src/vsg/ui/Keyboard.cpp b/src/vsg/ui/Keyboard.cpp index 474d37675e..19d8399c7f 100644 --- a/src/vsg/ui/Keyboard.cpp +++ b/src/vsg/ui/Keyboard.cpp @@ -90,7 +90,6 @@ bool Keyboard::pressed(KeySymbol key, bool ignore_handled_keys) return true; } - std::pair Keyboard::times(KeySymbol key, bool ignore_handled_keys) { auto itr = keyState.find(key); From 47f1b62bd609cf53421856aff79cd6ef7024e872 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 May 2023 12:48:08 +0100 Subject: [PATCH 35/35] Fixed typos --- CMakeLists.txt | 4 ++-- include/vsg/io/mem_stream.h | 2 +- src/vsg/app/CompileManager.cpp | 2 +- src/vsg/app/Trackball.cpp | 2 +- src/vsg/io/Path.cpp | 2 +- src/vsg/platform/win32/Win32_Window.cpp | 2 +- src/vsg/vk/Device.cpp | 4 ++-- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d4fe0095a..95d1e4ac75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,8 +44,8 @@ if (VSG_SUPPORTS_ShaderCompiler) if (Git_FOUND) - set(glslang_URL "https://github.com/vsg-dev/glslang.git" CACHE STRING "URL of the glslang git repositiory") - set(glslang_branch "VSG-1.0.x" CACHE STRING "branch/tag of the glslang git repositiory") + set(glslang_URL "https://github.com/vsg-dev/glslang.git" CACHE STRING "URL of the glslang git repository") + set(glslang_branch "VSG-1.0.x" CACHE STRING "branch/tag of the glslang git repository") execute_process(COMMAND ${GIT_EXECUTABLE} clone --depth 1 --branch ${glslang_branch} ${glslang_URL} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src diff --git a/include/vsg/io/mem_stream.h b/include/vsg/io/mem_stream.h index f93c8deed1..34e8974d27 100644 --- a/include/vsg/io/mem_stream.h +++ b/include/vsg/io/mem_stream.h @@ -21,7 +21,7 @@ namespace vsg { /// Input stream that enables reading from a read only block of memory - /// Like std::string_view the memory referenced by the mem_stream has been kept in memory for the duration of the mem_stream existance. + /// Like std::string_view the memory referenced by the mem_stream has been kept in memory for the duration of the mem_stream existence. class VSG_DECLSPEC mem_stream : public std::istream { public: diff --git a/src/vsg/app/CompileManager.cpp b/src/vsg/app/CompileManager.cpp index bb4e611df0..a949ba78a3 100644 --- a/src/vsg/app/CompileManager.cpp +++ b/src/vsg/app/CompileManager.cpp @@ -202,7 +202,7 @@ CompileResult CompileManager::compile(ref_ptr object, ContextSelectionFu catch (...) { vsg::debug("CompileManager::compile() exception caught"); - result.message = "Exception occured during compilation."; + result.message = "Exception occurred during compilation."; result.result = VK_ERROR_UNKNOWN; } diff --git a/src/vsg/app/Trackball.cpp b/src/vsg/app/Trackball.cpp index 5b185b4f1d..5f16a5543a 100644 --- a/src/vsg/app/Trackball.cpp +++ b/src/vsg/app/Trackball.cpp @@ -89,7 +89,7 @@ bool Trackball::withinRenderArea(const PointerEvent& pointerEvent) const bool Trackball::eventRelevant(const WindowEvent& event) const { - // if no windows have been assocated with Trackball with a Trackball::addWindow() then assume event is relevant and should be handled + // if no windows have been associated with Trackball with a Trackball::addWindow() then assume event is relevant and should be handled if (windowOffsets.empty()) return true; return (windowOffsets.count(event.window) > 0); diff --git a/src/vsg/io/Path.cpp b/src/vsg/io/Path.cpp index 6215dc271f..958589a644 100644 --- a/src/vsg/io/Path.cpp +++ b/src/vsg/io/Path.cpp @@ -263,7 +263,7 @@ Path Path::lexically_normal() const if (last_segment_was_double_dot && !path_segments.empty() && path_segments.back().compare(doubledot_str) != 0) { - // if the last segment was a double dot and it's no longer a double dot then treat it as a directory so add seperator + // if the last segment was a double dot and it's no longer a double dot then treat it as a directory so add separator new_path.concat(preferred_separator); } diff --git a/src/vsg/platform/win32/Win32_Window.cpp b/src/vsg/platform/win32/Win32_Window.cpp index 45ec47fe81..55b20fc1da 100644 --- a/src/vsg/platform/win32/Win32_Window.cpp +++ b/src/vsg/platform/win32/Win32_Window.cpp @@ -60,7 +60,7 @@ namespace vsgWin32 KeyboardMap::KeyboardMap() { - // Note that Windows virutal key 'A' etc. correspond to the unmodified character 'a', hence the map below assigns capital letters to their corresponding lowercase ones. + // Note that Windows virtual key 'A' etc. correspond to the unmodified character 'a', hence the map below assigns capital letters to their corresponding lowercase ones. // will modify this map. // clang-format off _vk2vsg = diff --git a/src/vsg/vk/Device.cpp b/src/vsg/vk/Device.cpp index 373cdc6a52..42aef95699 100644 --- a/src/vsg/vk/Device.cpp +++ b/src/vsg/vk/Device.cpp @@ -175,14 +175,14 @@ ref_ptr Device::getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex) if (queue->queueFamilyIndex() == queueFamilyIndex && queue->queueIndex() == queueIndex) return queue; } - debug("Device::getQueue(", queueFamilyIndex, ", ", queueIndex, ") failled back to next closest."); + debug("Device::getQueue(", queueFamilyIndex, ", ", queueIndex, ") failed back to next closest."); for (auto& queue : _queues) { if (queue->queueFamilyIndex() == queueFamilyIndex) return queue; } - warn("Device::getQueue(", queueFamilyIndex, ", ", queueIndex, ") failled to find any suitable Queue."); + warn("Device::getQueue(", queueFamilyIndex, ", ", queueIndex, ") failed to find any suitable Queue."); return {}; }