ソースを参照

Merge branch 'development' into jh/sync_develop

Signed-off-by: Jan Hanca <[email protected]>
Jan Hanca 1 ヶ月 前
コミット
5c1ee4654d
100 ファイル変更4137 行追加219 行削除
  1. 1 3
      .gitattributes
  2. 11 0
      Gems/ExternalProfilers/OptickProfiler/CMakeLists.txt
  3. 83 0
      Gems/ExternalProfilers/OptickProfiler/Code/CMakeLists.txt
  4. 129 0
      Gems/ExternalProfilers/OptickProfiler/Code/Source/OptickProfilerEventForwarder.cpp
  5. 70 0
      Gems/ExternalProfilers/OptickProfiler/Code/Source/OptickProfilerEventForwarder.h
  6. 51 0
      Gems/ExternalProfilers/OptickProfiler/Code/Source/ProfilerModule.cpp
  7. 114 0
      Gems/ExternalProfilers/OptickProfiler/Code/Source/ProfilerSystemComponent.cpp
  8. 54 0
      Gems/ExternalProfilers/OptickProfiler/Code/Source/ProfilerSystemComponent.h
  9. 28 0
      Gems/ExternalProfilers/OptickProfiler/Code/optick.patch
  10. 14 0
      Gems/ExternalProfilers/OptickProfiler/Code/optickprofiler_files.cmake
  11. 11 0
      Gems/ExternalProfilers/OptickProfiler/Code/optickprofiler_shared_files.cmake
  12. 23 0
      Gems/ExternalProfilers/OptickProfiler/gem.json
  13. 3 0
      Gems/ExternalProfilers/OptickProfiler/preview.png
  14. 11 0
      Gems/ExternalProfilers/SuperluminalProfiler/CMakeLists.txt
  15. 66 0
      Gems/ExternalProfilers/SuperluminalProfiler/Code/CMakeLists.txt
  16. 51 0
      Gems/ExternalProfilers/SuperluminalProfiler/Code/Source/ProfilerModule.cpp
  17. 101 0
      Gems/ExternalProfilers/SuperluminalProfiler/Code/Source/ProfilerSystemComponent.cpp
  18. 53 0
      Gems/ExternalProfilers/SuperluminalProfiler/Code/Source/ProfilerSystemComponent.h
  19. 56 0
      Gems/ExternalProfilers/SuperluminalProfiler/Code/Source/SuperluminalProfilerEventForwarder.cpp
  20. 49 0
      Gems/ExternalProfilers/SuperluminalProfiler/Code/Source/SuperluminalProfilerEventForwarder.h
  21. 14 0
      Gems/ExternalProfilers/SuperluminalProfiler/Code/superluminalprofiler_files.cmake
  22. 11 0
      Gems/ExternalProfilers/SuperluminalProfiler/Code/superluminalprofiler_shared_files.cmake
  23. 24 0
      Gems/ExternalProfilers/SuperluminalProfiler/gem.json
  24. 3 0
      Gems/ExternalProfilers/SuperluminalProfiler/preview.png
  25. 11 0
      Gems/ExternalProfilers/TracyProfiler/CMakeLists.txt
  26. 85 0
      Gems/ExternalProfilers/TracyProfiler/Code/CMakeLists.txt
  27. 51 0
      Gems/ExternalProfilers/TracyProfiler/Code/Source/ProfilerModule.cpp
  28. 101 0
      Gems/ExternalProfilers/TracyProfiler/Code/Source/ProfilerSystemComponent.cpp
  29. 53 0
      Gems/ExternalProfilers/TracyProfiler/Code/Source/ProfilerSystemComponent.h
  30. 83 0
      Gems/ExternalProfilers/TracyProfiler/Code/Source/TracyProfilerEventForwarder.cpp
  31. 56 0
      Gems/ExternalProfilers/TracyProfiler/Code/Source/TracyProfilerEventForwarder.h
  32. 14 0
      Gems/ExternalProfilers/TracyProfiler/Code/tracyprofiler_files.cmake
  33. 11 0
      Gems/ExternalProfilers/TracyProfiler/Code/tracyprofiler_shared_files.cmake
  34. 24 0
      Gems/ExternalProfilers/TracyProfiler/gem.json
  35. 3 0
      Gems/ExternalProfilers/TracyProfiler/preview.png
  36. 5 5
      Gems/LevelGeoreferencing/Code/CMakeLists.txt
  37. 3 3
      Gems/LevelGeoreferencing/Code/Platform/Android/PAL_android.cmake
  38. 3 3
      Gems/LevelGeoreferencing/Code/Platform/Linux/PAL_linux.cmake
  39. 3 3
      Gems/LevelGeoreferencing/Code/Platform/Mac/PAL_mac.cmake
  40. 3 3
      Gems/LevelGeoreferencing/Code/Platform/Windows/PAL_windows.cmake
  41. 3 3
      Gems/LevelGeoreferencing/Code/Platform/iOS/PAL_ios.cmake
  42. 8 8
      Gems/LevelGeoreferencing/Code/Source/Clients/GeoreferenceInternalStructures.h
  43. 7 7
      Gems/LevelGeoreferencing/Code/Source/Clients/GeoreferencingModule.cpp
  44. 7 7
      Gems/LevelGeoreferencing/Code/Source/Tools/GeoreferencingEditorModule.cpp
  45. 1 2
      Gems/LevelGeoreferencing/Code/Tests/Tools/GeoreferenceComponentTest.cpp
  46. 0 11
      Gems/LevelGeoreferencing/Code/Tests/Tools/GeoreferencingEditorTest.cpp
  47. 2 2
      Gems/LevelGeoreferencing/Registry/assetprocessor_settings.setreg
  48. 10 7
      Gems/LevelGeoreferencing/gem.json
  49. 4 3
      Gems/MachineLearning/gem.json
  50. 3 0
      Gems/OpenXRVk/Assets/Devices/Generic/Animations/LeftControllerAnimGraph.animgraph
  51. 3 0
      Gems/OpenXRVk/Assets/Devices/Generic/Animations/LeftControllerMotionSet.motionset
  52. 3 0
      Gems/OpenXRVk/Assets/Devices/Generic/Animations/RightControllerAnimGraph.animgraph
  53. 3 0
      Gems/OpenXRVk/Assets/Devices/Generic/Animations/RightControllerMotionSet.motionset
  54. 0 0
      Gems/OpenXRVk/Assets/Devices/Generic/Materials/placeholder
  55. 192 0
      Gems/OpenXRVk/Assets/Devices/Generic/Prefabs/Controllers.prefab
  56. 271 0
      Gems/OpenXRVk/Assets/Devices/Generic/Prefabs/LeftController.prefab
  57. 271 0
      Gems/OpenXRVk/Assets/Devices/Generic/Prefabs/RightController.prefab
  58. 0 0
      Gems/OpenXRVk/Assets/Devices/Generic/models/placeholder
  59. 0 0
      Gems/OpenXRVk/Assets/Devices/Generic/textures/placeholder
  60. 6 6
      Gems/OpenXRVk/Assets/OpenXRVk/Materials/RayInteractor.material
  61. 3 0
      Gems/OpenXRVk/Assets/OpenXRVk/Models/ray.fbx
  62. 192 0
      Gems/OpenXRVk/Assets/OpenXRVk/Prefabs/RayInteractor.prefab
  63. 192 0
      Gems/OpenXRVk/Assets/OpenXRVk/default.xractions
  64. 7 1
      Gems/OpenXRVk/Code/CMakeLists.txt
  65. 148 0
      Gems/OpenXRVk/Code/Source/Devices/Common/XRControllerAnimationsComponent.cpp
  66. 48 0
      Gems/OpenXRVk/Code/Source/Devices/Common/XRControllerAnimationsComponent.h
  67. 155 0
      Gems/OpenXRVk/Code/Source/Devices/Common/XRControllerComponent.cpp
  68. 62 0
      Gems/OpenXRVk/Code/Source/Devices/Common/XRControllerComponent.h
  69. 41 0
      Gems/OpenXRVk/Code/Source/Devices/Common/XRControllersConfig.cpp
  70. 45 0
      Gems/OpenXRVk/Code/Source/Devices/Common/XRControllersConfig.h
  71. 8 0
      Gems/OpenXRVk/Code/Source/OpenXRVkModule.cpp
  72. 6 0
      Gems/OpenXRVk/Code/Source/Platform/Android/platform_private_android_files.cmake
  73. 4 0
      Gems/OpenXRVk/Code/Source/Platform/Linux/platform_private_linux_files.cmake
  74. 6 0
      Gems/OpenXRVk/Code/Source/Platform/Windows/platform_private_windows_files.cmake
  75. 1 1
      Gems/OpenXRVk/Code/Source/XRCameraMovementComponent.cpp
  76. 213 0
      Gems/OpenXRVk/Code/Source/XRInteractableComponent.cpp
  77. 87 0
      Gems/OpenXRVk/Code/Source/XRInteractableComponent.h
  78. 364 0
      Gems/OpenXRVk/Code/Source/XRRayInteractorComponent.cpp
  79. 79 0
      Gems/OpenXRVk/Code/Source/XRRayInteractorComponent.h
  80. 4 0
      Gems/OpenXRVk/Code/openxrvk_static_common_files.cmake
  81. 2 2
      Gems/OpenXRVk/gem.json
  82. 63 0
      Gems/OpenXRVk_README_EN.md
  83. 0 18
      Gems/ProteusRobot/Assets/Materials/Proteus_chassis_Proteus.material
  84. 0 13
      Gems/ProteusRobot/Assets/Materials/Proteus_chassis_Side_Lights.material
  85. 0 19
      Gems/ProteusRobot/Assets/Materials/Proteus_chassis_wheel.material
  86. 0 3
      Gems/ProteusRobot/Assets/Proteus2_chassis.fbx
  87. 0 3
      Gems/ProteusRobot/Assets/Proteus2_lift.fbx
  88. 0 3
      Gems/ProteusRobot/Assets/Proteus_chassis.fbx
  89. 0 3
      Gems/ProteusRobot/Assets/Proteus_wheel.fbx
  90. 0 3
      Gems/ProteusRobot/Assets/Textures/Proteus_MaskMap.png
  91. 0 3
      Gems/ProteusRobot/Assets/Textures/Proteus_MaskMap_A.png
  92. 0 30
      Gems/ProteusRobot/README.md
  93. 0 34
      Gems/ProteusRobot/gem.json
  94. 0 3
      Gems/ProteusRobot/preview.png
  95. 11 0
      Gems/ROS2RobotImporter/Code/ros2robotimporter_editor_private_files.cmake
  96. 3 0
      Gems/ROS2SampleRobots/Assets/Components/OS2Lidar/Models/LidarOS2.fbx
  97. 47 0
      Gems/ROS2SampleRobots/Assets/Components/OS2Lidar/Models/LidarOS2.fbx.assetinfo
  98. 6 4
      Gems/ROS2SampleRobots/Assets/Components/OS2Lidar/Models/Materials/LidarOS2_OS2Material.material
  99. 3 0
      Gems/ROS2SampleRobots/Assets/Components/OS2Lidar/Models/Materials/Textures/AO_grey.png
  100. 3 0
      Gems/ROS2SampleRobots/Assets/Components/OS2Lidar/Models/Materials/Textures/Diffuse.png

+ 1 - 3
.gitattributes

@@ -124,11 +124,9 @@ Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Lucy/Lucy_low.fbx filter=lf
 Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Lucy/.wip/marmoset_bake.tbscene filter=lfs diff=lfs merge=lfs -text
 Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Lucy/.wip/marmoset_bake.tbscene filter=lfs diff=lfs merge=lfs -text
 Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Lucy/.wip/Brass/brass_bake.spp filter=lfs diff=lfs merge=lfs -text
 Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Lucy/.wip/Brass/brass_bake.spp filter=lfs diff=lfs merge=lfs -text
 Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Lucy/.wip/stone/stone_bake.spp filter=lfs diff=lfs merge=lfs -text
 Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Lucy/.wip/stone/stone_bake.spp filter=lfs diff=lfs merge=lfs -text
-Gems/ProteusRobot/docs/images/*.png filter= diff= merge= -text
-Gems/RosRobotSample/docs/images/*.png filter= diff= merge= -text
+Gems/ROS2SampleRobots/docs/images/*.png filter= diff= merge= -text
 Gems/WarehouseAutomation/docs/images/*.png filter= diff= merge= -text
 Gems/WarehouseAutomation/docs/images/*.png filter= diff= merge= -text
 Gems/WarehouseAssets/docs/images/*.png filter= diff= merge= -text
 Gems/WarehouseAssets/docs/images/*.png filter= diff= merge= -text
-Gems/WarehouseSample/docs/images/*.png filter= diff= merge= -text
 Templates/Ros2FleetRobotTemplate/docs/images/*.png filter= diff= merge= -text
 Templates/Ros2FleetRobotTemplate/docs/images/*.png filter= diff= merge= -text
 Gems/ROS2/docs/**/*.png -filter -diff -merge
 Gems/ROS2/docs/**/*.png -filter -diff -merge
 Templates/Ros2ProjectTemplate/Screenshots/*.png filter= diff= merge= -text
 Templates/Ros2ProjectTemplate/Screenshots/*.png filter= diff= merge= -text

+ 11 - 0
Gems/ExternalProfilers/OptickProfiler/CMakeLists.txt

@@ -0,0 +1,11 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+o3de_gem_setup("OptickProfiler")
+
+add_subdirectory(Code)

+ 83 - 0
Gems/ExternalProfilers/OptickProfiler/Code/CMakeLists.txt

@@ -0,0 +1,83 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+# Expose some internal of Optick for better integration with 03DE
+set(OPTICK_GIT_PATCH "${CMAKE_CURRENT_SOURCE_DIR}/optick.patch")
+
+# Add Optick dependency using FetchContent
+include(FetchContent)
+FetchContent_Declare(
+    Optick
+    GIT_REPOSITORY "https://github.com/bombomby/optick.git"
+    GIT_TAG "8abd28dee1a4034c973a3d32cd1777118e72df7e" # version 1.4.0+
+    PATCH_COMMAND cmake -P "${LY_ROOT_FOLDER}/cmake/PatchIfNotAlreadyPatched.cmake" ${OPTICK_GIT_PATCH}
+)
+
+set(OPTICK_ENABLED ON)
+set(OPTICK_BUILD_GUI_APP OFF)
+set(OPTICK_INSTALL_TARGETS OFF)
+
+message(STATUS "OptickProfiler Gem uses https://github.com/bombomby/optick.git version 1.4.0 (License: MIT)")
+message(STATUS "      With patch: ${OPTICK_GIT_PATCH}")
+
+FetchContent_MakeAvailable(Optick)
+
+# Let's not clutter the root of any IDE folder structure with 3rd party dependencies
+# Setting the FOLDER makes it show up there in the solution build in VS and similarly
+# any other IDEs that organize in folders.
+set_target_properties(
+        OptickCore 
+    PROPERTIES 
+        FOLDER "3rdParty Dependencies"
+)
+
+ly_add_target(
+    NAME ${gem_name}.Static STATIC
+    NAMESPACE Gem
+    FILES_CMAKE
+        optickprofiler_files.cmake
+    INCLUDE_DIRECTORIES
+        PUBLIC
+            Include
+        PRIVATE
+            Source
+    BUILD_DEPENDENCIES
+        PUBLIC
+            AZ::AzCore
+            AZ::AzFramework
+            OptickCore
+)
+
+ly_add_target(
+    NAME ${gem_name} ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
+    NAMESPACE Gem
+    FILES_CMAKE
+        optickprofiler_shared_files.cmake
+    INCLUDE_DIRECTORIES
+        PUBLIC
+            Include
+        PRIVATE
+            Source
+    BUILD_DEPENDENCIES
+        PRIVATE
+            Gem::${gem_name}.Static
+)
+
+ly_add_source_properties(
+    SOURCES
+        Source/ProfilerModule.cpp
+    PROPERTY COMPILE_DEFINITIONS
+        VALUES
+            O3DE_GEM_NAME=${gem_name}
+            O3DE_GEM_VERSION=${gem_version})
+
+ly_create_alias(NAME ${gem_name}.Servers NAMESPACE Gem TARGETS Gem::${gem_name})
+ly_create_alias(NAME ${gem_name}.Builders NAMESPACE Gem TARGETS Gem::${gem_name})
+ly_create_alias(NAME ${gem_name}.Clients NAMESPACE Gem TARGETS Gem::${gem_name})
+ly_create_alias(NAME ${gem_name}.Unified NAMESPACE Gem TARGETS Gem::${gem_name})
+ly_create_alias(NAME ${gem_name}.Tools NAMESPACE Gem TARGETS Gem::${gem_name})

+ 129 - 0
Gems/ExternalProfilers/OptickProfiler/Code/Source/OptickProfilerEventForwarder.cpp

@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <OptickProfilerEventForwarder.h>
+
+#include <AzCore/Debug/ProfilerBus.h>
+#include <AzCore/Interface/Interface.h>
+#include <AzCore/Serialization/SerializeContext.h>
+#include <AzCore/Utils/Utils.h>
+#include <AzCore/std/parallel/thread.h>
+#include <AzCore/std/time.h>
+#include <optick.h>
+
+namespace OptickProfiler
+{
+    thread_local Optick::EventStorage* OptickProfilerEventForwarder::m_pOptickStorage = nullptr;
+
+    bool OnOptickStateChanged(Optick::State::Type state)
+    {
+        switch (state)
+        {
+        case Optick::State::DUMP_CAPTURE:
+            {
+                auto projectName = AZ::Utils::GetProjectName();
+                Optick::AttachSummary("Project", projectName.c_str());
+            }
+            break;
+        }
+        return true;
+    }
+
+    void OptickProfilerEventForwarder::Init()
+    {
+        AZ::Interface<AZ::Debug::Profiler>::Register(this);
+        AZ::TickBus::Handler::BusConnect();
+        AZStd::ThreadEventBus::Handler::BusConnect();
+
+        Optick::SetStateChangedCallback(OnOptickStateChanged);
+        m_pOptickFrameTag = Optick::EventDescription::Create("Frame", "", 0);
+        m_pOptickStorage = Optick::RegisterStorage("Main Thread", AZStd::this_thread::get_id().m_id);
+
+        m_initialized = true;
+    }
+
+    void OptickProfilerEventForwarder::Shutdown()
+    {
+        if (!m_initialized)
+        {
+            return;
+        }
+
+        // When this call is made, no more thread profiling calls can be performed anymore
+        AZ::Interface<AZ::Debug::Profiler>::Unregister(this);
+
+        // Wait for the remaining threads that might still be processing its profiling calls
+        AZStd::unique_lock<AZStd::shared_mutex> shutdownLock(m_shutdownMutex);
+
+        AZStd::ThreadEventBus::Handler::BusDisconnect();
+        AZ::TickBus::Handler::BusDisconnect();
+
+        Optick::StopCapture();
+        Optick::Shutdown();
+    }
+
+    void OptickProfilerEventForwarder::BeginRegion(
+        [[maybe_unused]] const AZ::Debug::Budget* budget, [[maybe_unused]] const char* eventName, ...)
+    {
+        if (!m_pOptickStorage && m_threadIdToNameMutex.try_lock_shared())
+        {
+            AZStd::native_thread_id_type id = AZStd::this_thread::get_id().m_id;
+            const AZStd::string& name = m_threadIdToName.contains(id) ? m_threadIdToName.at(id) : "";
+
+            m_pOptickStorage = Optick::RegisterStorage(name.c_str(), id);
+            m_threadIdToNameMutex.unlock_shared();
+        }
+
+        // Try to lock here, the shutdownMutex will only be contested when the CpuProfiler is shutting down.
+        if (m_shutdownMutex.try_lock_shared())
+        {
+            Optick::EventDescription* pDesc = Optick::EventDescription::CreateShared(eventName);
+            Optick::Event::Push(m_pOptickStorage, pDesc, Optick::GetHighPrecisionTime());
+            m_shutdownMutex.unlock_shared();
+        }
+    }
+
+    void OptickProfilerEventForwarder::EndRegion([[maybe_unused]] const AZ::Debug::Budget* budget)
+    {
+        // Try to lock here, the shutdownMutex will only be contested when the CpuProfiler is shutting down.
+        if (m_shutdownMutex.try_lock_shared())
+        {
+            Optick::Event::Pop(m_pOptickStorage, Optick::GetHighPrecisionTime());
+            m_shutdownMutex.unlock_shared();
+        }
+    }
+
+    int OptickProfilerEventForwarder::GetTickOrder()
+    {
+        return AZ::ComponentTickBus::TICK_FIRST;
+    }
+
+    void OptickProfilerEventForwarder::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
+    {
+        const int64_t frameTick = Optick::GetHighPrecisionTime();
+
+        Optick::Event::Pop(m_pOptickStorage, frameTick);
+        Optick::EndFrame(Optick::FrameType::CPU);
+
+        Optick::Update();
+
+        const uint32_t frameNumber = Optick::BeginFrame(Optick::FrameType::CPU, frameTick);
+        Optick::Event::Push(m_pOptickStorage, Optick::GetFrameDescription(), frameTick);
+        Optick::AttachTag(m_pOptickStorage, *m_pOptickFrameTag, frameNumber, frameTick);
+    }
+
+    void OptickProfilerEventForwarder::OnThreadEnter(const AZStd::thread::id& id, const AZStd::thread_desc* desc)
+    {
+        AZStd::unique_lock<AZStd::shared_mutex> lock(m_threadIdToNameMutex);
+        m_threadIdToName[id.m_id] = desc->m_name;
+    }
+
+    void OptickProfilerEventForwarder::OnThreadExit([[maybe_unused]] const AZStd::thread::id& id)
+    {
+    }
+} // namespace OptickProfiler

+ 70 - 0
Gems/ExternalProfilers/OptickProfiler/Code/Source/OptickProfilerEventForwarder.h

@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Component/TickBus.h>
+#include <AzCore/Debug/Profiler.h>
+#include <AzCore/Memory/SystemAllocator.h>
+#include <AzCore/Name/Name.h>
+#include <AzCore/RTTI/RTTI.h>
+#include <AzCore/std/containers/unordered_map.h>
+#include <AzCore/std/parallel/mutex.h>
+#include <AzCore/std/parallel/shared_mutex.h>
+#include <AzCore/std/parallel/threadbus.h>
+
+namespace Optick
+{
+    struct EventDescription;
+    struct EventStorage;
+} // namespace Optick
+
+namespace OptickProfiler
+{
+    //! Listen to 03DE frame/profiling events and forward them to the Optick profiling library
+    class OptickProfilerEventForwarder final
+        : public AZ::Debug::Profiler
+        , public AZ::TickBus::Handler
+        , public AZStd::ThreadEventBus::Handler
+    {
+    public:
+        AZ_RTTI(OptickProfilerEventForwarder, "{E4076EA4-EF44-499A-9750-37B623BBBF7C}", AZ::Debug::Profiler);
+        AZ_CLASS_ALLOCATOR(OptickProfilerEventForwarder, AZ::SystemAllocator);
+
+        OptickProfilerEventForwarder() = default;
+        ~OptickProfilerEventForwarder() = default;
+
+        //! Registers/un-registers the AZ::Debug::Profiler instance to the interface
+        void Init();
+        void Shutdown();
+
+        //! AZ::Debug::Profiler overrides
+        void BeginRegion(const AZ::Debug::Budget* budget, const char* eventName, ...) final override;
+        void EndRegion(const AZ::Debug::Budget* budget) final override;
+
+        //! AZ::TickBus::Handler overrides
+        int GetTickOrder() final override;
+        void OnTick(float deltaTime, AZ::ScriptTimePoint timePoint) final override;
+
+        //! AZStd::ThreadEventBus::Handler overrides
+        virtual void OnThreadEnter(const AZStd::thread::id& id, const AZStd::thread_desc* desc) final override;
+        virtual void OnThreadExit(const AZStd::thread::id& id) final override;
+
+    private:
+        // This lock will only be contested when the OptickProfilerEventForwarder's Shutdown() method has been called
+        AZStd::shared_mutex m_shutdownMutex;
+
+        AZStd::shared_mutex m_threadIdToNameMutex;
+        AZStd::unordered_map<AZStd::native_thread_id_type, AZStd::string> m_threadIdToName;
+
+        static thread_local Optick::EventStorage* m_pOptickStorage;
+        Optick::EventDescription* m_pOptickFrameTag = nullptr;
+
+        bool m_initialized = false;
+    };
+} // namespace OptickProfiler

+ 51 - 0
Gems/ExternalProfilers/OptickProfiler/Code/Source/ProfilerModule.cpp

@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <ProfilerSystemComponent.h>
+
+#include <AzCore/Memory/SystemAllocator.h>
+#include <AzCore/Module/Module.h>
+
+namespace OptickProfiler
+{
+    class ProfilerModule : public AZ::Module
+    {
+    public:
+        AZ_RTTI(ProfilerModule, "{189570C0-0E0E-4826-8AEC-DCE972CFC9B2}", AZ::Module);
+        AZ_CLASS_ALLOCATOR(ProfilerModule, AZ::SystemAllocator);
+
+        ProfilerModule()
+        {
+            // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here.
+            // Add ALL components descriptors associated with this gem to m_descriptors.
+            // This will associate the AzTypeInfo information for the components with the the SerializeContext, BehaviorContext and
+            // EditContext. This happens through the [MyComponent]::Reflect() function.
+            m_descriptors.insert(
+                m_descriptors.end(),
+                {
+                    ProfilerSystemComponent::CreateDescriptor(),
+                });
+        }
+
+        /**
+         * Add required SystemComponents to the SystemEntity.
+         */
+        AZ::ComponentTypeList GetRequiredSystemComponents() const override
+        {
+            return AZ::ComponentTypeList{
+                azrtti_typeid<ProfilerSystemComponent>(),
+            };
+        }
+    };
+} // namespace OptickProfiler
+
+#if defined(O3DE_GEM_NAME)
+AZ_DECLARE_MODULE_CLASS(AZ_JOIN(Gem_, O3DE_GEM_NAME), OptickProfiler::ProfilerModule)
+#else
+AZ_DECLARE_MODULE_CLASS(Gem_OptickProfiler, OptickProfiler::ProfilerModule)
+#endif

+ 114 - 0
Gems/ExternalProfilers/OptickProfiler/Code/Source/ProfilerSystemComponent.cpp

@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include "ProfilerSystemComponent.h"
+
+#include <AzCore/IO/FileIO.h>
+#include <AzCore/RTTI/BehaviorContext.h>
+#include <AzCore/Serialization/EditContext.h>
+#include <AzCore/Serialization/EditContextConstants.inl>
+#include <AzCore/Serialization/SerializeContext.h>
+#include <optick.h>
+
+namespace OptickProfiler
+{
+    static constexpr AZ::Crc32 profilerServiceCrc = AZ_CRC_CE("ProfilerService");
+
+    void ProfilerSystemComponent::Reflect(AZ::ReflectContext* context)
+    {
+        if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
+        {
+            serialize->Class<ProfilerSystemComponent, AZ::Component>()->Version(0);
+        }
+    }
+
+    void ProfilerSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
+    {
+        provided.push_back(profilerServiceCrc);
+    }
+
+    void ProfilerSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
+    {
+        incompatible.push_back(profilerServiceCrc);
+    }
+
+    void ProfilerSystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required)
+    {
+    }
+
+    void ProfilerSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
+    {
+    }
+
+    ProfilerSystemComponent::ProfilerSystemComponent()
+    {
+        if (AZ::Debug::ProfilerSystemInterface::Get() == nullptr)
+        {
+            AZ::Debug::ProfilerSystemInterface::Register(this);
+        }
+    }
+
+    ProfilerSystemComponent::~ProfilerSystemComponent()
+    {
+        if (AZ::Debug::ProfilerSystemInterface::Get() == this)
+        {
+            AZ::Debug::ProfilerSystemInterface::Unregister(this);
+        }
+    }
+
+    void ProfilerSystemComponent::Activate()
+    {
+        m_eventForwarder.Init();
+    }
+
+    void ProfilerSystemComponent::Deactivate()
+    {
+        m_eventForwarder.Shutdown();
+    }
+
+    bool ProfilerSystemComponent::IsActive() const
+    {
+        return false;
+    }
+
+    void ProfilerSystemComponent::SetActive([[maybe_unused]] bool enabled)
+    {
+    }
+
+    bool ProfilerSystemComponent::CaptureFrame([[maybe_unused]] const AZStd::string& outputFilePath)
+    {
+        return false;
+    }
+
+    bool ProfilerSystemComponent::StartCapture(AZStd::string outputFilePath)
+    {
+        if (!m_cpuCaptureInProgress && Optick::StartCapture())
+        {
+            m_captureFile = AZStd::move(outputFilePath);
+            m_cpuCaptureInProgress = true;
+            return true;
+        }
+        return false;
+    }
+
+    bool ProfilerSystemComponent::EndCapture()
+    {
+        if (m_cpuCaptureInProgress && Optick::StopCapture())
+        {
+            m_cpuCaptureInProgress = false;
+            return Optick::SaveCapture(m_captureFile.c_str());
+        }
+        return false;
+    }
+
+    bool ProfilerSystemComponent::IsCaptureInProgress() const
+    {
+        return m_cpuCaptureInProgress;
+    }
+
+} // namespace OptickProfiler

+ 54 - 0
Gems/ExternalProfilers/OptickProfiler/Code/Source/ProfilerSystemComponent.h

@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include "OptickProfilerEventForwarder.h"
+
+#include <AzCore/Component/Component.h>
+#include <AzCore/Debug/ProfilerBus.h>
+
+namespace OptickProfiler
+{
+    class ProfilerSystemComponent
+        : public AZ::Component
+        , protected AZ::Debug::ProfilerRequests
+    {
+    public:
+        AZ_COMPONENT(ProfilerSystemComponent, "{E140D972-C1C0-44A7-A563-9F973944A8A1}");
+
+        static void Reflect(AZ::ReflectContext* context);
+
+        static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
+        static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
+        static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
+        static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
+
+        ProfilerSystemComponent();
+        ~ProfilerSystemComponent();
+
+    protected:
+        // AZ::Component interface implementation
+        void Activate() override;
+        void Deactivate() override;
+
+        // ProfilerRequests interface implementation
+        bool IsActive() const override;
+        void SetActive(bool active) override;
+        bool CaptureFrame(const AZStd::string& outputFilePath) override;
+        bool StartCapture(AZStd::string outputFilePath) override;
+        bool EndCapture() override;
+        bool IsCaptureInProgress() const override;
+
+    private:
+        AZStd::string m_captureFile;
+        AZStd::atomic_bool m_cpuCaptureInProgress{ false };
+        OptickProfilerEventForwarder m_eventForwarder;
+    };
+
+} // namespace OptickProfiler

+ 28 - 0
Gems/ExternalProfilers/OptickProfiler/Code/optick.patch

@@ -0,0 +1,28 @@
+diff --git a/src/optick.h b/src/optick.h
+index 96b28b9..8782d73 100644
+--- a/src/optick.h
++++ b/src/optick.h
+@@ -787,6 +787,7 @@ struct OPTICK_API GPUContextScope
+ };
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ OPTICK_API const EventDescription* GetFrameDescription(FrameType::Type frame = FrameType::CPU);
++OPTICK_API void AttachTag(EventStorage* storage, const EventDescription& description, uint32_t val, int64_t timestamp);
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ typedef void* (*AllocateFn)(size_t);
+ typedef void  (*DeallocateFn)(void*);
+diff --git a/src/optick_core.cpp b/src/optick_core.cpp
+index a992c4f..b5b3537 100644
+--- a/src/optick_core.cpp
++++ b/src/optick_core.cpp
+@@ -1823,6 +1823,11 @@ OPTICK_API const EventDescription* GetFrameDescription(FrameType::Type frame)
+ 	return Core::Get().GetFrameDescription(frame);
+ }
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++OPTICK_API void AttachTag(EventStorage* storage, const EventDescription& description, uint32_t val, int64_t timestamp)
++{
++    storage->tagU32Buffer.Add(TagU32(description, val, timestamp));
++}
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ OPTICK_API void SetAllocator(AllocateFn allocateFn, DeallocateFn deallocateFn, InitThreadCb initThreadCb)
+ {
+ 	Memory::SetAllocator(allocateFn, deallocateFn, initThreadCb);

+ 14 - 0
Gems/ExternalProfilers/OptickProfiler/Code/optickprofiler_files.cmake

@@ -0,0 +1,14 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    Source/OptickProfilerEventForwarder.h
+    Source/OptickProfilerEventForwarder.cpp
+    Source/ProfilerSystemComponent.cpp
+    Source/ProfilerSystemComponent.h
+)

+ 11 - 0
Gems/ExternalProfilers/OptickProfiler/Code/optickprofiler_shared_files.cmake

@@ -0,0 +1,11 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    Source/ProfilerModule.cpp
+)

+ 23 - 0
Gems/ExternalProfilers/OptickProfiler/gem.json

@@ -0,0 +1,23 @@
+{
+    "gem_name": "OptickProfiler",
+    "version": "0.0.0",
+    "display_name": "Optick Profiler",
+    "license": "Apache-2.0 Or MIT",
+    "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt",
+    "origin": "O3DE Extras",
+    "origin_url": "https://github.com/o3de/o3de-extras/development/Gems/ExternalProfilers/OptickProfiler",
+    "type": "Code",
+    "summary": "Implements the O3DE profiler tags to be used by the Optick third party profiler",
+    "canonical_tags": [
+        "Gem",
+        "Tools"
+    ],
+    "user_tags": [
+        "Profiler"
+    ],
+    "icon_path": "preview.png",
+    "requirements": "Users will need to download Optick GUI from the <a href='https://github.com/bombomby/optick/releases'>Github release</a>.",
+    "dependencies": [
+    ],
+    "provided_unique_service": "Profiler"
+}

+ 3 - 0
Gems/ExternalProfilers/OptickProfiler/preview.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b9aceaec5ac0ed223a91709a95b6679f498ea9ee91c47228dcd2af49bed805c2
+size 3343

+ 11 - 0
Gems/ExternalProfilers/SuperluminalProfiler/CMakeLists.txt

@@ -0,0 +1,11 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+o3de_gem_setup("SuperluminalProfiler")
+
+add_subdirectory(Code)

+ 66 - 0
Gems/ExternalProfilers/SuperluminalProfiler/Code/CMakeLists.txt

@@ -0,0 +1,66 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(SUPERLUMINAL_API_PATH "C:/Program Files/Superluminal/Performance/API" CACHE PATH "Path to the Superluminal 3rd party profiler API folder.")
+list(APPEND CMAKE_MODULE_PATH ${SUPERLUMINAL_API_PATH})
+
+if (NOT EXISTS ${SUPERLUMINAL_API_PATH})
+    message(FATAL_ERROR "Superluminal profiler not found. Either update SUPERLUMINAL_API_PATH cmake variable or download Superluminal from https://superluminal.eu/")
+else()
+    message(STATUS "SuperluminalProfiler Gem uses ${SUPERLUMINAL_API_PATH} (License: Commercial)")
+endif()
+
+find_package(SuperluminalAPI REQUIRED)
+
+ly_add_target(
+    NAME ${gem_name}.Static STATIC
+    NAMESPACE Gem
+    FILES_CMAKE
+        superluminalprofiler_files.cmake
+    INCLUDE_DIRECTORIES
+        PUBLIC
+            Include
+        PRIVATE
+            Source
+            ${SuperluminalAPI_INCLUDE_DIRS}
+    BUILD_DEPENDENCIES
+        PUBLIC
+            AZ::AzCore
+            AZ::AzFramework
+        PRIVATE
+            ${SuperluminalAPI_LIBS_RELEASE}
+)
+
+ly_add_target(
+    NAME ${gem_name} ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
+    NAMESPACE Gem
+    FILES_CMAKE
+        superluminalprofiler_shared_files.cmake
+    INCLUDE_DIRECTORIES
+        PUBLIC
+            Include
+        PRIVATE
+            Source
+    BUILD_DEPENDENCIES
+        PRIVATE
+            Gem::${gem_name}.Static
+)
+
+ly_add_source_properties(
+    SOURCES
+        Source/ProfilerModule.cpp
+    PROPERTY COMPILE_DEFINITIONS
+        VALUES
+            O3DE_GEM_NAME=${gem_name}
+            O3DE_GEM_VERSION=${gem_version})
+
+ly_create_alias(NAME ${gem_name}.Servers NAMESPACE Gem TARGETS Gem::${gem_name})
+ly_create_alias(NAME ${gem_name}.Builders NAMESPACE Gem TARGETS Gem::${gem_name})
+ly_create_alias(NAME ${gem_name}.Clients NAMESPACE Gem TARGETS Gem::${gem_name})
+ly_create_alias(NAME ${gem_name}.Unified NAMESPACE Gem TARGETS Gem::${gem_name})
+ly_create_alias(NAME ${gem_name}.Tools NAMESPACE Gem TARGETS Gem::${gem_name})

+ 51 - 0
Gems/ExternalProfilers/SuperluminalProfiler/Code/Source/ProfilerModule.cpp

@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <ProfilerSystemComponent.h>
+
+#include <AzCore/Memory/SystemAllocator.h>
+#include <AzCore/Module/Module.h>
+
+namespace SuperluminalProfiler
+{
+    class ProfilerModule : public AZ::Module
+    {
+    public:
+        AZ_RTTI(ProfilerModule, "{7C666AFB-E699-42FB-8F32-DAEE5A62CD01}", AZ::Module);
+        AZ_CLASS_ALLOCATOR(ProfilerModule, AZ::SystemAllocator);
+
+        ProfilerModule()
+        {
+            // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here.
+            // Add ALL components descriptors associated with this gem to m_descriptors.
+            // This will associate the AzTypeInfo information for the components with the the SerializeContext, BehaviorContext and
+            // EditContext. This happens through the [MyComponent]::Reflect() function.
+            m_descriptors.insert(
+                m_descriptors.end(),
+                {
+                    ProfilerSystemComponent::CreateDescriptor(),
+                });
+        }
+
+        /**
+         * Add required SystemComponents to the SystemEntity.
+         */
+        AZ::ComponentTypeList GetRequiredSystemComponents() const override
+        {
+            return AZ::ComponentTypeList{
+                azrtti_typeid<ProfilerSystemComponent>(),
+            };
+        }
+    };
+} // namespace SuperluminalProfiler
+
+#if defined(O3DE_GEM_NAME)
+AZ_DECLARE_MODULE_CLASS(AZ_JOIN(Gem_, O3DE_GEM_NAME), SuperluminalProfiler::ProfilerModule)
+#else
+AZ_DECLARE_MODULE_CLASS(Gem_SuperluminalProfiler, SuperluminalProfiler::ProfilerModule)
+#endif

+ 101 - 0
Gems/ExternalProfilers/SuperluminalProfiler/Code/Source/ProfilerSystemComponent.cpp

@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include "ProfilerSystemComponent.h"
+
+#include <AzCore/RTTI/BehaviorContext.h>
+#include <AzCore/Serialization/EditContext.h>
+#include <AzCore/Serialization/EditContextConstants.inl>
+#include <AzCore/Serialization/SerializeContext.h>
+
+namespace SuperluminalProfiler
+{
+    static constexpr AZ::Crc32 profilerServiceCrc = AZ_CRC_CE("ProfilerService");
+
+    void ProfilerSystemComponent::Reflect(AZ::ReflectContext* context)
+    {
+        if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
+        {
+            serialize->Class<ProfilerSystemComponent, AZ::Component>()->Version(0);
+        }
+    }
+
+    void ProfilerSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
+    {
+        provided.push_back(profilerServiceCrc);
+    }
+
+    void ProfilerSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
+    {
+        incompatible.push_back(profilerServiceCrc);
+    }
+
+    void ProfilerSystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required)
+    {
+    }
+
+    void ProfilerSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
+    {
+    }
+
+    ProfilerSystemComponent::ProfilerSystemComponent()
+    {
+        if (AZ::Debug::ProfilerSystemInterface::Get() == nullptr)
+        {
+            AZ::Debug::ProfilerSystemInterface::Register(this);
+        }
+    }
+
+    ProfilerSystemComponent::~ProfilerSystemComponent()
+    {
+        if (AZ::Debug::ProfilerSystemInterface::Get() == this)
+        {
+            AZ::Debug::ProfilerSystemInterface::Unregister(this);
+        }
+    }
+
+    void ProfilerSystemComponent::Activate()
+    {
+        m_eventForwarder.Init();
+    }
+
+    void ProfilerSystemComponent::Deactivate()
+    {
+        m_eventForwarder.Shutdown();
+    }
+
+    bool ProfilerSystemComponent::IsActive() const
+    {
+        return false;
+    }
+
+    void ProfilerSystemComponent::SetActive([[maybe_unused]] bool enabled)
+    {
+    }
+
+    bool ProfilerSystemComponent::CaptureFrame([[maybe_unused]] const AZStd::string& outputFilePath)
+    {
+        return true;
+    }
+
+    bool ProfilerSystemComponent::StartCapture([[maybe_unused]] AZStd::string outputFilePath)
+    {
+        return true;
+    }
+
+    bool ProfilerSystemComponent::EndCapture()
+    {
+        return true;
+    }
+
+    bool ProfilerSystemComponent::IsCaptureInProgress() const
+    {
+        return false;
+    }
+
+} // namespace SuperluminalProfiler

+ 53 - 0
Gems/ExternalProfilers/SuperluminalProfiler/Code/Source/ProfilerSystemComponent.h

@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include "SuperluminalProfilerEventForwarder.h"
+
+#include <AzCore/Component/Component.h>
+#include <AzCore/Debug/ProfilerBus.h>
+
+namespace SuperluminalProfiler
+{
+    class ProfilerSystemComponent
+        : public AZ::Component
+        , protected AZ::Debug::ProfilerRequests
+    {
+    public:
+        AZ_COMPONENT(ProfilerSystemComponent, "{C920A0CC-A053-4A0E-8550-DC44FF03A2D1}");
+
+        static void Reflect(AZ::ReflectContext* context);
+
+        static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
+        static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
+        static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
+        static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
+
+        ProfilerSystemComponent();
+        ~ProfilerSystemComponent();
+
+    protected:
+        // AZ::Component interface implementation
+        void Activate() override;
+        void Deactivate() override;
+
+        // ProfilerRequests interface implementation
+        bool IsActive() const override;
+        void SetActive(bool active) override;
+        bool CaptureFrame(const AZStd::string& outputFilePath) override;
+        bool StartCapture(AZStd::string outputFilePath) override;
+        bool EndCapture() override;
+        bool IsCaptureInProgress() const override;
+
+    private:
+        AZStd::atomic_bool m_cpuCaptureInProgress{ false };
+        SuperluminalProfilerEventForwarder m_eventForwarder;
+    };
+
+} // namespace SuperluminalProfiler

+ 56 - 0
Gems/ExternalProfilers/SuperluminalProfiler/Code/Source/SuperluminalProfilerEventForwarder.cpp

@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <SuperluminalProfilerEventForwarder.h>
+
+#include <AzCore/Interface/Interface.h>
+#include <AzCore/Serialization/SerializeContext.h>
+#include <Superluminal/PerformanceAPI.h>
+
+namespace SuperluminalProfiler
+{
+    void SuperluminalProfilerEventForwarder::Init()
+    {
+        AZ::Interface<AZ::Debug::Profiler>::Register(this);
+        m_initialized = true;
+    }
+
+    void SuperluminalProfilerEventForwarder::Shutdown()
+    {
+        if (!m_initialized)
+        {
+            return;
+        }
+
+        // When this call is made, no more thread profiling calls can be performed anymore
+        AZ::Interface<AZ::Debug::Profiler>::Unregister(this);
+
+        // Wait for the remaining threads that might still be processing its profiling calls
+        AZStd::unique_lock<AZStd::shared_mutex> shutdownLock(m_shutdownMutex);
+    }
+
+    void SuperluminalProfilerEventForwarder::BeginRegion(const AZ::Debug::Budget* budget, const char* eventName, ...)
+    {
+        // Try to lock here, the shutdownMutex will only be contested when the CpuProfiler is shutting down.
+        if (m_shutdownMutex.try_lock_shared())
+        {
+            PerformanceAPI_BeginEvent(eventName, budget->Name(), budget->Crc());
+            m_shutdownMutex.unlock_shared();
+        }
+    }
+
+    void SuperluminalProfilerEventForwarder::EndRegion([[maybe_unused]] const AZ::Debug::Budget* budget)
+    {
+        // Try to lock here, the shutdownMutex will only be contested when the CpuProfiler is shutting down.
+        if (m_shutdownMutex.try_lock_shared())
+        {
+            PerformanceAPI_EndEvent();
+            m_shutdownMutex.unlock_shared();
+        }
+    }
+} // namespace SuperluminalProfiler

+ 49 - 0
Gems/ExternalProfilers/SuperluminalProfiler/Code/Source/SuperluminalProfilerEventForwarder.h

@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Component/TickBus.h>
+#include <AzCore/Debug/Profiler.h>
+#include <AzCore/Memory/SystemAllocator.h>
+#include <AzCore/Name/Name.h>
+#include <AzCore/RTTI/RTTI.h>
+#include <AzCore/std/parallel/mutex.h>
+#include <AzCore/std/parallel/shared_mutex.h>
+
+namespace SuperluminalProfiler
+{
+    //! Listen to 03DE frame/profiling events and forward them to the Superluminal profiling library
+    class SuperluminalProfilerEventForwarder final : public AZ::Debug::Profiler
+    {
+    public:
+        AZ_RTTI(SuperluminalProfilerEventForwarder, "{A05E7DC4-AB00-41BC-A739-8E58908CB84F}", AZ::Debug::Profiler);
+        AZ_CLASS_ALLOCATOR(SuperluminalProfilerEventForwarder, AZ::SystemAllocator);
+
+        SuperluminalProfilerEventForwarder() = default;
+        ~SuperluminalProfilerEventForwarder() = default;
+
+        //! Registers/un-registers the AZ::Debug::Profiler instance to the interface
+        void Init();
+        void Shutdown();
+
+        //! AZ::Debug::Profiler overrides...
+        void BeginRegion(const AZ::Debug::Budget* budget, const char* eventName, ...) final override;
+        void EndRegion(const AZ::Debug::Budget* budget) final override;
+
+        //! Check to see if a programmatic capture is currently in progress, implies
+        //! that the profiler is active if returns True.
+        bool IsContinuousCaptureInProgress() const;
+
+    private:
+        // This lock will only be contested when the SuperluminalProfilerEventForwarder's Shutdown() method has been called
+        AZStd::shared_mutex m_shutdownMutex;
+
+        bool m_initialized = false;
+    };
+} // namespace SuperluminalProfiler

+ 14 - 0
Gems/ExternalProfilers/SuperluminalProfiler/Code/superluminalprofiler_files.cmake

@@ -0,0 +1,14 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    Source/SuperluminalProfilerEventForwarder.h
+    Source/SuperluminalProfilerEventForwarder.cpp
+    Source/ProfilerSystemComponent.cpp
+    Source/ProfilerSystemComponent.h
+)

+ 11 - 0
Gems/ExternalProfilers/SuperluminalProfiler/Code/superluminalprofiler_shared_files.cmake

@@ -0,0 +1,11 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    Source/ProfilerModule.cpp
+)

+ 24 - 0
Gems/ExternalProfilers/SuperluminalProfiler/gem.json

@@ -0,0 +1,24 @@
+{
+    "gem_name": "SuperluminalProfiler",
+    "version": "0.0.0",
+    "display_name": "Superluminal Profiler",
+    "license": "Apache-2.0 Or MIT",
+    "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt",
+    "origin": "O3DE Extras",
+    "origin_url": "https://github.com/o3de/o3de-extras/development/Gems/ExternalProfilers/SuperluminalProfiler",
+    "type": "Code",
+    "summary": "Implements the O3DE profiler tags to be used by the superluminal third party profiler",
+    "canonical_tags": [
+        "Gem",
+        "Tools"
+    ],
+    "user_tags": [
+        "Profiler"
+    ],
+    "icon_path": "preview.png",
+    "requirements": "Users will need to download Superluminal from the <a href='https://superluminal.eu/'>Superluminal Web Site</a>.",
+    "documentation_url": "https://www.superluminal.eu/docs/documentation.html",
+    "dependencies": [
+    ],
+    "provided_unique_service": "Profiler"
+}

+ 3 - 0
Gems/ExternalProfilers/SuperluminalProfiler/preview.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e94d306395c37690f4ff8cb71ebde477e7446e0b0c23e15f23c0a0d0c9ea221b
+size 3286

+ 11 - 0
Gems/ExternalProfilers/TracyProfiler/CMakeLists.txt

@@ -0,0 +1,11 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+o3de_gem_setup("TracyProfiler")
+
+add_subdirectory(Code)

+ 85 - 0
Gems/ExternalProfilers/TracyProfiler/Code/CMakeLists.txt

@@ -0,0 +1,85 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+# Add Tracy dependency using FetchContent
+include(FetchContent)
+FetchContent_Declare(
+    Tracy
+    GIT_REPOSITORY "https://github.com/wolfpld/tracy.git"
+    GIT_TAG "5d542dc09f3d9378d005092a4ad446bd405f819a" # version 0.11.1
+)
+
+set(TRACY_ENABLE ON)
+set(TRACY_CALLSTACK ON)
+set(TRACY_ON_DEMAND ON)
+
+FetchContent_MakeAvailable(Tracy)
+
+message(STATUS "TracyProfiler gem uses https://github.com/wolfpld/tracy version 0.11.1 (License: BSD-3-Clause)")
+
+# Let's not clutter the root of any IDE folder structure with 3rd party dependencies
+# Setting the FOLDER makes it show up there in the solution build in VS and similarly
+# any other IDEs that organize in folders.
+set_target_properties(
+        TracyClient 
+    PROPERTIES 
+        FOLDER "3rdParty Dependencies"
+)
+
+ly_add_target(
+    NAME ${gem_name}.Static STATIC
+    NAMESPACE Gem
+    FILES_CMAKE
+        tracyprofiler_files.cmake
+    INCLUDE_DIRECTORIES
+        PUBLIC
+            Include
+        PRIVATE
+            Source
+            ${Tracy_SOURCE_DIR}/public/tracy
+    COMPILE_DEFINITIONS
+        PRIVATE
+            TRACY_ENABLE
+    BUILD_DEPENDENCIES
+        PUBLIC
+            AZ::AzCore
+            AZ::AzFramework
+            TracyClient
+)
+
+ly_add_target(
+    NAME ${gem_name} ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
+    NAMESPACE Gem
+    FILES_CMAKE
+        tracyprofiler_shared_files.cmake
+    INCLUDE_DIRECTORIES
+        PUBLIC
+            Include
+        PRIVATE
+            Source
+    COMPILE_DEFINITIONS
+        PRIVATE
+            TRACY_ENABLE
+    BUILD_DEPENDENCIES
+        PRIVATE
+            Gem::${gem_name}.Static
+)
+
+ly_add_source_properties(
+    SOURCES
+        Source/ProfilerModule.cpp
+    PROPERTY COMPILE_DEFINITIONS
+        VALUES
+            O3DE_GEM_NAME=${gem_name}
+            O3DE_GEM_VERSION=${gem_version})
+
+ly_create_alias(NAME ${gem_name}.Servers NAMESPACE Gem TARGETS Gem::${gem_name})
+ly_create_alias(NAME ${gem_name}.Builders NAMESPACE Gem TARGETS Gem::${gem_name})
+ly_create_alias(NAME ${gem_name}.Clients NAMESPACE Gem TARGETS Gem::${gem_name})
+ly_create_alias(NAME ${gem_name}.Unified NAMESPACE Gem TARGETS Gem::${gem_name})
+ly_create_alias(NAME ${gem_name}.Tools NAMESPACE Gem TARGETS Gem::${gem_name})

+ 51 - 0
Gems/ExternalProfilers/TracyProfiler/Code/Source/ProfilerModule.cpp

@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <ProfilerSystemComponent.h>
+
+#include <AzCore/Memory/SystemAllocator.h>
+#include <AzCore/Module/Module.h>
+
+namespace TracyProfiler
+{
+    class ProfilerModule : public AZ::Module
+    {
+    public:
+        AZ_RTTI(ProfilerModule, "{BCE29245-571B-44C2-94E7-84D7E06F5A1F}", AZ::Module);
+        AZ_CLASS_ALLOCATOR(ProfilerModule, AZ::SystemAllocator);
+
+        ProfilerModule()
+        {
+            // Push results of [MyComponent]::CreateDescriptor() into m_descriptors here.
+            // Add ALL components descriptors associated with this gem to m_descriptors.
+            // This will associate the AzTypeInfo information for the components with the the SerializeContext, BehaviorContext and
+            // EditContext. This happens through the [MyComponent]::Reflect() function.
+            m_descriptors.insert(
+                m_descriptors.end(),
+                {
+                    ProfilerSystemComponent::CreateDescriptor(),
+                });
+        }
+
+        /**
+         * Add required SystemComponents to the SystemEntity.
+         */
+        AZ::ComponentTypeList GetRequiredSystemComponents() const override
+        {
+            return AZ::ComponentTypeList{
+                azrtti_typeid<ProfilerSystemComponent>(),
+            };
+        }
+    };
+} // namespace TracyProfiler
+
+#if defined(O3DE_GEM_NAME)
+AZ_DECLARE_MODULE_CLASS(AZ_JOIN(Gem_, O3DE_GEM_NAME), TracyProfiler::ProfilerModule)
+#else
+AZ_DECLARE_MODULE_CLASS(Gem_TracyProfiler, TracyProfiler::ProfilerModule)
+#endif

+ 101 - 0
Gems/ExternalProfilers/TracyProfiler/Code/Source/ProfilerSystemComponent.cpp

@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include "ProfilerSystemComponent.h"
+
+#include <AzCore/RTTI/BehaviorContext.h>
+#include <AzCore/Serialization/EditContext.h>
+#include <AzCore/Serialization/EditContextConstants.inl>
+#include <AzCore/Serialization/SerializeContext.h>
+
+namespace TracyProfiler
+{
+    static constexpr AZ::Crc32 profilerServiceCrc = AZ_CRC_CE("ProfilerService");
+
+    void ProfilerSystemComponent::Reflect(AZ::ReflectContext* context)
+    {
+        if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
+        {
+            serialize->Class<ProfilerSystemComponent, AZ::Component>()->Version(0);
+        }
+    }
+
+    void ProfilerSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
+    {
+        provided.push_back(profilerServiceCrc);
+    }
+
+    void ProfilerSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
+    {
+        incompatible.push_back(profilerServiceCrc);
+    }
+
+    void ProfilerSystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required)
+    {
+    }
+
+    void ProfilerSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
+    {
+    }
+
+    ProfilerSystemComponent::ProfilerSystemComponent()
+    {
+        if (AZ::Debug::ProfilerSystemInterface::Get() == nullptr)
+        {
+            AZ::Debug::ProfilerSystemInterface::Register(this);
+        }
+    }
+
+    ProfilerSystemComponent::~ProfilerSystemComponent()
+    {
+        if (AZ::Debug::ProfilerSystemInterface::Get() == this)
+        {
+            AZ::Debug::ProfilerSystemInterface::Unregister(this);
+        }
+    }
+
+    void ProfilerSystemComponent::Activate()
+    {
+        m_eventForwarder.Init();
+    }
+
+    void ProfilerSystemComponent::Deactivate()
+    {
+        m_eventForwarder.Shutdown();
+    }
+
+    bool ProfilerSystemComponent::IsActive() const
+    {
+        return false;
+    }
+
+    void ProfilerSystemComponent::SetActive([[maybe_unused]] bool enabled)
+    {
+    }
+
+    bool ProfilerSystemComponent::CaptureFrame([[maybe_unused]] const AZStd::string& outputFilePath)
+    {
+        return true;
+    }
+
+    bool ProfilerSystemComponent::StartCapture([[maybe_unused]] AZStd::string outputFilePath)
+    {
+        return true;
+    }
+
+    bool ProfilerSystemComponent::EndCapture()
+    {
+        return true;
+    }
+
+    bool ProfilerSystemComponent::IsCaptureInProgress() const
+    {
+        return false;
+    }
+
+} // namespace TracyProfiler

+ 53 - 0
Gems/ExternalProfilers/TracyProfiler/Code/Source/ProfilerSystemComponent.h

@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include "TracyProfilerEventForwarder.h"
+
+#include <AzCore/Component/Component.h>
+#include <AzCore/Debug/ProfilerBus.h>
+
+namespace TracyProfiler
+{
+    class ProfilerSystemComponent
+        : public AZ::Component
+        , protected AZ::Debug::ProfilerRequests
+    {
+    public:
+        AZ_COMPONENT(ProfilerSystemComponent, "{839DAD12-4571-4484-B71F-2133A5BC1137}");
+
+        static void Reflect(AZ::ReflectContext* context);
+
+        static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
+        static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
+        static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
+        static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
+
+        ProfilerSystemComponent();
+        ~ProfilerSystemComponent();
+
+    protected:
+        // AZ::Component interface implementation
+        void Activate() override;
+        void Deactivate() override;
+
+        // ProfilerRequests interface implementation
+        bool IsActive() const override;
+        void SetActive(bool active) override;
+        bool CaptureFrame(const AZStd::string& outputFilePath) override;
+        bool StartCapture(AZStd::string outputFilePath) override;
+        bool EndCapture() override;
+        bool IsCaptureInProgress() const override;
+
+    private:
+        AZStd::atomic_bool m_cpuCaptureInProgress{ false };
+        TracyProfilerEventForwarder m_eventForwarder;
+    };
+
+} // namespace TracyProfiler

+ 83 - 0
Gems/ExternalProfilers/TracyProfiler/Code/Source/TracyProfilerEventForwarder.cpp

@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <TracyProfilerEventForwarder.h>
+
+#include <AzCore/Interface/Interface.h>
+#include <AzCore/Serialization/SerializeContext.h>
+
+namespace TracyProfiler
+{
+    thread_local TracyProfilerEventForwarder::EventIdStack TracyProfilerEventForwarder::ms_threadLocalStorage;
+
+    void TracyProfilerEventForwarder::Init()
+    {
+        AZ::Interface<AZ::Debug::Profiler>::Register(this);
+        AZ::TickBus::Handler::BusConnect();
+        m_initialized = true;
+    }
+
+    void TracyProfilerEventForwarder::Shutdown()
+    {
+        if (!m_initialized)
+        {
+            return;
+        }
+
+        // When this call is made, no more thread profiling calls can be performed anymore
+        AZ::Interface<AZ::Debug::Profiler>::Unregister(this);
+
+        // Wait for the remaining threads that might still be processing its profiling calls
+        AZStd::unique_lock<AZStd::shared_mutex> shutdownLock(m_shutdownMutex);
+
+        AZ::TickBus::Handler::BusDisconnect();
+    }
+
+    void TracyProfilerEventForwarder::BeginRegion(const AZ::Debug::Budget* budget, const char* eventName, ...)
+    {
+        // Try to lock here, the shutdownMutex will only be contested when the CpuProfiler is shutting down.
+        if (m_shutdownMutex.try_lock_shared())
+        {
+            // Do not use the macro as we don't want to use static storage (else events are wrong)
+            ms_threadLocalStorage.push_back({});
+            TracyCZoneCtx& ctx = ms_threadLocalStorage.back();
+            ctx = ___tracy_emit_zone_begin_alloc_callstack(
+                ___tracy_alloc_srcloc_name(
+                    __LINE__, __FILE__, strlen(__FILE__), __FUNCTION__, strlen(__FUNCTION__), eventName, strlen(eventName), budget->Crc()),
+                TRACY_CALLSTACK,
+                true);
+            TracyCZoneText(ctx, budget->Name(), 1);
+            m_shutdownMutex.unlock_shared();
+        }
+    }
+
+    void TracyProfilerEventForwarder::EndRegion([[maybe_unused]] const AZ::Debug::Budget* budget)
+    {
+        // Try to lock here, the shutdownMutex will only be contested when the CpuProfiler is shutting down.
+        if (m_shutdownMutex.try_lock_shared() && !ms_threadLocalStorage.empty())
+        {
+            auto& ctx = ms_threadLocalStorage.back();
+            TracyCZoneEnd(ctx);
+            ms_threadLocalStorage.pop_back();
+
+            m_shutdownMutex.unlock_shared();
+        }
+    }
+
+    int TracyProfilerEventForwarder::GetTickOrder()
+    {
+        return AZ::ComponentTickBus::TICK_LAST;
+    }
+
+    void TracyProfilerEventForwarder::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
+    {
+        // From Tracy documentation about FrameMark : "Ideally, that would be right after the swap buffers command"
+        TracyCFrameMark;
+    }
+
+} // namespace TracyProfiler

+ 56 - 0
Gems/ExternalProfilers/TracyProfiler/Code/Source/TracyProfilerEventForwarder.h

@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Component/TickBus.h>
+#include <AzCore/Debug/Profiler.h>
+#include <AzCore/Memory/SystemAllocator.h>
+#include <AzCore/Name/Name.h>
+#include <AzCore/RTTI/RTTI.h>
+#include <AzCore/std/containers/vector.h>
+#include <AzCore/std/parallel/mutex.h>
+#include <AzCore/std/parallel/shared_mutex.h>
+#include <tracy/TracyC.h>
+
+namespace TracyProfiler
+{
+    //! Listen to 03DE frame/profiling events and forward them to the Tracy profiling library
+    class TracyProfilerEventForwarder final
+        : public AZ::Debug::Profiler
+        , public AZ::TickBus::Handler
+    {
+    public:
+        AZ_RTTI(TracyProfilerEventForwarder, "{9467E3F6-0581-4E46-A98A-F3C249FD7B24}", AZ::Debug::Profiler);
+        AZ_CLASS_ALLOCATOR(TracyProfilerEventForwarder, AZ::SystemAllocator);
+
+        TracyProfilerEventForwarder() = default;
+        ~TracyProfilerEventForwarder() = default;
+
+        //! Registers/un-registers the AZ::Debug::Profiler instance to the interface
+        void Init();
+        void Shutdown();
+
+        //! AZ::Debug::Profiler overrides...
+        void BeginRegion(const AZ::Debug::Budget* budget, const char* eventName, ...) final override;
+        void EndRegion(const AZ::Debug::Budget* budget) final override;
+
+        //! AZ::TickBus::Handler overrides
+        int GetTickOrder() override;
+        void OnTick(float deltaTime, AZ::ScriptTimePoint timePoint) override;
+
+    private:
+        using EventIdStack = AZStd::vector<TracyCZoneCtx>;
+        static thread_local EventIdStack ms_threadLocalStorage;
+
+        // This lock will only be contested when the TracyProfilerEventForwarder's Shutdown() method has been called
+        AZStd::shared_mutex m_shutdownMutex;
+
+        bool m_initialized = false;
+    };
+} // namespace TracyProfiler

+ 14 - 0
Gems/ExternalProfilers/TracyProfiler/Code/tracyprofiler_files.cmake

@@ -0,0 +1,14 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    Source/TracyProfilerEventForwarder.h
+    Source/TracyProfilerEventForwarder.cpp
+    Source/ProfilerSystemComponent.cpp
+    Source/ProfilerSystemComponent.h
+)

+ 11 - 0
Gems/ExternalProfilers/TracyProfiler/Code/tracyprofiler_shared_files.cmake

@@ -0,0 +1,11 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+set(FILES
+    Source/ProfilerModule.cpp
+)

+ 24 - 0
Gems/ExternalProfilers/TracyProfiler/gem.json

@@ -0,0 +1,24 @@
+{
+    "gem_name": "TracyProfiler",
+    "version": "0.0.0",
+    "display_name": "Tracy Profiler",
+    "license": "Apache-2.0 Or MIT",
+    "license_url": "https://github.com/o3de/o3de/blob/development/LICENSE.txt",
+    "origin": "O3DE Extras",
+    "origin_url": "https://github.com/o3de/o3de-extras/development/Gems/ExternalProfilers/TracyProfiler",
+    "type": "Code",
+    "summary": "Implements the O3DE profiler tags to be used by the Tracy third party profiler",
+    "canonical_tags": [
+        "Gem",
+        "Tools"
+    ],
+    "user_tags": [
+        "Profiler"
+    ],
+    "icon_path": "preview.png",
+    "requirements": "Users will need to download Tracy from the <a href='https://github.com/wolfpld/tracy/releases'>Github release</a>.",
+    "documentation_url": "https://github.com/wolfpld/tracy",
+    "dependencies": [
+    ],
+    "provided_unique_service": "Profiler"
+}

+ 3 - 0
Gems/ExternalProfilers/TracyProfiler/preview.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:577c064676b5b2b065697c98843dc2c4b8db56363548400d166aebaf14073c5f
+size 2486

+ 5 - 5
Gems/LevelGeoreferencing/Code/CMakeLists.txt

@@ -7,8 +7,8 @@
 # Get the platform specific folder ${pal_dir} for the current folder: ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}
 # Get the platform specific folder ${pal_dir} for the current folder: ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}
 # Note: o3de_pal_dir will take care of the details for us, as this may be a restricted platform
 # Note: o3de_pal_dir will take care of the details for us, as this may be a restricted platform
 #       in which case it will see if that platform is present here or in the restricted folder.
 #       in which case it will see if that platform is present here or in the restricted folder.
-#       i.e. It could here in our gem : Gems/Georeferencing/Code/Platform/<platorm_name>  or
-#            <restricted_folder>/<platform_name>/Gems/Georeferencing/Code
+#       i.e. It could here in our gem : Gems/LevelGeoreferencing/Code/Platform/<platorm_name>  or
+#            <restricted_folder>/<platform_name>/Gems/LevelGeoreferencing/Code
 o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} "${gem_restricted_path}" "${gem_path}" "${gem_parent_relative_path}")
 o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} "${gem_restricted_path}" "${gem_path}" "${gem_parent_relative_path}")
 
 
 # Now that we have the platform abstraction layer (PAL) folder for this folder, thats where we will find the
 # Now that we have the platform abstraction layer (PAL) folder for this folder, thats where we will find the
@@ -17,7 +17,7 @@ o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME} "${
 include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
 include(${pal_dir}/PAL_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
 
 
 # Check to see if building the Gem Modules are supported for the current platform
 # Check to see if building the Gem Modules are supported for the current platform
-if(NOT PAL_TRAIT_GEOREFERENCING_SUPPORTED)
+if(NOT PAL_TRAIT_LEVELGEOREFERENCING_SUPPORTED)
     return()
     return()
 endif()
 endif()
 
 
@@ -193,7 +193,7 @@ endif()
 # See if globally, tests are supported
 # See if globally, tests are supported
 if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
 if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
     # We globally support tests, see if we support tests on this platform for ${gem_name}.Tests
     # We globally support tests, see if we support tests on this platform for ${gem_name}.Tests
-    if(PAL_TRAIT_GEOREFERENCING_TEST_SUPPORTED)
+    if(PAL_TRAIT_LEVELGEOREFERENCING_TEST_SUPPORTED)
         # We support ${gem_name}.Tests on this platform, add dependency on the Private Object target
         # We support ${gem_name}.Tests on this platform, add dependency on the Private Object target
         ly_add_target(
         ly_add_target(
             NAME ${gem_name}.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
             NAME ${gem_name}.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
@@ -222,7 +222,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
     # If we are a host platform we want to add tools test like editor tests here
     # If we are a host platform we want to add tools test like editor tests here
     if(PAL_TRAIT_BUILD_HOST_TOOLS)
     if(PAL_TRAIT_BUILD_HOST_TOOLS)
         # We are a host platform, see if Editor tests are supported on this platform
         # We are a host platform, see if Editor tests are supported on this platform
-        if(PAL_TRAIT_GEOREFERENCING_EDITOR_TEST_SUPPORTED)
+        if(PAL_TRAIT_LEVELGEOREFERENCING_EDITOR_TEST_SUPPORTED)
             # We support ${gem_name}.Editor.Tests on this platform, add ${gem_name}.Editor.Tests target which depends on
             # We support ${gem_name}.Editor.Tests on this platform, add ${gem_name}.Editor.Tests target which depends on
             # private ${gem_name}.Editor.Private.Object target
             # private ${gem_name}.Editor.Private.Object target
             ly_add_target(
             ly_add_target(

+ 3 - 3
Gems/LevelGeoreferencing/Code/Platform/Android/PAL_android.cmake

@@ -3,6 +3,6 @@
 #
 #
 # SPDX-License-Identifier: Apache-2.0 OR MIT
 # SPDX-License-Identifier: Apache-2.0 OR MIT
 
 
-set(PAL_TRAIT_GEOREFERENCING_SUPPORTED TRUE)
-set(PAL_TRAIT_GEOREFERENCING_TEST_SUPPORTED FALSE)
-set(PAL_TRAIT_GEOREFERENCING_EDITOR_TEST_SUPPORTED FALSE)
+set(PAL_TRAIT_LEVELGEOREFERENCING_SUPPORTED TRUE)
+set(PAL_TRAIT_LEVELGEOREFERENCING_TEST_SUPPORTED FALSE)
+set(PAL_TRAIT_LEVELGEOREFERENCING_EDITOR_TEST_SUPPORTED FALSE)

+ 3 - 3
Gems/LevelGeoreferencing/Code/Platform/Linux/PAL_linux.cmake

@@ -3,6 +3,6 @@
 #
 #
 # SPDX-License-Identifier: Apache-2.0 OR MIT
 # SPDX-License-Identifier: Apache-2.0 OR MIT
 
 
-set(PAL_TRAIT_GEOREFERENCING_SUPPORTED TRUE)
-set(PAL_TRAIT_GEOREFERENCING_TEST_SUPPORTED TRUE)
-set(PAL_TRAIT_GEOREFERENCING_EDITOR_TEST_SUPPORTED TRUE)
+set(PAL_TRAIT_LEVELGEOREFERENCING_SUPPORTED TRUE)
+set(PAL_TRAIT_LEVELGEOREFERENCING_TEST_SUPPORTED TRUE)
+set(PAL_TRAIT_LEVELGEOREFERENCING_EDITOR_TEST_SUPPORTED TRUE)

+ 3 - 3
Gems/LevelGeoreferencing/Code/Platform/Mac/PAL_mac.cmake

@@ -3,6 +3,6 @@
 #
 #
 # SPDX-License-Identifier: Apache-2.0 OR MIT
 # SPDX-License-Identifier: Apache-2.0 OR MIT
 
 
-set(PAL_TRAIT_GEOREFERENCING_SUPPORTED TRUE)
-set(PAL_TRAIT_GEOREFERENCING_TEST_SUPPORTED FALSE)
-set(PAL_TRAIT_GEOREFERENCING_EDITOR_TEST_SUPPORTED FALSE)
+set(PAL_TRAIT_LEVELGEOREFERENCING_SUPPORTED TRUE)
+set(PAL_TRAIT_LEVELGEOREFERENCING_TEST_SUPPORTED FALSE)
+set(PAL_TRAIT_LEVELGEOREFERENCING_EDITOR_TEST_SUPPORTED FALSE)

+ 3 - 3
Gems/LevelGeoreferencing/Code/Platform/Windows/PAL_windows.cmake

@@ -3,6 +3,6 @@
 #
 #
 # SPDX-License-Identifier: Apache-2.0 OR MIT
 # SPDX-License-Identifier: Apache-2.0 OR MIT
 
 
-set(PAL_TRAIT_GEOREFERENCING_SUPPORTED TRUE)
-set(PAL_TRAIT_GEOREFERENCING_TEST_SUPPORTED TRUE)
-set(PAL_TRAIT_GEOREFERENCING_EDITOR_TEST_SUPPORTED TRUE)
+set(PAL_TRAIT_LEVELGEOREFERENCING_SUPPORTED TRUE)
+set(PAL_TRAIT_LEVELGEOREFERENCING_TEST_SUPPORTED TRUE)
+set(PAL_TRAIT_LEVELGEOREFERENCING_EDITOR_TEST_SUPPORTED TRUE)

+ 3 - 3
Gems/LevelGeoreferencing/Code/Platform/iOS/PAL_ios.cmake

@@ -3,6 +3,6 @@
 #
 #
 # SPDX-License-Identifier: Apache-2.0 OR MIT
 # SPDX-License-Identifier: Apache-2.0 OR MIT
 
 
-set(PAL_TRAIT_GEOREFERENCING_SUPPORTED TRUE)
-set(PAL_TRAIT_GEOREFERENCING_TEST_SUPPORTED FALSE)
-set(PAL_TRAIT_GEOREFERENCING_EDITOR_TEST_SUPPORTED FALSE)
+set(PAL_TRAIT_LEVELGEOREFERENCING_SUPPORTED TRUE)
+set(PAL_TRAIT_LEVELGEOREFERENCING_TEST_SUPPORTED FALSE)
+set(PAL_TRAIT_LEVELGEOREFERENCING_EDITOR_TEST_SUPPORTED FALSE)

+ 8 - 8
Gems/LevelGeoreferencing/Code/Source/Clients/GeoreferenceInternalStructures.h

@@ -1,11 +1,11 @@
 /*
 /*
-* Copyright (c) Contributors to the Open 3D Engine Project.
-* For complete copyright and license terms please see the LICENSE at the root
-* of this distribution.
-*
-* SPDX-License-Identifier: Apache-2.0 OR MIT
-*
-*/
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root
+ * of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
 
 
 #pragma once
 #pragma once
 #include <AzCore/Math/Vector3.h>
 #include <AzCore/Math/Vector3.h>
@@ -26,4 +26,4 @@ namespace Georeferencing::WGS
         double m_y = 0.0; //! Y coordinate in meters.
         double m_y = 0.0; //! Y coordinate in meters.
         double m_z = 0.0; //! Z coordinate in meters.
         double m_z = 0.0; //! Z coordinate in meters.
     };
     };
-}
+} // namespace Georeferencing::WGS

+ 7 - 7
Gems/LevelGeoreferencing/Code/Source/Clients/GeoreferencingModule.cpp

@@ -1,10 +1,10 @@
 /*
 /*
-* Copyright (c) Contributors to the Open 3D Engine Project.
-* For complete copyright and license terms please see the LICENSE at the root of this distribution.
-*
-* SPDX-License-Identifier: Apache-2.0 OR MIT
-*
-*/
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
 
 
 #include "GeoreferencingSystemComponent.h"
 #include "GeoreferencingSystemComponent.h"
 #include <Georeferencing/GeoreferencingTypeIds.h>
 #include <Georeferencing/GeoreferencingTypeIds.h>
@@ -22,5 +22,5 @@ namespace Georeferencing
 #if defined(O3DE_GEM_NAME)
 #if defined(O3DE_GEM_NAME)
 AZ_DECLARE_MODULE_CLASS(AZ_JOIN(Gem_, O3DE_GEM_NAME), Georeferencing::GeoreferencingModule)
 AZ_DECLARE_MODULE_CLASS(AZ_JOIN(Gem_, O3DE_GEM_NAME), Georeferencing::GeoreferencingModule)
 #else
 #else
-AZ_DECLARE_MODULE_CLASS(Gem_Georeferencing, Georeferencing::GeoreferencingModule)
+AZ_DECLARE_MODULE_CLASS(Gem_LevelGeoreferencing, Georeferencing::GeoreferencingModule)
 #endif
 #endif

+ 7 - 7
Gems/LevelGeoreferencing/Code/Source/Tools/GeoreferencingEditorModule.cpp

@@ -1,10 +1,10 @@
 /*
 /*
-* Copyright (c) Contributors to the Open 3D Engine Project.
-* For complete copyright and license terms please see the LICENSE at the root of this distribution.
-*
-* SPDX-License-Identifier: Apache-2.0 OR MIT
-*
-*/
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
 
 
 #include "GeoreferenceLevelEditorComponent.h"
 #include "GeoreferenceLevelEditorComponent.h"
 #include "GeoreferencingEditorSystemComponent.h"
 #include "GeoreferencingEditorSystemComponent.h"
@@ -48,5 +48,5 @@ namespace Georeferencing
 #if defined(O3DE_GEM_NAME)
 #if defined(O3DE_GEM_NAME)
 AZ_DECLARE_MODULE_CLASS(AZ_JOIN(Gem_, O3DE_GEM_NAME, _Editor), Georeferencing::GeoreferencingEditorModule)
 AZ_DECLARE_MODULE_CLASS(AZ_JOIN(Gem_, O3DE_GEM_NAME, _Editor), Georeferencing::GeoreferencingEditorModule)
 #else
 #else
-AZ_DECLARE_MODULE_CLASS(Gem_Georeferencing_Editor, Georeferencing::GeoreferencingEditorModule)
+AZ_DECLARE_MODULE_CLASS(Gem_LevelGeoreferencing_Editor, Georeferencing::GeoreferencingEditorModule)
 #endif
 #endif

+ 1 - 2
Gems/LevelGeoreferencing/Code/Tests/Tools/GeoreferenceComponentTest.cpp

@@ -53,7 +53,7 @@ namespace UnitTest
 
 
     void GeoreferenceComponentTestEnvironment::AddGemsAndComponents()
     void GeoreferenceComponentTestEnvironment::AddGemsAndComponents()
     {
     {
-        AddActiveGems(AZStd::to_array<AZStd::string_view>({ "Georeferencing" }));
+        AddActiveGems(AZStd::to_array<AZStd::string_view>({ "LevelGeoreferencing" }));
         AddDynamicModulePaths({});
         AddDynamicModulePaths({});
         AddComponentDescriptors(AZStd::initializer_list<AZ::ComponentDescriptor*>{
         AddComponentDescriptors(AZStd::initializer_list<AZ::ComponentDescriptor*>{
             Georeferencing::GeoReferenceLevelComponent::CreateDescriptor(),
             Georeferencing::GeoReferenceLevelComponent::CreateDescriptor(),
@@ -216,7 +216,6 @@ namespace UnitTest
         AZ::Vector3 resultLevel;
         AZ::Vector3 resultLevel;
         Georeferencing::GeoreferenceRequestsBus::BroadcastResult(
         Georeferencing::GeoreferenceRequestsBus::BroadcastResult(
             resultLevel, &Georeferencing::GeoreferenceRequests::ConvertFromWGS84ToLevel, queryCoordinate);
             resultLevel, &Georeferencing::GeoreferenceRequests::ConvertFromWGS84ToLevel, queryCoordinate);
-        printf("resultLevel: %f %f %f\n", resultLevel.GetX(), resultLevel.GetY(), resultLevel.GetZ());
         EXPECT_LT(resultLevel.GetX(), 0.0);
         EXPECT_LT(resultLevel.GetX(), 0.0);
         EXPECT_NEAR(resultLevel.GetY(), 0.0, OneMillimeter);
         EXPECT_NEAR(resultLevel.GetY(), 0.0, OneMillimeter);
     }
     }

+ 0 - 11
Gems/LevelGeoreferencing/Code/Tests/Tools/GeoreferencingEditorTest.cpp

@@ -1,11 +0,0 @@
-/*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
-
-#include <AzTest/AzTest.h>
-
-AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);

+ 2 - 2
Gems/LevelGeoreferencing/Registry/assetprocessor_settings.setreg

@@ -2,12 +2,12 @@
     "Amazon": {
     "Amazon": {
         "AssetProcessor": {
         "AssetProcessor": {
             "Settings": {
             "Settings": {
-                "ScanFolder Georeferencing/Assets": {
+                "ScanFolder LevelGeoreferencing/Assets": {
                     "watch": "@GEMROOT:LevelGeoreferencing@/Assets",
                     "watch": "@GEMROOT:LevelGeoreferencing@/Assets",
                     "recursive": 1,
                     "recursive": 1,
                     "order": 101
                     "order": 101
                 },
                 },
-                "ScanFolder Georeferencing/Registry": {
+                "ScanFolder LevelGeoreferencing/Registry": {
                     "watch": "@GEMROOT:LevelGeoreferencing@/Registry",
                     "watch": "@GEMROOT:LevelGeoreferencing@/Registry",
                     "recursive": 1,
                     "recursive": 1,
                     "order": 102
                     "order": 102

+ 10 - 7
Gems/LevelGeoreferencing/gem.json

@@ -12,17 +12,20 @@
         "Gem"
         "Gem"
     ],
     ],
     "user_tags": [
     "user_tags": [
-        "Georeferencing", "LevelGeoreferencing"
-    ],
-    "platforms": [
-        ""
+        "Georeferencing",
+        "LevelGeoreferencing"
     ],
     ],
+    "platforms": [],
     "icon_path": "preview.png",
     "icon_path": "preview.png",
     "requirements": "",
     "requirements": "",
     "documentation_url": "https://www.docs.o3de.org/docs/user-guide/interactivity/robotics/georeference/",
     "documentation_url": "https://www.docs.o3de.org/docs/user-guide/interactivity/robotics/georeference/",
     "dependencies": [],
     "dependencies": [],
-    "repo_uri": "",
-    "compatible_engines": [],
+    "compatible_engines": [
+        "o3de-sdk>=2.4.0",
+        "o3de>=2.4.0"
+    ],
     "engine_api_dependencies": [],
     "engine_api_dependencies": [],
-    "restricted": "LevelGeoreferencing"
+    "restricted": "LevelGeoreferencing",
+    "repo_uri": "https://raw.githubusercontent.com/o3de/o3de-extras/development",
+    "download_source_uri": "https://github.com/o3de/o3de-extras/releases/download/2.0/levelgeoreferencing-1.0.0-gem.zip"
 }
 }

+ 4 - 3
Gems/MachineLearning/gem.json

@@ -1,6 +1,6 @@
 {
 {
     "gem_name": "MachineLearning",
     "gem_name": "MachineLearning",
-    "version": "1.0.0",
+    "version": "1.0.1",
     "display_name": "MachineLearning",
     "display_name": "MachineLearning",
     "license": "License used i.e. Apache-2.0 or MIT",
     "license": "License used i.e. Apache-2.0 or MIT",
     "license_url": "Link to the license web site i.e. https://opensource.org/licenses/Apache-2.0",
     "license_url": "Link to the license web site i.e. https://opensource.org/licenses/Apache-2.0",
@@ -21,8 +21,9 @@
     "requirements": "Notice of any requirements for this Gem i.e. This requires X other gem",
     "requirements": "Notice of any requirements for this Gem i.e. This requires X other gem",
     "documentation_url": "Link to any documentation of your Gem",
     "documentation_url": "Link to any documentation of your Gem",
     "dependencies": [],
     "dependencies": [],
-    "repo_uri": "",
+    "repo_uri": "https://raw.githubusercontent.com/o3de/o3de-extras/development",
     "compatible_engines": [],
     "compatible_engines": [],
     "engine_api_dependencies": [],
     "engine_api_dependencies": [],
-    "restricted": "MachineLearning"
+    "restricted": "MachineLearning",
+    "download_source_uri": "https://github.com/o3de/o3de-extras/releases/download/2.0/machinelearning-1.0.1-gem.zip"
 }
 }

+ 3 - 0
Gems/OpenXRVk/Assets/Devices/Generic/Animations/LeftControllerAnimGraph.animgraph

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fd63702c4b43334415ff7bd7227367ee5e9823f74c8edcbd0c05882f7e5e46aa
+size 136451

+ 3 - 0
Gems/OpenXRVk/Assets/Devices/Generic/Animations/LeftControllerMotionSet.motionset

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:18f2711a7044077feecd795324d81a71fe2a3803b9cbc516dbeee5bafe4fe9fd
+size 7637

+ 3 - 0
Gems/OpenXRVk/Assets/Devices/Generic/Animations/RightControllerAnimGraph.animgraph

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:337c58a86060fb8d0c7d89cd67e2f8205dde87c06384f77b45ba7bb9f9a718c4
+size 136465

+ 3 - 0
Gems/OpenXRVk/Assets/Devices/Generic/Animations/RightControllerMotionSet.motionset

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:be715302cdaab2216e7190d67e98bc99ce0d1b47e912d63cb11452aa2f043f50
+size 7668

+ 0 - 0
Gems/RosRobotSample/.gitignore → Gems/OpenXRVk/Assets/Devices/Generic/Materials/placeholder


+ 192 - 0
Gems/OpenXRVk/Assets/Devices/Generic/Prefabs/Controllers.prefab

@@ -0,0 +1,192 @@
+{
+    "ContainerEntity": {
+        "Id": "ContainerEntity",
+        "Name": "Controllers",
+        "Components": {
+            "EditorDisabledCompositionComponent": {
+                "$type": "EditorDisabledCompositionComponent",
+                "Id": 11357894023729654831
+            },
+            "EditorEntityIconComponent": {
+                "$type": "EditorEntityIconComponent",
+                "Id": 17023271943703743605
+            },
+            "EditorEntitySortComponent": {
+                "$type": "EditorEntitySortComponent",
+                "Id": 1610347201491207069,
+                "Child Entity Order": [
+                    "Entity_[502204999943]",
+                    "Entity_[575219443975]",
+                    "Entity_[502204999943]"
+                ]
+            },
+            "EditorInspectorComponent": {
+                "$type": "EditorInspectorComponent",
+                "Id": 5940008202499332184
+            },
+            "EditorLockComponent": {
+                "$type": "EditorLockComponent",
+                "Id": 64446906535033282
+            },
+            "EditorOnlyEntityComponent": {
+                "$type": "EditorOnlyEntityComponent",
+                "Id": 11054853123186771157
+            },
+            "EditorPendingCompositionComponent": {
+                "$type": "EditorPendingCompositionComponent",
+                "Id": 12044208277534757400
+            },
+            "EditorPrefabComponent": {
+                "$type": "EditorPrefabComponent",
+                "Id": 17900113948436235606
+            },
+            "EditorVisibilityComponent": {
+                "$type": "EditorVisibilityComponent",
+                "Id": 2937543944525064124
+            },
+            "TransformComponent": {
+                "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                "Id": 13553483414585150393,
+                "Parent Entity": ""
+            }
+        }
+    },
+    "Entities": {
+        "Entity_[502204999943]": {
+            "Id": "Entity_[502204999943]",
+            "Name": "Right",
+            "Components": {
+                "EditorDisabledCompositionComponent": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 13608067013825982915
+                },
+                "EditorEntityIconComponent": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 3950567742883916883
+                },
+                "EditorEntitySortComponent": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 13480230269487453573,
+                    "Child Entity Order": [
+                        "Instance_[512988876364]/ContainerEntity",
+                        ""
+                    ]
+                },
+                "EditorInspectorComponent": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 3270009694194416244
+                },
+                "EditorLockComponent": {
+                    "$type": "EditorLockComponent",
+                    "Id": 7673774717023258037
+                },
+                "EditorOnlyEntityComponent": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 9324161707068135963
+                },
+                "EditorPendingCompositionComponent": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 15286864137765615482
+                },
+                "EditorVisibilityComponent": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 9586435967632900668
+                },
+                "TransformComponent": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 7001198118696855777,
+                    "Parent Entity": "ContainerEntity",
+                    "Transform Data": {
+                        "Translate": [
+                            0.04502541571855545,
+                            0.0,
+                            0.0
+                        ]
+                    }
+                }
+            }
+        },
+        "Entity_[575219443975]": {
+            "Id": "Entity_[575219443975]",
+            "Name": "Left",
+            "Components": {
+                "EditorDisabledCompositionComponent": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 7665032361584371768
+                },
+                "EditorEntityIconComponent": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 4450379146643673326
+                },
+                "EditorEntitySortComponent": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 16418746609808265667,
+                    "Child Entity Order": [
+                        "Instance_[474334170700]/ContainerEntity",
+                        ""
+                    ]
+                },
+                "EditorInspectorComponent": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 17572380977639100294
+                },
+                "EditorLockComponent": {
+                    "$type": "EditorLockComponent",
+                    "Id": 15065935608684742274
+                },
+                "EditorOnlyEntityComponent": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 5349450381474702831
+                },
+                "EditorPendingCompositionComponent": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 1084433394367455930
+                },
+                "EditorVisibilityComponent": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 17295682265341647703
+                },
+                "TransformComponent": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 8911280123017220605,
+                    "Parent Entity": "ContainerEntity",
+                    "Transform Data": {
+                        "Translate": [
+                            -0.07590436935424805,
+                            0.0,
+                            0.0
+                        ]
+                    }
+                }
+            }
+        }
+    },
+    "Instances": {
+        "Instance_[474334170700]": {
+            "Source": "Devices/Generic/Prefabs/LeftController.prefab",
+            "Patches": [
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/TransformComponent/Parent Entity",
+                    "value": "../Entity_[575219443975]"
+                }
+            ]
+        },
+        "Instance_[512988876364]": {
+            "Source": "Devices/Generic/Prefabs/RightController.prefab",
+            "Patches": [
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/TransformComponent/Parent Entity",
+                    "value": "../Entity_[502204999943]"
+                }
+            ]
+        },
+        "Instance_[605284215047]": {
+            "Source": "Devices/Meta Quest Touch Pro/Prefabs/LeftController.prefab"
+        },
+        "Instance_[639643953415]": {
+            "Source": "Devices/Meta Quest Touch Pro/Prefabs/RightController.prefab"
+        }
+    }
+}

+ 271 - 0
Gems/OpenXRVk/Assets/Devices/Generic/Prefabs/LeftController.prefab

@@ -0,0 +1,271 @@
+{
+    "ContainerEntity": {
+        "Id": "ContainerEntity",
+        "Name": "LeftController",
+        "Components": {
+            "EditorDisabledCompositionComponent": {
+                "$type": "EditorDisabledCompositionComponent",
+                "Id": 11779482774443351665
+            },
+            "EditorEntityIconComponent": {
+                "$type": "EditorEntityIconComponent",
+                "Id": 6871885639765190823
+            },
+            "EditorEntitySortComponent": {
+                "$type": "EditorEntitySortComponent",
+                "Id": 14220904085108013985,
+                "Child Entity Order": [
+                    "Entity_[462232764419]"
+                ]
+            },
+            "EditorInspectorComponent": {
+                "$type": "EditorInspectorComponent",
+                "Id": 420347287405289781
+            },
+            "EditorLockComponent": {
+                "$type": "EditorLockComponent",
+                "Id": 17385047416224256165
+            },
+            "EditorOnlyEntityComponent": {
+                "$type": "EditorOnlyEntityComponent",
+                "Id": 16609915588229987363
+            },
+            "EditorPendingCompositionComponent": {
+                "$type": "EditorPendingCompositionComponent",
+                "Id": 17291925012769339774
+            },
+            "EditorPrefabComponent": {
+                "$type": "EditorPrefabComponent",
+                "Id": 1023319176876402814
+            },
+            "EditorVisibilityComponent": {
+                "$type": "EditorVisibilityComponent",
+                "Id": 49410587080271721
+            },
+            "TransformComponent": {
+                "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                "Id": 10931142295262437896,
+                "Parent Entity": ""
+            }
+        }
+    },
+    "Entities": {
+        "Entity_[462232764419]": {
+            "Id": "Entity_[462232764419]",
+            "Name": "LeftController",
+            "Components": {
+                "EditorActorComponent": {
+                    "$type": "EditorActorComponent",
+                    "Id": 7041281474693402034,
+                    "ActorAsset": {
+                        "assetId": {
+                            "guid": "{B82CB27F-AD17-58A3-9868-9CFA43921B44}",
+                            "subId": 892174927
+                        },
+                        "loadBehavior": "QueueLoad",
+                        "assetHint": "assets/meta quest touch pro/models/questpro_controllers_left.actor"
+                    },
+                    "AttachmentTarget": ""
+                },
+                "EditorAnimGraphComponent": {
+                    "$type": "EditorAnimGraphComponent",
+                    "Id": 5729396345952890271,
+                    "AnimGraphAsset": {
+                        "assetId": {
+                            "guid": "{039BF2D8-83AC-581E-9C46-94A6D4B6E542}"
+                        },
+                        "assetHint": "devices/generic/animations/leftcontrolleranimgraph.animgraph"
+                    },
+                    "MotionSetAsset": {
+                        "assetId": {
+                            "guid": "{C0FA2FE5-9572-5436-AC06-A440FA1DE527}"
+                        },
+                        "assetHint": "devices/generic/animations/leftcontrollermotionset.motionset"
+                    },
+                    "ActiveMotionSetName": "LeftControllerMotionSet",
+                    "ParameterDefaults": {
+                        "Parameters": [
+                            {
+                                "$type": "AzFramework::ScriptPropertyNumber",
+                                "id": 888802634,
+                                "name": "Grip"
+                            },
+                            {
+                                "$type": "AzFramework::ScriptPropertyBoolean",
+                                "id": 443223901,
+                                "name": "Trigger"
+                            },
+                            {
+                                "$type": "AzFramework::ScriptPropertyBoolean",
+                                "id": 2544645905,
+                                "name": "Button_X"
+                            },
+                            {
+                                "$type": "AzFramework::ScriptPropertyBoolean",
+                                "id": 3769304967,
+                                "name": "Button_Y"
+                            },
+                            {
+                                "$type": "AzFramework::ScriptPropertyBoolean",
+                                "id": 1594372809,
+                                "name": "Button_Menu"
+                            },
+                            {
+                                "$type": "AzFramework::ScriptPropertyNumber",
+                                "id": 3235505549,
+                                "name": "ForwardBack",
+                                "value": 0.5
+                            },
+                            {
+                                "$type": "AzFramework::ScriptPropertyNumber",
+                                "id": 171951434,
+                                "name": "RightLeft",
+                                "value": 0.5
+                            },
+                            {
+                                "$type": "AzFramework::ScriptPropertyNumber",
+                                "id": 1000405998,
+                                "name": "VerticalHorizontal",
+                                "value": 0.5
+                            }
+                        ]
+                    }
+                },
+                "EditorDisabledCompositionComponent": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 14048002098962308286
+                },
+                "EditorEntityIconComponent": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 12181966342575173830
+                },
+                "EditorEntitySortComponent": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 15161252879554997311,
+                    "Child Entity Order": [
+                        "Instance_[1624203005390]/ContainerEntity"
+                    ]
+                },
+                "EditorInspectorComponent": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 11938472995850138981
+                },
+                "EditorLockComponent": {
+                    "$type": "EditorLockComponent",
+                    "Id": 9078205223083438436
+                },
+                "EditorMaterialComponent": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 9817255108497746443,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": {
+                                "{}": {
+                                    "MaterialAsset": {
+                                        "assetId": {
+                                            "guid": "{69AAAD7B-0EBA-53D7-82C6-F28C48534FB4}"
+                                        },
+                                        "assetHint": "assets/meta quest touch pro/materials/leftcontroller.azmaterial"
+                                    }
+                                }
+                            }
+                        }
+                    }
+                },
+                "EditorOnlyEntityComponent": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 12327722643749839211
+                },
+                "EditorPendingCompositionComponent": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 12670094709235704851
+                },
+                "EditorVisibilityComponent": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 2748069681797869774
+                },
+                "TransformComponent": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 16703995073445776278,
+                    "Parent Entity": "ContainerEntity"
+                },
+                "XRControllerAnimationsComponent": {
+                    "$type": "GenericComponentWrapper",
+                    "Id": 4907161421596322104,
+                    "m_template": {
+                        "$type": "XRControllerAnimationsComponent",
+                        "Controller Items config": [
+                            {
+                                "controlItemType": 1,
+                                "parameterControlLabel": "Grip",
+                                "controlActionLabel": "left_grip"
+                            },
+                            {
+                                "controlItemType": 1,
+                                "parameterControlLabel": "Trigger",
+                                "controlActionLabel": "left_trigger"
+                            },
+                            {
+                                "parameterControlLabel": "Button_X",
+                                "controlActionLabel": "left_button_x"
+                            },
+                            {
+                                "parameterControlLabel": "Button_Y",
+                                "controlActionLabel": "left_button_y"
+                            },
+                            {
+                                "parameterControlLabel": "Button_Menu",
+                                "controlActionLabel": "left_button_menu"
+                            },
+                            {
+                                "controlItemType": 2,
+                                "parameterControlLabel": "RightLeft",
+                                "controlActionLabel": "left_stick_x"
+                            },
+                            {
+                                "controlItemType": 2,
+                                "parameterControlLabel": "ForwardBack",
+                                "controlActionLabel": "left_stick_y"
+                            }
+                        ]
+                    }
+                },
+                "XRControllerComponent": {
+                    "$type": "GenericComponentWrapper",
+                    "Id": 7900506098284249803,
+                    "m_template": {
+                        "$type": "XRControllerComponent",
+                        "Label of Pose Label": "left_aim_pose"
+                    }
+                }
+            }
+        }
+    },
+    "Instances": {
+        "Instance_[1624203005390]": {
+            "Source": "OpenXRVk/Prefabs/RayInteractor.prefab",
+            "Patches": [
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/TransformComponent/Parent Entity",
+                    "value": "../Entity_[462232764419]"
+                },
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/TransformComponent/Transform Data/Translate/0",
+                    "value": 0.007355859503149986
+                },
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/TransformComponent/Transform Data/Translate/1",
+                    "value": 0.030208345502614975
+                },
+                {
+                    "op": "replace",
+                    "path": "/Entities/Entity_[2196353285566]/Components/OpenXRVk::XRRayInteractorComponent/m_template/Label of the grip button",
+                    "value": "left_grip"
+                }
+            ]
+        }
+    }
+}

+ 271 - 0
Gems/OpenXRVk/Assets/Devices/Generic/Prefabs/RightController.prefab

@@ -0,0 +1,271 @@
+{
+    "ContainerEntity": {
+        "Id": "ContainerEntity",
+        "Name": "RightController",
+        "Components": {
+            "EditorDisabledCompositionComponent": {
+                "$type": "EditorDisabledCompositionComponent",
+                "Id": 34078033412513395
+            },
+            "EditorEntityIconComponent": {
+                "$type": "EditorEntityIconComponent",
+                "Id": 14051435202281902661
+            },
+            "EditorEntitySortComponent": {
+                "$type": "EditorEntitySortComponent",
+                "Id": 9025176256997049541,
+                "Child Entity Order": [
+                    "Entity_[548132110339]"
+                ]
+            },
+            "EditorInspectorComponent": {
+                "$type": "EditorInspectorComponent",
+                "Id": 173019820387906955
+            },
+            "EditorLockComponent": {
+                "$type": "EditorLockComponent",
+                "Id": 11458128771806052389
+            },
+            "EditorOnlyEntityComponent": {
+                "$type": "EditorOnlyEntityComponent",
+                "Id": 874673196786636231
+            },
+            "EditorPendingCompositionComponent": {
+                "$type": "EditorPendingCompositionComponent",
+                "Id": 12769481896772108205
+            },
+            "EditorPrefabComponent": {
+                "$type": "EditorPrefabComponent",
+                "Id": 3083936774343637650
+            },
+            "EditorVisibilityComponent": {
+                "$type": "EditorVisibilityComponent",
+                "Id": 9680360673113429721
+            },
+            "TransformComponent": {
+                "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                "Id": 11869452665309692181,
+                "Parent Entity": ""
+            }
+        }
+    },
+    "Entities": {
+        "Entity_[548132110339]": {
+            "Id": "Entity_[548132110339]",
+            "Name": "RightController",
+            "Components": {
+                "EditorActorComponent": {
+                    "$type": "EditorActorComponent",
+                    "Id": 1151242312296902806,
+                    "ActorAsset": {
+                        "assetId": {
+                            "guid": "{4311EABE-3E23-55A1-A7B1-F5D850B5FAAE}",
+                            "subId": 4293839047
+                        },
+                        "loadBehavior": "QueueLoad",
+                        "assetHint": "assets/meta quest touch pro/models/questpro_controllers_right.actor"
+                    },
+                    "AttachmentTarget": ""
+                },
+                "EditorAnimGraphComponent": {
+                    "$type": "EditorAnimGraphComponent",
+                    "Id": 9228021136834747917,
+                    "AnimGraphAsset": {
+                        "assetId": {
+                            "guid": "{A9520B93-DD92-5190-80D7-E0766596BDAF}"
+                        },
+                        "assetHint": "devices/generic/animations/rightcontrolleranimgraph.animgraph"
+                    },
+                    "MotionSetAsset": {
+                        "assetId": {
+                            "guid": "{16981D70-E0B0-56B7-9C53-44FEA074CC30}"
+                        },
+                        "assetHint": "devices/generic/animations/rightcontrollermotionset.motionset"
+                    },
+                    "ActiveMotionSetName": "RightControllerMotion",
+                    "ParameterDefaults": {
+                        "Parameters": [
+                            {
+                                "$type": "AzFramework::ScriptPropertyNumber",
+                                "id": 888802634,
+                                "name": "Grip"
+                            },
+                            {
+                                "$type": "AzFramework::ScriptPropertyBoolean",
+                                "id": 443223901,
+                                "name": "Trigger"
+                            },
+                            {
+                                "$type": "AzFramework::ScriptPropertyBoolean",
+                                "id": 4089946065,
+                                "name": "Button_A"
+                            },
+                            {
+                                "$type": "AzFramework::ScriptPropertyBoolean",
+                                "id": 1791938155,
+                                "name": "Button_B"
+                            },
+                            {
+                                "$type": "AzFramework::ScriptPropertyBoolean",
+                                "id": 1578484111,
+                                "name": "Button_Oculus"
+                            },
+                            {
+                                "$type": "AzFramework::ScriptPropertyNumber",
+                                "id": 3235505549,
+                                "name": "ForwardBack",
+                                "value": 0.5
+                            },
+                            {
+                                "$type": "AzFramework::ScriptPropertyNumber",
+                                "id": 171951434,
+                                "name": "RightLeft",
+                                "value": 0.5
+                            },
+                            {
+                                "$type": "AzFramework::ScriptPropertyNumber",
+                                "id": 1000405998,
+                                "name": "VerticalHorizontal",
+                                "value": 0.5
+                            }
+                        ]
+                    }
+                },
+                "EditorDisabledCompositionComponent": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 15970460307388455415
+                },
+                "EditorEntityIconComponent": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 282401860055992202
+                },
+                "EditorEntitySortComponent": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 6244102222729912879,
+                    "Child Entity Order": [
+                        "Instance_[2350972108222]/ContainerEntity"
+                    ]
+                },
+                "EditorInspectorComponent": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 1047808035942075827
+                },
+                "EditorLockComponent": {
+                    "$type": "EditorLockComponent",
+                    "Id": 6100418284897881271
+                },
+                "EditorMaterialComponent": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 4816716514059182530,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": {
+                                "{}": {
+                                    "MaterialAsset": {
+                                        "assetId": {
+                                            "guid": "{C7DE388F-A267-54EE-8206-9E4798AEE907}"
+                                        },
+                                        "assetHint": "assets/meta quest touch pro/materials/rightcontroller.azmaterial"
+                                    }
+                                }
+                            }
+                        }
+                    }
+                },
+                "EditorOnlyEntityComponent": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 18248624067260463296
+                },
+                "EditorPendingCompositionComponent": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 11197243245082505255
+                },
+                "EditorVisibilityComponent": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 609030806181826849
+                },
+                "TransformComponent": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 6366583670024026618,
+                    "Parent Entity": "ContainerEntity"
+                },
+                "XRControllerAnimationsComponent": {
+                    "$type": "GenericComponentWrapper",
+                    "Id": 15144022874051115297,
+                    "m_template": {
+                        "$type": "XRControllerAnimationsComponent",
+                        "Controller Items config": [
+                            {
+                                "controlItemType": 1,
+                                "parameterControlLabel": "Grip",
+                                "controlActionLabel": "right_grip"
+                            },
+                            {
+                                "controlItemType": 1,
+                                "parameterControlLabel": "Trigger",
+                                "controlActionLabel": "right_trigger"
+                            },
+                            {
+                                "parameterControlLabel": "Button_A",
+                                "controlActionLabel": "right_button_a"
+                            },
+                            {
+                                "parameterControlLabel": "Button_B",
+                                "controlActionLabel": "right_button_b"
+                            },
+                            {
+                                "parameterControlLabel": "Button_Oculus",
+                                "controlActionLabel": "right_button_menu"
+                            },
+                            {
+                                "controlItemType": 2,
+                                "parameterControlLabel": "RightLeft",
+                                "controlActionLabel": "right_stick_x"
+                            },
+                            {
+                                "controlItemType": 2,
+                                "parameterControlLabel": "ForwardBack",
+                                "controlActionLabel": "right_stick_y"
+                            }
+                        ]
+                    }
+                },
+                "XRControllerComponent": {
+                    "$type": "GenericComponentWrapper",
+                    "Id": 5841023491515403141,
+                    "m_template": {
+                        "$type": "XRControllerComponent",
+                        "Label of Pose Label": "right_aim_pose"
+                    }
+                }
+            }
+        }
+    },
+    "Instances": {
+        "Instance_[2350972108222]": {
+            "Source": "OpenXRVk/Prefabs/RayInteractor.prefab",
+            "Patches": [
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/TransformComponent/Parent Entity",
+                    "value": "../Entity_[548132110339]"
+                },
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/TransformComponent/Transform Data/Translate/0",
+                    "value": -0.005869269371032715
+                },
+                {
+                    "op": "replace",
+                    "path": "/ContainerEntity/Components/TransformComponent/Transform Data/Translate/1",
+                    "value": 0.032036617398262024
+                },
+                {
+                    "op": "replace",
+                    "path": "/Entities/Entity_[2196353285566]/Components/OpenXRVk::XRRayInteractorComponent/m_template/Label of the grip button",
+                    "value": "right_grip"
+                }
+            ]
+        }
+    }
+}

+ 0 - 0
Gems/OpenXRVk/Assets/Devices/Generic/models/placeholder


+ 0 - 0
Gems/OpenXRVk/Assets/Devices/Generic/textures/placeholder


+ 6 - 6
Gems/WarehouseSample/Assets/O3DEScene/Materials/Warehouse_Glass.material → Gems/OpenXRVk/Assets/OpenXRVk/Materials/RayInteractor.material

@@ -3,13 +3,13 @@
     "materialTypeVersion": 5,
     "materialTypeVersion": 5,
     "propertyValues": {
     "propertyValues": {
         "baseColor.color": [
         "baseColor.color": [
-            0.5823450088500977,
-            0.6189604997634888,
-            0.8000000715255737,
+            0.3542229235172272,
+            0.8242465853691101,
+            0.11729609966278076,
             1.0
             1.0
         ],
         ],
-        "emissive.enable": true,
-        "emissive.intensity": 0.8199999928474426,
-        "opacity.factor": 1.0
+        "opacity.alphaAffectsSpecular": 1.0,
+        "opacity.factor": 1.0,
+        "opacity.mode": "TintedTransparent"
     }
     }
 }
 }

+ 3 - 0
Gems/OpenXRVk/Assets/OpenXRVk/Models/ray.fbx

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2cbc571a5100323a849b76e951e9a76f9d234cb38b34ffba92ff7d56d8a49d18
+size 12972

+ 192 - 0
Gems/OpenXRVk/Assets/OpenXRVk/Prefabs/RayInteractor.prefab

@@ -0,0 +1,192 @@
+{
+    "ContainerEntity": {
+        "Id": "ContainerEntity",
+        "Name": "RayInteractor",
+        "Components": {
+            "EditorDisabledCompositionComponent": {
+                "$type": "EditorDisabledCompositionComponent",
+                "Id": 2227815186201860258
+            },
+            "EditorEntityIconComponent": {
+                "$type": "EditorEntityIconComponent",
+                "Id": 10744641979834010771
+            },
+            "EditorEntitySortComponent": {
+                "$type": "EditorEntitySortComponent",
+                "Id": 4949324405703142810,
+                "Child Entity Order": [
+                    "Entity_[2192058318270]"
+                ]
+            },
+            "EditorInspectorComponent": {
+                "$type": "EditorInspectorComponent",
+                "Id": 1201926577550065779
+            },
+            "EditorLockComponent": {
+                "$type": "EditorLockComponent",
+                "Id": 17603052635468018183
+            },
+            "EditorOnlyEntityComponent": {
+                "$type": "EditorOnlyEntityComponent",
+                "Id": 3184305800476626102
+            },
+            "EditorPendingCompositionComponent": {
+                "$type": "EditorPendingCompositionComponent",
+                "Id": 7938192357227904073
+            },
+            "EditorPrefabComponent": {
+                "$type": "EditorPrefabComponent",
+                "Id": 12786602006929560455
+            },
+            "EditorVisibilityComponent": {
+                "$type": "EditorVisibilityComponent",
+                "Id": 13102936197979910553
+            },
+            "TransformComponent": {
+                "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                "Id": 17317814019723439938,
+                "Parent Entity": ""
+            }
+        }
+    },
+    "Entities": {
+        "Entity_[2192058318270]": {
+            "Id": "Entity_[2192058318270]",
+            "Name": "ray_fbx",
+            "Components": {
+                "EditorDisabledCompositionComponent": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 5440906560794845369
+                },
+                "EditorEntityIconComponent": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 2993054042583697911
+                },
+                "EditorEntitySortComponent": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 10741700824886114007,
+                    "Child Entity Order": [
+                        "Entity_[2196353285566]"
+                    ]
+                },
+                "EditorInspectorComponent": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 1999782007542185039
+                },
+                "EditorLockComponent": {
+                    "$type": "EditorLockComponent",
+                    "Id": 8915696561674110942
+                },
+                "EditorOnlyEntityComponent": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 8266807308697367214
+                },
+                "EditorPendingCompositionComponent": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 12068989806937283981
+                },
+                "EditorVisibilityComponent": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 17895674957098219917
+                },
+                "TransformComponent": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 167060676792668755,
+                    "Parent Entity": "ContainerEntity"
+                }
+            }
+        },
+        "Entity_[2196353285566]": {
+            "Id": "Entity_[2196353285566]",
+            "Name": "Cone",
+            "Components": {
+                "AZ::Render::EditorMeshComponent": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 6144249121899473172,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{C6B03C96-575B-55CF-894E-9AD4C7656ECF}",
+                                    "subId": 272552191
+                                },
+                                "assetHint": "openxrvk/models/default_ray_7635cf51_d27b_58ef_9b8a_c1699e0c66c5_.fbx.azmodel"
+                            }
+                        }
+                    }
+                },
+                "EditorDisabledCompositionComponent": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 2002554390524360313
+                },
+                "EditorEntityIconComponent": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 523349909469042047
+                },
+                "EditorEntitySortComponent": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 12749694841162977722
+                },
+                "EditorInspectorComponent": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 18109728839332408605
+                },
+                "EditorLockComponent": {
+                    "$type": "EditorLockComponent",
+                    "Id": 16982072039128690926
+                },
+                "EditorMaterialComponent": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 5154655906900271148,
+                    "Controller": {
+                        "Configuration": {
+                            "materials": {
+                                "{}": {
+                                    "MaterialAsset": {
+                                        "assetId": {
+                                            "guid": "{CAD44AEC-83F1-5A77-8FEF-25F07B0C35CB}"
+                                        },
+                                        "assetHint": "openxrvk/materials/rayinteractor.azmaterial"
+                                    }
+                                }
+                            }
+                        }
+                    }
+                },
+                "EditorNonUniformScaleComponent": {
+                    "$type": "EditorNonUniformScaleComponent",
+                    "Id": 677966525564674226,
+                    "NonUniformScale": [
+                        1.0,
+                        100.0,
+                        1.0
+                    ]
+                },
+                "EditorOnlyEntityComponent": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 15659880097353139111
+                },
+                "EditorPendingCompositionComponent": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 1460097817110925749
+                },
+                "EditorVisibilityComponent": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 17108302802936691524
+                },
+                "OpenXRVk::XRRayInteractorComponent": {
+                    "$type": "GenericComponentWrapper",
+                    "Id": 3334701848395183511,
+                    "m_template": {
+                        "$type": "OpenXRVk::XRRayInteractorComponent"
+                    }
+                },
+                "TransformComponent": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 15954602452704678992,
+                    "Parent Entity": "Entity_[2192058318270]"
+                }
+            }
+        }
+    }
+}

+ 192 - 0
Gems/OpenXRVk/Assets/OpenXRVk/default.xractions

@@ -79,6 +79,198 @@
 							</Class>
 							</Class>
 						</Class>
 						</Class>
 					</Class>
 					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="left_aim_pose" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="Left Aim Pose" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(L)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="Aim Pose" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="right_aim_pose" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="Right Aim Pose" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(R)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="Aim Pose" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="left_grip" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="Left Grip" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(L)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="Squeeze" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="right_grip" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="Right Grip" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(R)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="Squeeze" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="left_trigger" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="Left Trigger" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(L)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="Trigger Value" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="right_trigger" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="Right Trigger" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(R)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="Trigger Value" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="right_button_a" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="Button A" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(R)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="A Click" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="right_button_b" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="Button B" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(R)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="B Click" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="right_button_menu" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="right_button_menu" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(R)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="Thumbrest Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="right_stick_x" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="Horizontal Stick" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(R)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="Thumbstick X" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="right_stick_y" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="Vertical Stick" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(R)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="Thumbstick Y" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="left_button_x" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="Left Button X" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(L)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="X Click" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="left_button_y" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="Left Button Y" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(L)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="Y Click" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="left_button_menu" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="Left Button Menu" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(L)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="Menu Click" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="left_stick_x" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="Left Thumbstick X" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(L)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="Thumbstick X" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
+					<Class name="OpenXRActionDescriptor" field="element" version="1" type="{90BBF6F6-C7D6-4F64-B784-CE03F86DC36B}">
+						<Class name="AZStd::string" field="Name" value="left_stick_y" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="LocalizedName" value="Left Thumbstick Y" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::string" field="Comment" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;OpenXRActionPathDescriptor, allocator&gt;" field="ActionPathDescriptors" type="{6A1AA49C-7A58-5B23-8B25-30B162E65135}">
+							<Class name="OpenXRActionPathDescriptor" field="element" version="1" type="{F25D6382-C9E0-414B-A542-1758F5477D03}">
+								<Class name="AZStd::string" field="InteractionProfile" value="Oculus Touch" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="UserPath" value="(L)" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+								<Class name="AZStd::string" field="ComponentPath" value="Thumbstick Y" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							</Class>
+						</Class>
+					</Class>
 				</Class>
 				</Class>
 			</Class>
 			</Class>
 		</Class>
 		</Class>

+ 7 - 1
Gems/OpenXRVk/Code/CMakeLists.txt

@@ -64,6 +64,11 @@ ly_add_target(
             Gem::Atom_RHI_Vulkan.Reflect
             Gem::Atom_RHI_Vulkan.Reflect
             Gem::Atom_RHI_Vulkan.Glad.Static
             Gem::Atom_RHI_Vulkan.Glad.Static
             Gem::XR.Static
             Gem::XR.Static
+            Gem::PhysX.Static			
+            Gem::Atom_Feature_Common.Public			
+            Gem::CommonFeaturesAtom.Static
+            Gem::EMotionFXStaticLib
+            Gem::EMotionFX
 )
 )
 
 
 ly_add_target(
 ly_add_target(
@@ -114,10 +119,11 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS)
         BUILD_DEPENDENCIES
         BUILD_DEPENDENCIES
             PUBLIC
             PUBLIC
                 AZ::AzCore
                 AZ::AzCore
-                AZ::AzFramework
                 AZ::AssetBuilderSDK
                 AZ::AssetBuilderSDK
                 ${openxr_dependency}
                 ${openxr_dependency}
                 Gem::${gem_name}.Static
                 Gem::${gem_name}.Static
+                Gem::EMotionFXStaticLib
+                Gem::EMotionFX
     )
     )
 
 
     ly_add_target(
     ly_add_target(

+ 148 - 0
Gems/OpenXRVk/Code/Source/Devices/Common/XRControllerAnimationsComponent.cpp

@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include "XRControllerAnimationsComponent.h"
+
+#include <AzCore/Component/TransformBus.h>
+#include <AzCore/Serialization/SerializeContext.h>
+#include <AzCore/Serialization/EditContext.h>
+
+#include <OpenXRVk/OpenXRVkActionsInterface.h>
+
+#include <Integration/ActorComponentBus.h>
+
+#include <Integration/AnimGraphComponentBus.h>
+
+namespace OpenXRVk
+{
+    void XRControllerAnimationsComponent::Reflect(AZ::ReflectContext* context)
+    {
+        XRControllersConfig::Reflect(context);
+
+        if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
+        {
+            serializeContext->RegisterGenericType<XRControllersConfig>();
+
+            serializeContext->Class<XRControllerAnimationsComponent, AZ::Component>()
+                ->Version(1)
+                ->Field("Controller Items config", &XRControllerAnimationsComponent::m_controllersConfig)
+                ;
+
+            if (AZ::EditContext* editContext = serializeContext->GetEditContext())
+            {
+                editContext->Class<XRControllerAnimationsComponent>("XR Controller Animation", "Provides animations for controls on VR controller")
+                    ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
+                    ->Attribute(AZ::Edit::Attributes::Category, "XR")
+                    ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Component_Placeholder.svg")
+                    ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
+                    ->DataElement(AZ::Edit::UIHandlers::Default, &XRControllerAnimationsComponent::m_controllersConfig, "Controller Items config", "Configuration for each item of the controller")
+                    ;
+            }
+        }
+
+        if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
+        {
+            behaviorContext->Class<XRControllerAnimationsComponent>("XR Component Animation Group")
+                ->Attribute(AZ::Script::Attributes::Category, "OpenXRVk Gem Group")
+                ;
+        }
+    }
+
+    void XRControllerAnimationsComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
+    {
+        provided.push_back(AZ_CRC_CE("XRControllerAnimationService"));
+    }
+
+    void XRControllerAnimationsComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
+    {
+        incompatible.push_back(AZ_CRC_CE("XRControllerAnimationService"));
+    }
+
+    void XRControllerAnimationsComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
+    {
+        required.push_back(AZ_CRC_CE("TransformService"));
+    }
+
+    void XRControllerAnimationsComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
+    {
+    }
+
+    void XRControllerAnimationsComponent::Activate()
+    {
+        AZ::TickBus::Handler::BusConnect();
+    }
+
+    void XRControllerAnimationsComponent::Deactivate()
+    {
+        if (AZ::TickBus::Handler::BusIsConnected())
+        {
+            AZ::TickBus::Handler::BusDisconnect();
+        }
+    }
+
+    extern AZ::Transform ReadActionHandlePose(IOpenXRActions* iface, IOpenXRActions::ActionHandle actionHandle);
+    extern float ReadActionHandleFloat(IOpenXRActions* iface, IOpenXRActions::ActionHandle actionHandle, float deadZone);
+
+    void XRControllerAnimationsComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
+    {
+        auto actionsIFace = OpenXRActionsInterface::Get();
+        if (!actionsIFace)
+        {
+            return;
+        }
+
+        for (XRControllersConfig& cfg : m_controllersConfig)
+        {
+            if (!cfg.m_actionHandle.IsValid())
+            {
+                cfg.m_actionHandle = actionsIFace->GetActionHandle("main_action_set", cfg.m_actionName);
+                if (!cfg.m_actionHandle.IsValid())
+                {
+                    continue;
+                }
+            }
+            switch (cfg.m_controlItemType)
+            {
+                case XRControllersConfig::ControlItemType::Boolean:
+                {
+                    auto outcome = actionsIFace->GetActionStateBoolean(cfg.m_actionHandle);
+                    if (outcome.IsSuccess())
+                    {
+                        bool res = outcome.GetValue();
+                        if (res != cfg.m_prevBoolean)
+                        {
+                            EMotionFX::Integration::AnimGraphComponentRequestBus::Event(GetEntityId(), &EMotionFX::Integration::AnimGraphComponentRequestBus::Events::SetNamedParameterBool, cfg.m_animGraphParameter.c_str(), res);
+                            cfg.m_prevBoolean = res;
+                        }
+                    }
+                    break;
+                }
+                case XRControllersConfig::ControlItemType::Float:
+                {
+                    float res = ReadActionHandleFloat(actionsIFace, cfg.m_actionHandle, 0.001f);
+                    if (res != cfg.m_prevFloat)
+                    {
+                        EMotionFX::Integration::AnimGraphComponentRequestBus::Event(GetEntityId(), &EMotionFX::Integration::AnimGraphComponentRequestBus::Events::SetNamedParameterFloat, cfg.m_animGraphParameter.c_str(), res);
+                        cfg.m_prevFloat = res;
+                    }
+                    break;
+                }
+                case XRControllersConfig::ControlItemType::Vector2:
+                {
+                    float res = (ReadActionHandleFloat(actionsIFace, cfg.m_actionHandle, 0.001f) + 1.0f) / 2.0f;
+                    if (res != cfg.m_prevFloat)
+                    {
+                        EMotionFX::Integration::AnimGraphComponentRequestBus::Event(GetEntityId(), &EMotionFX::Integration::AnimGraphComponentRequestBus::Events::SetNamedParameterFloat, cfg.m_animGraphParameter.c_str(), res);
+                        cfg.m_prevFloat = res;
+                    }
+                    break;
+                }
+            }
+        }
+    }
+} // namespace OpenXRVk

+ 48 - 0
Gems/OpenXRVk/Code/Source/Devices/Common/XRControllerAnimationsComponent.h

@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Component/Component.h>
+#include <AzCore/Component/TickBus.h>
+#include <AzCore/Asset/AssetCommon.h>
+
+#include <OpenXRVk/OpenXRVkActionsInterface.h>
+#include "XRControllersConfig.h"
+
+namespace OpenXRVk
+{
+    //! XRControllerAnimationsComponent uses the OpenXRVk::OpenXRActionsInterface to read user input to animate a XR controller.
+    class XRControllerAnimationsComponent
+        : public AZ::Component
+        , public AZ::TickBus::Handler
+    {
+    public:
+        AZ_COMPONENT(XRControllerAnimationsComponent, "{A57B8F98-39A0-4B70-B7F7-2331E62A3276}");
+
+        static void Reflect(AZ::ReflectContext* context);
+
+        static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
+        static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
+        static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
+        static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
+
+    protected:
+        // AZ::Component
+        void Activate() override;
+        void Deactivate() override;
+
+        // AZ::TickBus::Handler
+        void OnTick(float deltaTime, AZ::ScriptTimePoint timePoint) override;
+
+    private:
+        // Serialized data...
+		AZStd::vector<XRControllersConfig> m_controllersConfig;
+    };
+
+} // namespace OpenXRVk

+ 155 - 0
Gems/OpenXRVk/Code/Source/Devices/Common/XRControllerComponent.cpp

@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include "XRControllerComponent.h"
+
+#include <AzCore/Component/TransformBus.h>
+#include <AzCore/Serialization/SerializeContext.h>
+#include <AzCore/Serialization/EditContext.h>
+#include <AzFramework/Components/CameraBus.h>
+
+#include <OpenXRVk/OpenXRVkActionsInterface.h>
+
+#include <AzCore/Math/Color.h>
+
+namespace OpenXRVk
+{
+    void XRControllerComponent::Reflect(AZ::ReflectContext* context)
+    {
+        if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
+        {
+            serializeContext->Class<XRControllerComponent, AZ::Component>()
+                ->Version(1)
+                ->Field("Label of Pose Label", &XRControllerComponent::m_controllerPoseActionLabel)
+                ;
+
+            if (AZ::EditContext* editContext = serializeContext->GetEditContext())
+            {
+                editContext->Class<XRControllerComponent>("XR Controller", "Provides movement/orientation of VR controller")
+                    ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
+                    ->Attribute(AZ::Edit::Attributes::Category, "XR")
+                    ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Component_Placeholder.svg")
+                    ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
+                    ->DataElement(AZ::Edit::UIHandlers::Default, &XRControllerComponent::m_controllerPoseActionLabel, "Action name of pose", "OpenXRActionsInterface ActionHandle label of pose")
+                    ;
+            }
+        }
+
+        if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
+        {
+            behaviorContext->Class<XRControllerComponent>("XR Component Group")
+                ->Attribute(AZ::Script::Attributes::Category, "OpenXRVk Gem Group")
+                ;
+        }
+    }
+
+    void XRControllerComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
+    {
+        provided.push_back(AZ_CRC_CE("XRControllerMovementService"));
+    }
+
+    void XRControllerComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
+    {
+        incompatible.push_back(AZ_CRC_CE("XRControllerMovementService"));
+    }
+
+    void XRControllerComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
+    {
+        required.push_back(AZ_CRC_CE("TransformService"));
+    }
+
+    void XRControllerComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
+    {
+    }
+
+    void XRControllerComponent::Activate()
+    {
+        Camera::CameraNotificationBus::Handler::BusConnect();
+        AZ::TickBus::Handler::BusConnect();
+    }
+
+    void XRControllerComponent::Deactivate()
+    {
+        if (AZ::TickBus::Handler::BusIsConnected())
+        {
+            AZ::TickBus::Handler::BusDisconnect();
+        }
+        Camera::CameraNotificationBus::Handler::BusDisconnect();
+    }
+
+    void XRControllerComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
+    {
+        if (m_cameraEntity == AZ::EntityId())
+        {
+            return;
+        }
+        ProcessOpenXRActions();
+
+        // Get the camera's transform
+        AZ::Transform cameraTransform;
+        AZ::TransformBus::EventResult(cameraTransform, m_cameraEntity, &AZ::TransformBus::Events::GetWorldTM);
+
+        // Current transform of the controller (in local space relative to the camera)
+        AZ::Transform controllerLocalTransform = m_movement;
+
+        // Convert the controller's local transform to world space by multiplying with the camera's transform
+        // Ensure correct order of multiplication: local transform first, then camera transform
+        AZ::Transform controllerWorldTransform = cameraTransform * controllerLocalTransform;
+
+        // Apply the new world transform to the controller's render object
+        AZ::TransformBus::Event(GetEntityId(), &AZ::TransformBus::Events::SetWorldTM, controllerWorldTransform);
+    }
+
+    static AZ::Transform ReadActionHandlePose(IOpenXRActions* iface, IOpenXRActions::ActionHandle actionHandle)
+    {
+        auto outcome = iface->GetActionStatePose(actionHandle);
+        if (!outcome.IsSuccess())
+        {
+            AZ::Transform value = AZ::Transform::CreateIdentity();
+            value.SetTranslation(AZ::Vector3(-1000, -1000, -1000));
+            // Most likely the controller went to sleep.
+            return value;
+        }
+        AZ::Transform value = outcome.GetValue();
+        if (value.GetTranslation().IsClose(AZ::Vector3::CreateZero()))
+        {
+            // To avoid rendering controllers when the camera is inside of them
+            value.SetTranslation(AZ::Vector3(-1000, -1000, -1000));
+        }
+        return value;
+    }
+
+    void XRControllerComponent::ProcessOpenXRActions()
+    {
+        auto actionsIFace = OpenXRActionsInterface::Get();
+        if (!actionsIFace)
+        {
+            return;
+        }
+
+        if (!m_controllerPoseHandle.IsValid())
+        {
+            // Try to cache all handles.
+            m_controllerPoseHandle = actionsIFace->GetActionHandle("main_action_set", m_controllerPoseActionLabel);
+            if (!m_controllerPoseHandle.IsValid())
+            {
+                // Most likely the Action System failed to load the ActionSets asset.
+                return;
+            }
+        }
+
+        m_movement = ReadActionHandlePose(actionsIFace, m_controllerPoseHandle);
+    }
+
+
+    // Camera::CameraNotificationBus::Handler overrides
+    void XRControllerComponent::OnActiveViewChanged(const AZ::EntityId& activeEntityId)
+    {
+        m_cameraEntity = activeEntityId;
+    }
+} // namespace OpenXRVk

+ 62 - 0
Gems/OpenXRVk/Code/Source/Devices/Common/XRControllerComponent.h

@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Component/Component.h>
+#include <AzCore/Component/TickBus.h>
+#include <AzFramework/Components/CameraBus.h>
+
+#include <OpenXRVk/OpenXRVkActionsInterface.h>
+
+namespace OpenXRVk
+{
+    //! XRControllerComponent uses the OpenXRVk::OpenXRActionsInterface to read user input to control an VR controller.
+    class XRControllerComponent
+        : public AZ::Component
+        , public AZ::TickBus::Handler
+        , public Camera::CameraNotificationBus::Handler
+    {
+    public:
+        AZ_COMPONENT(XRControllerComponent, "{5DA45A04-A900-345C-23DE-23BD03BC3820}");
+
+        static void Reflect(AZ::ReflectContext* context);
+
+        static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
+        static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
+        static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
+        static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
+
+    protected:
+        // AZ::Component
+        void Activate() override;
+        void Deactivate() override;
+
+        // Camera::CameraNotificationBus::Handler overrides
+        void OnActiveViewChanged(const AZ::EntityId&) override;
+
+        // AZ::TickBus::Handler
+        void OnTick(float deltaTime, AZ::ScriptTimePoint timePoint) override;
+
+    private:
+        void ProcessOpenXRActions();
+
+        AZ::EntityId m_cameraEntity;
+
+        // Transient data...
+        AZ::Transform m_movement = AZ::Transform::CreateIdentity();
+
+        // Serialized data...
+        AZStd::string m_controllerPoseActionLabel;
+
+        //! A cache of OpenXRVk Action Handles that provide straight
+        //! access into the user's input.
+        IOpenXRActions::ActionHandle m_controllerPoseHandle;
+    };
+
+} // namespace OpenXRVk

+ 41 - 0
Gems/OpenXRVk/Code/Source/Devices/Common/XRControllersConfig.cpp

@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <AzCore/Serialization/SerializeContext.h>
+#include <AzCore/Serialization/EditContext.h>
+#include <AzCore/Serialization/Json/RegistrationContext.h>
+
+#include "XRControllersConfig.h"
+
+namespace OpenXRVk
+{
+        void XRControllersConfig::Reflect(AZ::ReflectContext* context)
+        {
+            if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
+            {
+                serializeContext->Class<XRControllersConfig>()
+                    ->Field("controlItemType", &XRControllersConfig::m_controlItemType)
+                    ->Field("parameterControlLabel", &XRControllersConfig::m_animGraphParameter)
+                    ->Field("controlActionLabel", &XRControllersConfig::m_actionName)
+                ;
+
+                if (AZ::EditContext* editContext = serializeContext->GetEditContext())
+                {
+                    editContext->Class<XRControllersConfig>("XRControllersConfig", "")
+                        ->DataElement(AZ::Edit::UIHandlers::ComboBox, &XRControllersConfig::m_controlItemType, "Type of the item", "Is it button or grip slider or thumbstick")
+                            ->EnumAttribute(XRControllersConfig::ControlItemType::Boolean, "Button (boolean)")
+                            ->EnumAttribute(XRControllersConfig::ControlItemType::Float, "Trigger (float)")
+                            ->EnumAttribute(XRControllersConfig::ControlItemType::Vector2, "Thumbstick (360 degrees)")
+                        ->DataElement(AZ::Edit::UIHandlers::Default, &XRControllersConfig::m_animGraphParameter, "AnimGraph parameter", "Name of parameter that controls an animation of the control item in AnimGraph")
+                        ->DataElement(AZ::Edit::UIHandlers::Default, &XRControllersConfig::m_actionName, "Action name", "OpenXRActionsInterface ActionHandle label")
+                    ;
+                }
+            }
+        }
+
+} // namespace OpenXRVk

+ 45 - 0
Gems/OpenXRVk/Code/Source/Devices/Common/XRControllersConfig.h

@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+
+#include <AzCore/Memory/SystemAllocator.h>
+#include <AzCore/RTTI/ReflectContext.h>
+#include <AzCore/std/containers/vector.h>
+#include <AzCore/std/string/string.h>
+#include <OpenXRVk/OpenXRVkActionsInterface.h>
+
+namespace OpenXRVk
+{
+	//! Configuration that is used by XRControllerAnimationsComponent to animate an VR controller.
+	struct XRControllersConfig final
+	{
+		enum class ControlItemType : AZ::u32 {
+			Boolean,
+			Float,
+			Vector2
+		};
+
+		AZ_RTTI(XRControllersConfig, "{A32512BD-124A-723B-AA24-214BCD02CCAA}");
+		AZ_CLASS_ALLOCATOR(XRControllersConfig, AZ::SystemAllocator);
+
+		static void Reflect(AZ::ReflectContext* context);
+		
+		// Editor configuration properties
+		ControlItemType m_controlItemType;
+		AZStd::string m_animGraphParameter;
+		AZStd::string m_actionName;
+
+		// Runtime variables
+		IOpenXRActions::ActionHandle m_actionHandle;
+		bool m_prevBoolean = false;
+		float m_prevFloat = 0;
+	};	
+
+} // namespace OpenXRVk

+ 8 - 0
Gems/OpenXRVk/Code/Source/OpenXRVkModule.cpp

@@ -10,6 +10,10 @@
 #include <AzCore/Module/Module.h>
 #include <AzCore/Module/Module.h>
 #include <OpenXRVk/OpenXRVkSystemComponent.h>
 #include <OpenXRVk/OpenXRVkSystemComponent.h>
 #include <XRCameraMovementComponent.h>
 #include <XRCameraMovementComponent.h>
+#include "Devices/Common/XRControllerComponent.h"
+#include "Devices/Common/XRControllerAnimationsComponent.h"
+#include <XRRayInteractorComponent.h>
+#include <XRInteractableComponent.h>
 
 
 #if defined (OPENXRVK_BUILDERS)
 #if defined (OPENXRVK_BUILDERS)
 #include "Builders/OpenXRVkAssetsBuilderSystemComponent.h"
 #include "Builders/OpenXRVkAssetsBuilderSystemComponent.h"
@@ -31,6 +35,10 @@ namespace OpenXRVk
             m_descriptors.insert(m_descriptors.end(), {
             m_descriptors.insert(m_descriptors.end(), {
                 SystemComponent::CreateDescriptor(),
                 SystemComponent::CreateDescriptor(),
                 XRCameraMovementComponent::CreateDescriptor(),
                 XRCameraMovementComponent::CreateDescriptor(),
+                XRControllerComponent::CreateDescriptor(),
+				XRRayInteractorComponent::CreateDescriptor(),
+				XRInteractableComponent::CreateDescriptor(),
+                XRControllerAnimationsComponent::CreateDescriptor(),
                 #if defined (OPENXRVK_BUILDERS)
                 #if defined (OPENXRVK_BUILDERS)
                 OpenXRVkBuilders::OpenXRAssetsBuilderSystemComponent::CreateDescriptor(),
                 OpenXRVkBuilders::OpenXRAssetsBuilderSystemComponent::CreateDescriptor(),
                 #endif
                 #endif

+ 6 - 0
Gems/OpenXRVk/Code/Source/Platform/Android/platform_private_android_files.cmake

@@ -13,4 +13,10 @@ set(FILES
     ../Common/Default/InputDeviceXRController_Default.cpp
     ../Common/Default/InputDeviceXRController_Default.cpp
     ../Common/Default/OculusTouch_Default.cpp
     ../Common/Default/OculusTouch_Default.cpp
     ../Common/Default/OculusTouch_Default.h
     ../Common/Default/OculusTouch_Default.h
+    ../../Devices/Common/XRControllerComponent.cpp
+    ../../Devices/Common/XRControllerComponent.h
+	../../Devices/Common/XRControllerAnimationsComponent.cpp
+	../../Devices/Common/XRControllerAnimationsComponent.h
+	../../Devices/Common/XRControllersConfig.cpp
+	../../Devices/Common/XRControllersConfig.h
 )
 )

+ 4 - 0
Gems/OpenXRVk/Code/Source/Platform/Linux/platform_private_linux_files.cmake

@@ -12,5 +12,9 @@ set(FILES
     ../Common/Default/InputDeviceXRController_Default.cpp
     ../Common/Default/InputDeviceXRController_Default.cpp
     ../Common/Default/OculusTouch_Default.cpp
     ../Common/Default/OculusTouch_Default.cpp
     ../Common/Default/OculusTouch_Default.h
     ../Common/Default/OculusTouch_Default.h
+    ../Common/Default/XRControllerComponent.cpp
+    ../Common/Default/XRControllerComponent.h
+    ../Common/Default/XRControllerAnimationsComponent.cpp
+    ../Common/Default/XRControllerAnimationsComponent.h
     ../Common/Unimplemented/OpenXRVkCommon_Unimplemented.cpp
     ../Common/Unimplemented/OpenXRVkCommon_Unimplemented.cpp
 )
 )

+ 6 - 0
Gems/OpenXRVk/Code/Source/Platform/Windows/platform_private_windows_files.cmake

@@ -13,4 +13,10 @@ set(FILES
     ../Common/Default/OculusTouch_Default.cpp
     ../Common/Default/OculusTouch_Default.cpp
     ../Common/Default/OculusTouch_Default.h
     ../Common/Default/OculusTouch_Default.h
     ../Common/Unimplemented/OpenXRVkCommon_Unimplemented.cpp
     ../Common/Unimplemented/OpenXRVkCommon_Unimplemented.cpp
+    ../../Devices/Common/XRControllerComponent.cpp
+    ../../Devices/Common/XRControllerComponent.h
+	../../Devices/Common/XRControllerAnimationsComponent.cpp
+	../../Devices/Common/XRControllerAnimationsComponent.h
+	../../Devices/Common/XRControllersConfig.cpp
+	../../Devices/Common/XRControllersConfig.h
 )
 )

+ 1 - 1
Gems/OpenXRVk/Code/Source/XRCameraMovementComponent.cpp

@@ -39,7 +39,7 @@ namespace OpenXRVk
             {
             {
                 editContext->Class<XRCameraMovementComponent>("XR Camera Movement", "Provides XR controller input to control the camera")
                 editContext->Class<XRCameraMovementComponent>("XR Camera Movement", "Provides XR controller input to control the camera")
                     ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
                     ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
-                    ->Attribute(AZ::Edit::Attributes::Category, "Gameplay")
+                    ->Attribute(AZ::Edit::Attributes::Category, "XR")
                     ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Component_Placeholder.svg")
                     ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Component_Placeholder.svg")
                     ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
                     ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
                     ->DataElement(AZ::Edit::UIHandlers::Default, &XRCameraMovementComponent::m_moveSpeed, "Move Speed", "Speed of camera movement")
                     ->DataElement(AZ::Edit::UIHandlers::Default, &XRCameraMovementComponent::m_moveSpeed, "Move Speed", "Speed of camera movement")

+ 213 - 0
Gems/OpenXRVk/Code/Source/XRInteractableComponent.cpp

@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <XRInteractableComponent.h>
+
+#include <AzCore/Component/TransformBus.h>
+#include <AzCore/Serialization/SerializeContext.h>
+#include <AzCore/Serialization/EditContext.h>
+#include <AzCore/RTTI/BehaviorContext.h>
+
+#include <OpenXRVk/OpenXRVkActionsInterface.h>
+
+#include <Atom/RPI.Public/ViewProviderBus.h>
+#include <Atom/RPI.Public/View.h>
+#include <Atom/RPI.Public/ViewportContext.h>
+#include <Atom/RPI.Public/ViewportContextBus.h>
+#include <Atom/RPI.Public/Pass/PassFilter.h>
+#include <Atom/RPI.Public/ViewportContextManager.h>
+#include <Atom/RPI.Public/AuxGeom/AuxGeomDraw.h>
+#include <AzFramework/Components/CameraBus.h>
+#include <AzCore/Component/NonUniformScaleBus.h>
+
+#include <AzFramework/Physics/PhysicsScene.h>
+#include <AzFramework/Physics/PhysicsSystem.h>
+#include <AzFramework/Physics/Common/PhysicsSceneQueries.h>
+#include <AzFramework/Physics/Shape.h>
+
+#include <Source/RigidBodyComponent.h>
+#include <AzFramework/Physics/SimulatedBodies/RigidBody.h>
+
+namespace OpenXRVk
+{
+    void XRInteractableComponent::Reflect(AZ::ReflectContext* context)
+    {
+        if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
+        {
+            serializeContext->Class<XRInteractableComponent, AZ::Component>()
+                ->Version(1)
+                ->Field("Type of the interactable", &XRInteractableComponent::m_XRInteractableType)
+                ;
+
+            if (AZ::EditContext* editContext = serializeContext->GetEditContext())
+            {
+                editContext->Class<XRInteractableComponent>("XR Interactable", "Reacts on Ray Interactor from the XR controller")
+                    ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
+                    ->Attribute(AZ::Edit::Attributes::Category, "XR")
+                    ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Component_Placeholder.svg")
+                    ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
+                    ->DataElement(AZ::Edit::UIHandlers::ComboBox, &XRInteractableComponent::m_XRInteractableType, "Type of the interactable", "Type of the interactable")
+                      ->EnumAttribute(XRInteractableComponent::XRInteractableType::Simple, "Simple")
+                    ;
+            }
+        }
+
+        if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
+        {
+            behaviorContext->Class<XRInteractableComponent>("XRInteractable Component Group")
+                ->Attribute(AZ::Script::Attributes::Category, "OpenXRVk Gem Group")
+                ;
+        }
+    }
+
+    void XRInteractableComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
+    {
+        provided.push_back(AZ_CRC_CE("XRInteractableService"));
+    }
+
+    void XRInteractableComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
+    {
+        incompatible.push_back(AZ_CRC_CE("XRInteractableService"));
+    }
+
+    void XRInteractableComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
+    {
+        required.push_back(AZ_CRC_CE("TransformService"));
+        required.push_back(AZ_CRC_CE("PhysicsRigidBodyService"));
+    }
+
+    void XRInteractableComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
+    {
+    }
+
+    void XRInteractableComponent::Init()
+    {
+        
+    }
+
+    void XRInteractableComponent::Activate()
+    {
+        AZ::TickBus::Handler::BusConnect();
+        Physics::RigidBodyNotificationBus::Handler::BusConnect(GetEntityId());
+
+        m_cachedRigidBodyComponent = GetEntity()->FindComponent<PhysX::RigidBodyComponent>();
+    }
+
+    void XRInteractableComponent::Deactivate()
+    {
+        if (AZ::TickBus::Handler::BusIsConnected())
+        {
+            AZ::TickBus::Handler::BusDisconnect();
+        }
+        Physics::RigidBodyNotificationBus::Handler::BusDisconnect();
+    }
+
+    static float SmoothStep(float edge0, float edge1, float t)
+    {
+        t = AZ::GetClamp((t - edge0) / (edge1 - edge0), 0.0f, 1.0f);
+        return t * t * (3.0f - 2.0f * t);
+    }
+
+    void XRInteractableComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
+    {
+        if (!m_hovering)
+            return;
+
+        constexpr float animationDuration = 0.25f;
+        constexpr float increaseScaleFactor = 0.3f;
+
+        m_hoverTime += deltaTime;
+        float t = AZ::GetClamp(m_hoverTime / animationDuration, 0.0f, 1.0f);
+
+        float factor = m_scalingUp
+            ? SmoothStep(0.0f, 1.0f, t) * increaseScaleFactor + 1.0f  // 1.0 -> 1.increaseScaleFactor
+            : 1 + increaseScaleFactor - SmoothStep(0.0f, 1.0f, t) * increaseScaleFactor;  // 1.increaseScaleFactor -> 1.0
+
+        AZ::Vector3 newScale = m_originalScale * factor;
+        if (t >= 1.0f)
+        {
+            if (m_scalingUp)
+            {
+                m_scalingUp = false;
+                m_hoverTime = 0.0f;
+            }
+            else
+            {
+                newScale = m_originalScale;
+                m_hovering = false;
+            }
+        }
+
+        if (m_hasNonUniform)
+        {
+            AZ::NonUniformScaleRequestBus::Event(GetEntityId(), &AZ::NonUniformScaleRequests::SetScale, newScale);
+        }
+        else
+        {
+            AZ::TransformBus::Event(GetEntityId(), &AZ::TransformInterface::SetLocalUniformScale, newScale.GetX());
+        }
+    }
+
+    // Called when the pointer is hovering over this object
+    void XRInteractableComponent::OnHoverStart()
+    {
+        if (m_hovering)
+        {
+            return;
+        }
+        m_hoverTime = 0.0f;
+        m_hovering = true;
+        m_scalingUp = true;
+
+        if (!m_originalScaleCached)
+        {
+            CacheOriginalScale();
+        }
+    }
+
+    // Called when the pointer stops hovering over this object
+    void XRInteractableComponent::OnHoverEnd()
+    {
+    }
+
+    void XRInteractableComponent::CacheOriginalScale()
+    {
+        m_originalScale = AZ::Vector3::CreateOne();
+        m_hasNonUniform = false;
+
+        AZ::Vector3 testScale = AZ::Vector3::CreateOne();
+        AZ::NonUniformScaleRequestBus::EventResult(testScale, GetEntityId(), &AZ::NonUniformScaleRequests::GetScale);
+
+        if (!testScale.IsClose(AZ::Vector3::CreateOne()))
+        {
+            m_hasNonUniform = true;
+            m_originalScale = testScale;
+        }
+        else
+        {
+            float uniform = 1.0f;
+            AZ::TransformBus::EventResult(uniform, GetEntityId(), &AZ::TransformInterface::GetLocalUniformScale);
+            m_originalScale = AZ::Vector3(uniform);
+        }
+        m_originalScaleCached = true;
+    }
+
+    void XRInteractableComponent::OnGrab()
+    {
+        m_isGrabbing = true;
+        m_cachedRigidBodyComponent->DisablePhysics();
+    }
+
+    void XRInteractableComponent::OnRelease(const AZ::Vector3& impulse)
+    {
+        m_cachedRigidBodyComponent->EnablePhysics();
+        m_cachedRigidBodyComponent->ApplyLinearImpulse(impulse * m_cachedRigidBodyComponent->GetMass());
+        m_isGrabbing = false;
+    }
+
+} // namespace OpenXRVk

+ 87 - 0
Gems/OpenXRVk/Code/Source/XRInteractableComponent.h

@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Component/Component.h>
+#include <AzCore/Component/TickBus.h>
+#include <Atom/RPI.Public/AuxGeom/AuxGeomFeatureProcessorInterface.h>
+#include <AzCore/Component/Entity.h>
+#include <OpenXRVk/OpenXRVkActionsInterface.h>
+#include <AzFramework/Components/CameraBus.h>
+#include <AzFramework/Physics/RigidBodyBus.h>
+#include <AzFramework/Physics/SimulatedBodies/RigidBody.h>
+#include <Source/RigidBodyComponent.h>
+
+namespace OpenXRVk
+{
+    //! XRInteractableComponent defines that the object can be taken using the RayInteractor
+    class XRInteractableComponent
+        : public AZ::Component
+        , public AZ::TickBus::Handler
+        , public Physics::RigidBodyNotificationBus::Handler
+    {
+    public:
+
+        enum class XRInteractableType : AZ::u32 {
+            Simple
+        };
+
+        AZ_COMPONENT(OpenXRVk::XRInteractableComponent, "{9234ABCD-234B-12AB-242D-6436DEFC38BB}");
+
+        static void Reflect(AZ::ReflectContext* context);
+
+        static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
+        static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
+        static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
+        static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
+
+
+        // Called when the pointer is hovering over this object
+        virtual void OnHoverStart();
+
+        // Called when the pointer stops hovering over this object
+        virtual void OnHoverEnd();
+
+        virtual void OnGrab();
+        virtual void OnRelease(const AZ::Vector3& impulse);
+
+        bool IsHovering() { return m_isHovering; }
+        bool IsGrabbing() { return m_isGrabbing; }
+
+    protected:
+        // AZ::Component
+        void Init() override;
+        void Activate() override;
+        void Deactivate() override;
+
+        // AZ::TickBus::Handler
+        void OnTick(float deltaTime, AZ::ScriptTimePoint timePoint) override;
+
+    private:
+        bool m_isHovering = false;
+        XRInteractableType m_XRInteractableType = XRInteractableType::Simple;
+
+        // Animation state
+        float m_hoverTime = 0.0f;
+        bool m_hovering = false;
+        bool m_scalingUp = true;
+
+        // Scale state
+        AZ::Vector3 m_originalScale = AZ::Vector3::CreateOne();
+        bool m_hasNonUniform = false;
+
+        bool m_originalScaleCached = false;
+        void CacheOriginalScale();
+
+        bool m_isGrabbing = false;
+
+        PhysX::RigidBodyComponent* m_cachedRigidBodyComponent = nullptr;
+    };
+
+} // namespace OpenXRVk

+ 364 - 0
Gems/OpenXRVk/Code/Source/XRRayInteractorComponent.cpp

@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#include <XRRayInteractorComponent.h>
+#include <XRInteractableComponent.h>
+
+#include <AzCore/Component/TransformBus.h>
+#include <AzCore/Serialization/SerializeContext.h>
+#include <AzCore/Serialization/EditContext.h>
+#include <AzCore/RTTI/BehaviorContext.h>
+
+#include <OpenXRVk/OpenXRVkActionsInterface.h>
+
+#include <Atom/RPI.Public/ViewProviderBus.h>
+#include <Atom/RPI.Public/View.h>
+#include <Atom/RPI.Public/ViewportContext.h>
+#include <Atom/RPI.Public/ViewportContextBus.h>
+#include <Atom/RPI.Public/Pass/PassFilter.h>
+#include <Atom/RPI.Public/ViewportContextManager.h>
+#include <Atom/RPI.Public/AuxGeom/AuxGeomDraw.h>
+#include <AzFramework/Components/CameraBus.h>
+#include <AzCore/Component/NonUniformScaleBus.h>
+
+#include <AzFramework/Physics/PhysicsScene.h>
+#include <AzFramework/Physics/PhysicsSystem.h>
+#include <AzFramework/Physics/Common/PhysicsSceneQueries.h>
+#include <AzFramework/Physics/Shape.h>
+
+#include <Atom/RPI.Public/Material/Material.h>
+
+#include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
+#include <AzCore/Name/Name.h>
+
+#include <AzFramework/Physics/RigidBodyBus.h>
+#include <AzFramework/Physics/SimulatedBodies/RigidBody.h>
+
+namespace OpenXRVk
+{
+    const AZStd::string baseColorPropertyName = "baseColor.color";
+    const float translationToYScaleCoefficent = 100;
+    const float hoveringXZScaleCoefficient = 4;
+
+    void XRRayInteractorComponent::Reflect(AZ::ReflectContext* context)
+    {
+        if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
+        {
+            serializeContext->Class<XRRayInteractorComponent, AZ::Component>()
+                ->Version(1)
+                ->Field("Max length of the ray", &XRRayInteractorComponent::m_maxLength)
+                ->Field("The default color of the ray", &XRRayInteractorComponent::m_initialRayColor)
+                ->Field("The color when the ray hovers over some interactable object", &XRRayInteractorComponent::m_hoveringRayColor)
+                ->Field("Label of the grip button", &XRRayInteractorComponent::m_gripControlActionLabel)
+                ;
+
+            if (AZ::EditContext* editContext = serializeContext->GetEditContext())
+            {
+                editContext->Class<XRRayInteractorComponent>("XR Ray Interactor", "Draws ray interactor from the XR controller")
+                    ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
+                    ->Attribute(AZ::Edit::Attributes::Category, "XR")
+                    ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Component_Placeholder.svg")
+                    ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"))
+                    ->DataElement(AZ::Edit::UIHandlers::Default, &XRRayInteractorComponent::m_maxLength, "Max length of the ray", "Max length of the ray in meters")
+                    ->DataElement(AZ::Edit::UIHandlers::Default, &XRRayInteractorComponent::m_initialRayColor, "Default color", "The default color of the ray")
+                    ->DataElement(AZ::Edit::UIHandlers::Default, &XRRayInteractorComponent::m_hoveringRayColor, "Hovering color", "The color when the ray hovers over some interactable object")
+                    ->DataElement(AZ::Edit::UIHandlers::Default, &XRRayInteractorComponent::m_gripControlActionLabel, "Action name of the grip", "Action Handle Label of OpenXRActionsInterface")
+                    ;
+            }
+        }
+
+        if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
+        {
+            behaviorContext->Class<XRRayInteractorComponent>("XRRayInteractor Component Group")
+                ->Attribute(AZ::Script::Attributes::Category, "OpenXRVk Gem Group")
+                ;
+        }
+    }
+
+    void XRRayInteractorComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
+    {
+        provided.push_back(AZ_CRC_CE("XRRayInteractorService"));
+    }
+
+    void XRRayInteractorComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
+    {
+        incompatible.push_back(AZ_CRC_CE("XRRayInteractorService"));
+    }
+
+    void XRRayInteractorComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
+    {
+        required.push_back(AZ_CRC_CE("TransformService"));
+    }
+
+    void XRRayInteractorComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
+    {
+    }
+
+    void XRRayInteractorComponent::Init()
+    {
+    }
+
+    void XRRayInteractorComponent::Activate()
+    {
+        AZ::TickBus::Handler::BusConnect();
+    }
+
+    void XRRayInteractorComponent::Deactivate()
+    {
+        if (AZ::TickBus::Handler::BusIsConnected())
+        {
+            AZ::TickBus::Handler::BusDisconnect();
+        }
+    }
+
+    void XRRayInteractorComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
+    {
+        if (!m_colorDefined)
+        {
+            AZ::Render::MaterialAssignmentMap originalMaterials;
+            AZ::Render::MaterialComponentRequestBus::EventResult(
+                originalMaterials, GetEntityId(), &AZ::Render::MaterialComponentRequestBus::Events::GetMaterialMap);
+
+            if (!originalMaterials.empty())
+            {
+                for (const auto& [materialId, assignment] : originalMaterials)
+                {
+                    auto materialAsset = assignment.m_materialAsset;
+                    if (!materialAsset.IsReady())
+                        continue;
+                    // Waiting when the asset is ready
+                    auto const pIndex = assignment.m_materialInstance->FindPropertyIndex(AZ::Name("baseColor.color"));
+                    if (!pIndex.IsValid())
+                        continue;
+                    // Let's find the right material
+                    assignmentId = AZ::Render::MaterialAssignmentId::CreateDefault();
+
+                    AZ::Render::MaterialComponentRequestBus::Event(
+                        GetEntityId(),
+                        &AZ::Render::MaterialComponentRequestBus::Events::SetPropertyValueT<AZ::Color>, 
+                        assignmentId, baseColorPropertyName, m_initialRayColor);
+                    m_colorDefined = true;
+                }
+            }
+        }
+
+        ProcessOpenXRActions();
+
+        if (m_heldEntity.IsValid())
+        {
+            // Update held object's position relative to ray
+            AZ::Transform rayTransform;
+            AZ::TransformBus::EventResult(rayTransform, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
+            AZ::Transform targetTransform = rayTransform * m_grabOffset;
+            AZ::TransformBus::Event(m_heldEntity, &AZ::TransformBus::Events::SetWorldTM, targetTransform);
+
+            // Track velocity
+            AZ::Vector3 currentPosition = targetTransform.GetTranslation();
+            m_currentVelocity = (currentPosition - m_lastFramePosition) / deltaTime;
+            m_lastFramePosition = currentPosition;
+
+            // Release object when button is released
+            if (m_currentSqueezeValue < 0.1f)
+            {
+                ReleaseHeldEntity();
+            }
+            return;
+        }
+        else if (m_currentSqueezeValue > 0.9f && m_currentlyHoveredEntity.IsValid())
+        {
+            GrabHoveredEntity();
+            return;
+        }
+        else {
+            m_heldEntity.SetInvalid();
+        }
+
+        // Store initial nonUniform scale X and Z
+        AZ::Vector3 nonUniformScale;
+        AZ::NonUniformScaleRequestBus::EventResult(nonUniformScale, GetEntityId(), &AZ::NonUniformScaleRequestBus::Events::GetScale);
+        if (m_XZnonUniformScale == 0 && nonUniformScale.GetX() > 0)
+        {
+            m_XZnonUniformScale = nonUniformScale.GetX();
+        }
+
+        // Get the world transform of the current entity (typically the controller)
+        AZ::Transform rayOriginTransform;
+        AZ::TransformBus::EventResult(rayOriginTransform, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
+
+        // Define the ray start position and normalized direction
+        AZ::Vector3 start = rayOriginTransform.GetTranslation();
+        AZ::Vector3 direction = rayOriginTransform.GetBasisY().GetNormalized();
+
+        // Maximum ray length
+        float maxDistance = m_maxLength;
+
+        // Get the default physics scene
+        auto* sceneInterface = AZ::Interface<AzPhysics::SceneInterface>::Get();
+        AzPhysics::SceneHandle sceneHandle = sceneInterface->GetSceneHandle(AzPhysics::DefaultPhysicsSceneName);
+
+        if (sceneHandle == AzPhysics::InvalidSceneHandle)
+        {
+            AZ_Warning("XRRayInteractorComponent", false, "Invalid physics scene.");
+            return;
+        }
+
+        // Prepare the raycast request
+        AzPhysics::RayCastRequest request;
+        request.m_start = start;
+        request.m_direction = direction;
+        request.m_distance = maxDistance;
+        request.m_reportMultipleHits = false;
+
+        // Perform the raycast query
+        AzPhysics::SceneQueryHits hitResult;
+        sceneInterface->QueryScene(sceneHandle, &request, hitResult);
+
+        // Handle the result of the raycast
+        if (!hitResult.m_hits.empty())
+        {
+            AzPhysics::SceneQueryHit &hit = hitResult.m_hits[0];
+
+            // You can use hitResult.m_position or hitResult.m_entityId for further logic
+            if (hit.m_entityId.IsValid())
+            {
+                if (m_currentlyHoveredEntity != hit.m_entityId)
+                {
+                    CheckEndHovering();
+
+                    XRInteractableComponent* xrInteractableComponent = GetXRInterctableComponent(hit.m_entityId);
+                    if (xrInteractableComponent)     // Interactable component has changed
+                    {
+                        AZ::Render::MaterialComponentRequestBus::Event(
+                            GetEntityId(),
+                            &AZ::Render::MaterialComponentRequestBus::Events::SetPropertyValueT<AZ::Color>,
+                            assignmentId, baseColorPropertyName, m_hoveringRayColor);
+
+                        xrInteractableComponent->OnHoverStart();
+                        m_currentlyHoveredEntity = hit.m_entityId;
+                    }
+                }
+            }
+            else
+            {
+                CheckEndHovering();
+            }
+
+            float xzScale = m_currentlyHoveredEntity.IsValid() ? m_XZnonUniformScale * hoveringXZScaleCoefficient : m_XZnonUniformScale;
+            nonUniformScale.Set(xzScale, hit.m_distance * translationToYScaleCoefficent, xzScale);
+            AZ::NonUniformScaleRequestBus::Event(GetEntityId(), &AZ::NonUniformScaleRequestBus::Events::SetScale, nonUniformScale);
+        }
+        else
+        {
+            // Restore initial scale of the ray
+            nonUniformScale.Set(m_XZnonUniformScale, m_maxLength* translationToYScaleCoefficent, m_XZnonUniformScale);
+            AZ::NonUniformScaleRequestBus::Event(GetEntityId(), &AZ::NonUniformScaleRequestBus::Events::SetScale, nonUniformScale);
+            CheckEndHovering();
+        }
+    }
+
+    void XRRayInteractorComponent::CheckEndHovering()
+    {
+        if (m_currentlyHoveredEntity.IsValid())
+        {
+            XRInteractableComponent* oldCRInteractableComponent = GetXRInterctableComponent(m_currentlyHoveredEntity);
+            if (oldCRInteractableComponent)
+            {
+                oldCRInteractableComponent->OnHoverEnd();
+                m_currentlyHoveredEntity.SetInvalid();
+                AZ::Render::MaterialComponentRequestBus::Event(
+                    GetEntityId(),
+                    &AZ::Render::MaterialComponentRequestBus::Events::SetPropertyValueT<AZ::Color>,
+                    assignmentId, baseColorPropertyName, m_initialRayColor);
+            }
+        }
+    }
+
+    static float ReadActionHandleFloat(IOpenXRActions* iface, IOpenXRActions::ActionHandle actionHandle, float deadZone = 0.05f)
+    {
+        auto outcome = iface->GetActionStateFloat(actionHandle);
+        if (!outcome.IsSuccess())
+        {
+            // Most likely the controller went to sleep.
+            return 0.0f;
+        }
+        float value = outcome.GetValue();
+        if (fabsf(value) < deadZone)
+        {
+            return 0.0f;
+        }
+        return value;
+    }
+
+    void XRRayInteractorComponent::ProcessOpenXRActions()
+    {
+        m_currentSqueezeValue = 0;
+        auto actionsIFace = OpenXRActionsInterface::Get();
+        if (!actionsIFace)
+        {
+            return;
+        }
+
+        if (!m_controllerSqueezeHandle.IsValid())
+        {
+            // Try to cache all handles.
+            m_controllerSqueezeHandle = actionsIFace->GetActionHandle("main_action_set", m_gripControlActionLabel);
+            if (!m_controllerSqueezeHandle.IsValid())
+            {
+                // Most likely the Action System failed to load the ActionSets asset.
+                return;
+            }
+
+        }
+        m_currentSqueezeValue = ReadActionHandleFloat(actionsIFace, m_controllerSqueezeHandle);
+    }
+
+    void XRRayInteractorComponent::GrabHoveredEntity()
+    {
+        m_heldEntity = m_currentlyHoveredEntity;
+
+        AZ::Transform controllerWorldTM;
+        AZ::Transform objectWorldTM;
+        AZ::TransformBus::EventResult(controllerWorldTM, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
+        AZ::TransformBus::EventResult(objectWorldTM, m_heldEntity, &AZ::TransformBus::Events::GetWorldTM);
+        m_grabOffset = controllerWorldTM.GetInverse() * objectWorldTM;
+
+        m_lastFramePosition = objectWorldTM.GetTranslation();
+        m_currentVelocity = AZ::Vector3::CreateZero();
+
+        XRInteractableComponent* xrInteractableComponent = GetXRInterctableComponent(m_heldEntity);
+        if (xrInteractableComponent)
+        {
+            xrInteractableComponent->OnGrab();
+        }
+    }
+
+    void XRRayInteractorComponent::ReleaseHeldEntity()
+    {
+        // Call OnRelease on the XRInteractableComponent if available
+        XRInteractableComponent* xrInteractableComponent = GetXRInterctableComponent(m_heldEntity);
+        if (xrInteractableComponent)
+        {
+            xrInteractableComponent->OnRelease(m_currentVelocity);
+        }
+
+        m_heldEntity.SetInvalid();
+    }
+
+    XRInteractableComponent* XRRayInteractorComponent::GetXRInterctableComponent(AZ::EntityId entityId)
+    {
+        AZ::Entity* entity = nullptr;
+        AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, entityId);
+        if (entity)
+        {
+            return entity->FindComponent<XRInteractableComponent>();
+        }
+        return nullptr;
+    }
+
+
+} // namespace OpenXRVk

+ 79 - 0
Gems/OpenXRVk/Code/Source/XRRayInteractorComponent.h

@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#pragma once
+
+#include <AzCore/Component/Component.h>
+#include <AzCore/Component/TickBus.h>
+#include <Atom/RPI.Public/AuxGeom/AuxGeomFeatureProcessorInterface.h>
+#include <AzCore/Component/Entity.h>
+#include <OpenXRVk/OpenXRVkActionsInterface.h>
+#include <AzFramework/Components/CameraBus.h>
+#include <AtomLyIntegration/CommonFeatures/Material/MaterialAssignmentId.h>
+#include <XRInteractableComponent.h>
+
+namespace OpenXRVk
+{
+    //! XRRayInteractorComponent draws line from controller
+    class XRRayInteractorComponent
+        : public AZ::Component
+        , public AZ::TickBus::Handler
+    {
+    public:
+        AZ_COMPONENT(OpenXRVk::XRRayInteractorComponent, "{ABD92123-AB30-233B-23AA-123BDEFC3821}");
+
+        static void Reflect(AZ::ReflectContext* context);
+
+        static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
+        static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
+        static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
+        static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
+
+    protected:
+        // AZ::Component
+        void Init() override;
+        void Activate() override;
+        void Deactivate() override;
+
+        // AZ::TickBus::Handler
+        void OnTick(float deltaTime, AZ::ScriptTimePoint timePoint) override;
+
+    private:
+		AZ::EntityId m_currentlyHoveredEntity = AZ::EntityId();
+        float m_maxLength = 10;
+        AZStd::string m_gripControlActionLabel;
+
+        AZ::Color m_initialRayColor = AZ::Color(0.2f, 0.8f, 0.1f, 1.0f);
+        AZ::Color m_hoveringRayColor = AZ::Color(0.2f, 0.2f, 0.8f, 1.0f);
+        AZ::Render::MaterialAssignmentId assignmentId;
+        bool m_colorDefined = false;
+
+        float m_XZnonUniformScale = 0;
+
+        void CheckEndHovering();
+
+        void ProcessOpenXRActions();
+        //! A cache of OpenXRVk Action Handles that provide straight
+        //! access into the user's input.
+        IOpenXRActions::ActionHandle m_controllerSqueezeHandle;
+
+        float m_currentSqueezeValue = 0;
+
+        // Grab functionality
+        AZ::EntityId m_heldEntity = AZ::EntityId();
+        AZ::Transform m_grabOffset = AZ::Transform::CreateIdentity();
+        AZ::Vector3 m_lastFramePosition = AZ::Vector3::CreateZero();
+        AZ::Vector3 m_currentVelocity = AZ::Vector3::CreateZero();
+
+        XRInteractableComponent* GetXRInterctableComponent(AZ::EntityId entityId);
+        void GrabHoveredEntity();
+        void ReleaseHeldEntity();
+
+    };
+
+} // namespace OpenXRVk

+ 4 - 0
Gems/OpenXRVk/Code/openxrvk_static_common_files.cmake

@@ -44,4 +44,8 @@ set(FILES
     Source/OpenXRVkActionsManager.h
     Source/OpenXRVkActionsManager.h
     Source/OpenXRVkBehaviorReflection.cpp
     Source/OpenXRVkBehaviorReflection.cpp
     Source/OpenXRVkBehaviorReflection.h
     Source/OpenXRVkBehaviorReflection.h
+	Source/XRRayInteractorComponent.h
+	Source/XRRayInteractorComponent.cpp
+	Source/XRInteractableComponent.h
+	Source/XRInteractableComponent.cpp
 )
 )

+ 2 - 2
Gems/OpenXRVk/gem.json

@@ -15,6 +15,6 @@
     "documentation_url": "",
     "documentation_url": "",
     "dependencies": [],
     "dependencies": [],
     "repo_uri": "https://raw.githubusercontent.com/o3de/o3de-extras/development",
     "repo_uri": "https://raw.githubusercontent.com/o3de/o3de-extras/development",
-    "download_source_uri": "https://github.com/o3de/o3de-extras/releases/download/2.0/openxrvk-1.0.1-gem.zip",
-    "version": "1.0.1"
+    "download_source_uri": "https://github.com/o3de/o3de-extras/releases/download/2.0/openxrvk-1.1.0-gem.zip",
+    "version": "1.1.0"
 }
 }

+ 63 - 0
Gems/OpenXRVk_README_EN.md

@@ -0,0 +1,63 @@
+# Controller Models and Animations Setup in O3DE
+
+There are many VR devices on the market, each with different controllers, so developers are responsible for integrating the appropriate 3D models into their applications.
+
+This Gem provides asset templates that can help you implement your own 3D controller models more easily.
+
+The prefab at  
+`OpenXRVk\Assets\Devices\Generic\Prefabs\Controllers.prefab`  
+includes both left and right controllers:  
+- `OpenXRVk\Assets\Devices\Generic\Prefabs\LeftController.prefab`  
+- `OpenXRVk\Assets\Devices\Generic\Prefabs\RightController.prefab`
+
+We recommend copying the entire folder  
+`OpenXRVk\Assets\Devices\Generic\`  
+into your own project. Then, place your controller `.fbx` models (which contain `.motion` data and animations) into the appropriate subfolders.
+
+For example, Oculus Quest models can be downloaded from the official site:  
+https://developers.meta.com/horizon/downloads/package/oculus-controller-art/
+
+You will need to:
+- Convert the `.fbx` files from ASCII to binary format (e.g., using Autodesk FBX Converter).
+- Use Blender to split out individual animations for each button and joystick on the controller.
+
+Animations can be as short as one frame (e.g., to represent a "pressed" state).  
+For thumbsticks, you’ll need 4 separate animations: forward, backward, left, and right.
+
+Here is an example animation list for Oculus Quest Pro/3:
+
+```
+left_b_button_menu.fbx  
+left_b_button_x.fbx  
+left_b_button_y.fbx  
+left_b_thumbstick_000.fbx  
+left_b_thumbstick_090.fbx  
+left_b_thumbstick_180.fbx  
+left_b_thumbstick_270.fbx  
+left_b_trigger_front.fbx  
+left_b_trigger_grip.fbx  
+right_b_button_a.fbx  
+right_b_button_b.fbx  
+right_b_button_oculus.fbx  
+right_b_thumbstick_000.fbx  
+right_b_thumbstick_090.fbx  
+right_b_thumbstick_180.fbx  
+right_b_thumbstick_270.fbx  
+right_b_trigger_front.fbx  
+right_b_trigger_grip.fbx  
+```
+
+After loading the controller prefabs into the O3DE Editor, you may see missing or invalid property references.  
+You will need to assign the appropriate `Actor Asset`, `Material`, and `AnimGraph`.
+
+If you add new actions to `OpenXRVk\Assets\OpenXRVk\default.xractions` or create your own `.xractions` file, you must update the `XRControllerAnimation` component to match the correct action paths to the corresponding animations.
+
+---
+
+## Licensing and Distribution Notice
+
+Due to licensing restrictions, official controller 3D models (such as those for Oculus/Meta devices) are **not** included in this repository.  
+You must download them yourself from official sources and ensure your usage complies with their respective license agreements.
+
+Only template assets and instructions for integration are provided here.  
+Do **not** redistribute downloaded or proprietary models with your project unless explicitly permitted by the original license.

+ 0 - 18
Gems/ProteusRobot/Assets/Materials/Proteus_chassis_Proteus.material

@@ -1,18 +0,0 @@
-{
-    "materialType": "@gemroot:Atom_Feature_Common@/Assets/Materials/Types/StandardPBR.materialtype",
-    "materialTypeVersion": 5,
-    "propertyValues": {
-        "baseColor.textureMap": "../Textures/Proteus_BaseMap.png",
-        "emissive.enable": true,
-        "emissive.intensity": 7.420000076293945,
-        "emissive.textureMap": "../Textures/Lights_Emissive.png",
-        "metallic.textureMap": "../Textures/Proteus_MaskMap_R.png",
-        "normal.textureMap": "../Textures/Proteus_Normal.png",
-        "opacity.factor": 1.0,
-        "roughness.factor": 0.5,
-        "roughness.lowerBound": 0.49000000953674316,
-        "roughness.textureMap": "../Textures/Proteus_MaskMap_A.png",
-        "roughness.upperBound": 0.15000000596046448,
-        "specularF0.factor": 0.5099999904632568
-    }
-}

+ 0 - 13
Gems/ProteusRobot/Assets/Materials/Proteus_chassis_Side_Lights.material

@@ -1,13 +0,0 @@
-{
-    "materialType": "@gemroot:Atom_Feature_Common@/Assets/Materials/Types/StandardPBR.materialtype",
-    "materialTypeVersion": 5,
-    "propertyValues": {
-        "baseColor.textureMap": "../Textures/Lights_Emissive.png",
-        "emissive.enable": true,
-        "emissive.intensity": 7.0,
-        "emissive.textureMap": "../Textures/Lights_Emissive.png",
-        "normal.textureMap": "../Textures/Proteus_Normal.png",
-        "opacity.factor": 1.0,
-        "roughness.factor": 0.5
-    }
-}

+ 0 - 19
Gems/ProteusRobot/Assets/Materials/Proteus_chassis_wheel.material

@@ -1,19 +0,0 @@
-{
-    "materialType": "@gemroot:Atom_Feature_Common@/Assets/Materials/Types/StandardPBR.materialtype",
-    "materialTypeVersion": 5,
-    "propertyValues": {
-        "baseColor.textureBlendMode": "LinearLight",
-        "baseColor.textureMap": "../Textures/Proteus_BaseMap.png",
-        "emissive.enable": true,
-        "emissive.intensity": 7.420000076293945,
-        "emissive.textureMap": "../Textures/Lights_Emissive.png",
-        "metallic.textureMap": "../Textures/Proteus_MaskMap_R.png",
-        "normal.textureMap": "../Textures/Proteus_Normal.png",
-        "opacity.factor": 1.0,
-        "roughness.factor": 0.5,
-        "roughness.lowerBound": 0.20000000298023224,
-        "roughness.textureMap": "../Textures/Proteus_MaskMap_A.png",
-        "roughness.upperBound": 0.9399999976158142,
-        "specularF0.factor": 0.5099999904632568
-    }
-}

+ 0 - 3
Gems/ProteusRobot/Assets/Proteus2_chassis.fbx

@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:a62150544cf58a4527f317a0ea316d046f92fa90d38a61c0b2e99037095c59d0
-size 170876

+ 0 - 3
Gems/ProteusRobot/Assets/Proteus2_lift.fbx

@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:76809288546fa028f263dbdd20eacfe2730a90895dec38db826d5521ddf1fc3e
-size 79244

+ 0 - 3
Gems/ProteusRobot/Assets/Proteus_chassis.fbx

@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:4586a1c9a8e18c353d534b23222c6b1b1e11b3e842b7ed35f190548251999906
-size 225948

+ 0 - 3
Gems/ProteusRobot/Assets/Proteus_wheel.fbx

@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:6937ad1b662f2688000526b7bf871af33aac1acd99cfe4535b8e2ce70e902983
-size 32124

+ 0 - 3
Gems/ProteusRobot/Assets/Textures/Proteus_MaskMap.png

@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:ad1935486899cc0664f8d4aa428e626cb452dcfe639494fe420f96ee71ff62c0
-size 2267401

+ 0 - 3
Gems/ProteusRobot/Assets/Textures/Proteus_MaskMap_A.png

@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:676539bb24018bd20e5102c6e5d14148ff418758bd4da0c2e281a73f54632993
-size 567314

+ 0 - 30
Gems/ProteusRobot/README.md

@@ -1,30 +0,0 @@
-[![Apache License, Version 2.0][apache_shield]][apache]
-
-# Proteus Robot Gem for Open 3D Engine (O3DE)
-
-## Requirements
-- Any O3DE project with the [ROS 2 Gem](https://docs.o3de.org/docs/user-guide/interactivity/robotics/) enabled.
-
-Please refer to [O3DE documentation](https://docs.o3de.org/docs/user-guide/gems/) to learn more about Gems and about registering Gems in the system and O3DE projects.
-
-## Description
-This is an Asset Gem. It contains a simplified model of [Proteus Robot](https://robotsguide.com/robots/proteus) - an autonomous mobile robot that can pick up, transport, and drop off containers. It is delivered as a ready-to-use O3DE prefab, `Proteus.prefab`, containing visual models, physics and the following ROS 2 components:
-- `ROS2 Frame`
-- `ROS2 Robot Control`
-- `ROS2 Skid Steering Twist Control`
-- `ROS2 Lidar Sensor`
-
-Additionally, the model is equipped with links that are suitable for adding `Camera` and `Imu` sensors.
-
-The robot publishes Lidar Sensor's output on the`/base_link/pc` ROS 2 topic and can be driven using the `/base_link/cmd_vel` ROS 2 topic. An example of its use can be found in [ROS 2 Project Template](https://github.com/o3de/o3de-extras/tree/development/Templates/Ros2FleetRobotTemplate).
-
-## Screenshots
-![](docs/images/front.png)
-![](docs/images/back.png)
-
-## Acknowledgments
-This work is licensed under [Apache License, Version 2.0][apache]. You may elect at your option to use the [MIT License][mit] instead. Contributions must be made under both licenses.
-
-[apache]: https://opensource.org/licenses/Apache-2.0
-[mit]: https://opensource.org/licenses/MIT
-[apache_shield]: https://img.shields.io/badge/License-Apache_2.0-blue.svg

+ 0 - 34
Gems/ProteusRobot/gem.json

@@ -1,34 +0,0 @@
-{
-    "gem_name": "ProteusRobot",
-    "version": "2.1.0",
-    "display_name": "Proteus Robot",
-    "license": "Apache-2.0 or MIT",
-    "license_url": "https://opensource.org/licenses/Apache-2.0",
-    "origin": "RobotecAI",
-    "origin_url": "https://robotec.ai",
-    "type": "Asset",
-    "summary": "Proteus warehouse robot with Lidar sensor",
-    "canonical_tags": [
-        "Gem"
-    ],
-    "user_tags": [
-        "ProteusRobot"
-    ],
-    "platforms": [
-        "Linux"
-    ],
-    "icon_path": "preview.png",
-    "requirements": "Requires ROS 2 Gem",
-    "documentation_url": "",
-    "dependencies": [
-        "ROS2>=3.1.0"
-    ],
-    "compatible_engines": [
-        "o3de-sdk>=2.3.0",
-        "o3de>=2.3.0"
-    ],
-    "repo_uri": "https://raw.githubusercontent.com/o3de/o3de-extras/development",
-    "engine_api_dependencies": [],
-    "restricted": "ProteusRobot",
-    "download_source_uri": "https://github.com/o3de/o3de-extras/releases/download/2.0/proteusrobot-2.1.0-gem.zip"
-}

+ 0 - 3
Gems/ProteusRobot/preview.png

@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:4f1c54b47691f37f59463ff5926c44bba4783f526512485704167502d840f76c
-size 19282

+ 11 - 0
Gems/ROS2RobotImporter/Code/ros2robotimporter_editor_private_files.cmake

@@ -81,3 +81,14 @@ set(FILES
     Source/SdfAssetBuilder/SdfAssetBuilderSystemComponent.cpp
     Source/SdfAssetBuilder/SdfAssetBuilderSystemComponent.cpp
     Source/SdfAssetBuilder/SdfAssetBuilderSystemComponent.h
     Source/SdfAssetBuilder/SdfAssetBuilderSystemComponent.h
 )
 )
+
+# optional, legacy features compilation
+if (WITH_GAZEBO_MSGS)
+    list(APPEND FILES
+        Source/Spawner/ROS2SpawnerEditorComponent.cpp
+        Source/Spawner/ROS2SpawnerEditorComponent.h
+        Source/Spawner/ROS2SpawnPointEditorComponent.cpp
+        Source/Spawner/ROS2SpawnPointEditorComponent.h
+    )
+endif ()
+

+ 3 - 0
Gems/ROS2SampleRobots/Assets/Components/OS2Lidar/Models/LidarOS2.fbx

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:484c3c47bfaa8ca71a8c551f9126b392bc3c4ef80168e89de0fc4f853e03eb00
+size 243792

+ 47 - 0
Gems/ROS2SampleRobots/Assets/Components/OS2Lidar/Models/LidarOS2.fbx.assetinfo

@@ -0,0 +1,47 @@
+{
+    "values": [
+        {
+            "$type": "{5B03C8E6-8CEE-4DA0-A7FA-CD88689DD45B} MeshGroup",
+            "id": "{8B671FF3-450D-5007-AC79-F2E406301A08}",
+            "name": "LidarOS2",
+            "NodeSelectionList": {
+                "selectedNodes": [
+                    "RootNode.Collider"
+                ],
+                "unselectedNodes": [
+                    {},
+                    "RootNode",
+                    "RootNode.OS2"
+                ]
+            },
+            "MaterialSlots": [
+                "DefaultMaterial"
+            ],
+            "PhysicsMaterials": [
+                "<Default Physics Material>"
+            ]
+        },
+        {
+            "$type": "{07B356B7-3635-40B5-878A-FAC4EFD5AD86} MeshGroup",
+            "name": "LidarOS2",
+            "nodeSelectionList": {
+                "selectedNodes": [
+                    {},
+                    "RootNode",
+                    "RootNode.OS2"
+                ],
+                "unselectedNodes": [
+                    "RootNode.Collider"
+                ]
+            },
+            "rules": {
+                "rules": [
+                    {
+                        "$type": "MaterialRule"
+                    }
+                ]
+            },
+            "id": "{830ADBFF-66E2-505D-BEE1-EFBD789FDF62}"
+        }
+    ]
+}

+ 6 - 4
Gems/WarehouseSample/Assets/O3DEScene/Materials/Warehouse_Metal_Scratched.material → Gems/ROS2SampleRobots/Assets/Components/OS2Lidar/Models/Materials/LidarOS2_OS2Material.material

@@ -8,16 +8,18 @@
             0.800000011920929,
             0.800000011920929,
             1.0
             1.0
         ],
         ],
-        "baseColor.textureMap": "../Textures/Metal_Scratched_007_Basecolor.jpg",
+        "baseColor.textureMap": "Textures/Diffuse.png",
         "emissive.color": [
         "emissive.color": [
             0.0,
             0.0,
             0.0,
             0.0,
             0.0,
             0.0,
             1.0
             1.0
         ],
         ],
-        "normal.factor": 0.800000011920929,
-        "normal.textureMap": "../Textures/Metal_Scratched_007_Normal.jpg",
+        "metallic.textureMap": "Textures/Metallic.png",
+        "occlusion.diffuseTextureMap": "Textures/AO_grey.png",
         "opacity.factor": 1.0,
         "opacity.factor": 1.0,
-        "roughness.textureMap": "../Textures/Metal_Scratched_007_Roughness.jpg"
+        "roughness.lowerBound": 0.09000000357627869,
+        "roughness.textureMap": "Textures/Roughness.png",
+        "roughness.upperBound": 0.8100000023841858
     }
     }
 }
 }

+ 3 - 0
Gems/ROS2SampleRobots/Assets/Components/OS2Lidar/Models/Materials/Textures/AO_grey.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:da65cd46f8e182ce09bde559243ebe05f000f99c2ef3088266ac27cc2ed56f81
+size 915623

+ 3 - 0
Gems/ROS2SampleRobots/Assets/Components/OS2Lidar/Models/Materials/Textures/Diffuse.png

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a111f317cd4903a72c6f9b899b53737c008d68c9fff0b2389f40f40b880a43e0
+size 133579

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません