Path: blob/master/modules/openxr/extensions/openxr_valve_analog_threshold_extension.cpp
10278 views
/**************************************************************************/1/* openxr_valve_analog_threshold_extension.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "openxr_valve_analog_threshold_extension.h"31#include "../action_map/openxr_action_set.h"32#include "../action_map/openxr_interaction_profile.h"33#include "../openxr_api.h"3435// Implementation for:36// https://registry.khronos.org/OpenXR/specs/1.1/html/xrspec.html#XR_VALVE_analog_threshold3738///////////////////////////////////////////////////////////////////////////////////////////////////39// OpenXRValveAnalogThresholdExtension4041OpenXRValveAnalogThresholdExtension *OpenXRValveAnalogThresholdExtension::singleton = nullptr;4243OpenXRValveAnalogThresholdExtension *OpenXRValveAnalogThresholdExtension::get_singleton() {44return singleton;45}4647OpenXRValveAnalogThresholdExtension::OpenXRValveAnalogThresholdExtension() {48singleton = this;49}5051OpenXRValveAnalogThresholdExtension::~OpenXRValveAnalogThresholdExtension() {52singleton = nullptr;53}5455HashMap<String, bool *> OpenXRValveAnalogThresholdExtension::get_requested_extensions() {56HashMap<String, bool *> request_extensions;5758// Note, we're dependent on the binding modifier extension, this may be requested by multiple extension wrappers.59request_extensions[XR_KHR_BINDING_MODIFICATION_EXTENSION_NAME] = &binding_modifier_ext;60request_extensions[XR_VALVE_ANALOG_THRESHOLD_EXTENSION_NAME] = &threshold_ext;6162return request_extensions;63}6465bool OpenXRValveAnalogThresholdExtension::is_available() {66return binding_modifier_ext && threshold_ext;67}6869///////////////////////////////////////////////////////////////////////////////////////////////////70// OpenXRAnalogThresholdModifier7172void OpenXRAnalogThresholdModifier::_bind_methods() {73ClassDB::bind_method(D_METHOD("set_on_threshold", "on_threshold"), &OpenXRAnalogThresholdModifier::set_on_threshold);74ClassDB::bind_method(D_METHOD("get_on_threshold"), &OpenXRAnalogThresholdModifier::get_on_threshold);75ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "on_threshold", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_on_threshold", "get_on_threshold");7677ClassDB::bind_method(D_METHOD("set_off_threshold", "off_threshold"), &OpenXRAnalogThresholdModifier::set_off_threshold);78ClassDB::bind_method(D_METHOD("get_off_threshold"), &OpenXRAnalogThresholdModifier::get_off_threshold);79ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "off_threshold", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_off_threshold", "get_off_threshold");8081ClassDB::bind_method(D_METHOD("set_on_haptic", "haptic"), &OpenXRAnalogThresholdModifier::set_on_haptic);82ClassDB::bind_method(D_METHOD("get_on_haptic"), &OpenXRAnalogThresholdModifier::get_on_haptic);83ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "on_haptic", PROPERTY_HINT_RESOURCE_TYPE, "OpenXRHapticBase"), "set_on_haptic", "get_on_haptic");8485ClassDB::bind_method(D_METHOD("set_off_haptic", "haptic"), &OpenXRAnalogThresholdModifier::set_off_haptic);86ClassDB::bind_method(D_METHOD("get_off_haptic"), &OpenXRAnalogThresholdModifier::get_off_haptic);87ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "off_haptic", PROPERTY_HINT_RESOURCE_TYPE, "OpenXRHapticBase"), "set_off_haptic", "get_off_haptic");88}8990OpenXRAnalogThresholdModifier::OpenXRAnalogThresholdModifier() {91analog_threshold.type = XR_TYPE_INTERACTION_PROFILE_ANALOG_THRESHOLD_VALVE;92analog_threshold.next = nullptr;9394analog_threshold.onThreshold = 0.6;95analog_threshold.offThreshold = 0.4;96}9798void OpenXRAnalogThresholdModifier::set_on_threshold(float p_threshold) {99ERR_FAIL_COND(p_threshold < 0.0 || p_threshold > 1.0);100101analog_threshold.onThreshold = p_threshold;102emit_changed();103}104105float OpenXRAnalogThresholdModifier::get_on_threshold() const {106return analog_threshold.onThreshold;107}108109void OpenXRAnalogThresholdModifier::set_off_threshold(float p_threshold) {110ERR_FAIL_COND(p_threshold < 0.0 || p_threshold > 1.0);111112analog_threshold.offThreshold = p_threshold;113emit_changed();114}115116float OpenXRAnalogThresholdModifier::get_off_threshold() const {117return analog_threshold.offThreshold;118}119120void OpenXRAnalogThresholdModifier::set_on_haptic(const Ref<OpenXRHapticBase> &p_haptic) {121on_haptic = p_haptic;122emit_changed();123}124125Ref<OpenXRHapticBase> OpenXRAnalogThresholdModifier::get_on_haptic() const {126return on_haptic;127}128129void OpenXRAnalogThresholdModifier::set_off_haptic(const Ref<OpenXRHapticBase> &p_haptic) {130off_haptic = p_haptic;131emit_changed();132}133134Ref<OpenXRHapticBase> OpenXRAnalogThresholdModifier::get_off_haptic() const {135return off_haptic;136}137138PackedByteArray OpenXRAnalogThresholdModifier::get_ip_modification() {139PackedByteArray ret;140141OpenXRAPI *openxr_api = OpenXRAPI::get_singleton();142ERR_FAIL_NULL_V(openxr_api, ret);143144OpenXRValveAnalogThresholdExtension *analog_threshold_ext = OpenXRValveAnalogThresholdExtension::get_singleton();145if (!analog_threshold_ext || !analog_threshold_ext->is_available()) {146// Extension not enabled!147WARN_PRINT("Analog threshold extension is not enabled or available.");148return ret;149}150151ERR_FAIL_NULL_V(ip_binding, ret);152153Ref<OpenXRAction> action = ip_binding->get_action();154ERR_FAIL_COND_V(action.is_null(), ret);155156// Get our action set157Ref<OpenXRActionSet> action_set = action->get_action_set();158ERR_FAIL_COND_V(action_set.is_null(), ret);159RID action_set_rid = openxr_api->find_action_set(action_set->get_name());160ERR_FAIL_COND_V(!action_set_rid.is_valid(), ret);161162// Get our action163RID action_rid = openxr_api->find_action(action->get_name(), action_set_rid);164ERR_FAIL_COND_V(!action_rid.is_valid(), ret);165166analog_threshold.action = openxr_api->action_get_handle(action_rid);167168analog_threshold.binding = openxr_api->get_xr_path(ip_binding->get_binding_path());169ERR_FAIL_COND_V(analog_threshold.binding == XR_NULL_PATH, ret);170171// These are set already:172// - analog_threshold.onThreshold173// - analog_threshold.offThreshold174175if (on_haptic.is_valid()) {176analog_threshold.onHaptic = on_haptic->get_xr_structure();177} else {178analog_threshold.onHaptic = nullptr;179}180181if (off_haptic.is_valid()) {182analog_threshold.offHaptic = off_haptic->get_xr_structure();183} else {184analog_threshold.offHaptic = nullptr;185}186187// Copy into byte array so we can return it.188ERR_FAIL_COND_V(ret.resize(sizeof(XrInteractionProfileAnalogThresholdVALVE)) != OK, ret);189memcpy(ret.ptrw(), &analog_threshold, sizeof(XrInteractionProfileAnalogThresholdVALVE));190191return ret;192}193194195