From c71039c152bd63fe055916f74cd60bb1f04c0902 Mon Sep 17 00:00:00 2001 From: Bill Doyle Date: Wed, 10 Jul 2024 08:09:46 -0400 Subject: [PATCH 1/5] Allow reconfiguring action manifest at runtime As long as a game doesn't have an action manifest configured in the Steamworks publisher UI, it is free to call SetActionManifestPath as many times as it wants. --- src/xr_interface_openvr.cpp | 18 ++++++++++++++++++ src/xr_interface_openvr.h | 1 + 2 files changed, 19 insertions(+) diff --git a/src/xr_interface_openvr.cpp b/src/xr_interface_openvr.cpp index d69b61a..33577cf 100644 --- a/src/xr_interface_openvr.cpp +++ b/src/xr_interface_openvr.cpp @@ -24,6 +24,7 @@ void XRInterfaceOpenVR::_bind_methods() { ClassDB::bind_method(D_METHOD("set_default_action_set"), &XRInterfaceOpenVR::set_default_action_set); ADD_PROPERTY(PropertyInfo(Variant::STRING, "default_action_set"), "set_default_action_set", "get_default_action_set"); + ClassDB::bind_method(D_METHOD("set_action_manifest_path"), &XRInterfaceOpenVR::set_action_manifest_path); ClassDB::bind_method(D_METHOD("register_action_set"), &XRInterfaceOpenVR::register_action_set); ClassDB::bind_method(D_METHOD("set_active_action_set"), &XRInterfaceOpenVR::set_active_action_set); ClassDB::bind_method(D_METHOD("toggle_action_set_active"), &XRInterfaceOpenVR::toggle_action_set_active); @@ -63,6 +64,23 @@ void XRInterfaceOpenVR::set_tracking_universe(int p_universe) { } } +bool XRInterfaceOpenVR::set_action_manifest_path(const String p_path) { + if (ovr == nullptr) { + return false; + } + + vr::EVRInputError error = vr::VRInput()->SetActionManifestPath(p_path.utf8().get_data()); + + if (error != vr::VRInputError_None) { + Array arr; + arr.push_back(error); + UtilityFunctions::print(String("Could not set action manifest, OpenVR error: {0}").format(arr)); + return false; + } + + return true; +} + String XRInterfaceOpenVR::get_default_action_set() const { if (ovr == nullptr) { return String(); diff --git a/src/xr_interface_openvr.h b/src/xr_interface_openvr.h index e389a1d..012a380 100644 --- a/src/xr_interface_openvr.h +++ b/src/xr_interface_openvr.h @@ -37,6 +37,7 @@ class XRInterfaceOpenVR : public XRInterfaceExtension { String get_default_action_set() const; void set_default_action_set(const String p_name); + bool set_action_manifest_path(const String p_path); void register_action_set(const String p_action_set); void set_active_action_set(const String p_action_set); void toggle_action_set_active(const String p_action_set, const bool p_is_active); From fd448e8952306d50078afd8bbccdaabacbe5da9e Mon Sep 17 00:00:00 2001 From: Bill Doyle Date: Tue, 23 Jul 2024 09:53:56 -0400 Subject: [PATCH 2/5] Defer setting up actions until a manifest is set These are still the same hardcoded inputs, reading the manifest is a separate problem. --- src/open_vr/openvr_data.cpp | 172 +++++++++++++++++++----------------- src/open_vr/openvr_data.h | 1 + src/xr_interface_openvr.cpp | 11 +-- 3 files changed, 91 insertions(+), 93 deletions(-) diff --git a/src/open_vr/openvr_data.cpp b/src/open_vr/openvr_data.cpp index 7d9c3ed..9ed99b0 100644 --- a/src/open_vr/openvr_data.cpp +++ b/src/open_vr/openvr_data.cpp @@ -30,32 +30,10 @@ openvr_data::openvr_data() { play_area[i].z = 0.0f; } - // setting up our action set data - // TODO we should find a way to read this from our json - + // TODO: need to initialize the first action set because it's accessed instantly by the editor as a property. int default_action_set = register_action_set(String("/actions/godot")); action_sets[default_action_set].is_active = true; active_action_set_count = 1; - - // Our default actions, we should be loading this from our action json - - // TODO rename actions so this is 1:1 - add_input_action("primary", "primary", IT_VECTOR2); - add_input_action("secondary", "secondary", IT_VECTOR2); - add_input_action("trigger_value", "analog_trigger", IT_FLOAT); - add_input_action("grip_value", "analog_grip", IT_FLOAT); - - add_input_action("primary_click", "primary_click", IT_BOOL); - add_input_action("secondary_click", "secondary_click", IT_BOOL); - add_input_action("trigger_click", "trigger", IT_BOOL); - add_input_action("grip_click", "grip", IT_BOOL); - add_input_action("ax", "button_ax", IT_BOOL); - add_input_action("by", "button_by", IT_BOOL); - // add_input_action("menu", "???", IT_BOOL); - - // here we remove the _pose or we'll overlap action names but we don't want the _pose in Godot - add_pose_action("aim", "aim_pose"); - add_pose_action("grip", "grip_pose"); } openvr_data::~openvr_data() { @@ -251,6 +229,7 @@ bool openvr_data::initialise() { } } + // If we found an action manifest, use it. If not, move on and assume one will be set later. if (manifest_path.length() != 0) { String absolute_path; if (os->has_feature("editor")) { @@ -259,67 +238,8 @@ bool openvr_data::initialise() { absolute_path = exec_path.path_join(manifest_path); } - vr::EVRInputError err = vr::VRInput()->SetActionManifestPath(absolute_path.utf8().get_data()); - if (err == vr::VRInputError_None) { - Array arr; - arr.push_back(manifest_path); - UtilityFunctions::print(String("Loaded action json from: {0}").format(arr)); - } else { + if (!set_action_manifest_path(absolute_path)) { success = false; - Array arr; - arr.push_back(manifest_path); - UtilityFunctions::print(String("Failed to load action json from: {0}").format(arr)); - } - } else { - success = false; - UtilityFunctions::print(godot::String("Failed to find action file")); - } - } - - if (success) { - // TODO: Contemplate whether we should parse the JSON ourselves so we know what actions and action sets are available... - // we can then get action handles for all of them automatically. - - for (std::vector::iterator it = action_sets.begin(); it != action_sets.end(); ++it) { - vr::EVRInputError err = vr::VRInput()->GetActionSetHandle((const char *)it->name.utf8().get_data(), &it->handle); - if (err != vr::VRInputError_None) { - Array arr; - arr.push_back(String(it->name)); - UtilityFunctions::print(String("Failed to obtain action set handle for {0}").format(arr)); - } - } - - for (auto &input : inputs) { - // setup handle - char action_path[1024]; - // TODO at some point support additional action sets - sprintf(action_path, "%s/in/%s", (const char *)action_sets[0].name.utf8().get_data(), input.path); - - vr::EVRInputError err = vr::VRInput()->GetActionHandle(action_path, &input.handle); - if (err != vr::VRInputError_None) { - // maybe output something? - input.handle = vr::k_ulInvalidActionHandle; - - Array arr; - arr.push_back(String(action_path)); - UtilityFunctions::print(String("Failed to obtain action handle for {0}").format(arr)); - } - } - - for (auto &pose : poses) { - // setup handle - char action_path[1024]; - // TODO at some point support additional action sets - sprintf(action_path, "%s/in/%s", (const char *)action_sets[0].name.utf8().get_data(), pose.path); - - vr::EVRInputError err = vr::VRInput()->GetActionHandle(action_path, &pose.handle); - if (err != vr::VRInputError_None) { - // maybe output something? - pose.handle = vr::k_ulInvalidActionHandle; - - Array arr; - arr.push_back(String(action_path)); - UtilityFunctions::print(String("Failed to obtain action handle for {0}").format(arr)); } } } @@ -1022,6 +942,92 @@ void openvr_data::process_device_actions(tracked_device *p_device, uint64_t p_ms } } +bool openvr_data::set_action_manifest_path(const String p_path) { + if (hmd == nullptr) { + return false; + } + + vr::EVRInputError error = vr::VRInput()->SetActionManifestPath(p_path.utf8().get_data()); + + if (error != vr::VRInputError_None) { + Array arr; + arr.push_back(p_path); + arr.push_back(error); + UtilityFunctions::print(String("Could not set action manifest to {0}, OpenVR error: {1}").format(arr)); + return false; + } + + // Set up default action set. + // TODO: Replace this with parsing the manifest. + + int default_action_set = register_action_set(String("/actions/godot")); + action_sets[default_action_set].is_active = true; + active_action_set_count = 1; + + // TODO rename actions so this is 1:1 + add_input_action("primary", "primary", IT_VECTOR2); + add_input_action("secondary", "secondary", IT_VECTOR2); + add_input_action("trigger_value", "analog_trigger", IT_FLOAT); + add_input_action("grip_value", "analog_grip", IT_FLOAT); + + add_input_action("primary_click", "primary_click", IT_BOOL); + add_input_action("secondary_click", "secondary_click", IT_BOOL); + add_input_action("trigger_click", "trigger", IT_BOOL); + add_input_action("grip_click", "grip", IT_BOOL); + add_input_action("ax", "button_ax", IT_BOOL); + add_input_action("by", "button_by", IT_BOOL); + // add_input_action("menu", "???", IT_BOOL); + + // here we remove the _pose or we'll overlap action names but we don't want the _pose in Godot + add_pose_action("aim", "aim_pose"); + add_pose_action("grip", "grip_pose"); + + for (std::vector::iterator it = action_sets.begin(); it != action_sets.end(); ++it) { + vr::EVRInputError err = vr::VRInput()->GetActionSetHandle((const char *)it->name.utf8().get_data(), &it->handle); + if (err != vr::VRInputError_None) { + Array arr; + arr.push_back(String(it->name)); + UtilityFunctions::print(String("Failed to obtain action set handle for {0}").format(arr)); + } + } + + for (auto &input : inputs) { + // setup handle + char action_path[1024]; + // TODO at some point support additional action sets + sprintf(action_path, "%s/in/%s", (const char *)action_sets[0].name.utf8().get_data(), input.path); + + vr::EVRInputError err = vr::VRInput()->GetActionHandle(action_path, &input.handle); + if (err != vr::VRInputError_None) { + // maybe output something? + input.handle = vr::k_ulInvalidActionHandle; + + Array arr; + arr.push_back(String(action_path)); + UtilityFunctions::print(String("Failed to obtain action handle for {0}").format(arr)); + } + } + + for (auto &pose : poses) { + // setup handle + char action_path[1024]; + // TODO at some point support additional action sets + sprintf(action_path, "%s/in/%s", (const char *)action_sets[0].name.utf8().get_data(), pose.path); + + vr::EVRInputError err = vr::VRInput()->GetActionHandle(action_path, &pose.handle); + if (err != vr::VRInputError_None) { + // maybe output something? + pose.handle = vr::k_ulInvalidActionHandle; + + Array arr; + arr.push_back(String(action_path)); + UtilityFunctions::print(String("Failed to obtain action handle for {0}").format(arr)); + } + } + + return true; +} + //////////////////////////////////////////////////////////////// // Get the name of our default action set String openvr_data::get_default_action_set() const { diff --git a/src/open_vr/openvr_data.h b/src/open_vr/openvr_data.h index bba549f..5e05101 100644 --- a/src/open_vr/openvr_data.h +++ b/src/open_vr/openvr_data.h @@ -208,6 +208,7 @@ class openvr_data { //////////////////////////////////////////////////////////////// // action set + bool set_action_manifest_path(const godot::String p_path); godot::String get_default_action_set() const; void set_default_action_set(const godot::String p_name); int register_action_set(const godot::String p_action_set); diff --git a/src/xr_interface_openvr.cpp b/src/xr_interface_openvr.cpp index 33577cf..5da00b6 100644 --- a/src/xr_interface_openvr.cpp +++ b/src/xr_interface_openvr.cpp @@ -69,16 +69,7 @@ bool XRInterfaceOpenVR::set_action_manifest_path(const String p_path) { return false; } - vr::EVRInputError error = vr::VRInput()->SetActionManifestPath(p_path.utf8().get_data()); - - if (error != vr::VRInputError_None) { - Array arr; - arr.push_back(error); - UtilityFunctions::print(String("Could not set action manifest, OpenVR error: {0}").format(arr)); - return false; - } - - return true; + return ovr->set_action_manifest_path(p_path); } String XRInterfaceOpenVR::get_default_action_set() const { From 28cd647df8db5806c9a2a6e6f021aad6a06d43de Mon Sep 17 00:00:00 2001 From: Bill Doyle Date: Tue, 23 Jul 2024 12:58:05 -0400 Subject: [PATCH 3/5] Parse manifest json to set up actions and sets Not complete, still only actually getting handles for the default action set. --- demo/addons/godot-openvr/actions/actions.json | 16 ++-- src/open_vr/openvr_data.cpp | 73 ++++++++++++------- 2 files changed, 56 insertions(+), 33 deletions(-) diff --git a/demo/addons/godot-openvr/actions/actions.json b/demo/addons/godot-openvr/actions/actions.json index 091b837..6bdb202 100644 --- a/demo/addons/godot-openvr/actions/actions.json +++ b/demo/addons/godot-openvr/actions/actions.json @@ -7,32 +7,32 @@ ], "actions" : [ { - "name": "/actions/godot/in/aim_pose", + "name": "/actions/godot/in/aim", "requirement" : "mandatory", "type": "pose" }, { - "name": "/actions/godot/in/grip_pose", + "name": "/actions/godot/in/grip", "requirement" : "mandatory", "type": "pose" }, { - "name" : "/actions/godot/in/trigger", + "name" : "/actions/godot/in/trigger_click", "requirement" : "mandatory", "type" : "boolean" }, { - "name" : "/actions/godot/in/analog_trigger", + "name" : "/actions/godot/in/trigger_value", "requirement" : "suggested", "type" : "vector1" }, { - "name" : "/actions/godot/in/grip", + "name" : "/actions/godot/in/grip_click", "requirement" : "suggested", "type" : "boolean" }, { - "name" : "/actions/godot/in/analog_grip", + "name" : "/actions/godot/in/grip_value", "requirement" : "suggested", "type" : "vector1" }, @@ -57,12 +57,12 @@ "type" : "boolean" }, { - "name" : "/actions/godot/in/button_ax", + "name" : "/actions/godot/in/ax", "requirement" : "optional", "type" : "boolean" }, { - "name" : "/actions/godot/in/button_by", + "name" : "/actions/godot/in/by", "requirement" : "optional", "type" : "boolean" }, diff --git a/src/open_vr/openvr_data.cpp b/src/open_vr/openvr_data.cpp index 9ed99b0..ec91f7d 100644 --- a/src/open_vr/openvr_data.cpp +++ b/src/open_vr/openvr_data.cpp @@ -3,8 +3,10 @@ #include "openvr_data.h" -#include "godot_cpp/classes/time.hpp" -#include "godot_cpp/classes/xr_server.hpp" +#include +#include +#include +#include #include #include @@ -947,6 +949,28 @@ bool openvr_data::set_action_manifest_path(const String p_path) { return false; } + Error err; + String manifest_data = FileAccess::get_file_as_string(p_path); + if (manifest_data.is_empty()) { + Array arr; + err = FileAccess::get_open_error(); + arr.push_back(err); + UtilityFunctions::print(String("Could not read action manifest: {0}").format(arr)); + return false; + } + + JSON json; + err = json.parse(manifest_data); + if (err != OK) { + Array arr; + arr.push_back(err); + UtilityFunctions::print(String("Could not parse action manifest: {0}").format(arr)); + return false; + } + Dictionary manifest = json.get_data(); + Array manifest_action_sets = manifest.get("action_set", Array()); + Array manifest_actions = manifest.get("actions", Array()); + vr::EVRInputError error = vr::VRInput()->SetActionManifestPath(p_path.utf8().get_data()); if (error != vr::VRInputError_None) { @@ -957,30 +981,29 @@ bool openvr_data::set_action_manifest_path(const String p_path) { return false; } - // Set up default action set. - // TODO: Replace this with parsing the manifest. - - int default_action_set = register_action_set(String("/actions/godot")); - action_sets[default_action_set].is_active = true; - active_action_set_count = 1; + for (int i = 0; i < manifest_actions.size(); i++) { + String name = manifest_actions[i].get("name"); + String type = manifest_actions[i].get("type"); + + if (type == "boolean") { + add_input_action(name.utf8().get_data(), name.utf8().get_data(), IT_BOOL); + } else if (type == "vector1") { + add_input_action(name.utf8().get_data(), name.utf8().get_data(), IT_FLOAT); + } else if (type == "vector2") { + add_input_action(name.utf8().get_data(), name.utf8().get_data(), IT_VECTOR2); + } else if (type == "pose") { + add_pose_action(name.utf8().get_data(), name.utf8().get_data()); + } else if (type == "skeleton") { + continue; // TODO: Not handled. + } else if (type == "vibration") { + continue; // TODO: Currently these are picked up on the fly when trigger_haptic_pulse is called. + } + } - // TODO rename actions so this is 1:1 - add_input_action("primary", "primary", IT_VECTOR2); - add_input_action("secondary", "secondary", IT_VECTOR2); - add_input_action("trigger_value", "analog_trigger", IT_FLOAT); - add_input_action("grip_value", "analog_grip", IT_FLOAT); - - add_input_action("primary_click", "primary_click", IT_BOOL); - add_input_action("secondary_click", "secondary_click", IT_BOOL); - add_input_action("trigger_click", "trigger", IT_BOOL); - add_input_action("grip_click", "grip", IT_BOOL); - add_input_action("ax", "button_ax", IT_BOOL); - add_input_action("by", "button_by", IT_BOOL); - // add_input_action("menu", "???", IT_BOOL); - - // here we remove the _pose or we'll overlap action names but we don't want the _pose in Godot - add_pose_action("aim", "aim_pose"); - add_pose_action("grip", "grip_pose"); + for (int i = 0; i < manifest_action_sets.size(); i++) { + String name = manifest_action_sets[i].get("name"); + register_action_set(name); + } for (std::vector::iterator it = action_sets.begin(); it != action_sets.end(); ++it) { vr::EVRInputError err = vr::VRInput()->GetActionSetHandle((const char *)it->name.utf8().get_data(), &it->handle); From 5824888737ca04ae22caded196f927559d69d4da Mon Sep 17 00:00:00 2001 From: Bill Doyle Date: Tue, 23 Jul 2024 13:55:50 -0400 Subject: [PATCH 4/5] Move handle aquisition to where actions/sets are registered --- src/open_vr/openvr_data.cpp | 114 +++++++++++++++++------------------- 1 file changed, 53 insertions(+), 61 deletions(-) diff --git a/src/open_vr/openvr_data.cpp b/src/open_vr/openvr_data.cpp index ec91f7d..cfd3103 100644 --- a/src/open_vr/openvr_data.cpp +++ b/src/open_vr/openvr_data.cpp @@ -573,27 +573,34 @@ void openvr_data::pre_render_update() { // Note that we can't remove action sets once added so our index // shouldn't change int openvr_data::register_action_set(const String p_action_set) { - for (int i = 0; i < action_sets.size(); i++) { - if (action_sets[i].name == p_action_set) { - return i; + int set_index; + + for (set_index = 0; set_index < action_sets.size(); set_index++) { + if (action_sets[set_index].name == p_action_set) { + break; } } - action_set new_action_set; - new_action_set.name = p_action_set; - new_action_set.handle = vr::k_ulInvalidActionSetHandle; - new_action_set.is_active = false; + // If we didn't find the set, initialize a new one. + if (set_index == action_sets.size()) { + action_set set; + set.name = p_action_set; + set.handle = vr::k_ulInvalidActionSetHandle; + set.is_active = false; + action_sets.push_back(set); + } - if (is_initialised()) { - vr::EVRInputError err = vr::VRInput()->GetActionSetHandle((const char *)new_action_set.name.utf8().get_data(), &new_action_set.handle); + action_set *set = &action_sets[set_index]; + + // Whether it already existed or not, we may need to get a handle for it. The default set is created before we have a runtime connection. + if (set->handle == vr::k_ulInvalidActionSetHandle && is_initialised()) { + vr::EVRInputError err = vr::VRInput()->GetActionSetHandle((const char *)set->name.utf8().get_data(), &set->handle); if (err != vr::VRInputError_None) { - UtilityFunctions::print(String("Failed to obtain action set handle for ") + new_action_set.name); + UtilityFunctions::print(String("Failed to obtain action set handle for ") + set->name); } } - action_sets.push_back(new_action_set); - - return (int)action_sets.size() - 1; + return set_index; } //////////////////////////////////////////////////////////////// @@ -649,6 +656,11 @@ bool openvr_data::is_action_set_active(const String p_action_set) const { } void openvr_data::add_input_action(const char *p_action, const char *p_path, const InputType p_type) { + if (!is_initialised()) { + UtilityFunctions::print("Cannot add input action before connecting to OpenVR"); + return; + } + for (int i = 0; i < inputs.size(); i++) { if (inputs[i].name == p_action) { // already registered @@ -662,6 +674,15 @@ void openvr_data::add_input_action(const char *p_action, const char *p_path, con input.type = p_type; input.handle = vr::k_ulInvalidActionHandle; inputs.push_back(input); + + vr::EVRInputError err = vr::VRInput()->GetActionHandle(input.path, &input.handle); + if (err != vr::VRInputError_None) { + input.handle = vr::k_ulInvalidActionHandle; + + Array arr; + arr.push_back(String(input.path)); + UtilityFunctions::print(String("Failed to obtain action handle for {0}").format(arr)); + } } void openvr_data::remove_input_action(const char *p_action) { @@ -740,6 +761,11 @@ void openvr_data::trigger_haptic_pulse(const char *p_action, const char *p_devic } void openvr_data::add_pose_action(const char *p_action, const char *p_path) { + if (!is_initialised()) { + UtilityFunctions::print("Cannot add pose action before connecting to OpenVR"); + return; + } + for (int i = 0; i < poses.size(); i++) { if (poses[i].name == p_action) { // already registered @@ -752,6 +778,15 @@ void openvr_data::add_pose_action(const char *p_action, const char *p_path) { action.path = p_path; action.handle = vr::k_ulInvalidActionHandle; poses.push_back(action); + + vr::EVRInputError err = vr::VRInput()->GetActionHandle(action.path, &action.handle); + if (err != vr::VRInputError_None) { + action.handle = vr::k_ulInvalidActionHandle; + + Array arr; + arr.push_back(String(action.path)); + UtilityFunctions::print(String("Failed to obtain action handle for {0}").format(arr)); + } } void openvr_data::remove_pose_action(const char *p_action) { @@ -981,6 +1016,11 @@ bool openvr_data::set_action_manifest_path(const String p_path) { return false; } + for (int i = 0; i < manifest_action_sets.size(); i++) { + String name = manifest_action_sets[i].get("name"); + register_action_set(name); + } + for (int i = 0; i < manifest_actions.size(); i++) { String name = manifest_actions[i].get("name"); String type = manifest_actions[i].get("type"); @@ -1000,54 +1040,6 @@ bool openvr_data::set_action_manifest_path(const String p_path) { } } - for (int i = 0; i < manifest_action_sets.size(); i++) { - String name = manifest_action_sets[i].get("name"); - register_action_set(name); - } - - for (std::vector::iterator it = action_sets.begin(); it != action_sets.end(); ++it) { - vr::EVRInputError err = vr::VRInput()->GetActionSetHandle((const char *)it->name.utf8().get_data(), &it->handle); - if (err != vr::VRInputError_None) { - Array arr; - arr.push_back(String(it->name)); - UtilityFunctions::print(String("Failed to obtain action set handle for {0}").format(arr)); - } - } - - for (auto &input : inputs) { - // setup handle - char action_path[1024]; - // TODO at some point support additional action sets - sprintf(action_path, "%s/in/%s", (const char *)action_sets[0].name.utf8().get_data(), input.path); - - vr::EVRInputError err = vr::VRInput()->GetActionHandle(action_path, &input.handle); - if (err != vr::VRInputError_None) { - // maybe output something? - input.handle = vr::k_ulInvalidActionHandle; - - Array arr; - arr.push_back(String(action_path)); - UtilityFunctions::print(String("Failed to obtain action handle for {0}").format(arr)); - } - } - - for (auto &pose : poses) { - // setup handle - char action_path[1024]; - // TODO at some point support additional action sets - sprintf(action_path, "%s/in/%s", (const char *)action_sets[0].name.utf8().get_data(), pose.path); - - vr::EVRInputError err = vr::VRInput()->GetActionHandle(action_path, &pose.handle); - if (err != vr::VRInputError_None) { - // maybe output something? - pose.handle = vr::k_ulInvalidActionHandle; - - Array arr; - arr.push_back(String(action_path)); - UtilityFunctions::print(String("Failed to obtain action handle for {0}").format(arr)); - } - } - return true; } From 675bd308564db0852b4b114fa3dd90e5cc8898fa Mon Sep 17 00:00:00 2001 From: Bill Doyle Date: Wed, 24 Jul 2024 17:40:23 -0400 Subject: [PATCH 5/5] Fix actually loading and activating action sets I don't wanna talk about it. So many layers of wrong, and I somehow discovered them in reverse order. --- demo/addons/godot-openvr/actions/actions.json | 2 +- src/open_vr/openvr_data.cpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/demo/addons/godot-openvr/actions/actions.json b/demo/addons/godot-openvr/actions/actions.json index 6bdb202..2a1498e 100644 --- a/demo/addons/godot-openvr/actions/actions.json +++ b/demo/addons/godot-openvr/actions/actions.json @@ -1,5 +1,5 @@ { - "action_set" : [ + "action_sets" : [ { "name" : "/actions/godot", "usage" : "leftright" diff --git a/src/open_vr/openvr_data.cpp b/src/open_vr/openvr_data.cpp index cfd3103..dcb2d36 100644 --- a/src/open_vr/openvr_data.cpp +++ b/src/open_vr/openvr_data.cpp @@ -368,10 +368,7 @@ void openvr_data::process() { } } - // Pass the array to OpenVR - if (current_index == active_action_set_count) { - vr::VRInput()->UpdateActionState(active_action_sets.data(), sizeof(vr::VRActiveActionSet_t), active_action_set_count); - } + vr::VRInput()->UpdateActionState(active_action_sets.data(), sizeof(vr::VRActiveActionSet_t), active_action_set_count); } // update our poses structure, this tracks our controllers @@ -673,7 +670,6 @@ void openvr_data::add_input_action(const char *p_action, const char *p_path, con input.path = p_path; input.type = p_type; input.handle = vr::k_ulInvalidActionHandle; - inputs.push_back(input); vr::EVRInputError err = vr::VRInput()->GetActionHandle(input.path, &input.handle); if (err != vr::VRInputError_None) { @@ -683,6 +679,8 @@ void openvr_data::add_input_action(const char *p_action, const char *p_path, con arr.push_back(String(input.path)); UtilityFunctions::print(String("Failed to obtain action handle for {0}").format(arr)); } + + inputs.push_back(input); } void openvr_data::remove_input_action(const char *p_action) { @@ -777,7 +775,6 @@ void openvr_data::add_pose_action(const char *p_action, const char *p_path) { action.name = p_action; action.path = p_path; action.handle = vr::k_ulInvalidActionHandle; - poses.push_back(action); vr::EVRInputError err = vr::VRInput()->GetActionHandle(action.path, &action.handle); if (err != vr::VRInputError_None) { @@ -787,6 +784,8 @@ void openvr_data::add_pose_action(const char *p_action, const char *p_path) { arr.push_back(String(action.path)); UtilityFunctions::print(String("Failed to obtain action handle for {0}").format(arr)); } + + poses.push_back(action); } void openvr_data::remove_pose_action(const char *p_action) { @@ -1003,7 +1002,7 @@ bool openvr_data::set_action_manifest_path(const String p_path) { return false; } Dictionary manifest = json.get_data(); - Array manifest_action_sets = manifest.get("action_set", Array()); + Array manifest_action_sets = manifest.get("action_sets", Array()); Array manifest_actions = manifest.get("actions", Array()); vr::EVRInputError error = vr::VRInput()->SetActionManifestPath(p_path.utf8().get_data()); @@ -1018,7 +1017,8 @@ bool openvr_data::set_action_manifest_path(const String p_path) { for (int i = 0; i < manifest_action_sets.size(); i++) { String name = manifest_action_sets[i].get("name"); - register_action_set(name); + int action_set_index = register_action_set(name); + toggle_action_set_active(name, true); } for (int i = 0; i < manifest_actions.size(); i++) {