Added ARVRAnchor support and a few small enhancements

This commit is contained in:
BastiaanOlij 2017-08-03 18:58:05 +10:00
parent aef974e7a8
commit e7aed24add
5 changed files with 184 additions and 8 deletions

View File

@ -98,6 +98,7 @@ void ARVRController::_notification(int p_what) {
is_active = false;
button_states = 0;
} else {
is_active = true;
set_transform(tracker->get_transform(true));
int joy_id = tracker->get_joy_id();
@ -231,6 +232,118 @@ ARVRController::~ARVRController(){
////////////////////////////////////////////////////////////////////////////////////////////////////
void ARVRAnchor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
set_process_internal(true);
}; break;
case NOTIFICATION_EXIT_TREE: {
set_process_internal(false);
}; break;
case NOTIFICATION_INTERNAL_PROCESS: {
// get our ARVRServer
ARVRServer *arvr_server = ARVRServer::get_singleton();
ERR_FAIL_NULL(arvr_server);
// find the tracker for our anchor
ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_ANCHOR, anchor_id);
if (tracker == NULL) {
// this anchor is currently not available
is_active = false;
} else {
is_active = true;
Transform transform;
// we'll need our world_scale
real_t world_scale = arvr_server->get_world_scale();
// get our info from our tracker
transform.basis = tracker->get_orientation();
transform.origin = tracker->get_position(); // <-- already adjusted to world scale
// our basis is scaled to the size of the plane the anchor is tracking
// extract the size from our basis and reset the scale
size = transform.basis.get_scale() * world_scale;
transform.basis.set_scale(Vector3(1.0, 1.0, 1.0));
// apply our reference frame and set our transform
set_transform(arvr_server->get_reference_frame() * transform);
};
}; break;
default:
break;
};
};
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");
ClassDB::bind_method(D_METHOD("get_anchor_name"), &ARVRAnchor::get_anchor_name);
ClassDB::bind_method(D_METHOD("get_is_active"), &ARVRAnchor::get_is_active);
ClassDB::bind_method(D_METHOD("get_size"), &ARVRAnchor::get_size);
};
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.
anchor_id = p_anchor_id;
};
int ARVRAnchor::get_anchor_id(void) const {
return anchor_id;
};
Vector3 ARVRAnchor::get_size() const {
return size;
};
String ARVRAnchor::get_anchor_name(void) const {
// get our ARVRServer
ARVRServer *arvr_server = ARVRServer::get_singleton();
ERR_FAIL_NULL_V(arvr_server, String());
ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_ANCHOR, anchor_id);
if (tracker == NULL) {
return String("Not connected");
};
return tracker->get_name();
};
bool ARVRAnchor::get_is_active() const {
return is_active;
};
String ARVRAnchor::get_configuration_warning() const {
if (!is_visible() || !is_inside_tree())
return String();
// must be child node of ARVROrigin!
ARVROrigin *origin = get_parent()->cast_to<ARVROrigin>();
if (origin == NULL) {
return TTR("ARVRAnchor must have an ARVROrigin node as its parent");
};
if (anchor_id == 0) {
return TTR("The anchor id must not be 0 or this anchor will not be bound to an actual anchor");
};
return String();
};
ARVRAnchor::ARVRAnchor() {
anchor_id = 0;
is_active = true;
};
ARVRAnchor::~ARVRAnchor(){
// nothing to do here yet for now..
};
////////////////////////////////////////////////////////////////////////////////////////////////////
String ARVROrigin::get_configuration_warning() const {
if (!is_visible() || !is_inside_tree())
return String();

View File

@ -39,7 +39,7 @@
**/
/*
ARVRCamera is a subclass of camera which will register itself with its parent ARVROrigin and as a result is automatically positioned
ARVRCamera is a subclass of camera which will register itself with its parent ARVROrigin and as a result is automatically positioned
*/
class ARVRCamera : public Camera {
@ -56,9 +56,9 @@ public:
};
/*
ARVRController is a helper node that automatically updates it's position based on tracker data.
ARVRController is a helper node that automatically updates it's position based on tracker data.
It must be a child node of our ARVROrigin node
It must be a child node of our ARVROrigin node
*/
class ARVRController : public Spatial {
@ -91,6 +91,37 @@ public:
~ARVRController();
};
/*
ARVRAnchor is a helper node that automatically updates it's position based on anchor data, it represents a real world location.
It must be a child node of our ARVROrigin node
*/
class ARVRAnchor : public Spatial {
GDCLASS(ARVRAnchor, Spatial);
private:
int anchor_id;
bool is_active;
Vector3 size;
protected:
void _notification(int p_what);
static void _bind_methods();
public:
void set_anchor_id(int p_anchor_id);
int get_anchor_id(void) const;
String get_anchor_name(void) const;
bool get_is_active() const;
Vector3 get_size() const;
String get_configuration_warning() const;
ARVRAnchor();
~ARVRAnchor();
};
/*
ARVROrigin is special spatial node that acts as our origin point mapping our real world center of our tracking volume into our virtual world.

View File

@ -409,6 +409,7 @@ void register_scene_types() {
ClassDB::register_class<Listener>();
ClassDB::register_class<ARVRCamera>();
ClassDB::register_class<ARVRController>();
ClassDB::register_class<ARVRAnchor>();
ClassDB::register_class<ARVROrigin>();
ClassDB::register_class<InterpolatedCamera>();
ClassDB::register_class<MeshInstance>();

View File

@ -40,6 +40,13 @@ void ARVRPositionalTracker::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tracks_position"), &ARVRPositionalTracker::get_tracks_position);
ClassDB::bind_method(D_METHOD("get_position"), &ARVRPositionalTracker::get_position);
ClassDB::bind_method(D_METHOD("get_transform", "adjust_by_reference_frame"), &ARVRPositionalTracker::get_transform);
// these functions we don't want to expose to normal users but do need to be callable from GDNative
ClassDB::bind_method(D_METHOD("_set_type", "type"), &ARVRPositionalTracker::set_type);
ClassDB::bind_method(D_METHOD("_set_name", "name"), &ARVRPositionalTracker::set_name);
ClassDB::bind_method(D_METHOD("_set_joy_id", "joy_id"), &ARVRPositionalTracker::set_joy_id);
ClassDB::bind_method(D_METHOD("_set_orientation", "orientation"), &ARVRPositionalTracker::set_orientation);
ClassDB::bind_method(D_METHOD("_set_rw_position", "rw_position"), &ARVRPositionalTracker::set_rw_position);
};
void ARVRPositionalTracker::set_type(ARVRServer::TrackerType p_type) {
@ -102,14 +109,36 @@ bool ARVRPositionalTracker::get_tracks_position() const {
void ARVRPositionalTracker::set_position(const Vector3 &p_position) {
_THREAD_SAFE_METHOD_
ARVRServer *arvr_server = ARVRServer::get_singleton();
ERR_FAIL_NULL(arvr_server);
real_t world_scale = arvr_server->get_world_scale();
ERR_FAIL_COND(world_scale == 0);
tracks_position = true; // obviously we have this
position = p_position;
rw_position = p_position / world_scale;
};
Vector3 ARVRPositionalTracker::get_position() const {
_THREAD_SAFE_METHOD_
return position;
ARVRServer *arvr_server = ARVRServer::get_singleton();
ERR_FAIL_NULL_V(arvr_server, rw_position);
real_t world_scale = arvr_server->get_world_scale();
return rw_position * world_scale;
};
void ARVRPositionalTracker::set_rw_position(const Vector3 &p_rw_position) {
_THREAD_SAFE_METHOD_
tracks_position = true; // obviously we have this
rw_position = p_rw_position;
};
Vector3 ARVRPositionalTracker::get_rw_position() const {
_THREAD_SAFE_METHOD_
return rw_position;
};
Transform ARVRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const {

View File

@ -56,7 +56,7 @@ private:
bool tracks_orientation; // do we track orientation?
Basis orientation; // our orientation
bool tracks_position; // do we track position?
Vector3 position; // our position
Vector3 rw_position; // our position "in the real world, so without world_scale applied"
protected:
static void _bind_methods();
@ -73,8 +73,10 @@ public:
void set_orientation(const Basis &p_orientation);
Basis get_orientation() const;
bool get_tracks_position() const;
void set_position(const Vector3 &p_position);
Vector3 get_position() const;
void set_position(const Vector3 &p_position); // set position with world_scale applied
Vector3 get_position() const; // get position with world_scale applied
void set_rw_position(const Vector3 &p_rw_position);
Vector3 get_rw_position() const;
Transform get_transform(bool p_adjust_by_reference_frame) const;