1 | /**************************************************************************/ |
2 | /* openxr_interface.h */ |
3 | /**************************************************************************/ |
4 | /* This file is part of: */ |
5 | /* GODOT ENGINE */ |
6 | /* https://godotengine.org */ |
7 | /**************************************************************************/ |
8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
10 | /* */ |
11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
12 | /* a copy of this software and associated documentation files (the */ |
13 | /* "Software"), to deal in the Software without restriction, including */ |
14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
17 | /* the following conditions: */ |
18 | /* */ |
19 | /* The above copyright notice and this permission notice shall be */ |
20 | /* included in all copies or substantial portions of the Software. */ |
21 | /* */ |
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
29 | /**************************************************************************/ |
30 | |
31 | #ifndef OPENXR_INTERFACE_H |
32 | #define OPENXR_INTERFACE_H |
33 | |
34 | #include "action_map/openxr_action_map.h" |
35 | #include "extensions/openxr_fb_passthrough_extension_wrapper.h" |
36 | #include "openxr_api.h" |
37 | |
38 | #include "servers/xr/xr_interface.h" |
39 | #include "servers/xr/xr_positional_tracker.h" |
40 | |
41 | // declare some default strings |
42 | #define INTERACTION_PROFILE_NONE "/interaction_profiles/none" |
43 | |
44 | class OpenXRInterface : public XRInterface { |
45 | GDCLASS(OpenXRInterface, XRInterface); |
46 | |
47 | private: |
48 | OpenXRAPI *openxr_api = nullptr; |
49 | bool initialized = false; |
50 | XRInterface::TrackingStatus tracking_state; |
51 | OpenXRFbPassthroughExtensionWrapper *passthrough_wrapper = nullptr; |
52 | |
53 | // At a minimum we need a tracker for our head |
54 | Ref<XRPositionalTracker> head; |
55 | Transform3D head_transform; |
56 | Vector3 head_linear_velocity; |
57 | Vector3 head_angular_velocity; |
58 | Transform3D transform_for_view[2]; // We currently assume 2, but could be 4 for VARJO which we do not support yet |
59 | |
60 | void _load_action_map(); |
61 | |
62 | struct Action { // An action we've registered with OpenXR |
63 | String action_name; // Name of our action as presented to Godot (can be altered from the action map) |
64 | OpenXRAction::ActionType action_type; // The action type of this action |
65 | RID action_rid; // RID of the action registered with our OpenXR API |
66 | }; |
67 | struct ActionSet { // An action set we've registered with OpenXR |
68 | String action_set_name; // Name of our action set |
69 | bool is_active; // If true this action set is active and we will sync it |
70 | Vector<Action *> actions; // List of actions in this action set |
71 | RID action_set_rid; // RID of the action registered with our OpenXR API |
72 | }; |
73 | struct Tracker { // A tracker we've registered with OpenXR |
74 | String tracker_name; // Name of our tracker (can be altered from the action map) |
75 | Vector<Action *> actions; // Actions related to this tracker |
76 | Ref<XRPositionalTracker> positional_tracker; // Our positional tracker object that holds our tracker state |
77 | RID tracker_rid; // RID of the tracker registered with our OpenXR API |
78 | RID interaction_profile; // RID of the interaction profile bound to this tracker (can be null) |
79 | }; |
80 | |
81 | Vector<ActionSet *> action_sets; |
82 | Vector<RID> interaction_profiles; |
83 | Vector<Tracker *> trackers; |
84 | |
85 | ActionSet *create_action_set(const String &p_action_set_name, const String &p_localized_name, const int p_priority); |
86 | void free_action_sets(); |
87 | |
88 | Action *create_action(ActionSet *p_action_set, const String &p_action_name, const String &p_localized_name, OpenXRAction::ActionType p_action_type, const Vector<Tracker *> p_trackers); |
89 | Action *find_action(const String &p_action_name); |
90 | void free_actions(ActionSet *p_action_set); |
91 | |
92 | Tracker *find_tracker(const String &p_tracker_name, bool p_create = false); |
93 | void handle_tracker(Tracker *p_tracker); |
94 | void free_trackers(); |
95 | |
96 | void free_interaction_profiles(); |
97 | |
98 | void _set_default_pos(Transform3D &p_transform, double p_world_scale, uint64_t p_eye); |
99 | |
100 | protected: |
101 | static void _bind_methods(); |
102 | |
103 | public: |
104 | virtual StringName get_name() const override; |
105 | virtual uint32_t get_capabilities() const override; |
106 | |
107 | virtual PackedStringArray get_suggested_tracker_names() const override; |
108 | virtual TrackingStatus get_tracking_status() const override; |
109 | |
110 | bool initialize_on_startup() const; |
111 | virtual bool is_initialized() const override; |
112 | virtual bool initialize() override; |
113 | virtual void uninitialize() override; |
114 | virtual Dictionary get_system_info() override; |
115 | |
116 | virtual void trigger_haptic_pulse(const String &p_action_name, const StringName &p_tracker_name, double p_frequency, double p_amplitude, double p_duration_sec, double p_delay_sec = 0) override; |
117 | |
118 | virtual bool supports_play_area_mode(XRInterface::PlayAreaMode p_mode) override; |
119 | virtual XRInterface::PlayAreaMode get_play_area_mode() const override; |
120 | virtual bool set_play_area_mode(XRInterface::PlayAreaMode p_mode) override; |
121 | |
122 | float get_display_refresh_rate() const; |
123 | void set_display_refresh_rate(float p_refresh_rate); |
124 | Array get_available_display_refresh_rates() const; |
125 | |
126 | bool is_action_set_active(const String &p_action_set) const; |
127 | void set_action_set_active(const String &p_action_set, bool p_active); |
128 | Array get_action_sets() const; |
129 | |
130 | double get_render_target_size_multiplier() const; |
131 | void set_render_target_size_multiplier(double multiplier); |
132 | |
133 | virtual Size2 get_render_target_size() override; |
134 | virtual uint32_t get_view_count() override; |
135 | virtual Transform3D get_camera_transform() override; |
136 | virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override; |
137 | virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; |
138 | |
139 | virtual RID get_color_texture() override; |
140 | virtual RID get_depth_texture() override; |
141 | |
142 | virtual void process() override; |
143 | virtual void pre_render() override; |
144 | bool pre_draw_viewport(RID p_render_target) override; |
145 | virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override; |
146 | virtual void end_frame() override; |
147 | |
148 | virtual bool is_passthrough_supported() override; |
149 | virtual bool is_passthrough_enabled() override; |
150 | virtual bool start_passthrough() override; |
151 | virtual void stop_passthrough() override; |
152 | |
153 | /** environment blend mode. */ |
154 | virtual Array get_supported_environment_blend_modes() override; |
155 | virtual XRInterface::EnvironmentBlendMode get_environment_blend_mode() const override; |
156 | virtual bool set_environment_blend_mode(XRInterface::EnvironmentBlendMode mode) override; |
157 | |
158 | void on_state_ready(); |
159 | void on_state_visible(); |
160 | void on_state_focused(); |
161 | void on_state_stopping(); |
162 | void on_pose_recentered(); |
163 | void tracker_profile_changed(RID p_tracker, RID p_interaction_profile); |
164 | |
165 | /** Hand tracking. */ |
166 | enum Hand { |
167 | HAND_LEFT, |
168 | HAND_RIGHT, |
169 | HAND_MAX, |
170 | }; |
171 | |
172 | enum HandMotionRange { |
173 | HAND_MOTION_RANGE_UNOBSTRUCTED, |
174 | HAND_MOTION_RANGE_CONFORM_TO_CONTROLLER, |
175 | HAND_MOTION_RANGE_MAX |
176 | }; |
177 | |
178 | void set_motion_range(const Hand p_hand, const HandMotionRange p_motion_range); |
179 | HandMotionRange get_motion_range(const Hand p_hand) const; |
180 | |
181 | enum HandJoints { |
182 | HAND_JOINT_PALM = 0, |
183 | HAND_JOINT_WRIST = 1, |
184 | HAND_JOINT_THUMB_METACARPAL = 2, |
185 | HAND_JOINT_THUMB_PROXIMAL = 3, |
186 | HAND_JOINT_THUMB_DISTAL = 4, |
187 | HAND_JOINT_THUMB_TIP = 5, |
188 | HAND_JOINT_INDEX_METACARPAL = 6, |
189 | HAND_JOINT_INDEX_PROXIMAL = 7, |
190 | HAND_JOINT_INDEX_INTERMEDIATE = 8, |
191 | HAND_JOINT_INDEX_DISTAL = 9, |
192 | HAND_JOINT_INDEX_TIP = 10, |
193 | HAND_JOINT_MIDDLE_METACARPAL = 11, |
194 | HAND_JOINT_MIDDLE_PROXIMAL = 12, |
195 | HAND_JOINT_MIDDLE_INTERMEDIATE = 13, |
196 | HAND_JOINT_MIDDLE_DISTAL = 14, |
197 | HAND_JOINT_MIDDLE_TIP = 15, |
198 | HAND_JOINT_RING_METACARPAL = 16, |
199 | HAND_JOINT_RING_PROXIMAL = 17, |
200 | HAND_JOINT_RING_INTERMEDIATE = 18, |
201 | HAND_JOINT_RING_DISTAL = 19, |
202 | HAND_JOINT_RING_TIP = 20, |
203 | HAND_JOINT_LITTLE_METACARPAL = 21, |
204 | HAND_JOINT_LITTLE_PROXIMAL = 22, |
205 | HAND_JOINT_LITTLE_INTERMEDIATE = 23, |
206 | HAND_JOINT_LITTLE_DISTAL = 24, |
207 | HAND_JOINT_LITTLE_TIP = 25, |
208 | HAND_JOINT_MAX = 26, |
209 | }; |
210 | |
211 | Quaternion get_hand_joint_rotation(Hand p_hand, HandJoints p_joint) const; |
212 | Vector3 get_hand_joint_position(Hand p_hand, HandJoints p_joint) const; |
213 | float get_hand_joint_radius(Hand p_hand, HandJoints p_joint) const; |
214 | |
215 | Vector3 get_hand_joint_linear_velocity(Hand p_hand, HandJoints p_joint) const; |
216 | Vector3 get_hand_joint_angular_velocity(Hand p_hand, HandJoints p_joint) const; |
217 | |
218 | OpenXRInterface(); |
219 | ~OpenXRInterface(); |
220 | }; |
221 | |
222 | VARIANT_ENUM_CAST(OpenXRInterface::Hand) |
223 | VARIANT_ENUM_CAST(OpenXRInterface::HandMotionRange) |
224 | VARIANT_ENUM_CAST(OpenXRInterface::HandJoints) |
225 | |
226 | #endif // OPENXR_INTERFACE_H |
227 | |