diff --git a/demo/addons/godot-xr-tools/functions/Function_Direct_movement.gd b/demo/addons/godot-xr-tools/functions/Function_Direct_movement.gd index 55a1f9a..97a59e6 100644 --- a/demo/addons/godot-xr-tools/functions/Function_Direct_movement.gd +++ b/demo/addons/godot-xr-tools/functions/Function_Direct_movement.gd @@ -37,7 +37,8 @@ enum MOVEMENT_TYPE { MOVE_AND_ROTATE, MOVE_AND_STRAFE } @export var drag_factor = 0.1 # fly mode and strafe movement management -@export var move_type: MOVEMENT_TYPE = MOVEMENT_TYPE.MOVE_AND_ROTATE +# @export var move_type: MOVEMENT_TYPE = MOVEMENT_TYPE.MOVE_AND_ROTATE # temporarily disabled, enums broke +@export var move_type: int = 0 @export var fly_enabled = true @export var fly_move: String = "trigger_click" @export var fly_activate: String = "grip_click" @@ -215,13 +216,13 @@ func _physics_process(delta): # Apply our drag velocity *= (1.0 - drag_factor) - if move_type == MOVEMENT_TYPE.MOVE_AND_ROTATE: + if move_type == 0: ## 0 = MOVEMENT_TYPE.MOVE_AND_ROTATE if (abs(forwards_backwards) > 0.1 and tail.is_colliding()): var dir = camera_transform.basis.z dir.y = 0.0 velocity = dir.normalized() * -forwards_backwards * max_speed * XRServer.world_scale #velocity = velocity.linear_interpolate(dir, delta * 100.0) - elif move_type == MOVEMENT_TYPE.MOVE_AND_STRAFE: + elif move_type == 1: ## 1 = MOVEMENT_TYPE.MOVE_AND_STRAFE if ((abs(forwards_backwards) > 0.1 || abs(left_right) > 0.1) and tail.is_colliding()): var dir_forward = camera_transform.basis.z dir_forward.y = 0.0 diff --git a/demo/addons/godot-xr-tools/functions/Function_Teleport.gd b/demo/addons/godot-xr-tools/functions/Function_Teleport.gd index 4644eee..ea0e728 100644 --- a/demo/addons/godot-xr-tools/functions/Function_Teleport.gd +++ b/demo/addons/godot-xr-tools/functions/Function_Teleport.gd @@ -214,11 +214,11 @@ func _physics_process(delta): var start_pos = target_global_origin + (Vector3.UP * 0.5 * player_height) var end_pos = target_global_origin - (Vector3.UP * 1.1 * player_height) - var ray_query : PhysicsRayQueryParameters3D - ray_query.from = start_pos - ray_query.to = end_pos - ray_query.collision_mask = collision_mask - var intersects = state.intersect_ray(ray_query) + var params : PhysicsRayQueryParameters3D + params.from = start_pos + params.to = end_pos + params.collision_mask = collision_mask + var intersects = state.intersect_ray(params) if intersects.is_empty(): is_on_floor = false else: diff --git a/demo/player/ButtonStates.gd b/demo/player/ButtonStates.gd index 794b9b5..31fba78 100644 --- a/demo/player/ButtonStates.gd +++ b/demo/player/ButtonStates.gd @@ -22,11 +22,11 @@ func _process(delta): var trigger = controller.get_value("trigger_value") $VBoxContainer/Trigger/Value.value = 100.0 * trigger - $VBoxContainer/Trigger/Pressed.pressed = controller.is_button_pressed("trigger_click") + $VBoxContainer/Trigger/Pressed.button_pressed = controller.is_button_pressed("trigger_click") var grip = controller.get_value("grip_value") $VBoxContainer/Grip/Value.value = 100.0 * grip - $VBoxContainer/Grip/Pressed.pressed = controller.is_button_pressed("grip_click") - $VBoxContainer/AX/Pressed.pressed = controller.is_button_pressed("ax") - $VBoxContainer/BY/Pressed.pressed = controller.is_button_pressed("by") + $VBoxContainer/Grip/Pressed.button_pressed = controller.is_button_pressed("grip_click") + $VBoxContainer/AX/Pressed.button_pressed = controller.is_button_pressed("ax") + $VBoxContainer/BY/Pressed.button_pressed = controller.is_button_pressed("by") diff --git a/godot-cpp b/godot-cpp index c5fd3d0..4e2411a 160000 --- a/godot-cpp +++ b/godot-cpp @@ -1 +1 @@ -Subproject commit c5fd3d00d2c8cd56841a42597ccffbef281bd4d3 +Subproject commit 4e2411ad98089235eb90ac427354031b8aab70cc diff --git a/src/open_vr/openvr_data.cpp b/src/open_vr/openvr_data.cpp index 2da2924..c6c4fdc 100644 --- a/src/open_vr/openvr_data.cpp +++ b/src/open_vr/openvr_data.cpp @@ -384,6 +384,18 @@ void openvr_data::update_play_area() { } } +XRPose::TrackingConfidence openvr_data::confidence_from_tracking_result(vr::ETrackingResult p_tracking_result) { + switch (p_tracking_result) { + case vr::TrackingResult_Uninitialized: + return XRPose::XR_TRACKING_CONFIDENCE_NONE; + case vr::TrackingResult_Running_OK: + return XRPose::XR_TRACKING_CONFIDENCE_HIGH; + default: + return XRPose::XR_TRACKING_CONFIDENCE_LOW; + break; + } +} + void openvr_data::process() { // we need timing info for one or two things.. uint64_t msec = Time::get_singleton()->get_ticks_msec(); @@ -471,25 +483,28 @@ void openvr_data::process() { // update tracker if (i == 0) { // TODO make a positional tracker for this too? + XRPose::TrackingConfidence confidence = XRPose::XR_TRACKING_CONFIDENCE_NONE; if (tracked_device_pose[i].bPoseIsValid) { - // store our HMD transform + confidence = confidence_from_tracking_result(tracked_device_pose[i].eTrackingResult); hmd_transform = transform_from_matrix(&tracked_device_pose[i].mDeviceToAbsoluteTracking, 1.0); - if (head_tracker.is_valid()) { - Vector3 linear_velocity(tracked_device_pose[i].vVelocity.v[0], tracked_device_pose[i].vVelocity.v[1], tracked_device_pose[i].vVelocity.v[2]); - Vector3 angular_velocity(tracked_device_pose[i].vAngularVelocity.v[0], tracked_device_pose[i].vAngularVelocity.v[1], tracked_device_pose[i].vAngularVelocity.v[2]); + hmd_linear_velocity = Vector3(tracked_device_pose[i].vVelocity.v[0], tracked_device_pose[i].vVelocity.v[1], tracked_device_pose[i].vVelocity.v[2]); + hmd_angular_velocity = Vector3(tracked_device_pose[i].vAngularVelocity.v[0], tracked_device_pose[i].vAngularVelocity.v[1], tracked_device_pose[i].vAngularVelocity.v[2]); + } - head_tracker->set_pose("default", hmd_transform, linear_velocity, angular_velocity); - } + if (head_tracker.is_valid()) { + head_tracker->set_pose("default", hmd_transform, hmd_linear_velocity, hmd_angular_velocity, confidence); } + } else if (tracked_devices[i].tracker.is_valid()) { // We'll expose our main transform we got from GetLastPoses as the default pose if (tracked_device_pose[i].bPoseIsValid) { // update our location and orientation + XRPose::TrackingConfidence confidence = confidence_from_tracking_result(tracked_device_pose[i].eTrackingResult); Transform3D transform = transform_from_matrix(&tracked_device_pose[i].mDeviceToAbsoluteTracking, 1.0); Vector3 linear_velocity(tracked_device_pose[i].vVelocity.v[0], tracked_device_pose[i].vVelocity.v[1], tracked_device_pose[i].vVelocity.v[2]); Vector3 angular_velocity(tracked_device_pose[i].vAngularVelocity.v[0], tracked_device_pose[i].vAngularVelocity.v[1], tracked_device_pose[i].vAngularVelocity.v[2]); - tracked_devices[i].tracker->set_pose("default", transform, linear_velocity, angular_velocity); + tracked_devices[i].tracker->set_pose("default", transform, linear_velocity, angular_velocity, confidence); } else { tracked_devices[i].tracker->invalidate_pose("default"); } @@ -968,11 +983,12 @@ void openvr_data::process_device_actions(tracked_device *p_device, uint64_t p_ms } else if (!data.pose.bPoseIsValid) { p_device->tracker->invalidate_pose(pose.name); } else { + XRPose::TrackingConfidence confidence = confidence_from_tracking_result(data.pose.eTrackingResult); Transform3D transform = transform_from_matrix(&data.pose.mDeviceToAbsoluteTracking, 1.0); Vector3 linear_velocity(data.pose.vVelocity.v[0], data.pose.vVelocity.v[1], data.pose.vVelocity.v[2]); Vector3 angular_velocity(data.pose.vAngularVelocity.v[0], data.pose.vAngularVelocity.v[1], data.pose.vAngularVelocity.v[2]); - p_device->tracker->set_pose(pose.name, transform, linear_velocity, angular_velocity); + p_device->tracker->set_pose(pose.name, transform, linear_velocity, angular_velocity, confidence); } } else { p_device->tracker->invalidate_pose(pose.name); diff --git a/src/open_vr/openvr_data.h b/src/open_vr/openvr_data.h index e61db46..2c45617 100644 --- a/src/open_vr/openvr_data.h +++ b/src/open_vr/openvr_data.h @@ -107,6 +107,8 @@ class openvr_data { // tracked devices Ref head_tracker; godot::Transform3D hmd_transform; + godot::Vector3 hmd_linear_velocity; + godot::Vector3 hmd_angular_velocity; struct tracked_device { Ref tracker; @@ -122,6 +124,7 @@ class openvr_data { void attach_device(uint32_t p_device_index); void detach_device(uint32_t p_device_index); void process_device_actions(tracked_device *p_device, uint64_t p_msec); + XRPose::TrackingConfidence confidence_from_tracking_result(vr::ETrackingResult p_tracking_result); //////////////////////////////////////////////////////////////// // meshes (should see about moving this into a separate class) diff --git a/src/xr_interface_openvr.cpp b/src/xr_interface_openvr.cpp index cc1e507..ce199b3 100644 --- a/src/xr_interface_openvr.cpp +++ b/src/xr_interface_openvr.cpp @@ -329,7 +329,10 @@ PackedFloat64Array XRInterfaceOpenVR::_get_projection_for_view(int64_t p_view, d //////////////////////////////////////////////////////////////// // This is called after we render a frame so we can send the render output to OpenVR -void XRInterfaceOpenVR::_commit_views(const RID &p_render_target, const Rect2 &p_screen_rect) { +void XRInterfaceOpenVR::_post_draw_viewport(const RID &p_render_target, const Rect2 &p_screen_rect) { + // Note that at this point in time nothing has actually been rendered yet, this entry point gets called by Godot after + // all the rendering for our viewport has been prepared, but the queues have yet to be submitted to Vulkan + if (!p_screen_rect.has_no_area()) { // just blit left eye out to screen Rect2 src_rect; @@ -351,18 +354,25 @@ void XRInterfaceOpenVR::_commit_views(const RID &p_render_target, const Rect2 &p } } + texture_rid = get_render_target_texture(p_render_target); +}; + +void XRInterfaceOpenVR::_end_frame() { + // _end_frame gets called after Godot has fully prepared its rendering pipeline and submitted its rendering queues to Vulkan + if (!ovr->is_initialised()) { + return; + } + RenderingServer *rendering_server = RenderingServer::get_singleton(); ERR_FAIL_NULL(rendering_server); RenderingDevice *rendering_device = rendering_server->get_rendering_device(); ERR_FAIL_NULL(rendering_device); - // FIX ME - We're not getting the correct RID here - RID texture = get_render_target_texture(p_render_target); - uint64_t image = rendering_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_IMAGE, texture, 0); - uint32_t format = rendering_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_IMAGE_NATIVE_TEXTURE_FORMAT, texture, 0); + uint64_t image = rendering_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_IMAGE, texture_rid, 0); + uint32_t format = rendering_device->get_driver_resource(RenderingDevice::DRIVER_RESOURCE_VULKAN_IMAGE_NATIVE_TEXTURE_FORMAT, texture_rid, 0); // and now sent to OpenVR... - if (image != 0 && format != 0 && ovr->is_initialised()) { + if (image != 0 && format != 0) { // Submit to SteamVR vr::VRTextureBounds_t bounds; bounds.uMin = 0.0f; diff --git a/src/xr_interface_openvr.h b/src/xr_interface_openvr.h index 5637205..b7acfa6 100644 --- a/src/xr_interface_openvr.h +++ b/src/xr_interface_openvr.h @@ -25,7 +25,7 @@ class XRInterfaceOpenVR : public XRInterfaceExtension { uint32_t height = 0; OS::VideoDriver video_driver = OS::VIDEO_DRIVER_VULKAN; - int texture_id = 0; + RID texture_rid; public: // Properties @@ -66,9 +66,10 @@ class XRInterfaceOpenVR : public XRInterfaceExtension { virtual Transform3D _get_transform_for_view(int64_t p_view, const Transform3D &p_cam_transform) override; virtual PackedFloat64Array _get_projection_for_view(int64_t p_view, double p_aspect, double p_z_near, double p_z_far) override; - virtual void _commit_views(const RID &p_render_target, const Rect2 &p_screen_rect) override; - virtual void _process() override; + virtual void _post_draw_viewport(const RID &render_target, const Rect2 &screen_rect) override; + virtual void _end_frame() override; + virtual void _notification(int64_t what) override; XRInterfaceOpenVR();