Reserved controller ids 1 and 2 for left and right hand controllers and added new center on hmd option

This commit is contained in:
Bastiaan Olij 2017-12-21 23:10:44 +11:00
parent b068961c8f
commit 6fd51b6a1b
6 changed files with 66 additions and 18 deletions

View file

@ -62,7 +62,10 @@
</methods>
<members>
<member name="controller_id" type="int" setter="set_controller_id" getter="get_controller_id">
The controller's id. The first controller that the [ARVRServer] detects will have id 1, the second id 2, the third id 3, etc. When a controller is turned off, it's slot is freed. This ensures controllers will keep the same id even when controllers with lower ids are turned off.
The controller's id.
A controller id of 0 is unbound and will always result in an inactive node. Controller id 1 is reserved for the first controller that identifies itself as the left hand controller and id 2 is reserved for the first controller that identifies itself as the right hand controller.
For any other controller that the [ARVRServer] detects we continue with controller id 3.
When a controller is turned off, its slot is freed. This ensures controllers will keep the same id even when controllers with lower ids are turned off.
</member>
<member name="rumble" type="float" setter="set_rumble" getter="get_rumble">
The degree to which the tracker rumbles. Ranges from [code]0.0[/code] to [code]1.0[/code] with precision [code].01[/code]. If changed, updates [member ARVRPositionalTracker.rumble] accordingly.

View file

@ -14,7 +14,7 @@
<method name="center_on_hmd">
<return type="void">
</return>
<argument index="0" name="ignore_tilt" type="bool">
<argument index="0" name="rotation_mode" type="bool">
</argument>
<argument index="1" name="keep_height" type="bool">
</argument>
@ -154,5 +154,14 @@
<constant name="TRACKER_ANY" value="255" enum="TrackerType">
Used internally to select all trackers.
</constant>
<constant name="RESET_FULL_ROTATION" value="0" enum="RotationMode">
Fully reset the orientation of the HMD. Regardless of what direction the user is looking to in the real world. The user will look dead ahead in the virtual world.
</constant>
<constant name="RESET_BUT_KEEP_TILT" value="1" enum="RotationMode">
Resets the orientation but keeps the tilt of the device. So if we're looking down, we keep looking down but heading will be reset.
</constant>
<constant name="DONT_RESET_ROTATION" value="2" enum="RotationMode">
Does not reset the orientation of the HMD, only the position of the player gets centered.
</constant>
</constants>
</class>

View file

@ -231,7 +231,7 @@ void ARVRController::_notification(int p_what) {
void ARVRController::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_controller_id", "controller_id"), &ARVRController::set_controller_id);
ClassDB::bind_method(D_METHOD("get_controller_id"), &ARVRController::get_controller_id);
ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_id", PROPERTY_HINT_RANGE, "1,32,1"), "set_controller_id", "get_controller_id");
ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_id", PROPERTY_HINT_RANGE, "0,32,1"), "set_controller_id", "get_controller_id");
ClassDB::bind_method(D_METHOD("get_controller_name"), &ARVRController::get_controller_name);
// passthroughs to information about our related joystick
@ -251,7 +251,8 @@ void ARVRController::_bind_methods() {
};
void ARVRController::set_controller_id(int p_controller_id) {
// we don't check any bounds here, this controller may not yet be active and just be a place holder until it is.
// We don't check any bounds here, this controller may not yet be active and just be a place holder until it is.
// Note that setting this to 0 means this node is not bound to a controller yet.
controller_id = p_controller_id;
};
@ -420,7 +421,7 @@ void ARVRAnchor::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_anchor_id", "anchor_id"), &ARVRAnchor::set_anchor_id);
ClassDB::bind_method(D_METHOD("get_anchor_id"), &ARVRAnchor::get_anchor_id);
ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_id"), "set_anchor_id", "get_anchor_id");
ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_id", PROPERTY_HINT_RANGE, "0,32,1"), "set_anchor_id", "get_anchor_id");
ClassDB::bind_method(D_METHOD("get_anchor_name"), &ARVRAnchor::get_anchor_name);
ClassDB::bind_method(D_METHOD("get_is_active"), &ARVRAnchor::get_is_active);
@ -430,7 +431,8 @@ void ARVRAnchor::_bind_methods() {
};
void ARVRAnchor::set_anchor_id(int p_anchor_id) {
// we don't check any bounds here, this anchor may not yet be active and just be a place holder until it is.
// We don't check any bounds here, this anchor may not yet be active and just be a place holder until it is.
// Note that setting this to 0 means this node is not bound to an anchor yet.
anchor_id = p_anchor_id;
};

View file

@ -62,13 +62,15 @@ void ARVRPositionalTracker::_bind_methods() {
void ARVRPositionalTracker::set_type(ARVRServer::TrackerType p_type) {
if (type != p_type) {
type = p_type;
hand = ARVRPositionalTracker::TRACKER_HAND_UNKNOWN;
ARVRServer *arvr_server = ARVRServer::get_singleton();
ERR_FAIL_NULL(arvr_server);
// get a tracker id for our type
// note if this is a controller this will be 3 or higher but we may change it later.
tracker_id = arvr_server->get_free_tracker_id_for_type(p_type);
}
};
};
ARVRServer::TrackerType ARVRPositionalTracker::get_type() const {
@ -156,7 +158,24 @@ ARVRPositionalTracker::TrackerHand ARVRPositionalTracker::get_hand() const {
};
void ARVRPositionalTracker::set_hand(const ARVRPositionalTracker::TrackerHand p_hand) {
hand = p_hand;
ARVRServer *arvr_server = ARVRServer::get_singleton();
ERR_FAIL_NULL(arvr_server);
if (hand != p_hand) {
// we can only set this if we've previously set this to be a controller!!
ERR_FAIL_COND((type != ARVRServer::TRACKER_CONTROLLER) && (p_hand != ARVRPositionalTracker::TRACKER_HAND_UNKNOWN));
hand = p_hand;
if (hand == ARVRPositionalTracker::TRACKER_LEFT_HAND) {
if (!arvr_server->is_tracker_id_in_use_for_type(type, 1)) {
tracker_id = 1;
};
} else if (hand == ARVRPositionalTracker::TRACKER_RIGHT_HAND) {
if (!arvr_server->is_tracker_id_in_use_for_type(type, 2)) {
tracker_id = 2;
};
};
};
};
Transform ARVRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const {

View file

@ -43,7 +43,7 @@ void ARVRServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_world_scale"), &ARVRServer::get_world_scale);
ClassDB::bind_method(D_METHOD("set_world_scale"), &ARVRServer::set_world_scale);
ClassDB::bind_method(D_METHOD("get_reference_frame"), &ARVRServer::get_reference_frame);
ClassDB::bind_method(D_METHOD("center_on_hmd", "ignore_tilt", "keep_height"), &ARVRServer::center_on_hmd);
ClassDB::bind_method(D_METHOD("center_on_hmd", "rotation_mode", "keep_height"), &ARVRServer::center_on_hmd);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "world_scale"), "set_world_scale", "get_world_scale");
@ -63,6 +63,10 @@ void ARVRServer::_bind_methods() {
BIND_ENUM_CONSTANT(TRACKER_UNKNOWN);
BIND_ENUM_CONSTANT(TRACKER_ANY);
BIND_ENUM_CONSTANT(RESET_FULL_ROTATION);
BIND_ENUM_CONSTANT(RESET_BUT_KEEP_TILT);
BIND_ENUM_CONSTANT(DONT_RESET_ROTATION);
ADD_SIGNAL(MethodInfo("interface_added", PropertyInfo(Variant::STRING, "name")));
ADD_SIGNAL(MethodInfo("interface_removed", PropertyInfo(Variant::STRING, "name")));
@ -96,7 +100,7 @@ Transform ARVRServer::get_reference_frame() const {
return reference_frame;
};
void ARVRServer::center_on_hmd(bool p_ignore_tilt, bool p_keep_height) {
void ARVRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) {
if (primary_interface != NULL) {
// clear our current reference frame or we'll end up double adjusting it
reference_frame = Transform();
@ -105,7 +109,7 @@ void ARVRServer::center_on_hmd(bool p_ignore_tilt, bool p_keep_height) {
Transform new_reference_frame = primary_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, Transform());
// remove our tilt
if (p_ignore_tilt) {
if (p_rotation_mode == 1) {
// take the Y out of our Z
new_reference_frame.basis.set_axis(2, Vector3(new_reference_frame.basis.elements[0][2], 0.0, new_reference_frame.basis.elements[2][2]).normalized());
@ -114,6 +118,9 @@ void ARVRServer::center_on_hmd(bool p_ignore_tilt, bool p_keep_height) {
// and X is our cross reference
new_reference_frame.basis.set_axis(0, new_reference_frame.basis.get_axis(1).cross(new_reference_frame.basis.get_axis(2)).normalized());
} else if (p_rotation_mode == 2) {
// remove our rotation, we're only interesting in centering on position
new_reference_frame.basis = Basis();
};
// don't negate our height
@ -229,8 +236,12 @@ bool ARVRServer::is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p
};
int ARVRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) {
// we start checking at 1, 0 means that it's not a controller..
int tracker_id = 1;
// We start checking at 1, 0 means that it's not a controller..
// Note that for controller we reserve:
// - 1 for the left hand controller and
// - 2 for the right hand controller
// so we start at 3 :)
int tracker_id = p_tracker_type == ARVRServer::TRACKER_CONTROLLER ? 3 : 1;
while (is_tracker_id_in_use_for_type(p_tracker_type, tracker_id)) {
// try the next one

View file

@ -68,6 +68,12 @@ public:
TRACKER_ANY = 0xff /* used by get_connected_trackers to return all types */
};
enum RotationMode {
RESET_FULL_ROTATION = 0, /* we reset the full rotation, regardless of how the HMD is oriented, we're looking dead ahead */
RESET_BUT_KEEP_TILT = 1, /* reset rotation but keep tilt. */
DONT_RESET_ROTATION = 2, /* don't reset the rotation, we will only center on position */
};
private:
Vector<Ref<ARVRInterface> > interfaces;
Vector<ARVRPositionalTracker *> trackers;
@ -78,8 +84,6 @@ private:
Transform world_origin; /* our world origin point, maps a location in our virtual world to the origin point in our real world tracking volume */
Transform reference_frame; /* our reference frame */
bool is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const;
protected:
static ARVRServer *singleton;
@ -127,7 +131,7 @@ public:
and in the virtual world out of sync
*/
Transform get_reference_frame() const;
void center_on_hmd(bool p_ignore_tilt, bool p_keep_height);
void center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height);
/*
Interfaces are objects that 'glue' Godot to an AR or VR SDK such as the Oculus SDK, OpenVR, OpenHMD, etc.
@ -150,9 +154,8 @@ public:
/*
Our trackers are objects that expose the orientation and position of physical devices such as controller, anchor points, etc.
They are created and managed by our active AR/VR interfaces.
Note that for trackers that
*/
bool is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const;
int get_free_tracker_id_for_type(TrackerType p_tracker_type);
void add_tracker(ARVRPositionalTracker *p_tracker);
void remove_tracker(ARVRPositionalTracker *p_tracker);
@ -167,5 +170,6 @@ public:
#define ARVR ARVRServer
VARIANT_ENUM_CAST(ARVRServer::TrackerType);
VARIANT_ENUM_CAST(ARVRServer::RotationMode);
#endif