From 7b456c667ed8b95b4188ad19ea24d754bad39b1c Mon Sep 17 00:00:00 2001 From: patrickdown Date: Wed, 6 Dec 2023 09:30:54 -0500 Subject: [PATCH] Run clang-format on C++ source Added a .clang-format file Ran clang-format on the C++ source --- .clang-format | 199 +++++ extension/T5Integration/Glasses.cpp | 932 ++++++++++----------- extension/T5Integration/Glasses.h | 233 +++--- extension/T5Integration/Logging.cpp | 76 +- extension/T5Integration/Logging.h | 34 +- extension/T5Integration/ObjectRegistry.cpp | 97 ++- extension/T5Integration/ObjectRegistry.h | 9 +- extension/T5Integration/StateFlags.h | 47 +- extension/T5Integration/T5Math.h | 13 +- extension/T5Integration/T5Service.cpp | 133 ++- extension/T5Integration/T5Service.h | 74 +- extension/T5Integration/TaskSystem.cpp | 83 +- extension/T5Integration/TaskSystem.h | 89 +- extension/T5Integration/Wand.cpp | 73 +- extension/T5Integration/Wand.h | 33 +- extension/src/GodotT5Glasses.cpp | 106 ++- extension/src/GodotT5Glasses.h | 111 ++- extension/src/GodotT5Service.cpp | 165 ++-- extension/src/GodotT5Service.h | 30 +- extension/src/OpenGLGlasses.cpp | 80 +- extension/src/OpenGLGlasses.h | 49 +- extension/src/T5Camera3D.cpp | 110 ++- extension/src/T5Camera3D.h | 27 +- extension/src/T5Controller3D.cpp | 19 +- extension/src/T5Controller3D.h | 9 +- extension/src/T5Gameboard.cpp | 185 ++-- extension/src/T5Gameboard.h | 28 +- extension/src/T5Node3D.cpp | 250 +++--- extension/src/T5Node3D.h | 29 +- extension/src/T5Origin3D.cpp | 9 +- extension/src/T5Origin3D.h | 14 +- extension/src/TiltFiveXRInterface.cpp | 134 +-- extension/src/TiltFiveXRInterface.h | 90 +- extension/src/VulkanGlasses.cpp | 146 ++-- extension/src/VulkanGlasses.h | 50 +- extension/src/register_types.cpp | 33 +- 36 files changed, 1927 insertions(+), 1872 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..75d4177 --- /dev/null +++ b/.clang-format @@ -0,0 +1,199 @@ +# Commented out parameters are those with the same value as base LLVM style. +# We can uncomment them if we want to change their value, or enforce the +# chosen value in case the base style changes (last sync: Clang 14.0). +--- +### General config, applies to all languages ### +BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +# AlignArrayOfStructures: None +# AlignConsecutiveMacros: None +# AlignConsecutiveAssignments: None +# AlignConsecutiveBitFields: None +# AlignConsecutiveDeclarations: None +# AlignEscapedNewlines: Right +AlignOperands: DontAlign +AlignTrailingComments: false +# AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false +# AllowShortEnumsOnASingleLine: true +# AllowShortBlocksOnASingleLine: Never +# AllowShortCaseLabelsOnASingleLine: false +# AllowShortFunctionsOnASingleLine: All +# AllowShortLambdasOnASingleLine: All +# AllowShortIfStatementsOnASingleLine: Never +# AllowShortLoopsOnASingleLine: false +# AlwaysBreakAfterDefinitionReturnType: None +# AlwaysBreakAfterReturnType: None +# AlwaysBreakBeforeMultilineStrings: false +# AlwaysBreakTemplateDeclarations: MultiLine +# AttributeMacros: +# - __capability +# BinPackArguments: true +# BinPackParameters: true +# BraceWrapping: +# AfterCaseLabel: false +# AfterClass: false +# AfterControlStatement: Never +# AfterEnum: false +# AfterFunction: false +# AfterNamespace: false +# AfterObjCDeclaration: false +# AfterStruct: false +# AfterUnion: false +# AfterExternBlock: false +# BeforeCatch: false +# BeforeElse: false +# BeforeLambdaBody: false +# BeforeWhile: false +# IndentBraces: false +# SplitEmptyFunction: true +# SplitEmptyRecord: true +# SplitEmptyNamespace: true +# BreakBeforeBinaryOperators: None +# BreakBeforeConceptDeclarations: true +# BreakBeforeBraces: Attach +# BreakBeforeInheritanceComma: false +# BreakInheritanceList: BeforeColon +# BreakBeforeTernaryOperators: true +# BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: AfterColon +# BreakStringLiterals: true +ColumnLimit: 0 +# CommentPragmas: '^ IWYU pragma:' +# QualifierAlignment: Leave +# CompactNamespaces: false +ConstructorInitializerIndentWidth: 8 +ContinuationIndentWidth: 8 +Cpp11BracedListStyle: false +# DeriveLineEnding: true +DerivePointerAlignment: true +# DisableFormat: false +# EmptyLineAfterAccessModifier: Never +# EmptyLineBeforeAccessModifier: LogicalBlock +# ExperimentalAutoDetectBinPacking: false +# PackConstructorInitializers: BinPack +ConstructorInitializerAllOnOneLineOrOnePerLine: true +# AllowAllConstructorInitializersOnNextLine: true +# FixNamespaceComments: true +# ForEachMacros: +# - foreach +# - Q_FOREACH +# - BOOST_FOREACH +# IfMacros: +# - KJ_IF_MAYBE +# IncludeBlocks: Preserve +IncludeCategories: + - Regex: '".*"' + Priority: 1 + - Regex: '^<.*\.h>' + Priority: 2 + - Regex: '^<.*' + Priority: 3 +# IncludeIsMainRegex: '(Test)?$' +# IncludeIsMainSourceRegex: '' +# IndentAccessModifiers: false +IndentCaseLabels: true +# IndentCaseBlocks: false +# IndentGotoLabels: true +# IndentPPDirectives: None +# IndentExternBlock: AfterExternBlock +# IndentRequires: false +IndentWidth: 4 +# IndentWrappedFunctionNames: false +# InsertTrailingCommas: None +# JavaScriptQuotes: Leave +# JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +# LambdaBodyIndentation: Signature +# MacroBlockBegin: '' +# MacroBlockEnd: '' +# MaxEmptyLinesToKeep: 1 +# NamespaceIndentation: None +# PenaltyBreakAssignment: 2 +# PenaltyBreakBeforeFirstCallParameter: 19 +# PenaltyBreakComment: 300 +# PenaltyBreakFirstLessLess: 120 +# PenaltyBreakOpenParenthesis: 0 +# PenaltyBreakString: 1000 +# PenaltyBreakTemplateDeclaration: 10 +# PenaltyExcessCharacter: 1000000 +# PenaltyReturnTypeOnItsOwnLine: 60 +# PenaltyIndentedWhitespace: 0 +PointerAlignment: Left +# PPIndentWidth: -1 +# ReferenceAlignment: Pointer +# ReflowComments: true +# RemoveBracesLLVM: false +# SeparateDefinitionBlocks: Leave +# ShortNamespaceLines: 1 +# SortIncludes: CaseSensitive +# SortJavaStaticImport: Before +# SortUsingDeclarations: true +# SpaceAfterCStyleCast: false +# SpaceAfterLogicalNot: false +# SpaceAfterTemplateKeyword: true +# SpaceBeforeAssignmentOperators: true +# SpaceBeforeCaseColon: false +# SpaceBeforeCpp11BracedList: false +# SpaceBeforeCtorInitializerColon: true +# SpaceBeforeInheritanceColon: true +# SpaceBeforeParens: ControlStatements +# SpaceBeforeParensOptions: +# AfterControlStatements: true +# AfterForeachMacros: true +# AfterFunctionDefinitionName: false +# AfterFunctionDeclarationName: false +# AfterIfMacros: true +# AfterOverloadedOperator: false +# BeforeNonEmptyParentheses: false +# SpaceAroundPointerQualifiers: Default +# SpaceBeforeRangeBasedForLoopColon: true +# SpaceInEmptyBlock: false +# SpaceInEmptyParentheses: false +# SpacesBeforeTrailingComments: 1 +# SpacesInAngles: Never +# SpacesInConditionalStatement: false +# SpacesInContainerLiterals: true +# SpacesInCStyleCastParentheses: false +## Godot TODO: We'll want to use a min of 1, but we need to see how to fix +## our comment capitalization at the same time. +SpacesInLineCommentPrefix: + Minimum: 0 + Maximum: -1 +# SpacesInParentheses: false +# SpacesInSquareBrackets: false +# SpaceBeforeSquareBrackets: false +# BitFieldColonSpacing: Both +# StatementAttributeLikeMacros: +# - Q_EMIT +# StatementMacros: +# - Q_UNUSED +# - QT_REQUIRE_VERSION +TabWidth: 4 +# UseCRLF: false +UseTab: Always +# WhitespaceSensitiveMacros: +# - STRINGIZE +# - PP_STRINGIZE +# - BOOST_PP_STRINGIZE +# - NS_SWIFT_NAME +# - CF_SWIFT_NAME +--- +### C++ specific config ### +Language: Cpp +Standard: c++20 +--- +### ObjC specific config ### +Language: ObjC +# ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +# ObjCBreakBeforeNestedBlockParam: true +# ObjCSpaceAfterProperty: false +# ObjCSpaceBeforeProtocolList: true +--- +### Java specific config ### +Language: Java +# BreakAfterJavaFieldAnnotations: false +JavaImportGroups: ['org.godotengine', 'android', 'androidx', 'com.android', 'com.google', 'java', 'javax'] +... diff --git a/extension/T5Integration/Glasses.cpp b/extension/T5Integration/Glasses.cpp index 4ad4687..97437ce 100644 --- a/extension/T5Integration/Glasses.cpp +++ b/extension/T5Integration/Glasses.cpp @@ -1,206 +1,201 @@ -#include #include #include +#include #include #include - -using TaskSystem::task_sleep; using TaskSystem::run_in_foreground; using TaskSystem::run_now; +using TaskSystem::task_sleep; namespace T5Integration { - Glasses::SwapChainFrame::SwapChainFrame() { - glasses_pose.posGLS_GBD.x = 0; - glasses_pose.posGLS_GBD.y = 0; - glasses_pose.posGLS_GBD.z = 0; - glasses_pose.rotToGLS_GBD.x = 0; - glasses_pose.rotToGLS_GBD.y = 0; - glasses_pose.rotToGLS_GBD.z = 0; - glasses_pose.rotToGLS_GBD.w = 1; - glasses_pose.gameboardType = kT5_GameboardType_None; - left_eye_handle = 0; - right_eye_handle = 0; - } - - Glasses::Glasses(const std::string_view id) - : _id(id) { +Glasses::SwapChainFrame::SwapChainFrame() { + glasses_pose.posGLS_GBD.x = 0; + glasses_pose.posGLS_GBD.y = 0; + glasses_pose.posGLS_GBD.z = 0; + glasses_pose.rotToGLS_GBD.x = 0; + glasses_pose.rotToGLS_GBD.y = 0; + glasses_pose.rotToGLS_GBD.z = 0; + glasses_pose.rotToGLS_GBD.w = 1; + glasses_pose.gameboardType = kT5_GameboardType_None; + left_eye_handle = 0; + right_eye_handle = 0; +} + +Glasses::Glasses(const std::string_view id) : + _id(id) { + _scheduler = ObjectRegistry::scheduler(); + _math = ObjectRegistry::math(); + + _state.reset(GlassesState::UNAVAILABLE); + _previous_event_state.reset(GlassesState::UNAVAILABLE); + _previous_update_state.reset(GlassesState::UNAVAILABLE); + + set_swap_chain_size(1); +} + +Glasses::~Glasses() { + destroy_handle(); +} + +void Glasses::get_pose(T5_Vec3& out_position, T5_Quat& out_orientation) { + auto& pose = _swap_chain_frames[_current_frame_idx].glasses_pose; + + out_position = pose.posGLS_GBD; + out_orientation = pose.rotToGLS_GBD; +} + +void Glasses::get_glasses_position(float& out_pos_x, float& out_pos_y, float& out_pos_z) { + auto& pose = _swap_chain_frames[_current_frame_idx].glasses_pose; + + out_pos_x = pose.posGLS_GBD.x; + out_pos_y = pose.posGLS_GBD.y; + out_pos_z = pose.posGLS_GBD.z; +} + +void Glasses::get_glasses_orientation(float& out_quat_x, float& out_quat_y, float& out_quat_z, float& out_quat_w) { + auto& pose = _swap_chain_frames[_current_frame_idx].glasses_pose; + + out_quat_x = pose.rotToGLS_GBD.x; + out_quat_y = pose.rotToGLS_GBD.y; + out_quat_z = pose.rotToGLS_GBD.z; + out_quat_w = pose.rotToGLS_GBD.w; +} + +bool Glasses::is_wand_state_set(int wand_num, uint8_t flags) { + return wand_num < _wand_list.size() && (_wand_list[wand_num]._state & flags) == flags; +} + +bool Glasses::is_wand_state_changed(int wand_num, uint8_t flags) { + if (wand_num >= _wand_list.size()) + return false; + + auto current_state = _wand_list[wand_num]._state; + auto previous_state = _previous_wand_state[wand_num]; + auto changed = current_state ^ previous_state; + _previous_wand_state[wand_num] = previous_state & ~changed | current_state & changed; + return (changed & flags) != 0; +} + +bool Glasses::is_wand_pose_valid(int wand_num) { + return wand_num < _wand_list.size() && (_wand_list[wand_num]._state & WandState::POSE_VALID) != 0; +} + +void Glasses::get_wand_position(int wand_num, float& out_pos_x, float& out_pos_y, float& out_pos_z) { + if (wand_num < _wand_list.size()) { + out_pos_x = _wand_list[wand_num]._pose.posAim_GBD.x; + out_pos_y = _wand_list[wand_num]._pose.posAim_GBD.y; + out_pos_z = _wand_list[wand_num]._pose.posAim_GBD.z; + } else { + out_pos_x = out_pos_y = out_pos_z = 0; + } +} + +void Glasses::get_wand_orientation(int wand_num, float& out_quat_x, float& out_quat_y, float& out_quat_z, float& out_quat_w) { + if (wand_num < _wand_list.size()) { + out_quat_x = _wand_list[wand_num]._pose.rotToWND_GBD.x; + out_quat_y = _wand_list[wand_num]._pose.rotToWND_GBD.y; + out_quat_z = _wand_list[wand_num]._pose.rotToWND_GBD.z; + out_quat_w = _wand_list[wand_num]._pose.rotToWND_GBD.w; + } else { + out_quat_x = out_quat_y = out_quat_z = 0; + out_quat_w = 1; + } +} + +void Glasses::get_wand_trigger(int wand_num, float& out_trigger) { + out_trigger = 0; + if (wand_num < _wand_list.size()) { + out_trigger = _wand_list[wand_num]._analog.trigger; + } +} + +void Glasses::get_wand_stick(int wand_num, float& out_stick_x, float& out_stick_y) { + out_stick_x = 0; + out_stick_y = 0; + if (wand_num < _wand_list.size()) { + out_stick_x = _wand_list[wand_num]._analog.stick.x; + out_stick_y = _wand_list[wand_num]._analog.stick.y; + } +} + +void Glasses::get_wand_buttons(int wand_num, WandButtons& buttons) { + if (wand_num < _wand_list.size()) { + buttons = _wand_list[wand_num]._buttons; + } +} + +void Glasses::trigger_haptic_pulse(int wand_num, float amplitude, uint16_t duration) { + if (wand_num < _wand_list.size() && _state.is_current(GlassesState::CONNECTED)) { + std::lock_guard lock(g_t5_exclusivity_group_1); + t5SendImpulse(_glasses_handle, _wand_list[wand_num]._handle, amplitude, duration); + } +} + +void Glasses::set_swap_chain_size(int size) { + _swap_chain_frames.resize(size); +} + +void Glasses::set_swap_chain_texture_pair(int swap_chain_idx, intptr_t left_eye_handle, intptr_t right_eye_handle) { + _swap_chain_frames[swap_chain_idx].left_eye_handle = left_eye_handle; + _swap_chain_frames[swap_chain_idx].right_eye_handle = right_eye_handle; +} + +void Glasses::set_swap_chain_texture_array(int swap_chain_idx, intptr_t array_handle) { + _swap_chain_frames[swap_chain_idx].right_eye_handle = 0; + _swap_chain_frames[swap_chain_idx].left_eye_handle = array_handle; +} + +bool Glasses::allocate_handle(T5_Context context) { + T5_Result result; + { + std::lock_guard lock(g_t5_exclusivity_group_1); + result = t5CreateGlasses(context, _id.c_str(), &_glasses_handle); + } + if (result != T5_SUCCESS) { + LOG_T5_ERROR(result); + return false; + } + _state.set(GlassesState::CREATED); + _state.clear(GlassesState::UNAVAILABLE); + _scheduler->add_task(monitor_parameters()); + + return true; +} + +void Glasses::destroy_handle() { + _state.clear_all(); + { + std::lock_guard lock(g_t5_exclusivity_group_1); + t5DestroyGlasses(&_glasses_handle); + } + _glasses_handle = nullptr; +} + +CotaskPtr Glasses::monitor_connection() { + T5_Result result; - _scheduler = ObjectRegistry::scheduler(); - _math = ObjectRegistry::math(); + while (_glasses_handle && _state.is_current(GlassesState::SUSTAIN_CONNECTION)) { + T5_ConnectionState connectionState; + GlassesFlags _previous_monitor_state; - _state.reset(GlassesState::UNAVAILABLE); - _previous_event_state.reset(GlassesState::UNAVAILABLE); - _previous_update_state.reset(GlassesState::UNAVAILABLE); + _previous_monitor_state.sync_from(_state); - set_swap_chain_size(1); - } - - Glasses::~Glasses() { - destroy_handle(); - } - - void Glasses::get_pose(T5_Vec3& out_position, T5_Quat& out_orientation) { - auto& pose = _swap_chain_frames[_current_frame_idx].glasses_pose; - - out_position = pose.posGLS_GBD; - out_orientation = pose.rotToGLS_GBD; - } - - void Glasses::get_glasses_position(float& out_pos_x, float& out_pos_y, float& out_pos_z) { - auto& pose = _swap_chain_frames[_current_frame_idx].glasses_pose; - - out_pos_x = pose.posGLS_GBD.x; - out_pos_y = pose.posGLS_GBD.y; - out_pos_z = pose.posGLS_GBD.z; - } - - void Glasses::get_glasses_orientation(float& out_quat_x, float& out_quat_y, float& out_quat_z, float& out_quat_w) { - auto& pose = _swap_chain_frames[_current_frame_idx].glasses_pose; - - out_quat_x = pose.rotToGLS_GBD.x; - out_quat_y = pose.rotToGLS_GBD.y; - out_quat_z = pose.rotToGLS_GBD.z; - out_quat_w = pose.rotToGLS_GBD.w; - } - - bool Glasses::is_wand_state_set(int wand_num, uint8_t flags) { - return wand_num < _wand_list.size() && (_wand_list[wand_num]._state & flags) == flags; - } - - bool Glasses::is_wand_state_changed(int wand_num, uint8_t flags) { - if(wand_num >= _wand_list.size()) return false; - - auto current_state = _wand_list[wand_num]._state; - auto previous_state = _previous_wand_state[wand_num]; - auto changed = current_state ^ previous_state; - _previous_wand_state[wand_num] = previous_state & ~changed | current_state & changed; - return (changed & flags) != 0; - } - - bool Glasses::is_wand_pose_valid(int wand_num) { - return wand_num < _wand_list.size() && (_wand_list[wand_num]._state & WandState::POSE_VALID) != 0; - } - - void Glasses::get_wand_position(int wand_num, float& out_pos_x, float& out_pos_y, float& out_pos_z) { - if (wand_num < _wand_list.size()) { - out_pos_x = _wand_list[wand_num]._pose.posAim_GBD.x; - out_pos_y = _wand_list[wand_num]._pose.posAim_GBD.y; - out_pos_z = _wand_list[wand_num]._pose.posAim_GBD.z; - } - else { - out_pos_x = out_pos_y = out_pos_z = 0; - } - } - - void Glasses::get_wand_orientation(int wand_num, float& out_quat_x, float& out_quat_y, float& out_quat_z, float& out_quat_w) { - if (wand_num < _wand_list.size()) { - out_quat_x = _wand_list[wand_num]._pose.rotToWND_GBD.x; - out_quat_y = _wand_list[wand_num]._pose.rotToWND_GBD.y; - out_quat_z = _wand_list[wand_num]._pose.rotToWND_GBD.z; - out_quat_w = _wand_list[wand_num]._pose.rotToWND_GBD.w; - } - else { - out_quat_x = out_quat_y = out_quat_z = 0; - out_quat_w = 1; - } - } - - void Glasses::get_wand_trigger(int wand_num, float& out_trigger) { - out_trigger = 0; - if (wand_num < _wand_list.size()) { - out_trigger = _wand_list[wand_num]._analog.trigger; - } - } - - void Glasses::get_wand_stick(int wand_num, float& out_stick_x, float& out_stick_y) { - out_stick_x = 0; - out_stick_y = 0; - if (wand_num < _wand_list.size()) { - out_stick_x = _wand_list[wand_num]._analog.stick.x; - out_stick_y = _wand_list[wand_num]._analog.stick.y; - } - } - - void Glasses::get_wand_buttons(int wand_num, WandButtons& buttons) { - if (wand_num < _wand_list.size()) { - buttons = _wand_list[wand_num]._buttons; - } - } - - void Glasses::trigger_haptic_pulse(int wand_num, float amplitude, uint16_t duration) { - if(wand_num < _wand_list.size() && _state.is_current(GlassesState::CONNECTED)) { std::lock_guard lock(g_t5_exclusivity_group_1); - t5SendImpulse(_glasses_handle, _wand_list[wand_num]._handle, amplitude, duration); - } - } - - void Glasses::set_swap_chain_size(int size) { - _swap_chain_frames.resize(size); - } - - void Glasses::set_swap_chain_texture_pair(int swap_chain_idx, intptr_t left_eye_handle, intptr_t right_eye_handle) { - _swap_chain_frames[swap_chain_idx].left_eye_handle = left_eye_handle; - _swap_chain_frames[swap_chain_idx].right_eye_handle = right_eye_handle; - } - - void Glasses::set_swap_chain_texture_array(int swap_chain_idx, intptr_t array_handle) { - _swap_chain_frames[swap_chain_idx].right_eye_handle = 0; - _swap_chain_frames[swap_chain_idx].left_eye_handle = array_handle; - } - - bool Glasses::allocate_handle(T5_Context context) { - T5_Result result; - { - std::lock_guard lock(g_t5_exclusivity_group_1); - result = t5CreateGlasses(context, _id.c_str(), &_glasses_handle); + result = t5GetGlassesConnectionState(_glasses_handle, &connectionState); } if (result != T5_SUCCESS) { + // Doesn't seem to be anything recoverable here + co_await run_in_foreground; LOG_T5_ERROR(result); - return false; - } - _state.set(GlassesState::CREATED); - _state.clear(GlassesState::UNAVAILABLE); - _scheduler->add_task(monitor_parameters()); - - return true; - } - - void Glasses::destroy_handle() { - _state.clear_all(); - { - std::lock_guard lock(g_t5_exclusivity_group_1); - t5DestroyGlasses(&_glasses_handle); + _state.reset(GlassesState::ERROR); + co_return; } - _glasses_handle = nullptr; - } - - CotaskPtr Glasses::monitor_connection() { - T5_Result result; - - while (_glasses_handle && _state.is_current(GlassesState::SUSTAIN_CONNECTION)) { - T5_ConnectionState connectionState; - GlassesFlags _previous_monitor_state; - _previous_monitor_state.sync_from(_state); - - { - std::lock_guard lock(g_t5_exclusivity_group_1); - result = t5GetGlassesConnectionState(_glasses_handle, &connectionState); - } - if (result != T5_SUCCESS) { - // Doesn't seem to be anything recoverable here - co_await run_in_foreground; - LOG_T5_ERROR(result); - _state.reset(GlassesState::ERROR); - co_return; - } - - switch (connectionState) { - case kT5_ConnectionState_NotExclusivelyConnected: - { + switch (connectionState) { + case kT5_ConnectionState_NotExclusivelyConnected: { _state.clear(GlassesState::READY); { std::lock_guard lock(g_t5_exclusivity_group_1); @@ -209,13 +204,12 @@ namespace T5Integration { if (result == T5_SUCCESS || result == T5_ERROR_ALREADY_CONNECTED) continue; else if (result == T5_ERROR_UNAVAILABLE) { - // Some else has the glasses so stop + // Some else has the glasses so stop // trying to connect _state.clear(GlassesState::SUSTAIN_CONNECTION); _state.set(GlassesState::UNAVAILABLE); co_return; - } - else if (result == T5_ERROR_DEVICE_LOST) { + } else if (result == T5_ERROR_DEVICE_LOST) { _state.clear(GlassesState::SUSTAIN_CONNECTION); co_await run_in_foreground; LOG_T5_ERROR(result); @@ -228,8 +222,7 @@ namespace T5Integration { co_return; } case kT5_ConnectionState_ExclusiveReservation: - case kT5_ConnectionState_Disconnected: - { + case kT5_ConnectionState_Disconnected: { _state.clear(GlassesState::READY); { @@ -242,26 +235,23 @@ namespace T5Integration { break; } if (result == T5_ERROR_UNAVAILABLE) { - // Some else has the glasses so stop + // Some else has the glasses so stop // trying to connect _state.clear(GlassesState::SUSTAIN_CONNECTION); _state.set(GlassesState::UNAVAILABLE); - } - else if (result == T5_ERROR_DEVICE_LOST) { + } else if (result == T5_ERROR_DEVICE_LOST) { _state.clear(GlassesState::SUSTAIN_CONNECTION); co_await run_in_foreground; LOG_T5_ERROR(result); destroy_handle(); - } - else { + } else { _state.reset(GlassesState::ERROR); co_await run_in_foreground; LOG_T5_ERROR(result); } co_return; } - case kT5_ConnectionState_ExclusiveConnection: - { + case kT5_ConnectionState_ExclusiveConnection: { _state.set(GlassesState::READY); if (!_state.is_current(GlassesState::GRAPHICS_INIT)) { co_await run_in_foreground; @@ -269,378 +259,358 @@ namespace T5Integration { } break; } - } + } - if (_state.any_changed(_previous_monitor_state, GlassesState::READY | GlassesState::GRAPHICS_INIT)) { - if (_state.is_current(GlassesState::READY | GlassesState::GRAPHICS_INIT)) - _state.set(GlassesState::CONNECTED); - else - _state.clear(GlassesState::CONNECTED); - } - if (_state.is_current(GlassesState::READY)) { - if(_state.set_and_was_toggled(GlassesState::TRACKING_WANDS)) { - _scheduler->add_task(monitor_wands()); - } + if (_state.any_changed(_previous_monitor_state, GlassesState::READY | GlassesState::GRAPHICS_INIT)) { + if (_state.is_current(GlassesState::READY | GlassesState::GRAPHICS_INIT)) + _state.set(GlassesState::CONNECTED); + else + _state.clear(GlassesState::CONNECTED); + } + if (_state.is_current(GlassesState::READY)) { + if (_state.set_and_was_toggled(GlassesState::TRACKING_WANDS)) { + _scheduler->add_task(monitor_wands()); } - - co_await task_sleep( - _state.is_current(GlassesState::CONNECTED) ? - _poll_rate_for_monitoring : - _poll_rate_for_connecting); } + + co_await task_sleep( + _state.is_current(GlassesState::CONNECTED) ? _poll_rate_for_monitoring : _poll_rate_for_connecting); } +} - CotaskPtr Glasses::monitor_parameters() { - co_await query_ipd(); - co_await query_friendly_name(); +CotaskPtr Glasses::monitor_parameters() { + co_await query_ipd(); + co_await query_friendly_name(); - T5_Result result; - std::vector _changed_params; + T5_Result result; + std::vector _changed_params; - while (_glasses_handle && _state.is_current(GlassesState::CREATED)) { - co_await task_sleep(_poll_rate_for_monitoring); + while (_glasses_handle && _state.is_current(GlassesState::CREATED)) { + co_await task_sleep(_poll_rate_for_monitoring); - uint16_t buffer_size = 16; - _changed_params.resize(buffer_size); - { - std::lock_guard lock(g_t5_exclusivity_group_1); - result = t5GetChangedGlassesParams(_glasses_handle, _changed_params.data(), &buffer_size); - } - if (result != T5_SUCCESS) { - co_await run_in_foreground; - LOG_T5_ERROR(result); - co_return; - } + uint16_t buffer_size = 16; + _changed_params.resize(buffer_size); + { + std::lock_guard lock(g_t5_exclusivity_group_1); + result = t5GetChangedGlassesParams(_glasses_handle, _changed_params.data(), &buffer_size); + } + if (result != T5_SUCCESS) { + co_await run_in_foreground; + LOG_T5_ERROR(result); + co_return; + } - if (buffer_size == 0) - continue; + if (buffer_size == 0) + continue; - _changed_params.resize(buffer_size); - for (auto param : _changed_params) { - switch (param) { - case kT5_ParamGlasses_Float_IPD: - { + _changed_params.resize(buffer_size); + for (auto param : _changed_params) { + switch (param) { + case kT5_ParamGlasses_Float_IPD: { co_await query_ipd(); } - case kT5_ParamGlasses_UTF8_FriendlyName: - { + case kT5_ParamGlasses_UTF8_FriendlyName: { co_await query_friendly_name(); } default: - break; - } + break; } } } +} - CotaskPtr Glasses::monitor_wands() { - WandService wand_service; +CotaskPtr Glasses::monitor_wands() { + WandService wand_service; - if(!wand_service.start(_glasses_handle)) - co_return; + if (!wand_service.start(_glasses_handle)) + co_return; - co_await run_in_foreground; + co_await run_in_foreground; - if(!wand_service.is_running()) - { - _state.clear(GlassesState::TRACKING_WANDS); - LOG_T5_ERROR(wand_service.get_last_error()); - co_return; - } - - while (_glasses_handle && _state.is_current(GlassesState::SUSTAIN_CONNECTION) && wand_service.is_running()) { - - auto err = wand_service.get_last_error(); - if (err != T5_SUCCESS) { - LOG_T5_ERROR(err); - } - - wand_service.get_wand_data(_wand_list); - while(_wand_list.size() > _previous_wand_state.size()) - _previous_wand_state.push_back(0); - co_await run_in_foreground; - } + if (!wand_service.is_running()) { + _state.clear(GlassesState::TRACKING_WANDS); + LOG_T5_ERROR(wand_service.get_last_error()); + co_return; + } - wand_service.stop(); - _state.clear(GlassesState::TRACKING_WANDS); + while (_glasses_handle && _state.is_current(GlassesState::SUSTAIN_CONNECTION) && wand_service.is_running()) { auto err = wand_service.get_last_error(); if (err != T5_SUCCESS) { - LOG_T5_ERROR(wand_service.get_last_error()); + LOG_T5_ERROR(err); } - } - CotaskPtr Glasses::query_ipd() { - double ipd; - T5_Result result; - for (int tries = 0; tries < 10; ++tries) { - { - std::lock_guard lock(g_t5_exclusivity_group_1); - result = t5GetGlassesFloatParam(_glasses_handle, 0, kT5_ParamGlasses_Float_IPD, &ipd); - } - if (result != T5_ERROR_NO_SERVICE && result != T5_ERROR_IO_FAILURE) { - break; - } - co_await task_sleep(_poll_rate_for_connecting); - } + wand_service.get_wand_data(_wand_list); + while (_wand_list.size() > _previous_wand_state.size()) + _previous_wand_state.push_back(0); co_await run_in_foreground; - if (result != T5_SUCCESS) { - LOG_T5_ERROR(result); + } + + wand_service.stop(); + _state.clear(GlassesState::TRACKING_WANDS); + auto err = wand_service.get_last_error(); + if (err != T5_SUCCESS) { + LOG_T5_ERROR(wand_service.get_last_error()); + } +} + +CotaskPtr Glasses::query_ipd() { + double ipd; + T5_Result result; + for (int tries = 0; tries < 10; ++tries) { + { + std::lock_guard lock(g_t5_exclusivity_group_1); + result = t5GetGlassesFloatParam(_glasses_handle, 0, kT5_ParamGlasses_Float_IPD, &ipd); } - else { - _ipd = static_cast(ipd); + if (result != T5_ERROR_NO_SERVICE && result != T5_ERROR_IO_FAILURE) { + break; } + co_await task_sleep(_poll_rate_for_connecting); } + co_await run_in_foreground; + if (result != T5_SUCCESS) { + LOG_T5_ERROR(result); + } else { + _ipd = static_cast(ipd); + } +} - CotaskPtr Glasses::query_friendly_name() { - std::vector buffer; - size_t buffer_size = 64; - buffer.resize(buffer_size); +CotaskPtr Glasses::query_friendly_name() { + std::vector buffer; + size_t buffer_size = 64; + buffer.resize(buffer_size); - T5_Result result; - for (int tries = 0; tries < 10; ++tries) { - buffer_size = buffer.size(); - { - std::lock_guard lock(g_t5_exclusivity_group_1); - result = t5GetGlassesUtf8Param(_glasses_handle, 0, kT5_ParamGlasses_UTF8_FriendlyName, buffer.data(), &buffer_size); - } - if (result == T5_ERROR_OVERFLOW) { - buffer.resize(buffer_size); - continue; - } - else if (result != T5_ERROR_NO_SERVICE && result != T5_ERROR_IO_FAILURE) { - break; - } - co_await task_sleep(_poll_rate_for_connecting); + T5_Result result; + for (int tries = 0; tries < 10; ++tries) { + buffer_size = buffer.size(); + { + std::lock_guard lock(g_t5_exclusivity_group_1); + result = t5GetGlassesUtf8Param(_glasses_handle, 0, kT5_ParamGlasses_UTF8_FriendlyName, buffer.data(), &buffer_size); } - co_await run_in_foreground; - if (result == T5_SUCCESS) { + if (result == T5_ERROR_OVERFLOW) { buffer.resize(buffer_size); - _friendly_name = buffer.data(); + continue; + } else if (result != T5_ERROR_NO_SERVICE && result != T5_ERROR_IO_FAILURE) { + break; } - else if(result == T5_ERROR_SETTING_UNKNOWN) { - _friendly_name = _id; - } - else - LOG_T5_ERROR(result); + co_await task_sleep(_poll_rate_for_connecting); } + co_await run_in_foreground; + if (result == T5_SUCCESS) { + buffer.resize(buffer_size); + _friendly_name = buffer.data(); + } else if (result == T5_ERROR_SETTING_UNKNOWN) { + _friendly_name = _id; + } else + LOG_T5_ERROR(result); +} +void Glasses::connect(const std::string_view application_name) { + if (_glasses_handle) { + _application_name = application_name; - void Glasses::connect(const std::string_view application_name) { - if (_glasses_handle) { - _application_name = application_name; + _state.set(GlassesState::SUSTAIN_CONNECTION); + _scheduler->add_task(monitor_connection()); + } +} - _state.set(GlassesState::SUSTAIN_CONNECTION); - _scheduler->add_task(monitor_connection()); +void Glasses::disconnect() { + if (_state.is_current(GlassesState::READY)) { + T5_Result result; + { + std::lock_guard lock(g_t5_exclusivity_group_1); + result = t5ReleaseGlasses(_glasses_handle); + } + if (result != T5_SUCCESS) { + LOG_T5_ERROR(result); } } + _state.clear(GlassesState::READY | GlassesState::GRAPHICS_INIT | GlassesState::SUSTAIN_CONNECTION); + on_glasses_released(); +} - void Glasses::disconnect() { - if (_state.is_current(GlassesState::READY)) { - T5_Result result; - { - std::lock_guard lock(g_t5_exclusivity_group_1); - result = t5ReleaseGlasses(_glasses_handle); - } - if (result != T5_SUCCESS) { - LOG_T5_ERROR(result); - } - } - _state.clear(GlassesState::READY | GlassesState::GRAPHICS_INIT | GlassesState::SUSTAIN_CONNECTION); - on_glasses_released(); +void Glasses::start_display() { + if (_state.set_and_was_toggled(GlassesState::DISPLAY_STARTED)) { + on_start_display(); } +} - void Glasses::start_display() { - if(_state.set_and_was_toggled(GlassesState::DISPLAY_STARTED)) { - on_start_display(); - } +void Glasses::stop_display() { + if (_state.clear_and_was_toggled(GlassesState::DISPLAY_STARTED)) { + on_stop_display(); } +} - void Glasses::stop_display() { - if(_state.clear_and_was_toggled(GlassesState::DISPLAY_STARTED)) { - on_stop_display(); - } +bool Glasses::initialize_graphics() { + auto service = ObjectRegistry::service(); + auto graphics_api = service->get_graphics_api(); + auto graphics_context = service->get_graphics_context_handle(); + // t5 exclusivity group 3 - serialized in main thread + auto result = t5InitGlassesGraphicsContext(_glasses_handle, graphics_api, graphics_context); + // T5_ERROR_INVALID_STATE seems to mean previously initialized + bool is_graphics_initialized = (result == T5_SUCCESS || result == T5_ERROR_INVALID_STATE); + if (!is_graphics_initialized) { + LOG_T5_ERROR(result); + return false; } - bool Glasses::initialize_graphics() { + _state.set(GlassesState::GRAPHICS_INIT); - auto service = ObjectRegistry::service(); - auto graphics_api = service->get_graphics_api(); - auto graphics_context = service->get_graphics_context_handle(); - // t5 exclusivity group 3 - serialized in main thread - auto result = t5InitGlassesGraphicsContext(_glasses_handle, graphics_api, graphics_context); - // T5_ERROR_INVALID_STATE seems to mean previously initialized - bool is_graphics_initialized = (result == T5_SUCCESS || result == T5_ERROR_INVALID_STATE); - if (!is_graphics_initialized) { - LOG_T5_ERROR(result); - return false; - } + return true; +} - _state.set(GlassesState::GRAPHICS_INIT); +void Glasses::update_pose() { + if (!_state.is_current(GlassesState::CONNECTED)) + return; - return true; + T5_Result result; + { + std::lock_guard lock(g_t5_exclusivity_group_1); + result = t5GetGlassesPose(_glasses_handle, kT5_GlassesPoseUsage_GlassesPresentation, &_swap_chain_frames[_current_frame_idx].glasses_pose); } + bool isTracking = (result == T5_SUCCESS); - void Glasses::update_pose() { - if (!_state.is_current(GlassesState::CONNECTED)) - return; - - T5_Result result; - { - std::lock_guard lock(g_t5_exclusivity_group_1); - result = t5GetGlassesPose(_glasses_handle, kT5_GlassesPoseUsage_GlassesPresentation, &_swap_chain_frames[_current_frame_idx].glasses_pose); - } - bool isTracking = (result == T5_SUCCESS); + if (isTracking) { + _state.set(GlassesState::TRACKING); + } else { + _state.clear(GlassesState::TRACKING); - if (isTracking) { - _state.set(GlassesState::TRACKING); - } - else { - _state.clear(GlassesState::TRACKING); - - if (result == T5_ERROR_TRY_AGAIN) - return; - else if (result == T5_ERROR_NOT_CONNECTED) { - _state.clear(GlassesState::CONNECTED); - LOG_T5_ERROR(result); - } - else { - LOG_T5_ERROR(result); - _state.reset(GlassesState::ERROR); - } + if (result == T5_ERROR_TRY_AGAIN) + return; + else if (result == T5_ERROR_NOT_CONNECTED) { + _state.clear(GlassesState::CONNECTED); + LOG_T5_ERROR(result); + } else { + LOG_T5_ERROR(result); + _state.reset(GlassesState::ERROR); } - LOG_TOGGLE(false, isTracking, "Tracking started", "Tracking ended"); } + LOG_TOGGLE(false, isTracking, "Tracking started", "Tracking ended"); +} - void Glasses::get_eye_position(Eye eye, T5_Vec3& pos) { - - float dir = (eye == Left ? -1.0f : 1.0f); - auto ipd = get_ipd(); - pos.x = dir * ipd / 2.0f; - pos.y = 0.0f; - pos.z = 0.0f; +void Glasses::get_eye_position(Eye eye, T5_Vec3& pos) { + float dir = (eye == Left ? -1.0f : 1.0f); + auto ipd = get_ipd(); + pos.x = dir * ipd / 2.0f; + pos.y = 0.0f; + pos.z = 0.0f; - auto& pose = _swap_chain_frames[_current_frame_idx].glasses_pose; + auto& pose = _swap_chain_frames[_current_frame_idx].glasses_pose; - _math->rotate_vector( - pose.rotToGLS_GBD.x, - pose.rotToGLS_GBD.y, - pose.rotToGLS_GBD.z, + _math->rotate_vector( + pose.rotToGLS_GBD.x, + pose.rotToGLS_GBD.y, + pose.rotToGLS_GBD.z, pose.rotToGLS_GBD.w, pos.x, pos.y, pos.z, true); - pos.x += pose.posGLS_GBD.x; - pos.y += pose.posGLS_GBD.y; - pos.z += pose.posGLS_GBD.z; - } + pos.x += pose.posGLS_GBD.x; + pos.y += pose.posGLS_GBD.y; + pos.z += pose.posGLS_GBD.z; +} - void Glasses::send_frame() { - if (_state.is_current(GlassesState::TRACKING | GlassesState::CONNECTED)) { - - on_send_frame(_current_frame_idx); - - T5_FrameInfo frameInfo; +void Glasses::send_frame() { + if (_state.is_current(GlassesState::TRACKING | GlassesState::CONNECTED)) { + on_send_frame(_current_frame_idx); - int width; - int height; - Glasses::get_display_size(width, height); + T5_FrameInfo frameInfo; - frameInfo.vci.startY_VCI = static_cast(-tan((get_fov() * 3.1415926535 / 180.0) * 0.5f)); - frameInfo.vci.startX_VCI = frameInfo.vci.startY_VCI * (float)width / (float)height; - frameInfo.vci.width_VCI = -2.0f * frameInfo.vci.startX_VCI; - frameInfo.vci.height_VCI = -2.0f * frameInfo.vci.startY_VCI; + int width; + int height; + Glasses::get_display_size(width, height); - frameInfo.texWidth_PIX = width; - frameInfo.texHeight_PIX = height; + frameInfo.vci.startY_VCI = static_cast(-tan((get_fov() * 3.1415926535 / 180.0) * 0.5f)); + frameInfo.vci.startX_VCI = frameInfo.vci.startY_VCI * (float)width / (float)height; + frameInfo.vci.width_VCI = -2.0f * frameInfo.vci.startX_VCI; + frameInfo.vci.height_VCI = -2.0f * frameInfo.vci.startY_VCI; - frameInfo.leftTexHandle = (void*)_swap_chain_frames[_current_frame_idx].left_eye_handle; - frameInfo.rightTexHandle = (void*)_swap_chain_frames[_current_frame_idx].right_eye_handle; + frameInfo.texWidth_PIX = width; + frameInfo.texHeight_PIX = height; - auto& pose = _swap_chain_frames[_current_frame_idx].glasses_pose; + frameInfo.leftTexHandle = (void*)_swap_chain_frames[_current_frame_idx].left_eye_handle; + frameInfo.rightTexHandle = (void*)_swap_chain_frames[_current_frame_idx].right_eye_handle; - get_eye_position(Left, frameInfo.posLVC_GBD); - frameInfo.rotToLVC_GBD = pose.rotToGLS_GBD; - - get_eye_position(Right, frameInfo.posRVC_GBD); - frameInfo.rotToRVC_GBD = pose.rotToGLS_GBD; - - frameInfo.isUpsideDown = _is_upside_down_texture; - frameInfo.isSrgb = true; + auto& pose = _swap_chain_frames[_current_frame_idx].glasses_pose; - // t5 exclusivity group 3 - serialized in main thread - T5_Result result = t5SendFrameToGlasses(_glasses_handle, &frameInfo); - _current_frame_idx = (_current_frame_idx + 1) % _swap_chain_frames.size(); + get_eye_position(Left, frameInfo.posLVC_GBD); + frameInfo.rotToLVC_GBD = pose.rotToGLS_GBD; - LOG_TOGGLE(false, result == T5_SUCCESS, "Started sending frames", "Stoped sending frames"); - if (result == T5_SUCCESS) - return; - LOG_T5_ERROR(result); - if (result == T5_ERROR_NOT_CONNECTED) { - _state.clear(GlassesState::CONNECTED); - } - // not sure how we might get here - else if (result == T5_ERROR_GFX_CONTEXT_INIT_FAIL || result == T5_ERROR_INVALID_GFX_CONTEXT) { - _state.clear(GlassesState::GRAPHICS_INIT); - } - else { - _state.reset(GlassesState::ERROR); - } - } - } + get_eye_position(Right, frameInfo.posRVC_GBD); + frameInfo.rotToRVC_GBD = pose.rotToGLS_GBD; + frameInfo.isUpsideDown = _is_upside_down_texture; + frameInfo.isSrgb = true; - bool Glasses::update_connection() { + // t5 exclusivity group 3 - serialized in main thread + T5_Result result = t5SendFrameToGlasses(_glasses_handle, &frameInfo); + _current_frame_idx = (_current_frame_idx + 1) % _swap_chain_frames.size(); - if(_state.became_set(_previous_update_state, GlassesState::CONNECTED)) { - on_glasses_reserved(); + LOG_TOGGLE(false, result == T5_SUCCESS, "Started sending frames", "Stoped sending frames"); + if (result == T5_SUCCESS) + return; + LOG_T5_ERROR(result); + if (result == T5_ERROR_NOT_CONNECTED) { + _state.clear(GlassesState::CONNECTED); } - if(_state.became_clear(_previous_update_state, GlassesState::CONNECTED)) { - stop_display(); - on_glasses_dropped(); + // not sure how we might get here + else if (result == T5_ERROR_GFX_CONTEXT_INIT_FAIL || result == T5_ERROR_INVALID_GFX_CONTEXT) { + _state.clear(GlassesState::GRAPHICS_INIT); + } else { + _state.reset(GlassesState::ERROR); } - _previous_update_state.sync_from(_state); - - return true; } +} - bool Glasses::update_tracking() { - update_pose(); - on_tracking_updated(); - return true; +bool Glasses::update_connection() { + if (_state.became_set(_previous_update_state, GlassesState::CONNECTED)) { + on_glasses_reserved(); + } + if (_state.became_clear(_previous_update_state, GlassesState::CONNECTED)) { + stop_display(); + on_glasses_dropped(); } + _previous_update_state.sync_from(_state); - void Glasses::get_events(int index, std::vector& out_events) { - - if(_state.became_set(_previous_event_state, GlassesState::CREATED)) { - out_events.push_back(GlassesEvent(index, GlassesEvent::E_ADDED)); - } - if(_state.became_clear(_previous_event_state, GlassesState::CREATED)) { - out_events.push_back(GlassesEvent(index, GlassesEvent::E_LOST)); - } + return true; +} - if(_state.became_set(_previous_event_state, GlassesState::UNAVAILABLE)) { - out_events.push_back(GlassesEvent(index, GlassesEvent::E_UNAVAILABLE)); - } - if(_state.became_clear(_previous_event_state, GlassesState::UNAVAILABLE)) { - out_events.push_back(GlassesEvent(index, GlassesEvent::E_AVAILABLE)); - } +bool Glasses::update_tracking() { + update_pose(); + on_tracking_updated(); + return true; +} - if(_state.became_set(_previous_event_state, GlassesState::CONNECTED)) { - out_events.push_back(GlassesEvent(index, GlassesEvent::E_CONNECTED)); - } - if(_state.became_clear(_previous_event_state, GlassesState::CONNECTED)) { - out_events.push_back(GlassesEvent(index, GlassesEvent::E_DISCONNECTED)); - } +void Glasses::get_events(int index, std::vector& out_events) { + if (_state.became_set(_previous_event_state, GlassesState::CREATED)) { + out_events.push_back(GlassesEvent(index, GlassesEvent::E_ADDED)); + } + if (_state.became_clear(_previous_event_state, GlassesState::CREATED)) { + out_events.push_back(GlassesEvent(index, GlassesEvent::E_LOST)); + } - if(_state.became_set(_previous_event_state, GlassesState::TRACKING)) { - out_events.push_back(GlassesEvent(index, GlassesEvent::E_TRACKING)); - } - if(_state.became_clear(_previous_event_state, GlassesState::TRACKING)) { - out_events.push_back(GlassesEvent(index, GlassesEvent::E_NOT_TRACKING)); - } + if (_state.became_set(_previous_event_state, GlassesState::UNAVAILABLE)) { + out_events.push_back(GlassesEvent(index, GlassesEvent::E_UNAVAILABLE)); + } + if (_state.became_clear(_previous_event_state, GlassesState::UNAVAILABLE)) { + out_events.push_back(GlassesEvent(index, GlassesEvent::E_AVAILABLE)); + } + + if (_state.became_set(_previous_event_state, GlassesState::CONNECTED)) { + out_events.push_back(GlassesEvent(index, GlassesEvent::E_CONNECTED)); + } + if (_state.became_clear(_previous_event_state, GlassesState::CONNECTED)) { + out_events.push_back(GlassesEvent(index, GlassesEvent::E_DISCONNECTED)); + } - _previous_event_state.sync_from(_state); + if (_state.became_set(_previous_event_state, GlassesState::TRACKING)) { + out_events.push_back(GlassesEvent(index, GlassesEvent::E_TRACKING)); + } + if (_state.became_clear(_previous_event_state, GlassesState::TRACKING)) { + out_events.push_back(GlassesEvent(index, GlassesEvent::E_NOT_TRACKING)); } -} \ No newline at end of file + + _previous_event_state.sync_from(_state); +} +} //namespace T5Integration \ No newline at end of file diff --git a/extension/T5Integration/Glasses.h b/extension/T5Integration/Glasses.h index 837f54f..90968d9 100644 --- a/extension/T5Integration/Glasses.h +++ b/extension/T5Integration/Glasses.h @@ -1,10 +1,10 @@ #pragma once -#include -#include #include #include +#include #include +#include namespace T5Integration { @@ -16,6 +16,7 @@ using TaskSystem::Scheduler; float const g_default_fov = 48.0f; +// clang-format off namespace GlassesState { const uint16_t READY = 0x00000001; //0000000001 const uint16_t GRAPHICS_INIT = 0x00000002; //0000000010 @@ -29,120 +30,119 @@ namespace GlassesState { const uint16_t ERROR = 0x00000100; //0100000000 const uint16_t DISPLAY_STARTED = 0x00000200; //1000000000 } +// clang-format on struct GlassesEvent { - enum EType - { - E_NONE = 0, - E_ADDED = 1, - E_LOST = 2, - E_AVAILABLE = 3, - E_UNAVAILABLE = 4, - E_CONNECTED = 5, - E_DISCONNECTED = 6, - E_TRACKING = 7, - E_NOT_TRACKING = 8, - E_STOPPED_ON_ERROR = 9 - }; - GlassesEvent(int num, EType evt) - : glasses_num(num), event(evt) - {} - - int glasses_num; - EType event; + // clang-format off + enum EType + { + E_NONE = 0, + E_ADDED = 1, + E_LOST = 2, + E_AVAILABLE = 3, + E_UNAVAILABLE = 4, + E_CONNECTED = 5, + E_DISCONNECTED = 6, + E_TRACKING = 7, + E_NOT_TRACKING = 8, + E_STOPPED_ON_ERROR = 9 + }; + // clang-format on + + GlassesEvent(int num, EType evt) : + glasses_num(num), event(evt) {} + + int glasses_num; + EType event; }; -class Glasses -{ - friend T5Service; +class Glasses { + friend T5Service; - protected: - struct SwapChainFrame { - SwapChainFrame(); - T5_GlassesPose glasses_pose; - intptr_t left_eye_handle; - intptr_t right_eye_handle; - }; - - public: +protected: + struct SwapChainFrame { + SwapChainFrame(); + T5_GlassesPose glasses_pose; + intptr_t left_eye_handle; + intptr_t right_eye_handle; + }; + +public: using Ptr = std::shared_ptr; - enum Eye - { - Mono, - Left, - Right - }; - - Glasses(const std::string_view id); - virtual ~Glasses(); - - const std::string get_id(); - const std::string get_name(); - bool is_connected(); - bool is_available(); - bool is_tracking(); - - bool allocate_handle(T5_Context context); - void destroy_handle(); - void connect(const std::string_view application_name); - void disconnect(); + enum Eye { + Mono, + Left, + Right + }; + + Glasses(const std::string_view id); + virtual ~Glasses(); + + const std::string get_id(); + const std::string get_name(); + bool is_connected(); + bool is_available(); + bool is_tracking(); + + bool allocate_handle(T5_Context context); + void destroy_handle(); + void connect(const std::string_view application_name); + void disconnect(); void start_display(); void stop_display(); - - float get_ipd(); - float get_fov(); - void get_display_size(int& out_width, int& out_height); + float get_ipd(); + float get_fov(); + void get_display_size(int& out_width, int& out_height); void get_pose(T5_Vec3& out_position, T5_Quat& out_orientation); - void get_glasses_position(float& out_pos_x, float& out_pos_y, float& out_pos_z); - void get_glasses_orientation(float& out_quat_x, float& out_quat_y, float& out_quat_z, float& out_quat_w); + void get_glasses_position(float& out_pos_x, float& out_pos_y, float& out_pos_z); + void get_glasses_orientation(float& out_quat_x, float& out_quat_y, float& out_quat_z, float& out_quat_w); - int get_current_frame_idx() { return _current_frame_idx; } + int get_current_frame_idx() { return _current_frame_idx; } void send_frame(); - void set_upside_down_texture(bool is_upside_down); + void set_upside_down_texture(bool is_upside_down); - bool update_connection(); - bool update_tracking(); + bool update_connection(); + bool update_tracking(); - void get_events(int index, std::vector& out_events); - T5_GameboardType get_gameboard_type(); + void get_events(int index, std::vector& out_events); + T5_GameboardType get_gameboard_type(); int get_num_wands() { return _wand_list.size(); } - bool is_wand_state_set(int wand_num, uint8_t flags); - bool is_wand_state_changed(int wand_num, uint8_t flags); + bool is_wand_state_set(int wand_num, uint8_t flags); + bool is_wand_state_changed(int wand_num, uint8_t flags); bool is_wand_pose_valid(int wand_num); void get_wand_position(int wand_num, float& out_pos_x, float& out_pos_y, float& out_pos_z); void get_wand_orientation(int wand_num, float& out_quat_x, float& out_quat_y, float& out_quat_z, float& out_quat_w); - void get_wand_trigger(int wand_num, float& out_trigger); - void get_wand_stick(int wand_num, float& out_stick_x, float& out_stick_y); - void get_wand_buttons(int wand_num, WandButtons& buttons); + void get_wand_trigger(int wand_num, float& out_trigger); + void get_wand_stick(int wand_num, float& out_stick_x, float& out_stick_y); + void get_wand_buttons(int wand_num, WandButtons& buttons); - void trigger_haptic_pulse(int wand_num, float amplitude, uint16_t duration); + void trigger_haptic_pulse(int wand_num, float amplitude, uint16_t duration); - virtual void on_post_draw() {} + virtual void on_post_draw() {} protected: - - void set_swap_chain_size(int size); - void set_swap_chain_texture_pair(int swap_chain_idx, intptr_t left_eye_handle, intptr_t right_eye_handle); - void set_swap_chain_texture_array(int swap_chain_idx, intptr_t array_handle); + void set_swap_chain_size(int size); + void set_swap_chain_texture_pair(int swap_chain_idx, intptr_t left_eye_handle, intptr_t right_eye_handle); + void set_swap_chain_texture_array(int swap_chain_idx, intptr_t array_handle); virtual void on_start_display() {} virtual void on_stop_display() {} - virtual void on_glasses_reserved() {} - virtual void on_glasses_released() {} - virtual void on_glasses_dropped() {} - virtual void on_tracking_updated() {} - virtual void on_send_frame(int swap_chain_idx) {} + virtual void on_glasses_reserved() {} + virtual void on_glasses_released() {} + virtual void on_glasses_dropped() {} + virtual void on_tracking_updated() {} + virtual void on_send_frame(int swap_chain_idx) {} - GlassesFlags::FlagType get_current_state(); -private: + GlassesFlags::FlagType get_current_state(); +private: CotaskPtr monitor_connection(); CotaskPtr monitor_parameters(); CotaskPtr monitor_wands(); @@ -159,12 +159,11 @@ class Glasses void get_eye_position(Eye eye, T5_Vec3& pos); - void begin_reserved_state(); - void end_reserved_state(); - - private: + void begin_reserved_state(); + void end_reserved_state(); - Scheduler::Ptr _scheduler; +private: + Scheduler::Ptr _scheduler; T5Math::Ptr _math; std::string _id; @@ -172,8 +171,8 @@ class Glasses std::string _friendly_name; T5_Glasses _glasses_handle = nullptr; - int _current_frame_idx = 0; - std::vector _swap_chain_frames; + int _current_frame_idx = 0; + std::vector _swap_chain_frames; float _ipd = 0.059f; @@ -181,67 +180,59 @@ class Glasses GlassesFlags _previous_event_state; GlassesFlags _previous_update_state; - bool _is_upside_down_texture = false; + bool _is_upside_down_texture = false; WandList _wand_list; - std::vector _previous_wand_state; + std::vector _previous_wand_state; std::chrono::milliseconds _poll_rate_for_connecting = 100ms; std::chrono::milliseconds _poll_rate_for_monitoring = 2s; std::chrono::milliseconds _wait_time_for_wand_IO = 100s; - }; -inline const std::string Glasses::get_id() -{ - return _id; +inline const std::string Glasses::get_id() { + return _id; } - + inline const std::string Glasses::get_name() { - return _friendly_name; + return _friendly_name; } -inline bool Glasses::is_connected() -{ - return _state.is_current(GlassesState::CONNECTED); +inline bool Glasses::is_connected() { + return _state.is_current(GlassesState::CONNECTED); } -inline bool Glasses::is_available() -{ - return !(_state.is_current(GlassesState::SUSTAIN_CONNECTION) || _state.is_current(GlassesState::UNAVAILABLE)); +inline bool Glasses::is_available() { + return !(_state.is_current(GlassesState::SUSTAIN_CONNECTION) || _state.is_current(GlassesState::UNAVAILABLE)); } -inline bool Glasses::is_tracking() -{ - return is_connected() && _state.is_current(GlassesState::TRACKING); +inline bool Glasses::is_tracking() { + return is_connected() && _state.is_current(GlassesState::TRACKING); } -inline float Glasses::get_ipd() -{ - return static_cast(_ipd); +inline float Glasses::get_ipd() { + return static_cast(_ipd); } -inline float Glasses::get_fov() -{ - return 48.0f; +inline float Glasses::get_fov() { + return 48.0f; } -inline void Glasses::get_display_size(int& width, int& height) -{ - width = 1216; - height = 768; +inline void Glasses::get_display_size(int& width, int& height) { + width = 1216; + height = 768; } inline void Glasses::set_upside_down_texture(bool is_upside_down) { - _is_upside_down_texture = is_upside_down; + _is_upside_down_texture = is_upside_down; } inline T5_GameboardType Glasses::get_gameboard_type() { - return _swap_chain_frames[_current_frame_idx].glasses_pose.gameboardType; + return _swap_chain_frames[_current_frame_idx].glasses_pose.gameboardType; } inline GlassesFlags::FlagType Glasses::get_current_state() { - return _state.get_current(); + return _state.get_current(); } -} \ No newline at end of file +} //namespace T5Integration \ No newline at end of file diff --git a/extension/T5Integration/Logging.cpp b/extension/T5Integration/Logging.cpp index 5a145a2..d607c9b 100644 --- a/extension/T5Integration/Logging.cpp +++ b/extension/T5Integration/Logging.cpp @@ -1,55 +1,49 @@ -#include -#include #include - +#include +#include namespace T5Integration { - void DefaultLogger::log_error(const char* message, const char* func_name, const char* file_name, int line_num) { - std::cerr << file_name << "(" << line_num << ") [" << func_name << "] Error: " << message << std::endl; - } +void DefaultLogger::log_error(const char* message, const char* func_name, const char* file_name, int line_num) { + std::cerr << file_name << "(" << line_num << ") [" << func_name << "] Error: " << message << std::endl; +} - void DefaultLogger::log_warning(const char* message, const char* func_name, const char* file_name, int line_num) { - std::cerr << file_name << "(" << line_num << ") [" << func_name << "] Warning: " << message << std::endl; - } +void DefaultLogger::log_warning(const char* message, const char* func_name, const char* file_name, int line_num) { + std::cerr << file_name << "(" << line_num << ") [" << func_name << "] Warning: " << message << std::endl; +} - void DefaultLogger::log_string(const char* message) - { - std::cout << message << std::endl; - } +void DefaultLogger::log_string(const char* message) { + std::cout << message << std::endl; +} - void log_string(const char* message) { - ObjectRegistry::logger()->log_string(message); - } +void log_string(const char* message) { + ObjectRegistry::logger()->log_string(message); +} - - void log_error(const char* message, const char* p_function, const char* p_file, int p_line){ - ObjectRegistry::logger()->log_error(message, p_function, p_file, p_line); - } +void log_error(const char* message, const char* p_function, const char* p_file, int p_line) { + ObjectRegistry::logger()->log_error(message, p_function, p_file, p_line); +} - void log_warning(const char* message, const char* p_function, const char* p_file, int p_line) { - ObjectRegistry::logger()->log_warning(message, p_function, p_file, p_line); - } +void log_warning(const char* message, const char* p_function, const char* p_file, int p_line) { + ObjectRegistry::logger()->log_warning(message, p_function, p_file, p_line); +} - void log_tilt_five_error(T5_Result result_code, const char *p_function, const char *p_file, int p_line) { - ObjectRegistry::logger()->log_error(t5GetResultMessage(result_code), p_function, p_file, p_line); - } +void log_tilt_five_error(T5_Result result_code, const char* p_function, const char* p_file, int p_line) { + ObjectRegistry::logger()->log_error(t5GetResultMessage(result_code), p_function, p_file, p_line); +} - void log_tilt_five_warning(T5_Result result_code, const char *p_function, const char *p_file, int p_line) { - ObjectRegistry::logger()->log_warning(t5GetResultMessage(result_code), p_function, p_file, p_line); - } +void log_tilt_five_warning(T5_Result result_code, const char* p_function, const char* p_file, int p_line) { + ObjectRegistry::logger()->log_warning(t5GetResultMessage(result_code), p_function, p_file, p_line); +} - void log_toggle(bool newValue, bool& prevVal, const char* msg1, const char* msg2) - { - if(newValue != prevVal) - { - prevVal = newValue; - if(newValue) - log_message(msg1); - else - log_message(msg2); - - } +void log_toggle(bool newValue, bool& prevVal, const char* msg1, const char* msg2) { + if (newValue != prevVal) { + prevVal = newValue; + if (newValue) + log_message(msg1); + else + log_message(msg2); } +} -} \ No newline at end of file +} //namespace T5Integration \ No newline at end of file diff --git a/extension/T5Integration/Logging.h b/extension/T5Integration/Logging.h index 86bb7d1..c4df568 100644 --- a/extension/T5Integration/Logging.h +++ b/extension/T5Integration/Logging.h @@ -1,10 +1,10 @@ #pragma once +#include #include #include -#include namespace T5Integration { - + class Logger { public: using Ptr = std::shared_ptr; @@ -30,14 +30,14 @@ void log_toggle(bool current, bool& state, const char* msg1, const char* msg2); inline void log_message_stream(std::stringstream& stream) {} -template +template void log_message_stream(std::stringstream& stream, T var1, Types... var2) { stream << var1; log_message_stream(stream, var2...); } -template +template void log_message(T var1, Types... var2) { std::stringstream stream; stream << var1; @@ -47,16 +47,24 @@ void log_message(T var1, Types... var2) { } //namespace T5Integration - #define LOG_CHECK_POINT T5Integration::log_message("===> ", __func__, " : ", __LINE__); #ifndef LOG_CHECK_POINT_ONCE -#define LOG_CHECK_POINT_ONCE { static bool once ## __LINE__ = false; if(! once ## __LINE__) {LOG_CHECK_POINT once ## __LINE__ = true; }} +#define LOG_CHECK_POINT_ONCE \ + { \ + static bool once##__LINE__ = false; \ + if (!once##__LINE__) { \ + LOG_CHECK_POINT once##__LINE__ = true; \ + } \ + } #endif - #ifndef LOG_TOGGLE -#define LOG_TOGGLE(INIT, TEST, MSG1, MSG2) { static bool toggle ## __LINE__ = (INIT); T5Integration::log_toggle((TEST), toggle ## __LINE__, MSG1, MSG2); } +#define LOG_TOGGLE(INIT, TEST, MSG1, MSG2) \ + { \ + static bool toggle##__LINE__ = (INIT); \ + T5Integration::log_toggle((TEST), toggle##__LINE__, MSG1, MSG2); \ + } #endif #ifndef LOG_MESSAGE @@ -76,6 +84,12 @@ void log_message(T var1, Types... var2) { #endif #ifndef LOG_ERROR_ONCE -#define LOG_ERROR_ONCE(MSG) { static bool once ## __LINE__ = false; if(! once ## __LINE__) {LOG_ERROR(MSG); once ## __LINE__ = true; }} +#define LOG_ERROR_ONCE(MSG) \ + { \ + static bool once##__LINE__ = false; \ + if (!once##__LINE__) { \ + LOG_ERROR(MSG); \ + once##__LINE__ = true; \ + } \ + } #endif - diff --git a/extension/T5Integration/ObjectRegistry.cpp b/extension/T5Integration/ObjectRegistry.cpp index 7ec4b14..92e3344 100644 --- a/extension/T5Integration/ObjectRegistry.cpp +++ b/extension/T5Integration/ObjectRegistry.cpp @@ -1,56 +1,53 @@ -#include #include +#include namespace T5Integration { - ObjectRegistry* ObjectRegistry::_instance = nullptr; - - ObjectRegistry::ObjectRegistry() { - _instance = this; - } - - T5Service::Ptr ObjectRegistry::service() { - assert(_instance); - return _instance->get_service(); - } - - T5Math::Ptr ObjectRegistry::math() { - assert(_instance); - return _instance->get_math(); +ObjectRegistry* ObjectRegistry::_instance = nullptr; + +ObjectRegistry::ObjectRegistry() { + _instance = this; +} + +T5Service::Ptr ObjectRegistry::service() { + assert(_instance); + return _instance->get_service(); +} + +T5Math::Ptr ObjectRegistry::math() { + assert(_instance); + return _instance->get_math(); +} + +Logger::Ptr ObjectRegistry::logger() { + assert(_instance); + return _instance->get_logger(); +} + +Scheduler::Ptr ObjectRegistry::scheduler() { + assert(_instance); + return _instance->get_scheduler(); +} + +Logger::Ptr ObjectRegistry::get_logger() { + Logger::Ptr logger; + if (_logger.expired()) { + logger = std::make_shared(); + _logger = logger; + } else { + logger = _logger.lock(); } - - Logger::Ptr ObjectRegistry::logger() { - assert(_instance); - return _instance->get_logger(); - } - - Scheduler::Ptr ObjectRegistry::scheduler() { - assert(_instance); - return _instance->get_scheduler(); - } - - Logger::Ptr ObjectRegistry::get_logger() { - Logger::Ptr logger; - if (_logger.expired()) - { - logger = std::make_shared(); - _logger = logger; - } - else { - logger = _logger.lock(); - } - return logger; - } - - Scheduler::Ptr ObjectRegistry::get_scheduler() { - Scheduler::Ptr scheduler; - if (_scheduler.expired()) { - scheduler = std::make_shared(); - _scheduler = scheduler; - } - else { - scheduler = _scheduler.lock(); - } - return scheduler; + return logger; +} + +Scheduler::Ptr ObjectRegistry::get_scheduler() { + Scheduler::Ptr scheduler; + if (_scheduler.expired()) { + scheduler = std::make_shared(); + _scheduler = scheduler; + } else { + scheduler = _scheduler.lock(); } -} \ No newline at end of file + return scheduler; +} +} //namespace T5Integration \ No newline at end of file diff --git a/extension/T5Integration/ObjectRegistry.h b/extension/T5Integration/ObjectRegistry.h index acb5ca7..36a1bac 100644 --- a/extension/T5Integration/ObjectRegistry.h +++ b/extension/T5Integration/ObjectRegistry.h @@ -1,9 +1,9 @@ #pragma once -#include -#include #include #include +#include #include +#include namespace T5Integration { @@ -15,14 +15,12 @@ class ObjectRegistry { virtual ~ObjectRegistry() = default; public: - static T5Service::Ptr service(); static T5Math::Ptr math(); static Logger::Ptr logger(); static Scheduler::Ptr scheduler(); protected: - virtual T5Service::Ptr get_service() = 0; virtual T5Math::Ptr get_math() = 0; virtual Logger::Ptr get_logger(); @@ -32,6 +30,5 @@ class ObjectRegistry { Logger::Ptr::weak_type _logger; Scheduler::Ptr::weak_type _scheduler; - }; -} \ No newline at end of file +} //namespace T5Integration \ No newline at end of file diff --git a/extension/T5Integration/StateFlags.h b/extension/T5Integration/StateFlags.h index 97f864b..232c3d2 100644 --- a/extension/T5Integration/StateFlags.h +++ b/extension/T5Integration/StateFlags.h @@ -2,79 +2,66 @@ #include #include -template -class StateFlags -{ +template +class StateFlags { static_assert(std::is_integral_v); - public: - +public: using FlagType = T; - FlagType get_current() - { + FlagType get_current() { return _current.load(); } - void set(FlagType state) - { + void set(FlagType state) { _current.fetch_or(state); } - bool set_and_was_toggled(FlagType state) - { + bool set_and_was_toggled(FlagType state) { T old = _current.fetch_or(state); return (old & state) != state; } - void clear(FlagType state) - { + void clear(FlagType state) { _current.fetch_and(~state); } - bool clear_and_was_toggled(FlagType state) - { + bool clear_and_was_toggled(FlagType state) { T old = _current.fetch_and(~state); return (old & state) == state; } - void clear_all() - { + void clear_all() { _current.store(0); } - void reset(FlagType state) - { + void reset(FlagType state) { _current.store(state); } - bool is_current(FlagType state) const - { + bool is_current(FlagType state) const { return (_current.load() & state) == state; } - bool is_any_current(FlagType state) const - { + bool is_any_current(FlagType state) const { return (_current.load() & state) != 0; } - bool is_not_current(FlagType state) const - { + bool is_not_current(FlagType state) const { return (_current.load() & state) != state; } - bool any_changed(const StateFlags& from, FlagType query_state) const - { + bool any_changed(const StateFlags& from, FlagType query_state) const { return ((_current.load() ^ from._current.load()) & query_state) != 0; } bool became_set(const StateFlags& from, FlagType query_state) const { - return (_current.load() & query_state) == query_state && + return (_current.load() & query_state) == query_state && (from._current.load() & query_state) != query_state; } bool became_clear(const StateFlags& from, FlagType query_state) const { - return (_current.load() & query_state) != query_state && + return (_current.load() & query_state) != query_state && (from._current.load() & query_state) == query_state; } @@ -82,6 +69,6 @@ class StateFlags _current.store(from._current.load()); } - private: +private: std::atomic _current; }; diff --git a/extension/T5Integration/T5Math.h b/extension/T5Integration/T5Math.h index 69d7639..650d9c9 100644 --- a/extension/T5Integration/T5Math.h +++ b/extension/T5Integration/T5Math.h @@ -1,12 +1,13 @@ #pragma once +#include namespace T5Integration { - class T5Math { - public: - using Ptr = std::shared_ptr; +class T5Math { +public: + using Ptr = std::shared_ptr; - virtual void rotate_vector(float quat_x, float quat_y, float quat_z, float quat_w, float& vec_x, float& vec_y, float& vec_z, bool inverse = false) = 0; - }; + virtual void rotate_vector(float quat_x, float quat_y, float quat_z, float quat_w, float& vec_x, float& vec_y, float& vec_z, bool inverse = false) = 0; +}; -} \ No newline at end of file +} //namespace T5Integration \ No newline at end of file diff --git a/extension/T5Integration/T5Service.cpp b/extension/T5Integration/T5Service.cpp index 9348f86..2cb8874 100644 --- a/extension/T5Integration/T5Service.cpp +++ b/extension/T5Integration/T5Service.cpp @@ -1,7 +1,7 @@ -#include -#include -#include #include +#include +#include +#include namespace T5Integration { @@ -21,11 +21,10 @@ T5Service::~T5Service() { } bool T5Service::start_service(const std::string_view application_id, std::string_view application_version, uint8_t sdk_type) { - if(_state.is_current(T5ServiceState::RUNNING)) + if (_state.is_current(T5ServiceState::RUNNING)) return true; - if(_state.set_and_was_toggled(T5ServiceState::STARTING)) - { - if(_graphics_api == T5_GraphicsApi::kT5_GraphicsApi_None) { + if (_state.set_and_was_toggled(T5ServiceState::STARTING)) { + if (_graphics_api == T5_GraphicsApi::kT5_GraphicsApi_None) { LOG_ERROR("TiltFive graphics api is not set"); return false; } @@ -34,10 +33,10 @@ bool T5Service::start_service(const std::string_view application_id, std::string clientInfo.applicationId = application_id.data(); clientInfo.applicationVersion = application_version.data(); clientInfo.sdkType = sdk_type; - + auto result = t5CreateContext(&_context, &clientInfo, nullptr); - if(result != T5_SUCCESS) { + if (result != T5_SUCCESS) { LOG_T5_ERROR(result); return false; } @@ -51,19 +50,17 @@ bool T5Service::start_service(const std::string_view application_id, std::string } void T5Service::stop_service() { - if( _state.clear_and_was_toggled(T5ServiceState::RUNNING) || - _state.clear_and_was_toggled(T5ServiceState::STARTING)) - { + if (_state.clear_and_was_toggled(T5ServiceState::RUNNING) || + _state.clear_and_was_toggled(T5ServiceState::STARTING)) { _scheduler->stop(); - for(int i = 0; i < _glasses_list.size(); i++) { + for (int i = 0; i < _glasses_list.size(); i++) { _glasses_list[i]->stop_display(); _glasses_list[i]->disconnect(); _glasses_list[i]->destroy_handle(); } _glasses_list.clear(); - if(_context) - { + if (_context) { std::lock_guard lock(g_t5_exclusivity_group_1); t5DestroyContext(&_context); } @@ -72,31 +69,28 @@ void T5Service::stop_service() { } std::optional T5Service::find_glasses_idx(const std::string_view glasses_id) { - for(int i = 0; i < _glasses_list.size(); ++i) { - if(_glasses_list[i]->get_id() == glasses_id) + for (int i = 0; i < _glasses_list.size(); ++i) { + if (_glasses_list[i]->get_id() == glasses_id) return i; } return {}; } - CotaskPtr T5Service::startup_checks() { bool service_okay = false; co_await query_t5_service_version(); - if(_t5_service_version == "no service" || _t5_service_version == "unknown") { + if (_t5_service_version == "no service" || _t5_service_version == "unknown") { _state.set(T5ServiceState::T5_UNAVAILABLE); - } - else if(_t5_service_version == "service incompatible") { + } else if (_t5_service_version == "service incompatible") { _state.set(T5ServiceState::T5_INCOMPATIBLE_VERSION); - } - else { + } else { int major; int minor; int revision; - if(sscanf(_t5_service_version.c_str(), "%d.%d.%d", &major, &minor, &revision) == 3) { - if(major >= t5_version_major && minor >= t5_version_minor && revision >= t5_version_revision) { + if (sscanf(_t5_service_version.c_str(), "%d.%d.%d", &major, &minor, &revision) == 3) { + if (major >= t5_version_major && minor >= t5_version_minor && revision >= t5_version_revision) { service_okay = true; } else { _state.set(T5ServiceState::T5_INCOMPATIBLE_VERSION); @@ -108,16 +102,14 @@ CotaskPtr T5Service::startup_checks() { } } co_await run_in_foreground; - - if(service_okay) { + + if (service_okay) { _state.clear(T5ServiceState::STARTING); _state.set(T5ServiceState::RUNNING); - _scheduler->add_task(query_glasses_list()); - } - else { + _scheduler->add_task(query_glasses_list()); + } else { stop_service(); } - } CotaskPtr T5Service::query_t5_service_version() { @@ -126,37 +118,33 @@ CotaskPtr T5Service::query_t5_service_version() { buffer.resize(buffer_size); T5_Result result = T5_ERROR_IO_FAILURE; - for(int tries = 0; tries < 10; ++tries) { + for (int tries = 0; tries < 10; ++tries) { size_t buffer_size = buffer.size(); { std::lock_guard lock(g_t5_exclusivity_group_1); result = t5GetSystemUtf8Param(_context, kT5_ParamSys_UTF8_Service_Version, buffer.data(), &buffer_size); } - if(result == T5_ERROR_OVERFLOW) { + if (result == T5_ERROR_OVERFLOW) { buffer.resize(buffer_size); continue; - } - else if(result == T5_TIMEOUT && - result != T5_ERROR_NO_SERVICE && + } else if (result == T5_TIMEOUT && + result != T5_ERROR_NO_SERVICE && result != T5_ERROR_IO_FAILURE) { break; } co_await task_sleep(_poll_rate_for_retry); } co_await run_in_foreground; - if(result == T5_SUCCESS) { + if (result == T5_SUCCESS) { buffer.resize(buffer_size); _t5_service_version = buffer.data(); - } - else if(result == T5_ERROR_NO_SERVICE) { + } else if (result == T5_ERROR_NO_SERVICE) { LOG_T5_ERROR(result); _t5_service_version = "no service"; - } - else if(result == T5_ERROR_SERVICE_INCOMPATIBLE) { + } else if (result == T5_ERROR_SERVICE_INCOMPATIBLE) { LOG_T5_ERROR(result); _t5_service_version = "service incompatible"; - } - else { + } else { LOG_T5_ERROR(result); _t5_service_version = "unknown"; } @@ -170,23 +158,21 @@ CotaskPtr T5Service::query_glasses_list() { T5_Result result; bool first_resize = true; - for(;;) { + for (;;) { size_t bufferSize = buffer.size(); { std::lock_guard lock(g_t5_exclusivity_group_1); result = t5ListGlasses(_context, buffer.data(), &bufferSize); } - if(result == T5_ERROR_NO_SERVICE || result == T5_ERROR_IO_FAILURE) { + if (result == T5_ERROR_NO_SERVICE || result == T5_ERROR_IO_FAILURE) { co_await task_sleep(_poll_rate_for_retry); continue; - } - else if(result == T5_ERROR_OVERFLOW && first_resize) { + } else if (result == T5_ERROR_OVERFLOW && first_resize) { buffer.resize(bufferSize); first_resize = false; continue; - } - else if(result != T5_SUCCESS) { + } else if (result != T5_SUCCESS) { co_await run_in_foreground; LOG_T5_ERROR(result); co_return; @@ -196,9 +182,9 @@ CotaskPtr T5Service::query_glasses_list() { std::string_view str_view(buffer.data(), buffer.size()); std::vector parsed_id_list; - while(!str_view.empty()) { + while (!str_view.empty()) { auto pos = str_view.find_first_of('\0'); - if(pos == 0 || pos == std::string_view::npos) + if (pos == 0 || pos == std::string_view::npos) break; parsed_id_list.emplace_back(str_view.substr(0, pos)); str_view.remove_prefix(pos + 1); @@ -206,15 +192,15 @@ CotaskPtr T5Service::query_glasses_list() { co_await run_in_foreground; - for(auto& id : parsed_id_list) { + for (auto& id : parsed_id_list) { auto found = std::find_if( - _glasses_list.cbegin(), - _glasses_list.cend(), - [id](auto& gls) {return gls->get_id() == id; }); + _glasses_list.cbegin(), + _glasses_list.cend(), + [id](auto& gls) { return gls->get_id() == id; }); - if(found == _glasses_list.cend()) { + if (found == _glasses_list.cend()) { auto new_glasses = create_glasses(id); - if(new_glasses->allocate_handle(_context)) + if (new_glasses->allocate_handle(_context)) _glasses_list.emplace_back(std::move(new_glasses)); } } @@ -232,14 +218,16 @@ bool T5Service::is_service_started() { } void T5Service::reserve_glasses(int glasses_num, const std::string_view display_name) { - if(glasses_num < 0 || glasses_num >= _glasses_list.size()) return; + if (glasses_num < 0 || glasses_num >= _glasses_list.size()) + return; - if(should_glasses_be_reserved(glasses_num)) + if (should_glasses_be_reserved(glasses_num)) _glasses_list[glasses_num]->connect(display_name); } void T5Service::release_glasses(int glasses_num) { - if(glasses_num < 0 || glasses_num >= _glasses_list.size()) return; + if (glasses_num < 0 || glasses_num >= _glasses_list.size()) + return; _glasses_list[glasses_num]->disconnect(); } @@ -248,7 +236,7 @@ void T5Service::update_connection() { _scheduler->schedule_tasks(); _scheduler->log_exceptions([](auto msg) { log_message("Scheduler exception: ", msg); }); - for(int i = 0; i < _glasses_list.size(); ++i) { + for (int i = 0; i < _glasses_list.size(); ++i) { _glasses_list[i]->update_connection(); } @@ -256,14 +244,14 @@ void T5Service::update_connection() { } void T5Service::update_tracking() { - if(!is_service_started()) + if (!is_service_started()) return; _scheduler->schedule_tasks(); _scheduler->log_exceptions([](auto msg) { log_message("Scheduler exception: ", msg); }); - for(auto& glasses : _glasses_list) { - if(glasses->is_connected()) + for (auto& glasses : _glasses_list) { + if (glasses->is_connected()) glasses->update_tracking(); } @@ -271,32 +259,31 @@ void T5Service::update_tracking() { } void T5Service::get_service_events(std::vector& out_events) { - if(_state.became_set(_previous_event_state, T5ServiceState::T5_UNAVAILABLE)) { + if (_state.became_set(_previous_event_state, T5ServiceState::T5_UNAVAILABLE)) { out_events.push_back(T5ServiceEvent(T5ServiceEvent::E_T5_UNAVAILABLE)); } - if(_state.became_set(_previous_event_state, T5ServiceState::T5_INCOMPATIBLE_VERSION)) { + if (_state.became_set(_previous_event_state, T5ServiceState::T5_INCOMPATIBLE_VERSION)) { out_events.push_back(T5ServiceEvent(T5ServiceEvent::E_T5_INCOMPATIBLE_VERSION)); } - if(_state.became_set(_previous_event_state, T5ServiceState::RUNNING)) { + if (_state.became_set(_previous_event_state, T5ServiceState::RUNNING)) { out_events.push_back(T5ServiceEvent(T5ServiceEvent::E_RUNNING)); - } - if(_state.became_clear(_previous_event_state, T5ServiceState::RUNNING)) { + } + if (_state.became_clear(_previous_event_state, T5ServiceState::RUNNING)) { out_events.push_back(T5ServiceEvent(T5ServiceEvent::E_STOPPED)); } _previous_event_state.sync_from(_state); } void T5Service::get_glasses_events(std::vector& out_events) { - for(int i = 0; i < _glasses_list.size(); ++i) { + for (int i = 0; i < _glasses_list.size(); ++i) { _glasses_list[i]->get_events(i, out_events); } } void T5Service::get_gameboard_size(T5_GameboardType gameboard_type, T5_GameboardSize& gameboard_size) { auto result = t5GetGameboardSize(_context, gameboard_type, &gameboard_size); - if(result != T5_SUCCESS) + if (result != T5_SUCCESS) LOG_T5_ERROR(result); } - -} // T5Integration +} //namespace T5Integration diff --git a/extension/T5Integration/T5Service.h b/extension/T5Integration/T5Service.h index db992ce..e570d88 100644 --- a/extension/T5Integration/T5Service.h +++ b/extension/T5Integration/T5Service.h @@ -1,16 +1,16 @@ #pragma once +#include +#include +#include +#include #include #include -#include -#include -#include -#include namespace T5Integration { using TaskSystem::CotaskPtr; -using TaskSystem::Scheduler; using TaskSystem::run_in_foreground; +using TaskSystem::Scheduler; using TaskSystem::task_sleep; extern std::mutex g_t5_exclusivity_group_1; @@ -21,7 +21,7 @@ const int t5_version_major = 1; const int t5_version_minor = 4; const int t5_version_revision = 0; - +// clang-format off namespace T5ServiceState { const uint16_t RUNNING = 0x0001; const uint16_t STARTING = 0x0002; @@ -30,30 +30,30 @@ namespace T5ServiceState { const uint16_t T5_INCOMPATIBLE_VERSION = 0x0010; const uint16_t ERROR = 0x1000; }; +// clang-format on using T5ServiceFlags = StateFlags; +// clang-format off struct T5ServiceEvent { - enum EType - { - E_NONE = 0, - E_STOPPED = 1, - E_RUNNING = 2, - E_T5_UNAVAILABLE = 3, - E_T5_INCOMPATIBLE_VERSION = 4 - }; - T5ServiceEvent(EType evt) - : event(evt) - {} - - EType event; -}; + enum EType + { + E_NONE = 0, + E_STOPPED = 1, + E_RUNNING = 2, + E_T5_UNAVAILABLE = 3, + E_T5_INCOMPATIBLE_VERSION = 4 + }; + // clang-format on + T5ServiceEvent(EType evt) : + event(evt) {} -class T5Service { + EType event; +}; +class T5Service { public: - using Ptr = std::shared_ptr; T5Service(); @@ -66,8 +66,8 @@ class T5Service { void reserve_glasses(int glasses_num, const std::string_view display_name); void release_glasses(int glasses_num); - void set_upside_down_texture(int glasses_num, bool is_upside_down); - + void set_upside_down_texture(int glasses_num, bool is_upside_down); + int get_glasses_count() { return _glasses_list.size(); } std::optional find_glasses_idx(const std::string_view glasses_id); @@ -86,7 +86,6 @@ class T5Service { void get_gameboard_size(T5_GameboardType gameboard_type, T5_GameboardSize& gameboard_size); protected: - CotaskPtr startup_checks(); CotaskPtr query_t5_service_version(); CotaskPtr query_glasses_list(); @@ -102,7 +101,6 @@ class T5Service { void set_graphics_context(const T5_GraphicsContextVulkan& vulkan_context); protected: - std::string _application_id; std::string _application_version; @@ -139,21 +137,20 @@ inline T5_GraphicsApi T5Service::get_graphics_api() const { } inline bool T5Service::is_image_texture_array() const { - if (_graphics_api == T5_GraphicsApi::kT5_GraphicsApi_GL && - _opengl_graphics_context.textureMode == T5_GraphicsApi_GL_TextureMode::kT5_GraphicsApi_GL_TextureMode_Array) + if (_graphics_api == T5_GraphicsApi::kT5_GraphicsApi_GL && + _opengl_graphics_context.textureMode == T5_GraphicsApi_GL_TextureMode::kT5_GraphicsApi_GL_TextureMode_Array) return true; return false; } inline void* T5Service::get_graphics_context_handle() { - switch (_graphics_api) - { - case T5_GraphicsApi::kT5_GraphicsApi_GL: - return &_opengl_graphics_context; - case T5_GraphicsApi::kT5_GraphicsApi_Vulkan: - return &_vulkan_graphics_context; - default: - break; + switch (_graphics_api) { + case T5_GraphicsApi::kT5_GraphicsApi_GL: + return &_opengl_graphics_context; + case T5_GraphicsApi::kT5_GraphicsApi_Vulkan: + return &_vulkan_graphics_context; + default: + break; }; return nullptr; } @@ -167,7 +164,8 @@ inline const std::string T5Service::get_glasses_name(int glasses_idx) const { } inline void T5Service::set_upside_down_texture(int glasses_idx, bool is_upside_down) { - if(glasses_idx < _glasses_list.size()) _glasses_list[glasses_idx]->set_upside_down_texture(is_upside_down); + if (glasses_idx < _glasses_list.size()) + _glasses_list[glasses_idx]->set_upside_down_texture(is_upside_down); } -} +} //namespace T5Integration diff --git a/extension/T5Integration/TaskSystem.cpp b/extension/T5Integration/TaskSystem.cpp index 07a6112..f8ee491 100644 --- a/extension/T5Integration/TaskSystem.cpp +++ b/extension/T5Integration/TaskSystem.cpp @@ -42,26 +42,25 @@ TaskStatus Task::get_status() { return _status; } - TaskStatus Cotask::run_background_task() { auto& promise = _handle.promise(); - while(true) { - if(promise._sub_task) { + while (true) { + if (promise._sub_task) { auto status = promise._sub_task->run_background_task(); - if(!status.is_done()) + if (!status.is_done()) return status; promise._sub_task.reset(); - if(status.is_error()) + if (status.is_error()) return status; - if(is_foreground()) { + if (is_foreground()) { return run_in_foreground; } } _handle.resume(); - if(!promise._sub_task) + if (!promise._sub_task) return promise._status; - if(promise._sub_task->is_foreground()) { + if (promise._sub_task->is_foreground()) { return run_in_foreground; } } @@ -69,29 +68,28 @@ TaskStatus Cotask::run_background_task() { TaskStatus Cotask::run_foreground_task() { auto& promise = _handle.promise(); - while(true) { - if(promise._sub_task) { + while (true) { + if (promise._sub_task) { auto status = promise._sub_task->run_foreground_task(); - if(!status.is_done()) + if (!status.is_done()) return status; promise._sub_task.reset(); - if(status.is_error()) + if (status.is_error()) return status; - if(is_background()) { + if (is_background()) { return run_now; } } _handle.resume(); - if(!promise._sub_task) + if (!promise._sub_task) return _handle.promise()._status; - if(promise._sub_task->is_background()) { + if (promise._sub_task->is_background()) { return task_sleep(0); } } } - Scheduler::Scheduler() {} Scheduler::~Scheduler() { @@ -105,33 +103,30 @@ void Scheduler::start() { } void Scheduler::stop() { - if(_is_running) { + if (_is_running) { _is_running = false; _background_release.notify_one(); - if(_background_thread.joinable()) + if (_background_thread.joinable()) _background_thread.join(); _background_run_list.clear(); _background_wait_list.clear(); _foreground_list.clear(); - } } void Scheduler::add_task(TaskBase::Ptr&& task) { - if(task->is_background()) { - if(task->get_scheduled_time() < Clock::now() + _average_time) { + if (task->is_background()) { + if (task->get_scheduled_time() < Clock::now() + _average_time) { { std::lock_guard lk(_background_run_mutex); _background_run_list.push_front(std::forward(task)); } _background_release.notify_one(); - } - else { + } else { std::lock_guard lk(_background_wait_mutex); _background_wait_list.push_front(std::forward(task)); } - } - else { + } else { std::lock_guard lk(_foreground_mutex); _foreground_list.push_front(std::forward(task)); } @@ -139,11 +134,10 @@ void Scheduler::add_task(TaskBase::Ptr&& task) { void Scheduler::schedule_tasks() { auto time_now = Clock::now(); - if(_is_initial_run) { + if (_is_initial_run) { _average_time = Duration(0); _is_initial_run = false; - } - else { + } else { auto delta = std::chrono::duration_cast(time_now - _last_run); _average_time = (delta + _run_count * _average_time) / (_run_count + 1); @@ -156,7 +150,7 @@ void Scheduler::schedule_tasks() { } void Scheduler::do_background_tasks() { - while(_is_running) { + while (_is_running) { // Swap all tasks to local stack std::list do_list; { @@ -165,12 +159,12 @@ void Scheduler::do_background_tasks() { std::swap(_background_run_list, do_list); } // run them - for(auto& task : do_list) { - if(!_is_running) break; + for (auto& task : do_list) { + if (!_is_running) + break; try { task->set_status(task->run_background_task()); - } - catch(...) { + } catch (...) { task->set_status(capture_exception()); } } @@ -189,8 +183,8 @@ void Scheduler::do_background_tasks() { _foreground_list.splice(_foreground_list.end(), to_foreground); } std::list to_exception; - for(auto& task : do_list) { - if(task->is_exception()) { + for (auto& task : do_list) { + if (task->is_exception()) { to_exception.push_back(task->get_status()._exception); } std::lock_guard lk(_exception_mutex); @@ -215,7 +209,7 @@ void Scheduler::queue_background_tasks() { splice_if(test_list, do_background, [time_now](const TaskBase::Ptr& task) { return task->get_scheduled_time() <= time_now; }); // If we have some then move them to the run list - if(!do_background.empty()) { + if (!do_background.empty()) { { std::lock_guard lk(_background_run_mutex); _background_run_list.splice(_background_run_list.end(), do_background); @@ -224,25 +218,24 @@ void Scheduler::queue_background_tasks() { } // Put the ones that are left back - if(!test_list.empty()) { + if (!test_list.empty()) { std::lock_guard lk(_background_wait_mutex); _background_wait_list.splice(_background_wait_list.end(), test_list); } } void Scheduler::do_foreground_tasks() { - // Swap all tasks to local + // Swap all tasks to local std::list do_list; { std::lock_guard lk(_foreground_mutex); std::swap(_foreground_list, do_list); } // run them - for(auto& task : do_list) { + for (auto& task : do_list) { try { task->set_status(task->run_foreground_task()); - } - catch(...) { + } catch (...) { task->set_status(capture_exception()); } } @@ -261,8 +254,8 @@ void Scheduler::do_foreground_tasks() { _foreground_list.splice(_foreground_list.end(), to_foreground); } std::list to_exception; - for(auto& task : do_list) { - if(task->is_exception()) { + for (auto& task : do_list) { + if (task->is_exception()) { to_exception.push_back(task->get_status()._exception); } std::lock_guard lk(_exception_mutex); @@ -282,8 +275,8 @@ void Scheduler::log_exceptions(ExceptionLogger func) { std::lock_guard lk(_exception_mutex); std::swap(except_list, _exception_list); } - for(auto exc_ptr : except_list) { + for (auto exc_ptr : except_list) { func(what(exc_ptr)); } } -} +} //namespace TaskSystem diff --git a/extension/T5Integration/TaskSystem.h b/extension/T5Integration/TaskSystem.h index 1dd0cce..a0da280 100644 --- a/extension/T5Integration/TaskSystem.h +++ b/extension/T5Integration/TaskSystem.h @@ -1,13 +1,13 @@ #pragma once #include -#include -#include #include -#include -#include #include #include +#include +#include +#include +#include namespace TaskSystem { @@ -43,7 +43,7 @@ inline TaskStatus task_sleep(Duration duration) { } inline TaskStatus task_sleep(int duration) { - return { Clock::now() + Duration{duration}, TaskStatus::BACKGROUND, nullptr }; + return { Clock::now() + Duration{ duration }, TaskStatus::BACKGROUND, nullptr }; } inline TaskStatus capture_exception() { @@ -56,7 +56,6 @@ inline TaskStatus return_exception(std::exception_ptr exception) { class Scheduler; class TaskBase { public: - friend Scheduler; using Ptr = std::unique_ptr; @@ -79,7 +78,6 @@ class TaskBase { class Task : public TaskBase { public: - Task(); ~Task() override = default; @@ -94,22 +92,20 @@ class Task : public TaskBase { TaskStatus get_status() override; private: - TaskStatus _status; }; -inline Task::Task() - : _status(run_now) {} - +inline Task::Task() : + _status(run_now) {} class CotaskPtr; struct CotaskPromiseType { CotaskPtr get_return_object(); - std::suspend_always initial_suspend() { return{}; } + std::suspend_always initial_suspend() { return {}; } void return_void(); void unhandled_exception(); - std::suspend_always final_suspend() noexcept { return{}; } + std::suspend_always final_suspend() noexcept { return {}; } std::suspend_always await_transform(const TaskStatus& status); std::suspend_always await_transform(Task::Ptr&& sub_task); @@ -120,16 +116,16 @@ struct CotaskPromiseType { class Cotask : public TaskBase { public: - std::coroutine_handle _handle = nullptr; - Cotask(std::coroutine_handle handle) - : _handle(handle) {} + Cotask(std::coroutine_handle handle) : + _handle(handle) {} Cotask() = default; Cotask(Cotask&& rhs) noexcept - : _handle(std::exchange(rhs._handle, nullptr)) {} + : + _handle(std::exchange(rhs._handle, nullptr)) {} Cotask& operator=(Cotask&& rhs) noexcept { _handle = std::exchange(rhs._handle, nullptr); @@ -137,7 +133,7 @@ class Cotask : public TaskBase { } ~Cotask() override { - if(_handle) { + if (_handle) { _handle.destroy(); } } @@ -158,7 +154,9 @@ class Cotask : public TaskBase { class CotaskPtr : public std::unique_ptr { friend CotaskPromiseType; - CotaskPtr(Cotask* task_ptr) : std::unique_ptr(task_ptr) {} + CotaskPtr(Cotask* task_ptr) : + std::unique_ptr(task_ptr) {} + public: using promise_type = CotaskPromiseType; }; @@ -187,66 +185,66 @@ inline std::suspend_always CotaskPromiseType::await_transform(Task::Ptr&& sub_ta inline TaskTime Cotask::get_scheduled_time() { auto& promise = _handle.promise(); - if(promise._sub_task) + if (promise._sub_task) return promise._sub_task->get_scheduled_time(); return promise._status._scheduled_time; } inline bool Cotask::is_foreground() { auto& promise = _handle.promise(); - if(promise._sub_task) + if (promise._sub_task) return promise._sub_task->is_foreground(); return promise._status.is_foreground(); } inline bool Cotask::is_background() { auto& promise = _handle.promise(); - if(promise._sub_task) + if (promise._sub_task) return promise._sub_task->is_background(); return promise._status.is_background(); } inline bool Cotask::is_done() { auto& promise = _handle.promise(); - if(promise._sub_task) + if (promise._sub_task) return promise._sub_task->is_done(); return promise._status.is_done(); } inline bool Cotask::is_error() { auto& promise = _handle.promise(); - if(promise._sub_task) + if (promise._sub_task) return promise._sub_task->is_error(); return promise._status.is_error(); } inline bool Cotask::is_exception() { auto& promise = _handle.promise(); - if(promise._sub_task) + if (promise._sub_task) return promise._sub_task->is_exception(); return promise._status.is_exception(); } inline void Cotask::set_status(const TaskStatus& status) { auto& promise = _handle.promise(); - if(promise._sub_task) + if (promise._sub_task) promise._sub_task->set_status(status); promise._status = status; } inline TaskStatus Cotask::get_status() { auto& promise = _handle.promise(); - if(promise._sub_task) + if (promise._sub_task) return promise._sub_task->get_status(); return promise._status; } -template +template void splice_if(std::list& from_list, std::list& to_list, F pred) { auto it = from_list.begin(); - while(it != from_list.end()) { + while (it != from_list.end()) { auto cur = it++; - if(pred(*cur)) { + if (pred(*cur)) { to_list.splice(to_list.begin(), from_list, cur); } } @@ -255,17 +253,28 @@ void splice_if(std::list& from_list, std::list& to_list, F pred) { std::string what(const std::exception_ptr& eptr); template inline std::string nested_what(const T& e) { - try { std::rethrow_if_nested(e); } - catch(...) { return " (" + what(std::current_exception()) + ")"; } + try { + std::rethrow_if_nested(e); + } catch (...) { + return " (" + what(std::current_exception()) + ")"; + } return {}; } inline std::string what(const std::exception_ptr& eptr) { - if(!eptr) { throw std::bad_exception(); } - try { std::rethrow_exception(eptr); } - catch(const std::exception& e) { return e.what() + nested_what(e); } - catch(const std::string& e) { return e; } - catch(const char* e) { return e; } - catch(...) { return "unknown exception type"; } + if (!eptr) { + throw std::bad_exception(); + } + try { + std::rethrow_exception(eptr); + } catch (const std::exception& e) { + return e.what() + nested_what(e); + } catch (const std::string& e) { + return e; + } catch (const char* e) { + return e; + } catch (...) { + return "unknown exception type"; + } } class Scheduler { @@ -286,7 +295,6 @@ class Scheduler { void log_exceptions(ExceptionLogger func); private: - void do_background_tasks(); void queue_background_tasks(); void do_foreground_tasks(); @@ -312,5 +320,4 @@ class Scheduler { std::list _foreground_list; std::list _exception_list; }; -} // namespace TaskSystem - +} // namespace TaskSystem diff --git a/extension/T5Integration/Wand.cpp b/extension/T5Integration/Wand.cpp index e84c28e..343c1aa 100644 --- a/extension/T5Integration/Wand.cpp +++ b/extension/T5Integration/Wand.cpp @@ -1,5 +1,5 @@ -#include #include +#include #include namespace T5Integration { @@ -7,10 +7,9 @@ namespace T5Integration { extern std::mutex g_t5_exclusivity_group_1; void Wand::update_from_stream_event(T5_WandStreamEvent& event) { - switch(event.type) { - case kT5_WandStreamEventType_Connect: - { - if(_handle == 0) + switch (event.type) { + case kT5_WandStreamEventType_Connect: { + if (_handle == 0) _handle = event.wandId; _state = WandState::SYNCED | WandState::CONNECTED; _buttons = WandButtons{}; @@ -18,14 +17,12 @@ void Wand::update_from_stream_event(T5_WandStreamEvent& event) { _pose = WandPose{}; _battery = 0; } break; - case kT5_WandStreamEventType_Disconnect: - { + case kT5_WandStreamEventType_Disconnect: { _state = WandState::SYNCED; } break; - case kT5_WandStreamEventType_Report: - { + case kT5_WandStreamEventType_Report: { _state = WandState::SYNCED | WandState::CONNECTED; - if(event.report.buttonsValid) { + if (event.report.buttonsValid) { _state |= WandState::BUTTONS_VALID; _buttons.t5 = event.report.buttons.t5; _buttons.one = event.report.buttons.one; @@ -35,51 +32,45 @@ void Wand::update_from_stream_event(T5_WandStreamEvent& event) { _buttons.b = event.report.buttons.b; _buttons.x = event.report.buttons.x; _buttons.y = event.report.buttons.y; - } - else + } else _state &= ~WandState::BUTTONS_VALID; - if(event.report.analogValid) { + if (event.report.analogValid) { _state |= WandState::ANALOG_VALID; _analog.trigger = event.report.trigger; _analog.stick = event.report.stick; - } - else + } else _state &= ~WandState::ANALOG_VALID; - if(event.report.poseValid) { + if (event.report.poseValid) { _state |= WandState::POSE_VALID; _pose.rotToWND_GBD = event.report.rotToWND_GBD; _pose.posAim_GBD = event.report.posAim_GBD; _pose.posFingertips_GBD = event.report.posFingertips_GBD; _pose.posGrip_GBD = event.report.posGrip_GBD; - } - else + } else _state &= ~WandState::POSE_VALID; - if(event.report.batteryValid) { + if (event.report.batteryValid) { _state |= WandState::BATTERY_VALID; _battery = event.report.battery; - } - else + } else _state &= ~WandState::BATTERY_VALID; } break; - } } void Wand::update_from_wand(const Wand& other_wand) { _state = other_wand._state; - if(_state & WandState::BUTTONS_VALID) + if (_state & WandState::BUTTONS_VALID) _buttons = other_wand._buttons; - if(_state & WandState::ANALOG_VALID) + if (_state & WandState::ANALOG_VALID) _analog = other_wand._analog; - if(_state & WandState::POSE_VALID) + if (_state & WandState::POSE_VALID) _pose = other_wand._pose; - if(_state & WandState::BATTERY_VALID) + if (_state & WandState::BATTERY_VALID) _battery = other_wand._battery; } - bool WandService::start(T5_Glasses handle) { _glasses_handle = handle; _last_wand_error = T5_SUCCESS; @@ -90,7 +81,7 @@ bool WandService::start(T5_Glasses handle) { void WandService::stop() { _thread.get_stop_source().request_stop(); - if(_thread.joinable()) + if (_thread.joinable()) _thread.join(); } bool WandService::is_running() { @@ -102,25 +93,23 @@ void WandService::get_wand_data(WandList& list) { list = _wand_list; } - bool WandService::configure_wand_tracking(bool enable) { - T5_Result result = T5_SUCCESS; - for(int tries = 0; tries < 10; ++tries) { + for (int tries = 0; tries < 10; ++tries) { T5_WandStreamConfig config{ enable }; T5_Result result; { std::lock_guard lock(g_t5_exclusivity_group_1); result = t5ConfigureWandStreamForGlasses(_glasses_handle, &config); } - if(result != T5_ERROR_NO_SERVICE && result != T5_ERROR_IO_FAILURE) { + if (result != T5_ERROR_NO_SERVICE && result != T5_ERROR_IO_FAILURE) { break; } std::this_thread::sleep_for(_poll_rate_for_retry); } - if(result != T5_SUCCESS) { + if (result != T5_SUCCESS) { _last_wand_error = result; return false; } @@ -133,31 +122,29 @@ T5_Result WandService::get_last_error() { return tmp; } - void WandService::monitor_wands(std::stop_token s_token) { - if(!configure_wand_tracking(true)) + if (!configure_wand_tracking(true)) return; - while(!s_token.stop_requested()) { + while (!s_token.stop_requested()) { T5_WandStreamEvent event; // g_t5_exclusivity_group_2 but can't conflict with anything currently auto result = t5ReadWandStreamForGlasses(_glasses_handle, &event, _wait_time_for_wand_IO); - if(result == T5_TIMEOUT) + if (result == T5_TIMEOUT) continue; - else if(result != T5_SUCCESS) { + else if (result != T5_SUCCESS) { _last_wand_error = result; std::this_thread::sleep_for(std::chrono::milliseconds(20)); } - if(event.type != kT5_WandStreamEventType_Desync) { + if (event.type != kT5_WandStreamEventType_Desync) { std::lock_guard lock(_list_access); auto wand_ptr = find_wand(_wand_list, event.wandId); auto wand = wand_ptr ? wand_ptr : &_wand_list.emplace_back(); wand->update_from_stream_event(event); - } - else { + } else { std::lock_guard lock(_list_access); - for(auto& wand : _wand_list) { + for (auto& wand : _wand_list) { wand._state = 0; } } @@ -166,4 +153,4 @@ void WandService::monitor_wands(std::stop_token s_token) { configure_wand_tracking(false); _running = false; } -} // T5Integration +} //namespace T5Integration diff --git a/extension/T5Integration/Wand.h b/extension/T5Integration/Wand.h index e872f39..dc59afd 100644 --- a/extension/T5Integration/Wand.h +++ b/extension/T5Integration/Wand.h @@ -1,9 +1,8 @@ #pragma once -#include +#include #include +#include #include -#include - using namespace std::chrono_literals; @@ -16,17 +15,17 @@ const uint8_t BUTTONS_VALID = 0x04; const uint8_t ANALOG_VALID = 0x08; const uint8_t POSE_VALID = 0x10; const uint8_t BATTERY_VALID = 0x20; -}; +}; //namespace WandState struct WandButtons { - bool t5:1; - bool one:1; - bool two:1; - bool three:1; - bool a:1; - bool b:1; - bool x:1; - bool y:1; + bool t5 : 1; + bool one : 1; + bool two : 1; + bool three : 1; + bool a : 1; + bool b : 1; + bool x : 1; + bool y : 1; }; struct WandAnalog { @@ -84,13 +83,13 @@ class WandService { inline Wand* find_wand(WandList& list, T5_WandHandle handle) { auto it = std::find_if(list.begin(), list.end(), - [handle](auto& test_wand) { - return test_wand._handle == handle; - }); + [handle](auto& test_wand) { + return test_wand._handle == handle; + }); - if(it != list.end()) + if (it != list.end()) return std::addressof(*it); return nullptr; } -} // T5Integration \ No newline at end of file +} //namespace T5Integration \ No newline at end of file diff --git a/extension/src/GodotT5Glasses.cpp b/extension/src/GodotT5Glasses.cpp index 339258b..150fcf4 100644 --- a/extension/src/GodotT5Glasses.cpp +++ b/extension/src/GodotT5Glasses.cpp @@ -1,15 +1,15 @@ #include -#include +#include +#include #include #include -#include -#include -#include +#include +#include -using godot::Vector3; -using godot::Quaternion; using godot::Projection; +using godot::Quaternion; using godot::Variant; +using godot::Vector3; using godot::XRServer; using T5Integration::WandButtons; @@ -18,12 +18,11 @@ namespace WandState = T5Integration::WandState; namespace GodotT5Integration { -GodotT5Glasses::GodotT5Glasses(std::string_view id) -: Glasses(id) { +GodotT5Glasses::GodotT5Glasses(std::string_view id) : + Glasses(id) { set_swap_chain_size(g_swap_chain_length); } - Transform3D GodotT5Glasses::get_head_transform(Vector3 eye_offset) { Quaternion orientation; Vector3 position; @@ -72,7 +71,7 @@ Transform3D GodotT5Glasses::get_wand_transform(int wand_num) { Transform3D wandPose; wandPose.set_origin(position); - wandPose.set_basis(orientation * Quaternion(Vector3(1,0,0), Math_PI / 2.0f)); + wandPose.set_basis(orientation * Quaternion(Vector3(1, 0, 0), Math_PI / 2.0f)); return wandPose; } @@ -90,25 +89,25 @@ PackedFloat64Array GodotT5Glasses::get_projection_for_eye(Glasses::Eye view, dou arr[i] = m[i]; } - return arr; + return arr; } void GodotT5Glasses::on_glasses_reserved() { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL(xr_server); - char buffer[64]; - ERR_FAIL_COND(snprintf(buffer, 64, "/user/%s/head", get_id().c_str()) > 64); + char buffer[64]; + ERR_FAIL_COND(snprintf(buffer, 64, "/user/%s/head", get_id().c_str()) > 64); _head.instantiate(); _head->set_tracker_type(XRServer::TRACKER_HEAD); _head->set_tracker_name(buffer); _head->set_tracker_desc("Players head"); - xr_server->add_tracker(_head); + xr_server->add_tracker(_head); } void GodotT5Glasses::on_glasses_released() { - if(_head.is_valid()) { + if (_head.is_valid()) { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL(xr_server); @@ -117,7 +116,7 @@ void GodotT5Glasses::on_glasses_released() { } void GodotT5Glasses::on_glasses_dropped() { - if(_head.is_valid()) { + if (_head.is_valid()) { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL(xr_server); @@ -126,25 +125,25 @@ void GodotT5Glasses::on_glasses_dropped() { } void GodotT5Glasses::on_tracking_updated() { - if(_head.is_valid()) { + if (_head.is_valid()) { if (is_tracking()) { _head->set_pose( - "default", - get_head_transform(), - Vector3(), - Vector3(), - godot::XRPose::XR_TRACKING_CONFIDENCE_HIGH); + "default", + get_head_transform(), + Vector3(), + Vector3(), + godot::XRPose::XR_TRACKING_CONFIDENCE_HIGH); } else { _head->invalidate_pose("default"); } } auto num_wands = get_num_wands(); - for(int wand_idx = 0; wand_idx < num_wands; ++wand_idx) { - if(wand_idx == _wand_trackers.size()) + for (int wand_idx = 0; wand_idx < num_wands; ++wand_idx) { + if (wand_idx == _wand_trackers.size()) add_tracker(); update_wand(wand_idx); - } + } } bool GodotT5Glasses::is_in_use() { @@ -167,37 +166,36 @@ void GodotT5Glasses::add_tracker() { Ref positional_tracker; positional_tracker.instantiate(); - char buffer[64]; - ERR_FAIL_COND(snprintf(buffer, 64, "/user/%s/wand_%d", get_id().c_str(), new_id) > 64); - - positional_tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER); - positional_tracker->set_tracker_name(buffer); - positional_tracker->set_tracker_desc("Tracks wand"); + char buffer[64]; + ERR_FAIL_COND(snprintf(buffer, 64, "/user/%s/wand_%d", get_id().c_str(), new_id) > 64); - _wand_trackers.push_back(positional_tracker); + positional_tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER); + positional_tracker->set_tracker_name(buffer); + positional_tracker->set_tracker_desc("Tracks wand"); + + _wand_trackers.push_back(positional_tracker); } void GodotT5Glasses::update_wand(int wand_idx) { - auto xr_server = XRServer::get_singleton(); auto tracker = _wand_trackers[wand_idx]; - if(is_wand_state_changed(wand_idx, WandState::CONNECTED)) { - if(is_wand_state_set(wand_idx, WandState::CONNECTED)) { + if (is_wand_state_changed(wand_idx, WandState::CONNECTED)) { + if (is_wand_state_set(wand_idx, WandState::CONNECTED)) { xr_server->add_tracker(tracker); - } else { + } else { xr_server->remove_tracker(tracker); return; } } - if(is_wand_state_set(wand_idx, WandState::POSE_VALID)) { + if (is_wand_state_set(wand_idx, WandState::POSE_VALID)) { auto wand_transform = get_wand_transform(wand_idx); tracker->set_pose("default", wand_transform, Vector3(), Vector3(), godot::XRPose::XR_TRACKING_CONFIDENCE_HIGH); - } else { + } else { tracker->invalidate_pose("default"); } - if(is_wand_state_set(wand_idx, WandState::ANALOG_VALID)) { + if (is_wand_state_set(wand_idx, WandState::ANALOG_VALID)) { float trigger_value; get_wand_trigger(wand_idx, trigger_value); tracker->set_input("trigger", Variant(trigger_value)); @@ -205,14 +203,13 @@ void GodotT5Glasses::update_wand(int wand_idx) { get_wand_stick(wand_idx, stick.x, stick.y); tracker->set_input("stick", Variant(stick)); - if(trigger_value > _trigger_click_threshold + g_trigger_hysteresis_range) { + if (trigger_value > _trigger_click_threshold + g_trigger_hysteresis_range) { tracker->set_input("trigger_click", Variant(true)); - } - else if(trigger_value < (_trigger_click_threshold - g_trigger_hysteresis_range)) { + } else if (trigger_value < (_trigger_click_threshold - g_trigger_hysteresis_range)) { tracker->set_input("trigger_click", Variant(false)); } } - if(is_wand_state_set(wand_idx, WandState::BUTTONS_VALID)) { + if (is_wand_state_set(wand_idx, WandState::BUTTONS_VALID)) { WandButtons buttons; get_wand_buttons(wand_idx, buttons); @@ -223,21 +220,20 @@ void GodotT5Glasses::update_wand(int wand_idx) { tracker->set_input("button_1", Variant(buttons.one)); tracker->set_input("button_2", Variant(buttons.two)); tracker->set_input("button_3", Variant(buttons.three)); - tracker->set_input("button_t5", Variant(buttons.t5)); + tracker->set_input("button_t5", Variant(buttons.t5)); } } -bool GodotT5Glasses::get_tracker_association(StringName tracker_name, int& out_wand_idx) { - for(out_wand_idx = 0; out_wand_idx < _wand_trackers.size(); ++out_wand_idx) { - auto b1 = tracker_name.to_utf8_buffer(); - auto b2 = _wand_trackers[out_wand_idx]->get_tracker_name().to_utf8_buffer(); +bool GodotT5Glasses::get_tracker_association(StringName tracker_name, int &out_wand_idx) { + for (out_wand_idx = 0; out_wand_idx < _wand_trackers.size(); ++out_wand_idx) { + auto b1 = tracker_name.to_utf8_buffer(); + auto b2 = _wand_trackers[out_wand_idx]->get_tracker_name().to_utf8_buffer(); - if(tracker_name == _wand_trackers[out_wand_idx]->get_tracker_name()) - return true; - } - out_wand_idx = -1; - return false; + if (tracker_name == _wand_trackers[out_wand_idx]->get_tracker_name()) + return true; + } + out_wand_idx = -1; + return false; } - -} // GodotT5Integration \ No newline at end of file +} //namespace GodotT5Integration \ No newline at end of file diff --git a/extension/src/GodotT5Glasses.h b/extension/src/GodotT5Glasses.h index 12ff30d..5c31b83 100644 --- a/extension/src/GodotT5Glasses.h +++ b/extension/src/GodotT5Glasses.h @@ -1,92 +1,87 @@ #pragma once #include -#include -#include -#include -#include -#include +#include #include +#include +#include +#include +#include -using godot::RID; +using godot::PackedFloat64Array; using godot::Ref; -using godot::XRPositionalTracker; +using godot::RID; +using godot::StringName; +using godot::Transform3D; using godot::Vector2; using godot::Vector3; -using godot::Transform3D; -using godot::StringName; -using godot::PackedFloat64Array; +using godot::XRPositionalTracker; using T5Integration::Glasses; namespace GodotT5Integration { - constexpr int g_swap_chain_length = 3; - constexpr float g_trigger_hysteresis_range = 0.002; // Sort of arbitrary assume 8 bit DAC +/-(1/256)/2 - - class GodotT5Service; +constexpr int g_swap_chain_length = 3; +constexpr float g_trigger_hysteresis_range = 0.002; // Sort of arbitrary assume 8 bit DAC +/-(1/256)/2 - class GodotT5Glasses : public Glasses { - friend GodotT5Service; +class GodotT5Service; - public: - using Ptr = std::shared_ptr; +class GodotT5Glasses : public Glasses { + friend GodotT5Service; - GodotT5Glasses(std::string_view id); - virtual ~GodotT5Glasses() { } +public: + using Ptr = std::shared_ptr; - bool is_in_use(); - bool is_reserved(); + GodotT5Glasses(std::string_view id); + virtual ~GodotT5Glasses() {} - Vector2 get_render_size(); - virtual Transform3D get_head_transform(Vector3 eye_offset = Vector3()); - virtual Vector3 get_eye_offset(Glasses::Eye eye); - virtual Transform3D get_eye_transform(Glasses::Eye eye); - virtual PackedFloat64Array get_projection_for_eye(Glasses::Eye view, double aspect, double z_near, double z_far); + bool is_in_use(); + bool is_reserved(); - virtual Transform3D get_wand_transform(int wand_num); - - virtual RID get_color_texture() = 0; + Vector2 get_render_size(); + virtual Transform3D get_head_transform(Vector3 eye_offset = Vector3()); + virtual Vector3 get_eye_offset(Glasses::Eye eye); + virtual Transform3D get_eye_transform(Glasses::Eye eye); + virtual PackedFloat64Array get_projection_for_eye(Glasses::Eye view, double aspect, double z_near, double z_far); - StringName get_wand_tracker_name(int wand_idx); + virtual Transform3D get_wand_transform(int wand_num); - bool get_tracker_association(StringName tracker_name, int& out_wand_idx); + virtual RID get_color_texture() = 0; + StringName get_wand_tracker_name(int wand_idx); - void set_trigger_click_threshold(float threshold); + bool get_tracker_association(StringName tracker_name, int& out_wand_idx); - protected: - virtual void on_glasses_reserved() override; - virtual void on_glasses_released() override; - virtual void on_glasses_dropped() override; + void set_trigger_click_threshold(float threshold); - virtual void on_tracking_updated() override; +protected: + virtual void on_glasses_reserved() override; + virtual void on_glasses_released() override; + virtual void on_glasses_dropped() override; - private: + virtual void on_tracking_updated() override; - void add_tracker() ; - void update_wand(int wand_idx); +private: + void add_tracker(); + void update_wand(int wand_idx); - Ref _head; - std::vector> _wand_trackers; + Ref _head; + std::vector> _wand_trackers; - float _trigger_click_threshold; - }; + float _trigger_click_threshold; +}; - inline bool GodotT5Glasses::is_reserved() { - return is_connected(); - } - - inline StringName GodotT5Glasses::get_wand_tracker_name(int wand_idx) { - ERR_FAIL_INDEX_V(wand_idx, get_num_wands(), StringName()); - - return _wand_trackers[wand_idx]->get_tracker_name(); - } +inline bool GodotT5Glasses::is_reserved() { + return is_connected(); +} - inline void GodotT5Glasses::set_trigger_click_threshold(float threshold) { - _trigger_click_threshold = threshold; - } +inline StringName GodotT5Glasses::get_wand_tracker_name(int wand_idx) { + ERR_FAIL_INDEX_V(wand_idx, get_num_wands(), StringName()); + return _wand_trackers[wand_idx]->get_tracker_name(); } +inline void GodotT5Glasses::set_trigger_click_threshold(float threshold) { + _trigger_click_threshold = threshold; +} - +} //namespace GodotT5Integration diff --git a/extension/src/GodotT5Service.cpp b/extension/src/GodotT5Service.cpp index ac7a011..5857d9c 100644 --- a/extension/src/GodotT5Service.cpp +++ b/extension/src/GodotT5Service.cpp @@ -1,32 +1,30 @@ #include +#include #include #include #include -#include -#include -#include -#include -#include -#include #include +#include +#include #include +#include +#include #include -#include +#include -using godot::Variant; -using godot::Quaternion; +using godot::Error; using godot::Image; -using godot::RenderingServer; +using godot::Quaternion; using godot::RenderingDevice; +using godot::RenderingServer; using godot::TypedArray; -using godot::Error; -using godot::XRServer; using godot::UtilityFunctions; +using godot::Variant; +using godot::XRServer; using TextureLayeredType = godot::RenderingServer::TextureLayeredType; using T5Integration::Glasses; -using T5Integration::WandButtons; using T5Integration::log_message; - +using T5Integration::WandButtons; namespace WandState = T5Integration::WandState; @@ -34,63 +32,61 @@ namespace GodotT5Integration { GodotT5ObjectRegistry g_godot_t5_services; -GodotT5Service::GodotT5Service() - : T5Service() -{ } +GodotT5Service::GodotT5Service() : + T5Service() {} std::unique_ptr GodotT5Service::create_glasses(const std::string_view id) { - if(get_graphics_api() == kT5_GraphicsApi_GL) - return std::unique_ptr(new OpenGLGlasses(id)); - else if(get_graphics_api() == kT5_GraphicsApi_Vulkan) - return std::unique_ptr(new VulkanGlasses(id)); - - ERR_FAIL_V_MSG(std::unique_ptr(), "Unknown graphics API"); + if (get_graphics_api() == kT5_GraphicsApi_GL) + return std::unique_ptr(new OpenGLGlasses(id)); + else if (get_graphics_api() == kT5_GraphicsApi_Vulkan) + return std::unique_ptr(new VulkanGlasses(id)); + + ERR_FAIL_V_MSG(std::unique_ptr(), "Unknown graphics API"); } void GodotT5Service::use_opengl_api() { - T5_GraphicsContextGL graphics_context; - graphics_context.textureMode = T5_GraphicsApi_GL_TextureMode::kT5_GraphicsApi_GL_TextureMode_Array; - graphics_context.leftEyeArrayIndex = 0; - graphics_context.rightEyeArrayIndex = 1; - set_graphics_context(graphics_context); + T5_GraphicsContextGL graphics_context; + graphics_context.textureMode = T5_GraphicsApi_GL_TextureMode::kT5_GraphicsApi_GL_TextureMode_Array; + graphics_context.leftEyeArrayIndex = 0; + graphics_context.rightEyeArrayIndex = 1; + set_graphics_context(graphics_context); } void GodotT5Service::use_vulkan_api() { - RenderingServer *rendering_server = RenderingServer::get_singleton(); - ERR_FAIL_NULL(rendering_server); - RenderingDevice *rendering_device = rendering_server->get_rendering_device(); - ERR_FAIL_NULL(rendering_device); - - T5_GraphicsContextVulkan graphics_context; - graphics_context.instance = (void*)rendering_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_INSTANCE, RID(), 0); - graphics_context.physicalDevice = (void*)rendering_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_PHYSICAL_DEVICE, RID(), 0); - graphics_context.device = (void*)rendering_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_DEVICE, RID(), 0); - graphics_context.queue = (void*)rendering_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_QUEUE, RID(), 0); - graphics_context.queueFamilyIndex = (uint32_t)rendering_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_QUEUE_FAMILY_INDEX, RID(), 0); - graphics_context.textureMode = kT5_GraphicsApi_Vulkan_TextureMode_ImageView; - set_graphics_context(graphics_context); + RenderingServer* rendering_server = RenderingServer::get_singleton(); + ERR_FAIL_NULL(rendering_server); + RenderingDevice* rendering_device = rendering_server->get_rendering_device(); + ERR_FAIL_NULL(rendering_device); + + T5_GraphicsContextVulkan graphics_context; + graphics_context.instance = (void*)rendering_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_INSTANCE, RID(), 0); + graphics_context.physicalDevice = (void*)rendering_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_PHYSICAL_DEVICE, RID(), 0); + graphics_context.device = (void*)rendering_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_DEVICE, RID(), 0); + graphics_context.queue = (void*)rendering_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_QUEUE, RID(), 0); + graphics_context.queueFamilyIndex = (uint32_t)rendering_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_QUEUE_FAMILY_INDEX, RID(), 0); + graphics_context.textureMode = kT5_GraphicsApi_Vulkan_TextureMode_ImageView; + set_graphics_context(graphics_context); } bool GodotT5Service::get_tracker_association(StringName tracker_name, int& out_glasses_idx, int& out_wand_idx) { - for(out_glasses_idx = 0; out_glasses_idx < _glasses_list.size(); ++out_glasses_idx) { - auto godot_glasses = std::static_pointer_cast(_glasses_list[out_glasses_idx]); - if(godot_glasses->get_tracker_association(tracker_name, out_wand_idx)) { - return true; - } - } - out_glasses_idx = -1; - out_wand_idx = -1; - return false; + for (out_glasses_idx = 0; out_glasses_idx < _glasses_list.size(); ++out_glasses_idx) { + auto godot_glasses = std::static_pointer_cast(_glasses_list[out_glasses_idx]); + if (godot_glasses->get_tracker_association(tracker_name, out_wand_idx)) { + return true; + } + } + out_glasses_idx = -1; + out_wand_idx = -1; + return false; } -void GodotT5Math::rotate_vector(float quat_x, float quat_y, float quat_z, float quat_w, float& vec_x, float& vec_y, float& vec_z, bool inverse) { - - godot::Quaternion orient(quat_x, quat_y, quat_z, quat_w); - godot::Vector3 vec(vec_x, vec_y, vec_z); +void GodotT5Math::rotate_vector(float quat_x, float quat_y, float quat_z, float quat_w, float& vec_x, float& vec_y, float& vec_z, bool inverse) { + godot::Quaternion orient(quat_x, quat_y, quat_z, quat_w); + godot::Vector3 vec(vec_x, vec_y, vec_z); - if (inverse) { - orient = orient.inverse(); - } + if (inverse) { + orient = orient.inverse(); + } vec = orient.xform(vec); @@ -99,58 +95,55 @@ void GodotT5Math::rotate_vector(float quat_x, float quat_y, float quat_z, float vec_z = vec.z; } -void GodotT5Logger::log_error(const char* message, const char* func_name, const char* file_name, int line_num) { - godot::_err_print_error(func_name, file_name, line_num, "TiltFiveXRInterface", message, true, false); +void GodotT5Logger::log_error(const char* message, const char* func_name, const char* file_name, int line_num) { + godot::_err_print_error(func_name, file_name, line_num, "TiltFiveXRInterface", message, true, false); } void GodotT5Logger::log_warning(const char* message, const char* func_name, const char* file_name, int line_num) { - godot::_err_print_error(func_name, file_name, line_num, "TiltFiveXRInterface", message, true, false); + godot::_err_print_error(func_name, file_name, line_num, "TiltFiveXRInterface", message, true, false); } void GodotT5Logger::log_string(const char* message) { - Variant v_msg = message; - UtilityFunctions::print_verbose(v_msg); + Variant v_msg = message; + UtilityFunctions::print_verbose(v_msg); } GodotT5Service::Ptr GodotT5ObjectRegistry::service() { assert(_instance); - return std::static_pointer_cast(ObjectRegistry::service()); + return std::static_pointer_cast(ObjectRegistry::service()); } T5Integration::T5Service::Ptr GodotT5ObjectRegistry::get_service() { - GodotT5Service::Ptr service; + GodotT5Service::Ptr service; if (_service.expired()) { service = std::make_shared(); - _service = service; - } - else { - service = _service.lock(); - } - return service; + _service = service; + } else { + service = _service.lock(); + } + return service; } T5Integration::T5Math::Ptr GodotT5ObjectRegistry::get_math() { - GodotT5Math::Ptr math; + GodotT5Math::Ptr math; if (_math.expired()) { math = std::make_shared(); - _math = math; - } - else { - math = _math.lock(); - } + _math = math; + } else { + math = _math.lock(); + } return math; } T5Integration::Logger::Ptr GodotT5ObjectRegistry::get_logger() { - GodotT5Logger::Ptr logger; - if (_logger.expired()) { - logger = std::make_shared(); - _logger = logger; - } - else { - logger = std::static_pointer_cast(_logger.lock()); - } - return logger; + GodotT5Logger::Ptr logger; + if (_logger.expired()) { + logger = std::make_shared(); + _logger = logger; + } else { + logger = std::static_pointer_cast(_logger.lock()); + } + return logger; } -} \ No newline at end of file +} //namespace GodotT5Integration \ No newline at end of file diff --git a/extension/src/GodotT5Service.h b/extension/src/GodotT5Service.h index df9644d..03ea267 100644 --- a/extension/src/GodotT5Service.h +++ b/extension/src/GodotT5Service.h @@ -1,33 +1,29 @@ #pragma once +#include #include #include -#include +#include +#include +#include #include -#include -#include -#include namespace GodotT5Integration { namespace GD = godot; -using GD::Transform3D; -using GD::Vector2; -using GD::Vector3; using GD::Ref; using GD::RID; using GD::StringName; +using GD::Transform3D; +using GD::Vector2; +using GD::Vector3; using GD::XRPositionalTracker; using T5Integration::Glasses; - class GodotT5Service : public T5Integration::T5Service { - protected: - std::unique_ptr create_glasses(const std::string_view id) override; - public: using Ptr = std::shared_ptr; @@ -35,7 +31,7 @@ class GodotT5Service : public T5Integration::T5Service { GodotT5Service(); GodotT5Glasses::Ptr get_glasses(int glasses_idx) { - // Safe to down cast + // Safe to down cast return std::static_pointer_cast(_glasses_list[glasses_idx]); } @@ -46,7 +42,7 @@ class GodotT5Service : public T5Integration::T5Service { }; class GodotT5Math : public T5Integration::T5Math { - public: +public: using Ptr = std::shared_ptr; void rotate_vector(float quat_x, float quat_y, float quat_z, float quat_w, float& vec_x, float& vec_y, float& vec_z, bool inverse = false) override; }; @@ -59,9 +55,8 @@ class GodotT5Logger : public T5Integration::Logger { void log_string(const char* message) override; }; - class GodotT5ObjectRegistry : public T5Integration::ObjectRegistry { - public: +public: GodotT5ObjectRegistry() = default; ~GodotT5ObjectRegistry() = default; @@ -71,10 +66,9 @@ class GodotT5ObjectRegistry : public T5Integration::ObjectRegistry { T5Integration::T5Math::Ptr get_math() override; T5Integration::Logger::Ptr get_logger() override; - protected: +protected: GodotT5Service::Ptr::weak_type _service; GodotT5Math::Ptr::weak_type _math; }; - -} +} //namespace GodotT5Integration diff --git a/extension/src/OpenGLGlasses.cpp b/extension/src/OpenGLGlasses.cpp index 1dc1727..bd0b08b 100644 --- a/extension/src/OpenGLGlasses.cpp +++ b/extension/src/OpenGLGlasses.cpp @@ -1,78 +1,76 @@ +#include #include +#include #include #include -#include -#include -#include +#include - -using godot::RenderingServer; using godot::Image; +using godot::RenderingServer; using godot::TypedArray; namespace GodotT5Integration { -OpenGLGlasses::OpenGLGlasses(std::string_view id) -: GodotT5Glasses(id) { - _swap_chain_textures.resize(g_swap_chain_length); +OpenGLGlasses::OpenGLGlasses(std::string_view id) : + GodotT5Glasses(id) { + _swap_chain_textures.resize(g_swap_chain_length); } void OpenGLGlasses::SwapChainTextures::allocate_textures(int width, int height) { - auto render_server = RenderingServer::get_singleton(); + auto render_server = RenderingServer::get_singleton(); - if(is_allocated) - deallocate_textures(); + if (is_allocated) + deallocate_textures(); - Ref dummy_image = Image::create(width, height, false, godot::Image::FORMAT_RGBA8); - godot::Color bg(0,0,0); - dummy_image->fill(bg); + Ref dummy_image = Image::create(width, height, false, godot::Image::FORMAT_RGBA8); + godot::Color bg(0, 0, 0); + dummy_image->fill(bg); - TypedArray image_arr; - image_arr.append(dummy_image); - image_arr.append(dummy_image); + TypedArray image_arr; + image_arr.append(dummy_image); + image_arr.append(dummy_image); - render_tex.instantiate(); - render_tex->create_from_images(image_arr); + render_tex.instantiate(); + render_tex->create_from_images(image_arr); is_allocated = true; } void OpenGLGlasses::SwapChainTextures::deallocate_textures() { - render_tex.unref(); + render_tex.unref(); is_allocated = false; } void OpenGLGlasses::allocate_textures() { - auto render_server = RenderingServer::get_singleton(); - - int width, height; - Glasses::get_display_size(width, height); - for(int i = 0; i < _swap_chain_textures.size(); i++) { - _swap_chain_textures[i].allocate_textures(width, height); - set_swap_chain_texture_array(i, render_server->texture_get_native_handle(_swap_chain_textures[i].render_tex->get_rid())); - } + auto render_server = RenderingServer::get_singleton(); + + int width, height; + Glasses::get_display_size(width, height); + for (int i = 0; i < _swap_chain_textures.size(); i++) { + _swap_chain_textures[i].allocate_textures(width, height); + set_swap_chain_texture_array(i, render_server->texture_get_native_handle(_swap_chain_textures[i].render_tex->get_rid())); + } } void OpenGLGlasses::deallocate_textures() { - auto render_server = RenderingServer::get_singleton(); + auto render_server = RenderingServer::get_singleton(); - for(int i = 0; i < _swap_chain_textures.size(); i++) { - _swap_chain_textures[i].deallocate_textures(); - set_swap_chain_texture_array(i, 0); - } + for (int i = 0; i < _swap_chain_textures.size(); i++) { + _swap_chain_textures[i].deallocate_textures(); + set_swap_chain_texture_array(i, 0); + } } void OpenGLGlasses::on_start_display() { - allocate_textures(); + allocate_textures(); } -void OpenGLGlasses::on_stop_display() { - deallocate_textures(); +void OpenGLGlasses::on_stop_display() { + deallocate_textures(); } -RID OpenGLGlasses::get_color_texture() -{ - int current_frame = get_current_frame_idx(); - return _swap_chain_textures[current_frame].render_tex->get_rid(); +RID OpenGLGlasses::get_color_texture() { + int current_frame = get_current_frame_idx(); + return _swap_chain_textures[current_frame].render_tex->get_rid(); } -} // GodotT5Integration \ No newline at end of file +} //namespace GodotT5Integration \ No newline at end of file diff --git a/extension/src/OpenGLGlasses.h b/extension/src/OpenGLGlasses.h index 586f7a1..c83466e 100644 --- a/extension/src/OpenGLGlasses.h +++ b/extension/src/OpenGLGlasses.h @@ -1,42 +1,37 @@ #pragma once #include -#include -#include #include +#include +#include using godot::RID; -using godot::Transform3D; using godot::Texture2DArray; +using godot::Transform3D; namespace GodotT5Integration { - class OpenGLGlasses : public GodotT5Glasses { - - struct SwapChainTextures { - void allocate_textures(int width, int height); - void deallocate_textures(); - - bool is_allocated = false; - Ref render_tex; - }; - - public: - - OpenGLGlasses(std::string_view id); - - virtual RID get_color_texture() override; +class OpenGLGlasses : public GodotT5Glasses { + struct SwapChainTextures { + void allocate_textures(int width, int height); + void deallocate_textures(); - private: + bool is_allocated = false; + Ref render_tex; + }; - void allocate_textures(); - void deallocate_textures(); +public: + OpenGLGlasses(std::string_view id); - virtual void on_start_display() override; - virtual void on_stop_display() override; + virtual RID get_color_texture() override; - private: +private: + void allocate_textures(); + void deallocate_textures(); - std::vector _swap_chain_textures; - }; -} + virtual void on_start_display() override; + virtual void on_stop_display() override; +private: + std::vector _swap_chain_textures; +}; +} //namespace GodotT5Integration diff --git a/extension/src/T5Camera3D.cpp b/extension/src/T5Camera3D.cpp index 1d28d5d..95c4fb7 100644 --- a/extension/src/T5Camera3D.cpp +++ b/extension/src/T5Camera3D.cpp @@ -1,15 +1,14 @@ #include #include -#include #include +#include #include -using godot::XRServer; using godot::Callable; using godot::ClassDB; using godot::D_METHOD; using godot::PropertyInfo; - +using godot::XRServer; void T5Camera3D::set_tracker(const StringName p_tracker_name) { if (tracker.is_valid() && tracker->get_tracker_name() == p_tracker_name) { @@ -36,52 +35,49 @@ StringName T5Camera3D::get_tracker() const { } bool T5Camera3D::get_is_active() const { - if (tracker.is_null()) { - return false; - } else if (!tracker->has_pose(pose_name)) { - return false; - } else { - return true; - } + if (tracker.is_null()) { + return false; + } else if (!tracker->has_pose(pose_name)) { + return false; + } else { + return true; + } } bool T5Camera3D::get_has_tracking_data() const { - if (tracker.is_null()) { - return false; - } else if (!tracker->has_pose(pose_name)) { - return false; - } else { - return tracker->get_pose(pose_name)->get_has_tracking_data(); - } + if (tracker.is_null()) { + return false; + } else if (!tracker->has_pose(pose_name)) { + return false; + } else { + return tracker->get_pose(pose_name)->get_has_tracking_data(); + } } Ref T5Camera3D::get_pose() { - if (tracker.is_valid()) { - return tracker->get_pose(pose_name); - } else { - return Ref(); - } + if (tracker.is_valid()) { + return tracker->get_pose(pose_name); + } else { + return Ref(); + } } -PackedStringArray T5Camera3D::get_configuration_warnings(PackedStringArray& warnings) const { - - if (is_visible() && is_inside_tree()) { +PackedStringArray T5Camera3D::get_configuration_warnings(PackedStringArray &warnings) const { + if (is_visible() && is_inside_tree()) { // must be child node of T5Origin3D! T5Origin3D *origin = Object::cast_to(get_parent()); if (origin == nullptr) { warnings.push_back("T5Camera3D must have an T5Origin3D node as its parent."); } - if (tracker_name.is_empty()) { - warnings.push_back("No tracker name is set."); - } - } + if (tracker_name.is_empty()) { + warnings.push_back("No tracker name is set."); + } + } - return warnings; + return warnings; } - - T5Camera3D::T5Camera3D() { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL(xr_server); @@ -121,25 +117,24 @@ void T5Camera3D::_bind_methods() { ClassDB::bind_method(D_METHOD("_pose_changed", "pose"), &T5Camera3D::_pose_changed); } - void T5Camera3D::_bind_tracker() { - ERR_FAIL_COND_MSG(tracker.is_valid(), "Unbind the current tracker first"); - - XRServer *xr_server = XRServer::get_singleton(); - if (xr_server != nullptr) { - tracker = xr_server->get_tracker(tracker_name); - if (tracker.is_null()) { - // It is possible and valid if the tracker isn't available (yet), in this case we just exit - return; - } - - tracker->connect("pose_changed", Callable(this, "_pose_changed")); - - Ref pose = get_pose(); - if (pose.is_valid()) { - set_transform(pose->get_adjusted_transform()); - } - } + ERR_FAIL_COND_MSG(tracker.is_valid(), "Unbind the current tracker first"); + + XRServer *xr_server = XRServer::get_singleton(); + if (xr_server != nullptr) { + tracker = xr_server->get_tracker(tracker_name); + if (tracker.is_null()) { + // It is possible and valid if the tracker isn't available (yet), in this case we just exit + return; + } + + tracker->connect("pose_changed", Callable(this, "_pose_changed")); + + Ref pose = get_pose(); + if (pose.is_valid()) { + set_transform(pose->get_adjusted_transform()); + } + } } void T5Camera3D::_unbind_tracker() { @@ -151,9 +146,9 @@ void T5Camera3D::_unbind_tracker() { void T5Camera3D::_changed_tracker(const StringName p_tracker_name, int p_tracker_type) { if (p_tracker_name == tracker_name) { - // just in case unref our current tracker - _unbind_tracker(); - + // just in case unref our current tracker + _unbind_tracker(); + _bind_tracker(); } } @@ -165,9 +160,8 @@ void T5Camera3D::_removed_tracker(const StringName p_tracker_name, int p_tracker } void T5Camera3D::_pose_changed(const Variant p_obj) { - auto pose = Object::cast_to(p_obj); - if (pose && pose->get_name() == pose_name) { - set_transform(pose->get_adjusted_transform()); - } + auto pose = Object::cast_to(p_obj); + if (pose && pose->get_name() == pose_name) { + set_transform(pose->get_adjusted_transform()); + } } - diff --git a/extension/src/T5Camera3D.h b/extension/src/T5Camera3D.h index 2e1c8b1..b1c1eef 100644 --- a/extension/src/T5Camera3D.h +++ b/extension/src/T5Camera3D.h @@ -1,42 +1,42 @@ #ifndef T5_CAMERA_3D_H #define T5_CAMERA_3D_H -// -// The XR node hierarchy was duplicated because of the need +// +// The XR node hierarchy was duplicated because of the need // to set a tracker name for the Camera node. This was not // possible for XRCamera3D in Godot 4.1. This required creating // a custom T5Camera3D node. However since XROrigin3D requires an // XRCamera3D as a child this meant that it need to be replaced // too. This cascaded to the whole XR hierarchy because of // interdependencies. If the XRCamera3D nodes are fixed in the -// future it should be possible to depreciate this custom +// future it should be possible to depreciate this custom // T5 node hierarchy. // -#include -#include #include +#include +#include -using godot::Variant; -using godot::Ref; using godot::Camera3D; +using godot::PackedStringArray; +using godot::Ref; using godot::StringName; -using godot::XRPositionalTracker; +using godot::Variant; using godot::XRPose; -using godot::PackedStringArray; +using godot::XRPositionalTracker; class T5Camera3D : public Camera3D { GDCLASS(T5Camera3D, Camera3D); -public: +public: void set_tracker(const StringName p_tracker_name); StringName get_tracker() const; - bool get_is_active() const; + bool get_is_active() const; bool get_has_tracking_data() const; Ref get_pose(); PackedStringArray get_configuration_warnings(PackedStringArray& warnings) const; - // These are override from Camera3D currently not exposed as virtual in + // These are override from Camera3D currently not exposed as virtual in //GDExtension - + // virtual Vector3 project_local_ray_normal(const Point2 &p_pos) const override; // virtual Point2 unproject_position(const Vector3 &p_pos) const override; // virtual Vector3 project_position(const Point2 &p_point, real_t p_z_depth) const override; @@ -59,5 +59,4 @@ class T5Camera3D : public Camera3D { void _pose_changed(const Variant p_pose); }; - #endif // T5_CAMERA_3D_H \ No newline at end of file diff --git a/extension/src/T5Controller3D.cpp b/extension/src/T5Controller3D.cpp index fa875b6..b02dc33 100644 --- a/extension/src/T5Controller3D.cpp +++ b/extension/src/T5Controller3D.cpp @@ -1,17 +1,18 @@ #include #include +using godot::Callable; using godot::ClassDB; -using godot::PropertyInfo; using godot::D_METHOD; -using godot::Variant; using godot::MethodInfo; -using godot::Callable; +using godot::PropertyInfo; +using godot::Variant; -#define DEF_SNAME(arg) StringName& sn_##arg() { \ - static StringName name = #arg; \ - return name; \ -} +#define DEF_SNAME(arg) \ + StringName &sn_##arg() { \ + static StringName name = #arg; \ + return name; \ + } DEF_SNAME(button_pressed) DEF_SNAME(button_released) @@ -24,7 +25,7 @@ void T5Controller3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_float", "name"), &T5Controller3D::get_float); ClassDB::bind_method(D_METHOD("get_vector2", "name"), &T5Controller3D::get_vector2); ClassDB::bind_method(D_METHOD("trigger_haptic_pulse", "amplitude", "duration"), &T5Controller3D::trigger_haptic_pulse); - + ClassDB::bind_method(D_METHOD("_button_pressed", "name"), &T5Controller3D::_button_pressed); ClassDB::bind_method(D_METHOD("_button_released", "name"), &T5Controller3D::_button_released); ClassDB::bind_method(D_METHOD("_input_float_changed", "name", "value"), &T5Controller3D::_input_float_changed); @@ -146,6 +147,6 @@ Vector2 T5Controller3D::get_vector2(const StringName &p_name) const { void T5Controller3D::trigger_haptic_pulse(float amplitude, int duration) { auto glasses = get_associated_glasses(); auto wand_num = get_associated_wand_num(); - if(glasses && wand_num >= 0) + if (glasses && wand_num >= 0) glasses->trigger_haptic_pulse(wand_num, amplitude, duration); } diff --git a/extension/src/T5Controller3D.h b/extension/src/T5Controller3D.h index 6668147..6c5b5e8 100644 --- a/extension/src/T5Controller3D.h +++ b/extension/src/T5Controller3D.h @@ -1,21 +1,21 @@ #ifndef T5_CONTROLLER_3D_H #define T5_CONTROLLER_3D_H -// -// The XR node hierarchy was duplicated because of the need +// +// The XR node hierarchy was duplicated because of the need // to set a tracker name for the Camera node. This was not // possible for XRCamera3D in Godot 4.1. This required creating // a custom T5Camera3D node. However since XROrigin3D requires an // XRCamera3D as a child this meant that it need to be replaced // too. This cascaded to the whole XR hierarchy because of // interdependencies. If the XRCamera3D nodes are fixed in the -// future it should be possible to depreciate this custom +// future it should be possible to depreciate this custom // T5 node hierarchy. // #include -using godot::Variant; using godot::String; using godot::StringName; +using godot::Variant; using godot::Vector2; class T5Controller3D : public T5Node3D { @@ -44,7 +44,6 @@ class T5Controller3D : public T5Node3D { void _input_vector2_changed(const String &p_name, Vector2 p_value); private: - }; #endif // T5_CONTROLLER_3D_H \ No newline at end of file diff --git a/extension/src/T5Gameboard.cpp b/extension/src/T5Gameboard.cpp index ca957f3..5ae3701 100644 --- a/extension/src/T5Gameboard.cpp +++ b/extension/src/T5Gameboard.cpp @@ -1,84 +1,78 @@ #include +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include - +using godot::Callable; using godot::ClassDB; using godot::D_METHOD; -using godot::PropertyInfo; -using godot::Variant; -using godot::Callable; +using godot::Engine; using godot::Object; -using godot::UtilityFunctions; -using godot::ResourceLoader; using godot::PackedScene; +using godot::PropertyInfo; +using godot::ResourceLoader; using godot::SceneTree; +using godot::UtilityFunctions; +using godot::Variant; using godot::Vector3; -using godot::Engine; const char le_name[] = "LE"; const char xe_name[] = "XE"; const char raised_xe_name[] = "Raised XE"; void T5Gameboard::set_content_scale(float scale) { - content_scale = scale; - set_board_state(); + content_scale = scale; + set_board_state(); } -float T5Gameboard::get_content_scale() const{ - return content_scale; +float T5Gameboard::get_content_scale() const { + return content_scale; } void T5Gameboard::set_gameboard_type(String gb_type) { - if(gb_type == le_name) { - gameboard_type = TiltFiveXRInterface::LE_GAMEBOARD; - } - else if(gb_type == xe_name) { - gameboard_type = TiltFiveXRInterface::XE_GAMEBOARD; - } - else if(gb_type == raised_xe_name) { - gameboard_type = TiltFiveXRInterface::XE_RAISED_GAMEBOARD; - } - else { - gameboard_type = TiltFiveXRInterface::NO_GAMEBOARD_SET; - } - set_board_state(); - + if (gb_type == le_name) { + gameboard_type = TiltFiveXRInterface::LE_GAMEBOARD; + } else if (gb_type == xe_name) { + gameboard_type = TiltFiveXRInterface::XE_GAMEBOARD; + } else if (gb_type == raised_xe_name) { + gameboard_type = TiltFiveXRInterface::XE_RAISED_GAMEBOARD; + } else { + gameboard_type = TiltFiveXRInterface::NO_GAMEBOARD_SET; + } + set_board_state(); } -String T5Gameboard::get_gameboard_type() const{ - switch (gameboard_type) - { - case TiltFiveXRInterface::LE_GAMEBOARD: - return le_name; - case TiltFiveXRInterface::XE_GAMEBOARD: - return xe_name; - case TiltFiveXRInterface::XE_RAISED_GAMEBOARD: - return raised_xe_name; - default: - break; - } - return "Unknown"; +String T5Gameboard::get_gameboard_type() const { + switch (gameboard_type) { + case TiltFiveXRInterface::LE_GAMEBOARD: + return le_name; + case TiltFiveXRInterface::XE_GAMEBOARD: + return xe_name; + case TiltFiveXRInterface::XE_RAISED_GAMEBOARD: + return raised_xe_name; + default: + break; + } + return "Unknown"; } void T5Gameboard::set_show_at_runtime(bool show) { - show_at_runtime = show; - set_board_state(); + show_at_runtime = show; + set_board_state(); } bool T5Gameboard::get_show_at_runtime() const { - return show_at_runtime; + return show_at_runtime; } void T5Gameboard::set_layer_mask(uint32_t p_mask) { layers = p_mask; - set_board_state(); + set_board_state(); } uint32_t T5Gameboard::get_layer_mask() const { @@ -103,86 +97,79 @@ bool T5Gameboard::get_layer_mask_value(int p_layer_number) const { return layers & (1 << (p_layer_number - 1)); } - -T5Gameboard::T5Gameboard(){ - +T5Gameboard::T5Gameboard() { } -T5Gameboard::~T5Gameboard(){ - +T5Gameboard::~T5Gameboard() { } Node3D* T5Gameboard::add_scene(String path) { - Ref scene = ResourceLoader::get_singleton()->load(path, "PackedScene"); - ERR_FAIL_COND_V_MSG(scene.is_null(), nullptr, godot::vformat("Failed to load: %s", path)); - - auto node = scene->instantiate(); - auto node_3d = Object::cast_to(node); - if(!node_3d) { - node->queue_free(); - ERR_FAIL_V_MSG(nullptr, godot::vformat("Not Node3D: %s", path)); - } - if(node_3d->get_child_count() == 0 || node->get_child(0)->get_class() != "MeshInstance3D") { - node->queue_free(); - ERR_FAIL_V_MSG(nullptr, godot::vformat("Not Node3D and MeshInstance3D: %s", path)); - } - - add_child(node_3d); - return node_3d; + Ref scene = ResourceLoader::get_singleton()->load(path, "PackedScene"); + ERR_FAIL_COND_V_MSG(scene.is_null(), nullptr, godot::vformat("Failed to load: %s", path)); + + auto node = scene->instantiate(); + auto node_3d = Object::cast_to(node); + if (!node_3d) { + node->queue_free(); + ERR_FAIL_V_MSG(nullptr, godot::vformat("Not Node3D: %s", path)); + } + if (node_3d->get_child_count() == 0 || node->get_child(0)->get_class() != "MeshInstance3D") { + node->queue_free(); + ERR_FAIL_V_MSG(nullptr, godot::vformat("Not Node3D and MeshInstance3D: %s", path)); + } + + add_child(node_3d); + return node_3d; } void T5Gameboard::set_board_state() { - - bool show_board = show_at_runtime || Engine::get_singleton()->is_editor_hint(); - if(le_node) { - le_node->set_scale(Vector3(content_scale, content_scale, content_scale)); - le_node->set_visible(gameboard_type == TiltFiveXRInterface::LE_GAMEBOARD && show_board); - auto mesh_inst = Object::cast_to(le_node->get_child(0)); - mesh_inst->set_layer_mask(layers); - } - if(xe_node) { - xe_node->set_scale(Vector3(content_scale, content_scale, content_scale)); - xe_node->set_visible(gameboard_type == TiltFiveXRInterface::XE_GAMEBOARD && show_board); - auto mesh_inst = Object::cast_to(le_node->get_child(0)); - mesh_inst->set_layer_mask(layers); - } - if(raised_xe_node) { - raised_xe_node->set_scale(Vector3(content_scale, content_scale, content_scale)); - raised_xe_node->set_visible(gameboard_type == TiltFiveXRInterface::XE_RAISED_GAMEBOARD && show_board); - auto mesh_inst = Object::cast_to(le_node->get_child(0)); - mesh_inst->set_layer_mask(layers); - } + bool show_board = show_at_runtime || Engine::get_singleton()->is_editor_hint(); + if (le_node) { + le_node->set_scale(Vector3(content_scale, content_scale, content_scale)); + le_node->set_visible(gameboard_type == TiltFiveXRInterface::LE_GAMEBOARD && show_board); + auto mesh_inst = Object::cast_to(le_node->get_child(0)); + mesh_inst->set_layer_mask(layers); + } + if (xe_node) { + xe_node->set_scale(Vector3(content_scale, content_scale, content_scale)); + xe_node->set_visible(gameboard_type == TiltFiveXRInterface::XE_GAMEBOARD && show_board); + auto mesh_inst = Object::cast_to(le_node->get_child(0)); + mesh_inst->set_layer_mask(layers); + } + if (raised_xe_node) { + raised_xe_node->set_scale(Vector3(content_scale, content_scale, content_scale)); + raised_xe_node->set_visible(gameboard_type == TiltFiveXRInterface::XE_RAISED_GAMEBOARD && show_board); + auto mesh_inst = Object::cast_to(le_node->get_child(0)); + mesh_inst->set_layer_mask(layers); + } } void T5Gameboard::_ready() { - le_node = add_scene("res://addons/tiltfive/assets/T5_border.glb"); - xe_node = add_scene("res://addons/tiltfive/assets/T5_border_XE.glb"); - raised_xe_node = add_scene("res://addons/tiltfive/assets/T5_border_XE_raised.glb"); - set_board_state(); + le_node = add_scene("res://addons/tiltfive/assets/T5_border.glb"); + xe_node = add_scene("res://addons/tiltfive/assets/T5_border_XE.glb"); + raised_xe_node = add_scene("res://addons/tiltfive/assets/T5_border_XE_raised.glb"); + set_board_state(); } void T5Gameboard::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_content_scale", "scale"), &T5Gameboard::set_content_scale); + ClassDB::bind_method(D_METHOD("set_content_scale", "scale"), &T5Gameboard::set_content_scale); ClassDB::bind_method(D_METHOD("get_content_scale"), &T5Gameboard::get_content_scale); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "content_scale", godot::PROPERTY_HINT_RANGE, "0.001, 1000.0, or_greater, hide_slider"), "set_content_scale", "get_content_scale"); ClassDB::bind_method(D_METHOD("set_gameboard_type", "gameboard_type"), &T5Gameboard::set_gameboard_type); ClassDB::bind_method(D_METHOD("get_gameboard_type"), &T5Gameboard::get_gameboard_type); - auto hint = godot::vformat("%s,%s,%s", le_name, xe_name, raised_xe_name); + auto hint = godot::vformat("%s,%s,%s", le_name, xe_name, raised_xe_name); ADD_PROPERTY(PropertyInfo(Variant::STRING, "gameboard_type", godot::PROPERTY_HINT_ENUM, hint), "set_gameboard_type", "get_gameboard_type"); - ClassDB::bind_method(D_METHOD("set_show_at_runtime", "show"), &T5Gameboard::set_show_at_runtime); + ClassDB::bind_method(D_METHOD("set_show_at_runtime", "show"), &T5Gameboard::set_show_at_runtime); ClassDB::bind_method(D_METHOD("get_show_at_runtime"), &T5Gameboard::get_show_at_runtime); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_at_runtime", godot::PROPERTY_HINT_NONE), "set_show_at_runtime", "get_show_at_runtime"); - ClassDB::bind_method(D_METHOD("set_layer_mask", "mask"), &T5Gameboard::set_layer_mask); + ClassDB::bind_method(D_METHOD("set_layer_mask", "mask"), &T5Gameboard::set_layer_mask); ClassDB::bind_method(D_METHOD("get_layer_mask"), &T5Gameboard::get_layer_mask); - ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", godot::PROPERTY_HINT_LAYERS_3D_RENDER), "set_layer_mask", "get_layer_mask"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", godot::PROPERTY_HINT_LAYERS_3D_RENDER), "set_layer_mask", "get_layer_mask"); ClassDB::bind_method(D_METHOD("set_layer_mask_value", "layer_number", "value"), &T5Gameboard::set_layer_mask_value); ClassDB::bind_method(D_METHOD("get_layer_mask_value", "layer_number"), &T5Gameboard::get_layer_mask_value); - }; - - \ No newline at end of file diff --git a/extension/src/T5Gameboard.h b/extension/src/T5Gameboard.h index 690d07f..0aa8169 100644 --- a/extension/src/T5Gameboard.h +++ b/extension/src/T5Gameboard.h @@ -2,12 +2,12 @@ #define T5_GAMEBOARD_H #include -#include -#include #include +#include +#include #include #include -#include +#include using godot::Ref; using godot::String; @@ -18,7 +18,6 @@ class T5Gameboard : public Node3D { GDCLASS(T5Gameboard, Node3D); public: - void _ready() override; void set_content_scale(float scale); @@ -36,29 +35,24 @@ class T5Gameboard : public Node3D { void set_layer_mask_value(int p_layer_number, bool p_enable); bool get_layer_mask_value(int p_layer_number) const; + T5Gameboard(); + ~T5Gameboard(); - T5Gameboard(); - ~T5Gameboard(); - protected: - static void _bind_methods(); private: - Node3D* add_scene(String path); - void set_board_state(); + Node3D* add_scene(String path); + void set_board_state(); float content_scale = 1.0; TiltFiveXRInterface::GameBoardType gameboard_type = TiltFiveXRInterface::GameBoardType::LE_GAMEBOARD; - bool show_at_runtime = false; + bool show_at_runtime = false; uint32_t layers = 1; - Node3D* le_node = nullptr; - Node3D* xe_node = nullptr; - Node3D* raised_xe_node = nullptr; + Node3D* le_node = nullptr; + Node3D* xe_node = nullptr; + Node3D* raised_xe_node = nullptr; }; - - - #endif // T5_GAMEBOARD_H \ No newline at end of file diff --git a/extension/src/T5Node3D.cpp b/extension/src/T5Node3D.cpp index e043844..9227254 100644 --- a/extension/src/T5Node3D.cpp +++ b/extension/src/T5Node3D.cpp @@ -1,136 +1,132 @@ -#include -#include #include #include +#include +#include +#include #include #include #include -#include +using godot::Callable; using godot::ClassDB; using godot::D_METHOD; +using godot::Object; using godot::PropertyInfo; using godot::Variant; -using godot::Object; -using godot::Callable; -using godot::Object; using GodotT5Integration::GodotT5Service; using T5Integration::ObjectRegistry; - - void T5Node3D::set_tracker(const StringName p_tracker_name) { - if (tracker.is_valid() && tracker->get_tracker_name() == p_tracker_name) { - // didn't change - return; - } + if (tracker.is_valid() && tracker->get_tracker_name() == p_tracker_name) { + // didn't change + return; + } - // just in case - _unbind_tracker(); + // just in case + _unbind_tracker(); - // copy the name - tracker_name = p_tracker_name; - pose_name = "default"; + // copy the name + tracker_name = p_tracker_name; + pose_name = "default"; - // see if it's already available - _bind_tracker(); + // see if it's already available + _bind_tracker(); - update_configuration_warnings(); - notify_property_list_changed(); + update_configuration_warnings(); + notify_property_list_changed(); } StringName T5Node3D::get_tracker() const { - return tracker_name; + return tracker_name; } void T5Node3D::set_pose_name(const StringName p_pose_name) { - pose_name = p_pose_name; + pose_name = p_pose_name; - // Update pose if we are bound to a tracker with a valid pose - Ref pose = get_pose(); - if (pose.is_valid()) { - set_transform(pose->get_adjusted_transform()); - } + // Update pose if we are bound to a tracker with a valid pose + Ref pose = get_pose(); + if (pose.is_valid()) { + set_transform(pose->get_adjusted_transform()); + } } StringName T5Node3D::get_pose_name() const { - return pose_name; + return pose_name; } bool T5Node3D::get_is_active() const { - if (tracker.is_null()) { - return false; - } else if (!tracker->has_pose(pose_name)) { - return false; - } else { - return true; - } + if (tracker.is_null()) { + return false; + } else if (!tracker->has_pose(pose_name)) { + return false; + } else { + return true; + } } bool T5Node3D::get_has_tracking_data() const { - if (tracker.is_null()) { - return false; - } else if (!tracker->has_pose(pose_name)) { - return false; - } else { - return tracker->get_pose(pose_name)->get_has_tracking_data(); - } + if (tracker.is_null()) { + return false; + } else if (!tracker->has_pose(pose_name)) { + return false; + } else { + return tracker->get_pose(pose_name)->get_has_tracking_data(); + } } Ref T5Node3D::get_pose() { - if (tracker.is_valid()) { - return tracker->get_pose(pose_name); - } else { - return Ref(); - } + if (tracker.is_valid()) { + return tracker->get_pose(pose_name); + } else { + return Ref(); + } } -PackedStringArray T5Node3D::get_configuration_warnings(PackedStringArray& warnings) const { - - if (is_visible() && is_inside_tree()) { +PackedStringArray T5Node3D::get_configuration_warnings(PackedStringArray &warnings) const { + if (is_visible() && is_inside_tree()) { // must be child node of T5Origin3D! T5Origin3D *origin = Object::cast_to(get_parent()); if (origin == nullptr) { warnings.push_back("T5Node3D must have an T5Origin3D node as its parent."); } - if (tracker_name.is_empty()) { - warnings.push_back("No tracker name is set."); - } + if (tracker_name.is_empty()) { + warnings.push_back("No tracker name is set."); + } - if (pose_name.is_empty()) { - warnings.push_back("No pose is set."); - } - } + if (pose_name.is_empty()) { + warnings.push_back("No pose is set."); + } + } - return warnings; + return warnings; } -T5Node3D::T5Node3D() { - XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL(xr_server); +T5Node3D::T5Node3D() { + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); + + xr_server->connect("tracker_added", Callable(this, "_changed_tracker")); + xr_server->connect("tracker_updated", Callable(this, "_changed_tracker")); + xr_server->connect("tracker_removed", Callable(this, "_removed_tracker")); - xr_server->connect("tracker_added", Callable(this, "_changed_tracker")); - xr_server->connect("tracker_updated", Callable(this, "_changed_tracker")); - xr_server->connect("tracker_removed", Callable(this, "_removed_tracker")); - - // check if our tracker already exists and if so, bind it... + // check if our tracker already exists and if so, bind it... _bind_tracker(); } T5Node3D::~T5Node3D() { _unbind_tracker(); - XRServer *xr_server = XRServer::get_singleton(); - ERR_FAIL_NULL(xr_server); + XRServer *xr_server = XRServer::get_singleton(); + ERR_FAIL_NULL(xr_server); - xr_server->disconnect("tracker_added", Callable(this, "_changed_tracker")); - xr_server->disconnect("tracker_updated", Callable(this, "_changed_tracker")); - xr_server->disconnect("tracker_removed", Callable(this, "_removed_tracker")); + xr_server->disconnect("tracker_added", Callable(this, "_changed_tracker")); + xr_server->disconnect("tracker_updated", Callable(this, "_changed_tracker")); + xr_server->disconnect("tracker_removed", Callable(this, "_removed_tracker")); } void T5Node3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_tracker", "tracker_name"), &T5Node3D::set_tracker); + ClassDB::bind_method(D_METHOD("set_tracker", "tracker_name"), &T5Node3D::set_tracker); ClassDB::bind_method(D_METHOD("get_tracker"), &T5Node3D::get_tracker); ADD_PROPERTY(PropertyInfo(Variant::STRING, "tracker", godot::PROPERTY_HINT_ENUM_SUGGESTION), "set_tracker", "get_tracker"); @@ -142,85 +138,83 @@ void T5Node3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_has_tracking_data"), &T5Node3D::get_has_tracking_data); ClassDB::bind_method(D_METHOD("get_pose"), &T5Node3D::get_pose); - ClassDB::bind_method(D_METHOD("_changed_tracker", "tracker_name", "tracker_type"), &T5Node3D::_changed_tracker); - ClassDB::bind_method(D_METHOD("_removed_tracker", "tracker_name", "tracker_type"), &T5Node3D::_removed_tracker); - ClassDB::bind_method(D_METHOD("_pose_changed", "pose"), &T5Node3D::_pose_changed); + ClassDB::bind_method(D_METHOD("_changed_tracker", "tracker_name", "tracker_type"), &T5Node3D::_changed_tracker); + ClassDB::bind_method(D_METHOD("_removed_tracker", "tracker_name", "tracker_type"), &T5Node3D::_removed_tracker); + ClassDB::bind_method(D_METHOD("_pose_changed", "pose"), &T5Node3D::_pose_changed); }; -void T5Node3D::_bind_tracker() { - ERR_FAIL_COND_MSG(tracker.is_valid(), "Unbind the current tracker first"); +void T5Node3D::_bind_tracker() { + ERR_FAIL_COND_MSG(tracker.is_valid(), "Unbind the current tracker first"); - XRServer *xr_server = XRServer::get_singleton(); - if (xr_server != nullptr) { - tracker = xr_server->get_tracker(tracker_name); - if (tracker.is_null()) { - // It is possible and valid if the tracker isn't available (yet), in this case we just exit - return; - } - - tracker->connect("pose_changed", Callable(this, "_pose_changed")); + XRServer *xr_server = XRServer::get_singleton(); + if (xr_server != nullptr) { + tracker = xr_server->get_tracker(tracker_name); + if (tracker.is_null()) { + // It is possible and valid if the tracker isn't available (yet), in this case we just exit + return; + } - Ref pose = get_pose(); - if (pose.is_valid()) { - set_transform(pose->get_adjusted_transform()); - } + tracker->connect("pose_changed", Callable(this, "_pose_changed")); - } + Ref pose = get_pose(); + if (pose.is_valid()) { + set_transform(pose->get_adjusted_transform()); + } + } } void T5Node3D::_unbind_tracker() { - if (tracker.is_valid()) { - tracker->disconnect("pose_changed", Callable(this, "_pose_changed")); - tracker.unref(); + if (tracker.is_valid()) { + tracker->disconnect("pose_changed", Callable(this, "_pose_changed")); + tracker.unref(); - _indexes_associated = false; - _glasses_idx = -1; - _wand_idx = -1; - } + _indexes_associated = false; + _glasses_idx = -1; + _wand_idx = -1; + } } void T5Node3D::_changed_tracker(const StringName p_tracker_name, int p_tracker_type) { - if (tracker_name == p_tracker_name) { - // just in case unref our current tracker - _unbind_tracker(); + if (tracker_name == p_tracker_name) { + // just in case unref our current tracker + _unbind_tracker(); - // get our new tracker - _bind_tracker(); - } + // get our new tracker + _bind_tracker(); + } } void T5Node3D::_removed_tracker(const StringName p_tracker_name, int p_tracker_type) { - if (tracker_name == p_tracker_name) { - // unref our tracker, it's no longer available - _unbind_tracker(); - } + if (tracker_name == p_tracker_name) { + // unref our tracker, it's no longer available + _unbind_tracker(); + } } -void T5Node3D::_pose_changed(Object* p_obj) { - auto pose = Object::cast_to(p_obj); - if (pose && pose->get_name() == pose_name) { - set_transform(pose->get_adjusted_transform()); - } +void T5Node3D::_pose_changed(Object *p_obj) { + auto pose = Object::cast_to(p_obj); + if (pose && pose->get_name() == pose_name) { + set_transform(pose->get_adjusted_transform()); + } } GodotT5Glasses::Ptr T5Node3D::get_associated_glasses() { - auto service = std::static_pointer_cast(ObjectRegistry::service()); - if(!_indexes_associated) { - service->get_tracker_association(tracker_name, _glasses_idx, _wand_idx); - _indexes_associated = true; - } - if(_glasses_idx >= 0) { + auto service = std::static_pointer_cast(ObjectRegistry::service()); + if (!_indexes_associated) { + service->get_tracker_association(tracker_name, _glasses_idx, _wand_idx); + _indexes_associated = true; + } + if (_glasses_idx >= 0) { return service->get_glasses(_glasses_idx); } - return GodotT5Glasses::Ptr(); + return GodotT5Glasses::Ptr(); } int T5Node3D::get_associated_wand_num() { - if(!_indexes_associated) { - auto service = std::static_pointer_cast(ObjectRegistry::service()); - service->get_tracker_association(tracker_name, _glasses_idx, _wand_idx); - _indexes_associated = true; - } - return _wand_idx; + if (!_indexes_associated) { + auto service = std::static_pointer_cast(ObjectRegistry::service()); + service->get_tracker_association(tracker_name, _glasses_idx, _wand_idx); + _indexes_associated = true; + } + return _wand_idx; } - diff --git a/extension/src/T5Node3D.h b/extension/src/T5Node3D.h index 1622ed3..7fdc66e 100644 --- a/extension/src/T5Node3D.h +++ b/extension/src/T5Node3D.h @@ -1,54 +1,53 @@ #ifndef T5_NODE_3D_H #define T5_NODE_3D_H -// -// The XR node hierarchy was duplicated because of the need +// +// The XR node hierarchy was duplicated because of the need // to set a tracker name for the Camera node. This was not // possible for XRCamera3D in Godot 4.1. This required creating // a custom T5Camera3D node. However since XROrigin3D requires an // XRCamera3D as a child this meant that it need to be replaced // too. This cascaded to the whole XR hierarchy because of // interdependencies. If the XRCamera3D nodes are fixed in the -// future it should be possible to depreciate this custom +// future it should be possible to depreciate this custom // T5 node hierarchy. // #include -#include -#include +#include #include +#include #include #include -#include +#include +using godot::Node3D; +using godot::PackedStringArray; using godot::Ref; -using godot::XRServer; using godot::String; using godot::StringName; -using godot::PackedStringArray; using godot::XRPose; using godot::XRPositionalTracker; -using godot::Node3D; -using GodotT5Integration::GodotT5Service; +using godot::XRServer; using GodotT5Integration::GodotT5Glasses; +using GodotT5Integration::GodotT5Service; using T5Integration::ObjectRegistry; class T5Node3D : public Node3D { GDCLASS(T5Node3D, Node3D); public: - //void _validate_property(PropertyInfo &p_property) const; void set_tracker(const StringName p_tracker_name); StringName get_tracker() const; void set_pose_name(const StringName p_pose_name); StringName get_pose_name() const; - bool get_is_active() const; + bool get_is_active() const; bool get_has_tracking_data() const; Ref get_pose(); PackedStringArray get_configuration_warnings(PackedStringArray& warnings) const; - T5Node3D(); - ~T5Node3D(); - + T5Node3D(); + ~T5Node3D(); + protected: Ref tracker; diff --git a/extension/src/T5Origin3D.cpp b/extension/src/T5Origin3D.cpp index fac12d0..a6c9229 100644 --- a/extension/src/T5Origin3D.cpp +++ b/extension/src/T5Origin3D.cpp @@ -2,9 +2,9 @@ #include using godot::ClassDB; +using godot::D_METHOD; using godot::MethodInfo; using godot::PropertyInfo; -using godot::D_METHOD; using godot::Variant; void T5Origin3D::_bind_methods() { @@ -13,18 +13,17 @@ void T5Origin3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_gameboard_scale", "scale"), &T5Origin3D::set_gameboard_scale); // Properties. - ClassDB::add_property("T5Origin3D", PropertyInfo(Variant::FLOAT, "gameboard_scale"), "set_gameboard_scale", "get_gameboard_scale"); + ClassDB::add_property("T5Origin3D", PropertyInfo(Variant::FLOAT, "gameboard_scale"), "set_gameboard_scale", "get_gameboard_scale"); // Signals ADD_SIGNAL(MethodInfo("gameboard_scale_changed", PropertyInfo(Variant::FLOAT, "scale"))); } - real_t T5Origin3D::get_gameboard_scale() { - return _scale; + return _scale; } void T5Origin3D::set_gameboard_scale(real_t scale) { - _scale = scale; + _scale = scale; emit_signal("gameboard_scale_changed", _scale); } diff --git a/extension/src/T5Origin3D.h b/extension/src/T5Origin3D.h index 7ca2a30..807ef60 100644 --- a/extension/src/T5Origin3D.h +++ b/extension/src/T5Origin3D.h @@ -1,14 +1,14 @@ #ifndef T5_ORIGIN_3D_H #define T5_ORIGIN_3D_H -// -// The XR node hierarchy was duplicated because of the need +// +// The XR node hierarchy was duplicated because of the need // to set a tracker name for the Camera node. This was not // possible for XRCamera3D in Godot 4.1. This required creating // a custom T5Camera3D node. However since XROrigin3D requires an // XRCamera3D as a child this meant that it need to be replaced // too. This cascaded to the whole XR hierarchy because of // interdependencies. If the XRCamera3D nodes are fixed in the -// future it should be possible to depreciate this custom +// future it should be possible to depreciate this custom // T5 node hierarchy. // #include @@ -19,16 +19,14 @@ class T5Origin3D : public Node3D { GDCLASS(T5Origin3D, Node3D); public: - - real_t get_gameboard_scale(); - void set_gameboard_scale(real_t scale); + real_t get_gameboard_scale(); + void set_gameboard_scale(real_t scale); protected: static void _bind_methods(); private: - float _scale = 1.0; - + float _scale = 1.0; }; #endif // T5_ORIGIN_3D_H \ No newline at end of file diff --git a/extension/src/TiltFiveXRInterface.cpp b/extension/src/TiltFiveXRInterface.cpp index d9c590d..1be8611 100644 --- a/extension/src/TiltFiveXRInterface.cpp +++ b/extension/src/TiltFiveXRInterface.cpp @@ -1,8 +1,8 @@ #include "TiltFiveXRInterface.h" +#include +#include #include #include -#include -#include using namespace godot; using GodotT5Integration::GodotT5ObjectRegistry; @@ -64,7 +64,7 @@ String TiltFiveXRInterface::get_application_id() const { return application_id; } -void TiltFiveXRInterface::set_application_id(const String &p_string) { +void TiltFiveXRInterface::set_application_id(const String& p_string) { application_id = p_string; } @@ -72,7 +72,7 @@ String TiltFiveXRInterface::get_application_version() const { return application_version; } -void TiltFiveXRInterface::set_application_version(const String &p_string) { +void TiltFiveXRInterface::set_application_version(const String& p_string) { application_version = p_string; } @@ -83,16 +83,16 @@ float TiltFiveXRInterface::get_trigger_click_threshold() { void TiltFiveXRInterface::set_trigger_click_threshold(float threshold) { _trigger_click_threshold = threshold; - for(auto& entry : _glasses_index) { - if(!entry.glasses.expired()) { + for (auto& entry : _glasses_index) { + if (!entry.glasses.expired()) { entry.glasses.lock()->set_trigger_click_threshold(_trigger_click_threshold); } } } TiltFiveXRInterface::GlassesIndexEntry* TiltFiveXRInterface::lookup_glasses_entry(StringName glasses_id) { - for(auto& entry : _glasses_index) { - if(glasses_id == entry.id) { + for (auto& entry : _glasses_index) { + if (glasses_id == entry.id) { return &entry; } } @@ -102,11 +102,12 @@ TiltFiveXRInterface::GlassesIndexEntry* TiltFiveXRInterface::lookup_glasses_entr TiltFiveXRInterface::GlassesIndexEntry* TiltFiveXRInterface::lookup_glasses_by_render_target(RID test_render_target) { auto render_server = RenderingServer::get_singleton(); - for(auto& entry : _glasses_index) { + for (auto& entry : _glasses_index) { auto viewport = Object::cast_to(ObjectDB::get_instance(entry.viewport_id)); - if(!viewport) continue; + if (!viewport) + continue; auto glasses_render_target = render_server->viewport_get_render_target(viewport->get_viewport_rid()); - if(test_render_target == glasses_render_target) { + if (test_render_target == glasses_render_target) { return &entry; } } @@ -114,10 +115,11 @@ TiltFiveXRInterface::GlassesIndexEntry* TiltFiveXRInterface::lookup_glasses_by_r } TiltFiveXRInterface::GlassesIndexEntry* TiltFiveXRInterface::lookup_glasses_by_viewport(RID test_viewport) { - for(auto& entry : _glasses_index) { + for (auto& entry : _glasses_index) { auto viewport = Object::cast_to(ObjectDB::get_instance(entry.viewport_id)); - if(!viewport) continue; - if(test_viewport == viewport->get_viewport_rid()) { + if (!viewport) + continue; + if (test_viewport == viewport->get_viewport_rid()) { return &entry; } } @@ -140,10 +142,10 @@ bool TiltFiveXRInterface::_initialize() { t5_service = GodotT5ObjectRegistry::service(); ERR_FAIL_COND_V_MSG(!t5_service, false, "Couldn't obtain GodotT5Service singleton"); - RenderingServer *rendering_server = RenderingServer::get_singleton(); + RenderingServer* rendering_server = RenderingServer::get_singleton(); ERR_FAIL_NULL_V(rendering_server, false); - RenderingDevice *rendering_device = rendering_server->get_rendering_device(); - if(rendering_device){ + RenderingDevice* rendering_device = rendering_server->get_rendering_device(); + if (rendering_device) { t5_service->use_vulkan_api(); } else { t5_service->use_opengl_api(); @@ -161,7 +163,7 @@ bool TiltFiveXRInterface::_initialize() { void TiltFiveXRInterface::_uninitialize() { if (_initialised) { - if(t5_service->is_service_started()) { + if (t5_service->is_service_started()) { t5_service->stop_service(); } t5_service.reset(); @@ -176,7 +178,8 @@ void TiltFiveXRInterface::_uninitialize() { } void TiltFiveXRInterface::reserve_glasses(const StringName glasses_id, const String display_name) { - if(!t5_service) return; + if (!t5_service) + return; auto entry = lookup_glasses_entry(glasses_id); ERR_FAIL_COND_MSG(!entry, "Glasses id was not found"); @@ -186,7 +189,8 @@ void TiltFiveXRInterface::reserve_glasses(const StringName glasses_id, const Str } void TiltFiveXRInterface::start_display(const StringName glasses_id, Variant vobj, Variant oobj) { - if(!t5_service) return; + if (!t5_service) + return; auto entry = lookup_glasses_entry(glasses_id); ERR_FAIL_COND_MSG(!entry, "Glasses id was not found"); @@ -201,7 +205,7 @@ void TiltFiveXRInterface::start_display(const StringName glasses_id, Variant vob void TiltFiveXRInterface::_start_display(TiltFiveXRInterface::GlassesIndexEntry& entry, SubViewport* viewport, T5Origin3D* gameboard) { auto glasses = entry.glasses.lock(); - if(!glasses->is_reserved()) { + if (!glasses->is_reserved()) { WARN_PRINT("Glasses need to be reserved to display viewport"); return; } @@ -219,11 +223,10 @@ void TiltFiveXRInterface::stop_display(const StringName glasses_id) { _stop_display(*entry); } - void TiltFiveXRInterface::_stop_display(GlassesIndexEntry& entry) { auto glasses = entry.glasses.lock(); auto viewport = Object::cast_to(ObjectDB::get_instance(entry.viewport_id)); - if(viewport) { + if (viewport) { viewport->set_use_xr(false); viewport->set_update_mode(godot::SubViewport::UpdateMode::UPDATE_DISABLED); } @@ -233,7 +236,8 @@ void TiltFiveXRInterface::_stop_display(GlassesIndexEntry& entry) { } void TiltFiveXRInterface::release_glasses(const StringName glasses_id) { - if(!t5_service) return; + if (!t5_service) + return; auto entry = lookup_glasses_entry(glasses_id); ERR_FAIL_COND_MSG(!entry, "Glasses id was not found"); @@ -242,31 +246,34 @@ void TiltFiveXRInterface::release_glasses(const StringName glasses_id) { } PackedStringArray TiltFiveXRInterface::get_available_glasses_ids() { - if(!t5_service) return PackedStringArray(); - + if (!t5_service) + return PackedStringArray(); + PackedStringArray available_list; - for(int i = 0; i < t5_service->get_glasses_count(); i++) { + for (int i = 0; i < t5_service->get_glasses_count(); i++) { auto glasses = t5_service->get_glasses(i); - if(glasses->is_available()) + if (glasses->is_available()) available_list.append(glasses->get_id().c_str()); } return available_list; } PackedStringArray TiltFiveXRInterface::get_reserved_glasses_ids() { - if(!t5_service) return PackedStringArray(); - + if (!t5_service) + return PackedStringArray(); + PackedStringArray reserved_list; - for(int i = 0; i < t5_service->get_glasses_count(); i++) { + for (int i = 0; i < t5_service->get_glasses_count(); i++) { auto glasses = t5_service->get_glasses(i); - if(glasses->is_in_use()) + if (glasses->is_in_use()) reserved_list.append(glasses->get_id().c_str()); } return reserved_list; } TiltFiveXRInterface::GameBoardType TiltFiveXRInterface::get_gameboard_type(const StringName glasses_id) { - if(!t5_service) return NO_GAMEBOARD_SET; + if (!t5_service) + return NO_GAMEBOARD_SET; auto entry = lookup_glasses_entry(glasses_id); ERR_FAIL_COND_V_MSG(!entry, NO_GAMEBOARD_SET, "Glasses id was not found"); @@ -276,7 +283,8 @@ TiltFiveXRInterface::GameBoardType TiltFiveXRInterface::get_gameboard_type(const AABB TiltFiveXRInterface::get_gameboard_extents(GameBoardType gameboard_type) { AABB result; - if(!t5_service) return result; + if (!t5_service) + return result; T5_GameboardSize size; t5_service->get_gameboard_size(static_cast(gameboard_type), size); @@ -305,7 +313,7 @@ XRInterface::PlayAreaMode TiltFiveXRInterface::_get_play_area_mode() const { } XRInterface::TrackingStatus TiltFiveXRInterface::_get_tracking_status() const { - if(!_render_glasses) { + if (!_render_glasses) { WARN_PRINT_ONCE("Glasses not set"); return XRInterface::TrackingStatus::XR_NOT_TRACKING; } @@ -313,7 +321,7 @@ XRInterface::TrackingStatus TiltFiveXRInterface::_get_tracking_status() const { } Vector2 TiltFiveXRInterface::_get_render_target_size() { - if(!_render_glasses) { + if (!_render_glasses) { WARN_PRINT_ONCE("Glasses not set"); return Vector2(1216, 768); } @@ -330,7 +338,7 @@ Transform3D TiltFiveXRInterface::_get_camera_transform() { if (!_initialised) { return Transform3D(); } - if(!_render_glasses) { + if (!_render_glasses) { WARN_PRINT_ONCE("Glasses not set"); return Transform3D(); } @@ -345,13 +353,13 @@ Transform3D TiltFiveXRInterface::_get_camera_transform() { return hmd_transform; } -Transform3D TiltFiveXRInterface::_get_transform_for_view(uint32_t view, const Transform3D &origin_transform) { +Transform3D TiltFiveXRInterface::_get_transform_for_view(uint32_t view, const Transform3D& origin_transform) { ERR_FAIL_NULL_V_MSG(xr_server, Transform3D(), "XRServer unavailable"); if (!_initialised) { return Transform3D(); } - if(!_render_glasses) { + if (!_render_glasses) { WARN_PRINT_ONCE("Glasses not set"); return Transform3D(); } @@ -373,7 +381,7 @@ PackedFloat64Array TiltFiveXRInterface::_get_projection_for_view(uint32_t p_view if (!_initialised) { return arr; } - if(!_render_glasses) { + if (!_render_glasses) { WARN_PRINT_ONCE("Glasses not set"); return arr; } @@ -383,7 +391,7 @@ PackedFloat64Array TiltFiveXRInterface::_get_projection_for_view(uint32_t p_view return _render_glasses->get_projection_for_eye(p_view == 0 ? Eye::Left : Eye::Right, aspect, z_near * world_scale, z_far * world_scale); } -bool TiltFiveXRInterface::_pre_draw_viewport(const RID &render_target) { +bool TiltFiveXRInterface::_pre_draw_viewport(const RID& render_target) { ERR_FAIL_NULL_V_MSG(xr_server, false, "XRServer unavailable"); ERR_FAIL_COND_V_MSG(_render_glasses, false, "Rendering viewport already set"); auto entry = lookup_glasses_by_render_target(render_target); @@ -391,37 +399,37 @@ bool TiltFiveXRInterface::_pre_draw_viewport(const RID &render_target) { _render_glasses = entry->glasses.lock(); - if(!_render_glasses->is_reserved()) + if (!_render_glasses->is_reserved()) return false; auto gameboard = Object::cast_to(ObjectDB::get_instance(entry->gameboard_id)); - if(!gameboard) + if (!gameboard) return false; xr_server->set_world_origin(gameboard->get_global_transform()); xr_server->set_world_scale(gameboard->get_gameboard_scale()); - + entry->rendering = true; return true; } -void TiltFiveXRInterface::_post_draw_viewport(const RID &render_target, const Rect2 &screen_rect) { +void TiltFiveXRInterface::_post_draw_viewport(const RID& render_target, const Rect2& screen_rect) { _render_glasses->on_post_draw(); _render_glasses.reset(); } void TiltFiveXRInterface::_end_frame() { - for(auto& entry : _glasses_index) { - if(entry.rendering) { + for (auto& entry : _glasses_index) { + if (entry.rendering) { entry.glasses.lock()->send_frame(); entry.rendering = false; } - } + } } PackedStringArray TiltFiveXRInterface::_get_suggested_tracker_names() const { PackedStringArray tracker_names; - + tracker_names.append("glasses/tilt_five_wand_1"); tracker_names.append("glasses/tilt_five_wand_2"); tracker_names.append("glasses/tilt_five_wand_3"); @@ -430,9 +438,9 @@ PackedStringArray TiltFiveXRInterface::_get_suggested_tracker_names() const { return tracker_names; } -PackedStringArray TiltFiveXRInterface::_get_suggested_pose_names(const StringName &tracker_name) const { +PackedStringArray TiltFiveXRInterface::_get_suggested_pose_names(const StringName& tracker_name) const { PackedStringArray tracker_names; - + tracker_names.append("aim"); tracker_names.append("grip"); tracker_names.append("finger"); @@ -441,25 +449,25 @@ PackedStringArray TiltFiveXRInterface::_get_suggested_pose_names(const StringNam } void TiltFiveXRInterface::_process() { - if(!t5_service) return; + if (!t5_service) + return; t5_service->update_connection(); t5_service->update_tracking(); _service_events.clear(); t5_service->get_service_events(_service_events); - for(int i = 0; i < _service_events.size(); i++) { + for (int i = 0; i < _service_events.size(); i++) { emit_signal("service_event", _service_events[i].event); } _glasses_events.clear(); t5_service->get_glasses_events(_glasses_events); - for(int i = 0; i < _glasses_events.size(); i++) { + for (int i = 0; i < _glasses_events.size(); i++) { auto glasses_idx = _glasses_events[i].glasses_num; - switch (_glasses_events[i].event) - { + switch (_glasses_events[i].event) { case GlassesEvent::E_ADDED: { - if(_glasses_index.size() != glasses_idx) { + if (_glasses_index.size() != glasses_idx) { WARN_PRINT("Glasses index"); } _glasses_index.resize(glasses_idx + 1); @@ -474,14 +482,14 @@ void TiltFiveXRInterface::_process() { } break; case GlassesEvent::E_CONNECTED: { ++reserved_glasses_count; - if(reserved_glasses_count > 0 && !is_primary()) { + if (reserved_glasses_count > 0 && !is_primary()) { set_primary(true); } } break; case GlassesEvent::E_DISCONNECTED: { _stop_display(_glasses_index[glasses_idx]); --reserved_glasses_count; - if(reserved_glasses_count == 0 && is_primary()) { + if (reserved_glasses_count == 0 && is_primary()) { set_primary(false); } } break; @@ -489,8 +497,9 @@ void TiltFiveXRInterface::_process() { case GlassesEvent::E_UNAVAILABLE: { _stop_display(_glasses_index[glasses_idx]); } break; - - default: break; + + default: + break; } emit_signal("glasses_event", _glasses_index[_glasses_events[i].glasses_num].id, (int)_glasses_events[i].event); } @@ -498,10 +507,9 @@ void TiltFiveXRInterface::_process() { RID TiltFiveXRInterface::_get_color_texture() { ERR_FAIL_COND_V_MSG(!_render_glasses, RID(), "Glasses not set"); - return _render_glasses->get_color_texture(); + return _render_glasses->get_color_texture(); } - bool TiltFiveXRInterface::_get_anchor_detection_is_enabled() const { return false; } diff --git a/extension/src/TiltFiveXRInterface.h b/extension/src/TiltFiveXRInterface.h index cd680a0..0aefcf3 100644 --- a/extension/src/TiltFiveXRInterface.h +++ b/extension/src/TiltFiveXRInterface.h @@ -3,31 +3,31 @@ #include -#include -#include #include +#include +#include #include -#include #include +#include #include -using godot::XRInterfaceExtension; -using godot::XRServer; -using godot::String; -using godot::StringName; -using godot::Vector2; -using godot::Transform3D; +using godot::AABB; +using godot::ObjectID; using godot::PackedFloat64Array; +using godot::PackedStringArray; using godot::Rect2; using godot::RID; +using godot::String; +using godot::StringName; using godot::SubViewport; -using godot::PackedStringArray; -using godot::ObjectID; +using godot::Transform3D; using godot::Variant; -using godot::AABB; -using GodotT5Integration::GodotT5Service; +using godot::Vector2; +using godot::XRInterfaceExtension; +using godot::XRServer; using GodotT5Integration::GodotT5Glasses; +using GodotT5Integration::GodotT5Service; using T5Integration::GlassesEvent; using T5Integration::T5ServiceEvent; @@ -37,12 +37,14 @@ static constexpr uint8_t kSdkTypeCommunityGodot = 0x70; class TiltFiveXRInterface : public XRInterfaceExtension { GDCLASS(TiltFiveXRInterface, XRInterfaceExtension); + // clang-format off enum GameBoardType { - NO_GAMEBOARD_SET = kT5_GameboardType_None, - LE_GAMEBOARD = kT5_GameboardType_LE, - XE_GAMEBOARD = kT5_GameboardType_XE, + NO_GAMEBOARD_SET = kT5_GameboardType_None, + LE_GAMEBOARD = kT5_GameboardType_LE, + XE_GAMEBOARD = kT5_GameboardType_XE, XE_RAISED_GAMEBOARD = kT5_GameboardType_XE_Raised }; + // clang-format on struct GlassesIndexEntry { StringName id; @@ -56,26 +58,28 @@ class TiltFiveXRInterface : public XRInterfaceExtension { public: // Constants. + // clang-format off enum ServiceEventType { - E_SERVICE_STOPPED = T5ServiceEvent::E_STOPPED, - E_SERVICE_RUNNING = T5ServiceEvent::E_RUNNING, - E_SERVICE_T5_UNAVAILABLE = T5ServiceEvent::E_T5_UNAVAILABLE, + E_SERVICE_STOPPED = T5ServiceEvent::E_STOPPED, + E_SERVICE_RUNNING = T5ServiceEvent::E_RUNNING, + E_SERVICE_T5_UNAVAILABLE = T5ServiceEvent::E_T5_UNAVAILABLE, E_SERVICE_T5_INCOMPATIBLE_VERSION = T5ServiceEvent::E_T5_INCOMPATIBLE_VERSION }; - enum GlassesEventType - { - E_GLASSES_ADDED = GlassesEvent::E_ADDED, - E_GLASSES_LOST = GlassesEvent::E_LOST, - E_GLASSES_AVAILABLE = GlassesEvent::E_AVAILABLE, - E_GLASSES_UNAVAILABLE = GlassesEvent::E_UNAVAILABLE, - E_GLASSES_RESERVED = GlassesEvent::E_CONNECTED, - E_GLASSES_DROPPED = GlassesEvent::E_DISCONNECTED, - E_GLASSES_TRACKING = GlassesEvent::E_TRACKING, - E_GLASSES_NOT_TRACKING = GlassesEvent::E_NOT_TRACKING, - E_GLASSES_STOPPED_ON_ERROR = GlassesEvent::E_STOPPED_ON_ERROR - }; + enum GlassesEventType + { + E_GLASSES_ADDED = GlassesEvent::E_ADDED, + E_GLASSES_LOST = GlassesEvent::E_LOST, + E_GLASSES_AVAILABLE = GlassesEvent::E_AVAILABLE, + E_GLASSES_UNAVAILABLE = GlassesEvent::E_UNAVAILABLE, + E_GLASSES_RESERVED = GlassesEvent::E_CONNECTED, + E_GLASSES_DROPPED = GlassesEvent::E_DISCONNECTED, + E_GLASSES_TRACKING = GlassesEvent::E_TRACKING, + E_GLASSES_NOT_TRACKING = GlassesEvent::E_NOT_TRACKING, + E_GLASSES_STOPPED_ON_ERROR = GlassesEvent::E_STOPPED_ON_ERROR + }; + // clang-format on // Property setters and getters. @@ -95,7 +99,7 @@ class TiltFiveXRInterface : public XRInterfaceExtension { void stop_display(const StringName glasses_id); void release_glasses(const StringName glasses_id); - GameBoardType get_gameboard_type(const StringName glasses_id); + GameBoardType get_gameboard_type(const StringName glasses_id); AABB get_gameboard_extents(GameBoardType gameboard_type); PackedStringArray get_available_glasses_ids(); @@ -119,9 +123,9 @@ class TiltFiveXRInterface : public XRInterfaceExtension { virtual Transform3D _get_camera_transform() override; virtual Transform3D _get_transform_for_view(uint32_t view, const Transform3D &cam_transform) override; virtual PackedFloat64Array _get_projection_for_view(uint32_t view, double aspect, double z_near, double z_far) override; - + virtual bool _pre_draw_viewport(const RID &render_target); - virtual void _post_draw_viewport(const RID &render_target, const Rect2 &screen_rect) override; + virtual void _post_draw_viewport(const RID &render_target, const Rect2 &screen_rect) override; virtual void _end_frame() override; virtual PackedStringArray _get_suggested_tracker_names() const override; @@ -130,7 +134,7 @@ class TiltFiveXRInterface : public XRInterfaceExtension { virtual void _process() override; virtual RID _get_color_texture() override; - + virtual bool _get_anchor_detection_is_enabled() const override; virtual void _set_anchor_detection_is_enabled(bool enabled) override; virtual int32_t _get_camera_feed_id() const override; @@ -140,17 +144,15 @@ class TiltFiveXRInterface : public XRInterfaceExtension { protected: static void _bind_methods(); - - void _start_display(GlassesIndexEntry& entry, SubViewport* viewport, T5Origin3D* xr_origin); - void _stop_display(GlassesIndexEntry& entry); - GlassesIndexEntry* lookup_glasses_entry(StringName glasses_id); - GlassesIndexEntry* lookup_glasses_by_render_target(RID render_target); - GlassesIndexEntry* lookup_glasses_by_viewport(RID render_target); + void _start_display(GlassesIndexEntry &entry, SubViewport *viewport, T5Origin3D *xr_origin); + void _stop_display(GlassesIndexEntry &entry); + GlassesIndexEntry *lookup_glasses_entry(StringName glasses_id); + GlassesIndexEntry *lookup_glasses_by_render_target(RID render_target); + GlassesIndexEntry *lookup_glasses_by_viewport(RID render_target); private: - bool _initialised = false; XRServer *xr_server = nullptr; @@ -162,11 +164,11 @@ class TiltFiveXRInterface : public XRInterfaceExtension { std::vector _glasses_events; std::vector _service_events; - GodotT5Service::Ptr t5_service; + GodotT5Service::Ptr t5_service; GodotT5Glasses::Ptr _render_glasses; - int reserved_glasses_count = 0; + int reserved_glasses_count = 0; }; VARIANT_ENUM_CAST(TiltFiveXRInterface::GameBoardType) diff --git a/extension/src/VulkanGlasses.cpp b/extension/src/VulkanGlasses.cpp index 3411bf1..fe5df89 100644 --- a/extension/src/VulkanGlasses.cpp +++ b/extension/src/VulkanGlasses.cpp @@ -1,76 +1,75 @@ +#include #include -#include -#include +#include #include #include +#include +#include #include -#include -#include -#include +#include - -using godot::RenderingServer; -using godot::RenderingDevice; using godot::RDTextureFormat; using godot::RDTextureView; +using godot::RenderingDevice; +using godot::RenderingServer; using godot::Vector3; namespace GodotT5Integration { -VulkanGlasses::VulkanGlasses(std::string_view id) -: GodotT5Glasses(id) { - _swap_chain_textures.resize(g_swap_chain_length); +VulkanGlasses::VulkanGlasses(std::string_view id) : + GodotT5Glasses(id) { + _swap_chain_textures.resize(g_swap_chain_length); } void VulkanGlasses::SwapChainTextures::allocate_textures(int width, int height) { - if(is_allocated) - deallocate_textures(); - - auto render_server = RenderingServer::get_singleton(); - auto render_device = render_server->get_rendering_device(); - - Ref texture_format_render; - texture_format_render.instantiate(); - - texture_format_render->set_texture_type(RenderingDevice::TextureType::TEXTURE_TYPE_2D_ARRAY); - texture_format_render->set_format(RenderingDevice::DataFormat::DATA_FORMAT_R8G8B8A8_UNORM); - texture_format_render->set_width(width); - texture_format_render->set_height(height); - texture_format_render->set_depth(1); - texture_format_render->set_array_layers(2); - texture_format_render->set_mipmaps(1); - texture_format_render->set_samples(RenderingDevice::TextureSamples::TEXTURE_SAMPLES_1); - texture_format_render->set_usage_bits(RenderingDevice::TEXTURE_USAGE_SAMPLING_BIT | RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RenderingDevice::TEXTURE_USAGE_CAN_COPY_FROM_BIT); + if (is_allocated) + deallocate_textures(); + + auto render_server = RenderingServer::get_singleton(); + auto render_device = render_server->get_rendering_device(); + + Ref texture_format_render; + texture_format_render.instantiate(); + + texture_format_render->set_texture_type(RenderingDevice::TextureType::TEXTURE_TYPE_2D_ARRAY); + texture_format_render->set_format(RenderingDevice::DataFormat::DATA_FORMAT_R8G8B8A8_UNORM); + texture_format_render->set_width(width); + texture_format_render->set_height(height); + texture_format_render->set_depth(1); + texture_format_render->set_array_layers(2); + texture_format_render->set_mipmaps(1); + texture_format_render->set_samples(RenderingDevice::TextureSamples::TEXTURE_SAMPLES_1); + texture_format_render->set_usage_bits(RenderingDevice::TEXTURE_USAGE_SAMPLING_BIT | RenderingDevice::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RenderingDevice::TEXTURE_USAGE_CAN_COPY_FROM_BIT); texture_format_render->add_shareable_format(RenderingDevice::DataFormat::DATA_FORMAT_R8G8B8A8_UNORM); texture_format_render->add_shareable_format(RenderingDevice::DataFormat::DATA_FORMAT_R8G8B8A8_SRGB); - Ref texture_view; - texture_view.instantiate(); - - render_tex = render_device->texture_create(texture_format_render, texture_view); + Ref texture_view; + texture_view.instantiate(); + + render_tex = render_device->texture_create(texture_format_render, texture_view); - left_eye_tex = render_device->texture_create_shared_from_slice(texture_view, render_tex, 0, 0); - right_eye_tex = render_device->texture_create_shared_from_slice(texture_view, render_tex, 1, 0); + left_eye_tex = render_device->texture_create_shared_from_slice(texture_view, render_tex, 0, 0); + right_eye_tex = render_device->texture_create_shared_from_slice(texture_view, render_tex, 1, 0); - left_tex_handle = render_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_IMAGE_VIEW, left_eye_tex, 0); - right_tex_handle = render_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_IMAGE_VIEW, right_eye_tex, 0); + left_tex_handle = render_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_IMAGE_VIEW, left_eye_tex, 0); + right_tex_handle = render_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_IMAGE_VIEW, right_eye_tex, 0); is_allocated = true; } void VulkanGlasses::SwapChainTextures::deallocate_textures() { - if(!is_allocated) + if (!is_allocated) return; - auto render_server = RenderingServer::get_singleton(); - auto render_device = render_server->get_rendering_device(); + auto render_server = RenderingServer::get_singleton(); + auto render_device = render_server->get_rendering_device(); - if(right_eye_tex.is_valid()) - render_device->free_rid(right_eye_tex); - if(left_eye_tex.is_valid()) - render_device->free_rid(left_eye_tex); - if(render_tex.is_valid()) - render_device->free_rid(render_tex); + if (right_eye_tex.is_valid()) + render_device->free_rid(right_eye_tex); + if (left_eye_tex.is_valid()) + render_device->free_rid(left_eye_tex); + if (render_tex.is_valid()) + render_device->free_rid(render_tex); left_tex_handle = 0; right_tex_handle = 0; @@ -79,42 +78,41 @@ void VulkanGlasses::SwapChainTextures::deallocate_textures() { } void VulkanGlasses::allocate_textures() { - auto render_server = RenderingServer::get_singleton(); - auto render_device = render_server->get_rendering_device(); - - int width, height; - Glasses::get_display_size(width, height); - for(int i = 0; i < _swap_chain_textures.size(); i++) { - _swap_chain_textures[i].allocate_textures(width, height); - set_swap_chain_texture_pair( - i, - reinterpret_cast(&_swap_chain_textures[i].left_tex_handle), - reinterpret_cast(&_swap_chain_textures[i].right_tex_handle)); - } - - set_upside_down_texture(true); + auto render_server = RenderingServer::get_singleton(); + auto render_device = render_server->get_rendering_device(); + + int width, height; + Glasses::get_display_size(width, height); + for (int i = 0; i < _swap_chain_textures.size(); i++) { + _swap_chain_textures[i].allocate_textures(width, height); + set_swap_chain_texture_pair( + i, + reinterpret_cast(&_swap_chain_textures[i].left_tex_handle), + reinterpret_cast(&_swap_chain_textures[i].right_tex_handle)); + } + + set_upside_down_texture(true); } void VulkanGlasses::deallocate_textures() { - auto render_server = RenderingServer::get_singleton(); + auto render_server = RenderingServer::get_singleton(); - for(int i = 0; i < _swap_chain_textures.size(); i++) { - _swap_chain_textures[i].deallocate_textures(); - set_swap_chain_texture_pair(i, 0, 0); - } + for (int i = 0; i < _swap_chain_textures.size(); i++) { + _swap_chain_textures[i].deallocate_textures(); + set_swap_chain_texture_pair(i, 0, 0); + } } void VulkanGlasses::on_start_display() { - allocate_textures(); + allocate_textures(); } -void VulkanGlasses::on_stop_display() { - deallocate_textures(); +void VulkanGlasses::on_stop_display() { + deallocate_textures(); } - -RID VulkanGlasses::get_color_texture() -{ - int current_frame = get_current_frame_idx(); - return _swap_chain_textures[current_frame].render_tex; + +RID VulkanGlasses::get_color_texture() { + int current_frame = get_current_frame_idx(); + return _swap_chain_textures[current_frame].render_tex; } -} // GodotT5Integration \ No newline at end of file +} //namespace GodotT5Integration \ No newline at end of file diff --git a/extension/src/VulkanGlasses.h b/extension/src/VulkanGlasses.h index f74f2c2..5fbce04 100644 --- a/extension/src/VulkanGlasses.h +++ b/extension/src/VulkanGlasses.h @@ -6,37 +6,33 @@ using godot::RID; namespace GodotT5Integration { - class VulkanGlasses : public GodotT5Glasses { +class VulkanGlasses : public GodotT5Glasses { + struct SwapChainTextures { + void allocate_textures(int width, int height); + void deallocate_textures(); - struct SwapChainTextures { - void allocate_textures(int width, int height); - void deallocate_textures(); + bool is_allocated = false; + RID render_tex; + RID left_eye_tex; + RID right_eye_tex; - bool is_allocated = false; - RID render_tex; - RID left_eye_tex; - RID right_eye_tex; + intptr_t left_tex_handle; + intptr_t right_tex_handle; + }; - intptr_t left_tex_handle; - intptr_t right_tex_handle; - }; +public: + VulkanGlasses(std::string_view id); - public: + virtual RID get_color_texture() override; - VulkanGlasses(std::string_view id); - - virtual RID get_color_texture() override; +private: + void allocate_textures(); + void deallocate_textures(); - private: + virtual void on_start_display() override; + virtual void on_stop_display() override; - void allocate_textures(); - void deallocate_textures(); - - virtual void on_start_display() override; - virtual void on_stop_display() override; - - private: - - std::vector _swap_chain_textures; - }; -} +private: + std::vector _swap_chain_textures; +}; +} //namespace GodotT5Integration diff --git a/extension/src/register_types.cpp b/extension/src/register_types.cpp index b144529..28bc9d8 100644 --- a/extension/src/register_types.cpp +++ b/extension/src/register_types.cpp @@ -1,19 +1,18 @@ -#include -#include -#include #include #include #include +#include +#include #include +#include +#include #include #include #include -#include using namespace godot; -void initialize_tiltfive_types(ModuleInitializationLevel p_level) -{ +void initialize_tiltfive_types(ModuleInitializationLevel p_level) { if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; } @@ -23,8 +22,6 @@ void initialize_tiltfive_types(ModuleInitializationLevel p_level) ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); - - } void uninitialize_tiltfive_types(ModuleInitializationLevel p_level) { @@ -33,19 +30,17 @@ void uninitialize_tiltfive_types(ModuleInitializationLevel p_level) { } } -extern "C" -{ +extern "C" { - // Initialization. +// Initialization. - GDExtensionBool GDE_EXPORT tiltfive_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) - { - godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization); +GDExtensionBool GDE_EXPORT tiltfive_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) { + godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization); - init_obj.register_initializer(initialize_tiltfive_types); - init_obj.register_terminator(uninitialize_tiltfive_types); - init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE); + init_obj.register_initializer(initialize_tiltfive_types); + init_obj.register_terminator(uninitialize_tiltfive_types); + init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE); - return init_obj.init(); - } + return init_obj.init(); +} }