Skip to content
This repository has been archived by the owner on Feb 1, 2024. It is now read-only.

Commit

Permalink
Fix the controller vibration API
Browse files Browse the repository at this point in the history
The vrapi_SetHapticVibrationSimple(...) method is supposed to be called once per frame.
To comply, the new logic batches the vibration requests (last one wins), and fire the method call once per frame during `_process` if a vibration request for the controller is available.
The API exposed by the plugin is augmented to take a `duration_in_ms` parameter, which the logic uses to keep firing vrapi_SetHapticVibrationSimple(...) calls until the duration has been reached.
  • Loading branch information
m4gr3d committed May 24, 2020
1 parent 88f7894 commit cc5ef67
Show file tree
Hide file tree
Showing 15 changed files with 235 additions and 123 deletions.
5 changes: 4 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ trim_trailing_whitespace = true

[*.{cpp,hpp,c,h,mm}]
indent_size = 4
ij_c_indent_namespace_members = 4
ij_c_indent_namespace_members = 0

[{*.gradle,AndroidManifest.xml}]
indent_size = 4

[*.gd]
indent_style = tab
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func _initialize_ovr_mobile_arvr_interface():
if (ovr_utilities): ovr_utilities = ovr_utilities.new()
if (ovr_hand_tracking): ovr_hand_tracking = ovr_hand_tracking.new()
if (ovr_vr_api_proxy): ovr_vr_api_proxy = ovr_vr_api_proxy.new()

# Connect to the plugin signals
_connect_to_signals()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ var ovr_tracking_transform = null;
var ovr_utilities = null;
var ovr_vr_api_proxy = null;

# Dictionary tracking the remaining duration for controllers vibration
var controllers_vibration_duration = {}

# some of the Oculus VrAPI constants are defined in this file. Have a look into it to learn more
var ovrVrApiTypes = load("res://addons/godot_ovrmobile/OvrVrApiTypes.gd").new();
Expand All @@ -35,6 +37,7 @@ func _ready():
func _process(delta_t):
_check_and_perform_runtime_config()
_check_move(delta_t)
_update_controllers_vibration(delta_t)


# this code check for the OVRMobile inteface; and if successful also initializes the
Expand Down Expand Up @@ -71,7 +74,7 @@ func _initialize_ovr_mobile_arvr_interface():
if (ovr_tracking_transform): ovr_tracking_transform = ovr_tracking_transform.new()
if (ovr_utilities): ovr_utilities = ovr_utilities.new()
if (ovr_vr_api_proxy): ovr_vr_api_proxy = ovr_vr_api_proxy.new()

# Connect to the plugin signals
_connect_to_signals()

Expand Down Expand Up @@ -164,6 +167,27 @@ func _check_move(delta_t):
self.transform.origin += strafe_dir * move_vector.x * delta_t;


func _start_controller_vibration(controller, duration, rumble_intensity):
print("Starting vibration of controller " + str(controller) + " for " + str(duration) + " at " + str(rumble_intensity))
controllers_vibration_duration[controller.controller_id] = duration
controller.set_rumble(rumble_intensity)

func _update_controllers_vibration(delta_t):
# Check if there are any controllers currently vibrating
if (controllers_vibration_duration.empty()):
return

# Update the remaining vibration duration for each controller
for i in ARVRServer.get_tracker_count():
var tracker = ARVRServer.get_tracker(i)
if (controllers_vibration_duration.has(tracker.get_tracker_id())):
var remaining_duration = controllers_vibration_duration[tracker.get_tracker_id()] - (delta_t * 1000)
if (remaining_duration < 0):
controllers_vibration_duration.erase(tracker.get_tracker_id())
tracker.set_rumble(0)
else:
controllers_vibration_duration[tracker.get_tracker_id()] = remaining_duration

# current button mapping for the touch controller
# godot itself also exposes some of these constants via JOY_VR_* and JOY_OCULUS_*
# this enum here is to document everything in place and includes the touch event mappings
Expand All @@ -188,44 +212,47 @@ enum CONTROLLER_BUTTON {

# this is a function connected to the button release signal from the controller
func _on_LeftTouchController_button_pressed(button):
if (button != CONTROLLER_BUTTON.YB): return;

# examples on using the ovr api from gdscript
if (ovr_guardian_system):
print(" ovr_guardian_system.get_boundary_visible() == " + str(ovr_guardian_system.get_boundary_visible()));
#ovr_guardian_system.request_boundary_visible(true); # make the boundary always visible

# the oriented bounding box is the largest box that fits into the currently defined guardian
# the return value of this function is an array with [Transform(), Vector3()] where the Vector3
# is the scale of the box and Transform contains the position and orientation of the box.
# The height is not yet tracked by the oculus system and will be a default value.
print(" ovr_guardian_system.get_boundary_oriented_bounding_box() == " + str(ovr_guardian_system.get_boundary_oriented_bounding_box()));

if (ovr_tracking_transform):
print(" ovr_tracking_transform.get_tracking_space() == " + str(ovr_tracking_transform.get_tracking_space()));

# you can change the tracking space to control where the default floor level is and
# how recentring should behave.
#ovr_guardian_system.set_tracking_space(ovrVrApiTypes.OvrTrackingSpace.VRAPI_TRACKING_SPACE_STAGE);

if (ovr_utilities):
print(" ovr_utilities.get_ipd() == " + str(ovr_utilities.get_ipd()));

# you can access the accelerations and velocitys for the head and controllers
# that are predicted by the Oculus VrApi via these funcitons:
var controller_id = $LeftTouchController.controller_id;
print(" ovr_utilities.get_controller_linear_velocity(controller_id) == " + str(ovr_utilities.get_controller_linear_velocity(controller_id)));
print(" ovr_utilities.get_controller_linear_acceleration(controller_id) == " + str(ovr_utilities.get_controller_linear_acceleration(controller_id)));
print(" ovr_utilities.get_controller_angular_velocity(controller_id) == " + str(ovr_utilities.get_controller_angular_velocity(controller_id)));
print(" ovr_utilities.get_controller_angular_acceleration(controller_id) == " + str(ovr_utilities.get_controller_angular_acceleration(controller_id)));

if (button == CONTROLLER_BUTTON.YB):
# examples on using the ovr api from gdscript
if (ovr_guardian_system):
print(" ovr_guardian_system.get_boundary_visible() == " + str(ovr_guardian_system.get_boundary_visible()));
#ovr_guardian_system.request_boundary_visible(true); # make the boundary always visible

# the oriented bounding box is the largest box that fits into the currently defined guardian
# the return value of this function is an array with [Transform(), Vector3()] where the Vector3
# is the scale of the box and Transform contains the position and orientation of the box.
# The height is not yet tracked by the oculus system and will be a default value.
print(" ovr_guardian_system.get_boundary_oriented_bounding_box() == " + str(ovr_guardian_system.get_boundary_oriented_bounding_box()));

if (ovr_tracking_transform):
print(" ovr_tracking_transform.get_tracking_space() == " + str(ovr_tracking_transform.get_tracking_space()));

# you can change the tracking space to control where the default floor level is and
# how recentring should behave.
#ovr_guardian_system.set_tracking_space(ovrVrApiTypes.OvrTrackingSpace.VRAPI_TRACKING_SPACE_STAGE);

if (ovr_utilities):
print(" ovr_utilities.get_ipd() == " + str(ovr_utilities.get_ipd()));

# you can access the accelerations and velocitys for the head and controllers
# that are predicted by the Oculus VrApi via these funcitons:
var controller_id = $LeftTouchController.controller_id;
print(" ovr_utilities.get_controller_linear_velocity(controller_id) == " + str(ovr_utilities.get_controller_linear_velocity(controller_id)));
print(" ovr_utilities.get_controller_linear_acceleration(controller_id) == " + str(ovr_utilities.get_controller_linear_acceleration(controller_id)));
print(" ovr_utilities.get_controller_angular_velocity(controller_id) == " + str(ovr_utilities.get_controller_angular_velocity(controller_id)));
print(" ovr_utilities.get_controller_angular_acceleration(controller_id) == " + str(ovr_utilities.get_controller_angular_acceleration(controller_id)));

if (button == CONTROLLER_BUTTON.XA):
_start_controller_vibration($LeftTouchController, 40, 0.5)

func _on_RightTouchController_button_pressed(button):
if (button != CONTROLLER_BUTTON.YB): return;
if (button == CONTROLLER_BUTTON.YB):
if (ovr_utilities):
# use this for fade to black for example: here we just do a color change
ovr_utilities.set_default_layer_color_scale(Color(0.5, 0.0, 1.0, 1.0));

if (ovr_utilities):
# use this for fade to black for example: here we just do a color change
ovr_utilities.set_default_layer_color_scale(Color(0.5, 0.0, 1.0, 1.0));
if (button == CONTROLLER_BUTTON.XA):
_start_controller_vibration($RightTouchController, 40, 0.5)


func _on_RightTouchController_button_release(button):
Expand Down
Binary file modified plugin/libs/godot-lib.3.2.2.beta.release.aar
Binary file not shown.
33 changes: 15 additions & 18 deletions plugin/src/main/cpp/api/ovr_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,18 @@
#include "api_common.h"

namespace ovrmobile {
bool vibrate_controller(OvrMobileSession *session, int controller_id, float intensity) {
return check_session_initialized<bool>(session, [&]() {
bool result = false;
const OvrMobileController *controller = session->get_ovr_mobile_controller();
if (controller) {
const OvrMobileController::ControllerState *state = controller->get_controller_state_by_id(
controller_id);
if (state &&
OvrMobileController::supports_haptic_vibration(state->remote_capabilities)) {
result = vrapi_SetHapticVibrationSimple(session->get_ovr_mobile_context(),
state->remote_capabilities.Header.DeviceID,
intensity) == ovrSuccess;
}
}
return result;
}, []() { return false; });
}
} // namespace ovrmobile
bool vibrate_controller(OvrMobileSession* session,
int controller_id,
int duration_in_ms,
float intensity) {
return check_session_initialized<bool>(session, [&]() {
bool result = false;
OvrMobileController* controller = session->get_ovr_mobile_controller();
if (controller) {
controller->vibrate_controller(controller_id, duration_in_ms, intensity);
result = true;
}
return result;
}, []() { return false; });
}
} // namespace ovrmobile
5 changes: 4 additions & 1 deletion plugin/src/main/cpp/api/ovr_input.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
namespace ovrmobile {
// Vibrate the controller matching the given controller ID.
// Returns true if the controller was vibrated, false otherwise.
bool vibrate_controller(OvrMobileSession *session, int controller_id, float intensity);
bool vibrate_controller(OvrMobileSession* session,
int controller_id,
int duration_in_ms,
float intensity);
} // namespace ovrmobile

#endif // OVR_INPUT_H
4 changes: 4 additions & 0 deletions plugin/src/main/cpp/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ inline bool check_bit(uint32_t in, uint32_t bits) {
return (in & bits) != 0;
}

inline double get_time_in_ms() {
return vrapi_GetTimeInSeconds() * 1000;
}

void godot_transform_from_ovrMatrix(godot_transform *p_dest, const ovrMatrix4f *p_matrix, godot_real p_world_scale);

void godot_transform_from_ovr_pose(godot_transform *dest, const ovrPosef &pose, const float world_scale);
Expand Down
2 changes: 2 additions & 0 deletions plugin/src/main/cpp/gdnative/godot_ovrmobile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "gdnative/nativescript/ovr_tracking_transform_ns.h"
#include "gdnative/nativescript/ovr_utilities_ns.h"
#include "gdnative/nativescript/ovr_hand_tracking_ns.h"
#include "gdnative/nativescript/ovr_input_ns.h"

// experimental low-level VrApi access
#include "gdnative/nativescript/ovr_vr_api_proxy_ns.h"
Expand All @@ -42,6 +43,7 @@ void GDN_EXPORT godot_ovrmobile_nativescript_init(void *handle) {
register_gdnative_utilities(handle);
register_gdnative_hand_tracking(handle);
register_gdnative_vr_api_proxy(handle);
register_gdnative_input(handle);
}

void GDN_EXPORT godot_ovrmobile_nativescript_terminate(void *handle) {
Expand Down
12 changes: 0 additions & 12 deletions plugin/src/main/cpp/gdnative/nativescript/ovr_input_ns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ void register_gdnative_input(void *handle) {
// register all the functions that we want to expose via the OvrInput class in GDScript
godot_instance_method method = { NULL, NULL, NULL };
godot_method_attributes attributes = { GODOT_METHOD_RPC_MODE_DISABLED };

method.method = &vibrate_controller;
godot::nativescript_api->godot_nativescript_register_method(handle, kClassName, "vibrate_controller", attributes, method);
}

GDCALLINGCONV void *ovr_input_constructor(godot_object *instance, void *method_data) {
Expand All @@ -30,12 +27,3 @@ GDCALLINGCONV void ovr_input_destructor(godot_object *instance, void *method_dat
reset_ovr_config_data_struct(static_cast<ovr_config_data_struct *>(user_data));
}
}

GDCALLINGCONV godot_variant vibrate_controller(godot_object *instance, void *method_data, void *p_user_data, int num_args, godot_variant **args) {
CHECK_USER_DATA(
const int controller_id = godot::api->godot_variant_as_int(args[0]);
const double intensity = godot::api->godot_variant_as_real(args[1]);
godot::api->godot_variant_new_bool(&ret, ovrmobile::vibrate_controller(ovr_mobile_session, controller_id, intensity));

)
}
2 changes: 0 additions & 2 deletions plugin/src/main/cpp/gdnative/nativescript/ovr_input_ns.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ extern "C" {
GDCALLINGCONV void *ovr_input_constructor(godot_object *instance, void *method_data);
GDCALLINGCONV void ovr_input_destructor(godot_object *instance, void *method_data, void *user_data);

GDCALLINGCONV godot_variant vibrate_controller(godot_object *instance, void *method_data, void *p_user_data, int num_args, godot_variant **args);

#ifdef __cplusplus
};
#endif
Expand Down
12 changes: 8 additions & 4 deletions plugin/src/main/cpp/jni/ovr_input_jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@
extern "C" {

JNIEXPORT void JNICALL
JNI_METHOD(nativeVibrateController)(JNIEnv *env, jclass clazz, jint controller_id,
jfloat intensity) {
ovrmobile::vibrate_controller(get_session(), controller_id, intensity);
JNI_METHOD(vibrateController)(JNIEnv* env,
jclass,
jobject,
jint controller_id,
jint duration_in_ms,
jfloat intensity) {
ovrmobile::vibrate_controller(get_session(), controller_id, duration_in_ms, intensity);
}

};
};
Loading

0 comments on commit cc5ef67

Please sign in to comment.