initial commit, 4.5 stable
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled
This commit is contained in:
6
servers/xr/SCsub
Normal file
6
servers/xr/SCsub
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
from misc.utility.scons_hints import *
|
||||
|
||||
Import("env")
|
||||
|
||||
env.add_source_files(env.servers_sources, "*.cpp")
|
194
servers/xr/xr_body_tracker.cpp
Normal file
194
servers/xr/xr_body_tracker.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
/**************************************************************************/
|
||||
/* xr_body_tracker.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "xr_body_tracker.h"
|
||||
|
||||
void XRBodyTracker::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_has_tracking_data", "has_data"), &XRBodyTracker::set_has_tracking_data);
|
||||
ClassDB::bind_method(D_METHOD("get_has_tracking_data"), &XRBodyTracker::get_has_tracking_data);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_body_flags", "flags"), &XRBodyTracker::set_body_flags);
|
||||
ClassDB::bind_method(D_METHOD("get_body_flags"), &XRBodyTracker::get_body_flags);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_joint_flags", "joint", "flags"), &XRBodyTracker::set_joint_flags);
|
||||
ClassDB::bind_method(D_METHOD("get_joint_flags", "joint"), &XRBodyTracker::get_joint_flags);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_joint_transform", "joint", "transform"), &XRBodyTracker::set_joint_transform);
|
||||
ClassDB::bind_method(D_METHOD("get_joint_transform", "joint"), &XRBodyTracker::get_joint_transform);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "has_tracking_data", PROPERTY_HINT_NONE), "set_has_tracking_data", "get_has_tracking_data");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "body_flags", PROPERTY_HINT_FLAGS, "Upper Body,Lower Body,Hands"), "set_body_flags", "get_body_flags");
|
||||
|
||||
BIND_BITFIELD_FLAG(BODY_FLAG_UPPER_BODY_SUPPORTED);
|
||||
BIND_BITFIELD_FLAG(BODY_FLAG_LOWER_BODY_SUPPORTED);
|
||||
BIND_BITFIELD_FLAG(BODY_FLAG_HANDS_SUPPORTED);
|
||||
|
||||
BIND_ENUM_CONSTANT(JOINT_ROOT);
|
||||
BIND_ENUM_CONSTANT(JOINT_HIPS);
|
||||
BIND_ENUM_CONSTANT(JOINT_SPINE);
|
||||
BIND_ENUM_CONSTANT(JOINT_CHEST);
|
||||
BIND_ENUM_CONSTANT(JOINT_UPPER_CHEST);
|
||||
BIND_ENUM_CONSTANT(JOINT_NECK);
|
||||
BIND_ENUM_CONSTANT(JOINT_HEAD);
|
||||
BIND_ENUM_CONSTANT(JOINT_HEAD_TIP);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_SHOULDER);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_UPPER_ARM);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_LOWER_ARM);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_SHOULDER);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_UPPER_ARM);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_LOWER_ARM);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_UPPER_LEG);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_LOWER_LEG);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_FOOT);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_TOES);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_UPPER_LEG);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_LOWER_LEG);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_FOOT);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_TOES);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_HAND);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_PALM);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_WRIST);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_THUMB_METACARPAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_THUMB_PHALANX_PROXIMAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_THUMB_PHALANX_DISTAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_THUMB_TIP);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_INDEX_FINGER_METACARPAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_INDEX_FINGER_PHALANX_PROXIMAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_INDEX_FINGER_PHALANX_INTERMEDIATE);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_INDEX_FINGER_PHALANX_DISTAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_INDEX_FINGER_TIP);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_MIDDLE_FINGER_METACARPAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_MIDDLE_FINGER_PHALANX_PROXIMAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_MIDDLE_FINGER_PHALANX_INTERMEDIATE);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_MIDDLE_FINGER_PHALANX_DISTAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_MIDDLE_FINGER_TIP);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_RING_FINGER_METACARPAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_RING_FINGER_PHALANX_PROXIMAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_RING_FINGER_PHALANX_INTERMEDIATE);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_RING_FINGER_PHALANX_DISTAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_RING_FINGER_TIP);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_PINKY_FINGER_METACARPAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_PINKY_FINGER_PHALANX_PROXIMAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_PINKY_FINGER_PHALANX_INTERMEDIATE);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_PINKY_FINGER_PHALANX_DISTAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_PINKY_FINGER_TIP);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_HAND);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_PALM);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_WRIST);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_THUMB_METACARPAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_THUMB_PHALANX_PROXIMAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_THUMB_PHALANX_DISTAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_THUMB_TIP);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_INDEX_FINGER_METACARPAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_INDEX_FINGER_PHALANX_PROXIMAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_INDEX_FINGER_PHALANX_INTERMEDIATE);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_INDEX_FINGER_PHALANX_DISTAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_INDEX_FINGER_TIP);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_MIDDLE_FINGER_METACARPAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_MIDDLE_FINGER_PHALANX_PROXIMAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_MIDDLE_FINGER_PHALANX_INTERMEDIATE);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_MIDDLE_FINGER_PHALANX_DISTAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_MIDDLE_FINGER_TIP);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_RING_FINGER_METACARPAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_RING_FINGER_PHALANX_PROXIMAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_RING_FINGER_PHALANX_INTERMEDIATE);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_RING_FINGER_PHALANX_DISTAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_RING_FINGER_TIP);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_PINKY_FINGER_METACARPAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_PINKY_FINGER_PHALANX_PROXIMAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_PINKY_FINGER_PHALANX_INTERMEDIATE);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_PINKY_FINGER_PHALANX_DISTAL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_PINKY_FINGER_TIP);
|
||||
BIND_ENUM_CONSTANT(JOINT_LOWER_CHEST);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_SCAPULA);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_WRIST_TWIST);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_SCAPULA);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_WRIST_TWIST);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_FOOT_TWIST);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_HEEL);
|
||||
BIND_ENUM_CONSTANT(JOINT_LEFT_MIDDLE_FOOT);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_FOOT_TWIST);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_HEEL);
|
||||
BIND_ENUM_CONSTANT(JOINT_RIGHT_MIDDLE_FOOT);
|
||||
BIND_ENUM_CONSTANT(JOINT_MAX);
|
||||
|
||||
BIND_BITFIELD_FLAG(JOINT_FLAG_ORIENTATION_VALID);
|
||||
BIND_BITFIELD_FLAG(JOINT_FLAG_ORIENTATION_TRACKED);
|
||||
BIND_BITFIELD_FLAG(JOINT_FLAG_POSITION_VALID);
|
||||
BIND_BITFIELD_FLAG(JOINT_FLAG_POSITION_TRACKED);
|
||||
}
|
||||
|
||||
void XRBodyTracker::set_tracker_type(XRServer::TrackerType p_type) {
|
||||
ERR_FAIL_COND_MSG(p_type != XRServer::TRACKER_BODY, "XRBodyTracker must be of type TRACKER_BODY.");
|
||||
}
|
||||
|
||||
void XRBodyTracker::set_tracker_hand(const XRPositionalTracker::TrackerHand p_hand) {
|
||||
ERR_FAIL_COND_MSG(p_hand != XRPositionalTracker::TRACKER_HAND_UNKNOWN, "XRBodyTracker cannot specify hand.");
|
||||
}
|
||||
|
||||
void XRBodyTracker::set_has_tracking_data(bool p_has_tracking_data) {
|
||||
has_tracking_data = p_has_tracking_data;
|
||||
}
|
||||
|
||||
bool XRBodyTracker::get_has_tracking_data() const {
|
||||
return has_tracking_data;
|
||||
}
|
||||
|
||||
void XRBodyTracker::set_body_flags(BitField<BodyFlags> p_body_flags) {
|
||||
body_flags = p_body_flags;
|
||||
}
|
||||
|
||||
BitField<XRBodyTracker::BodyFlags> XRBodyTracker::get_body_flags() const {
|
||||
return body_flags;
|
||||
}
|
||||
|
||||
void XRBodyTracker::set_joint_flags(Joint p_joint, BitField<JointFlags> p_flags) {
|
||||
ERR_FAIL_INDEX(p_joint, JOINT_MAX);
|
||||
joint_flags[p_joint] = p_flags;
|
||||
}
|
||||
|
||||
BitField<XRBodyTracker::JointFlags> XRBodyTracker::get_joint_flags(Joint p_joint) const {
|
||||
ERR_FAIL_INDEX_V(p_joint, JOINT_MAX, BitField<JointFlags>());
|
||||
return joint_flags[p_joint];
|
||||
}
|
||||
|
||||
void XRBodyTracker::set_joint_transform(Joint p_joint, const Transform3D &p_transform) {
|
||||
ERR_FAIL_INDEX(p_joint, JOINT_MAX);
|
||||
joint_transforms[p_joint] = p_transform;
|
||||
}
|
||||
|
||||
Transform3D XRBodyTracker::get_joint_transform(Joint p_joint) const {
|
||||
ERR_FAIL_INDEX_V(p_joint, JOINT_MAX, Transform3D());
|
||||
return joint_transforms[p_joint];
|
||||
}
|
||||
|
||||
XRBodyTracker::XRBodyTracker() {
|
||||
type = XRServer::TRACKER_BODY;
|
||||
}
|
185
servers/xr/xr_body_tracker.h
Normal file
185
servers/xr/xr_body_tracker.h
Normal file
@@ -0,0 +1,185 @@
|
||||
/**************************************************************************/
|
||||
/* xr_body_tracker.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "servers/xr/xr_positional_tracker.h"
|
||||
|
||||
class XRBodyTracker : public XRPositionalTracker {
|
||||
GDCLASS(XRBodyTracker, XRPositionalTracker);
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
public:
|
||||
enum BodyFlags {
|
||||
BODY_FLAG_UPPER_BODY_SUPPORTED = 1,
|
||||
BODY_FLAG_LOWER_BODY_SUPPORTED = 2,
|
||||
BODY_FLAG_HANDS_SUPPORTED = 4,
|
||||
};
|
||||
|
||||
enum Joint {
|
||||
JOINT_ROOT,
|
||||
|
||||
// Upper Body Joints
|
||||
JOINT_HIPS,
|
||||
JOINT_SPINE,
|
||||
JOINT_CHEST,
|
||||
JOINT_UPPER_CHEST,
|
||||
JOINT_NECK,
|
||||
JOINT_HEAD,
|
||||
JOINT_HEAD_TIP,
|
||||
JOINT_LEFT_SHOULDER,
|
||||
JOINT_LEFT_UPPER_ARM,
|
||||
JOINT_LEFT_LOWER_ARM,
|
||||
JOINT_RIGHT_SHOULDER,
|
||||
JOINT_RIGHT_UPPER_ARM,
|
||||
JOINT_RIGHT_LOWER_ARM,
|
||||
|
||||
// Lower Body Joints
|
||||
JOINT_LEFT_UPPER_LEG,
|
||||
JOINT_LEFT_LOWER_LEG,
|
||||
JOINT_LEFT_FOOT,
|
||||
JOINT_LEFT_TOES,
|
||||
JOINT_RIGHT_UPPER_LEG,
|
||||
JOINT_RIGHT_LOWER_LEG,
|
||||
JOINT_RIGHT_FOOT,
|
||||
JOINT_RIGHT_TOES,
|
||||
|
||||
// Left Hand Joints
|
||||
JOINT_LEFT_HAND,
|
||||
JOINT_LEFT_PALM,
|
||||
JOINT_LEFT_WRIST,
|
||||
JOINT_LEFT_THUMB_METACARPAL,
|
||||
JOINT_LEFT_THUMB_PHALANX_PROXIMAL,
|
||||
JOINT_LEFT_THUMB_PHALANX_DISTAL,
|
||||
JOINT_LEFT_THUMB_TIP,
|
||||
JOINT_LEFT_INDEX_FINGER_METACARPAL,
|
||||
JOINT_LEFT_INDEX_FINGER_PHALANX_PROXIMAL,
|
||||
JOINT_LEFT_INDEX_FINGER_PHALANX_INTERMEDIATE,
|
||||
JOINT_LEFT_INDEX_FINGER_PHALANX_DISTAL,
|
||||
JOINT_LEFT_INDEX_FINGER_TIP,
|
||||
JOINT_LEFT_MIDDLE_FINGER_METACARPAL,
|
||||
JOINT_LEFT_MIDDLE_FINGER_PHALANX_PROXIMAL,
|
||||
JOINT_LEFT_MIDDLE_FINGER_PHALANX_INTERMEDIATE,
|
||||
JOINT_LEFT_MIDDLE_FINGER_PHALANX_DISTAL,
|
||||
JOINT_LEFT_MIDDLE_FINGER_TIP,
|
||||
JOINT_LEFT_RING_FINGER_METACARPAL,
|
||||
JOINT_LEFT_RING_FINGER_PHALANX_PROXIMAL,
|
||||
JOINT_LEFT_RING_FINGER_PHALANX_INTERMEDIATE,
|
||||
JOINT_LEFT_RING_FINGER_PHALANX_DISTAL,
|
||||
JOINT_LEFT_RING_FINGER_TIP,
|
||||
JOINT_LEFT_PINKY_FINGER_METACARPAL,
|
||||
JOINT_LEFT_PINKY_FINGER_PHALANX_PROXIMAL,
|
||||
JOINT_LEFT_PINKY_FINGER_PHALANX_INTERMEDIATE,
|
||||
JOINT_LEFT_PINKY_FINGER_PHALANX_DISTAL,
|
||||
JOINT_LEFT_PINKY_FINGER_TIP,
|
||||
|
||||
// Right Hand Joints
|
||||
JOINT_RIGHT_HAND,
|
||||
JOINT_RIGHT_PALM,
|
||||
JOINT_RIGHT_WRIST,
|
||||
JOINT_RIGHT_THUMB_METACARPAL,
|
||||
JOINT_RIGHT_THUMB_PHALANX_PROXIMAL,
|
||||
JOINT_RIGHT_THUMB_PHALANX_DISTAL,
|
||||
JOINT_RIGHT_THUMB_TIP,
|
||||
JOINT_RIGHT_INDEX_FINGER_METACARPAL,
|
||||
JOINT_RIGHT_INDEX_FINGER_PHALANX_PROXIMAL,
|
||||
JOINT_RIGHT_INDEX_FINGER_PHALANX_INTERMEDIATE,
|
||||
JOINT_RIGHT_INDEX_FINGER_PHALANX_DISTAL,
|
||||
JOINT_RIGHT_INDEX_FINGER_TIP,
|
||||
JOINT_RIGHT_MIDDLE_FINGER_METACARPAL,
|
||||
JOINT_RIGHT_MIDDLE_FINGER_PHALANX_PROXIMAL,
|
||||
JOINT_RIGHT_MIDDLE_FINGER_PHALANX_INTERMEDIATE,
|
||||
JOINT_RIGHT_MIDDLE_FINGER_PHALANX_DISTAL,
|
||||
JOINT_RIGHT_MIDDLE_FINGER_TIP,
|
||||
JOINT_RIGHT_RING_FINGER_METACARPAL,
|
||||
JOINT_RIGHT_RING_FINGER_PHALANX_PROXIMAL,
|
||||
JOINT_RIGHT_RING_FINGER_PHALANX_INTERMEDIATE,
|
||||
JOINT_RIGHT_RING_FINGER_PHALANX_DISTAL,
|
||||
JOINT_RIGHT_RING_FINGER_TIP,
|
||||
JOINT_RIGHT_PINKY_FINGER_METACARPAL,
|
||||
JOINT_RIGHT_PINKY_FINGER_PHALANX_PROXIMAL,
|
||||
JOINT_RIGHT_PINKY_FINGER_PHALANX_INTERMEDIATE,
|
||||
JOINT_RIGHT_PINKY_FINGER_PHALANX_DISTAL,
|
||||
JOINT_RIGHT_PINKY_FINGER_TIP,
|
||||
|
||||
// Extra joints that aren't part of the Godot humanoid skeleton, but are commonly used in some VR avatars.
|
||||
JOINT_LOWER_CHEST,
|
||||
JOINT_LEFT_SCAPULA,
|
||||
JOINT_LEFT_WRIST_TWIST,
|
||||
JOINT_RIGHT_SCAPULA,
|
||||
JOINT_RIGHT_WRIST_TWIST,
|
||||
JOINT_LEFT_FOOT_TWIST,
|
||||
JOINT_LEFT_HEEL,
|
||||
JOINT_LEFT_MIDDLE_FOOT,
|
||||
JOINT_RIGHT_FOOT_TWIST,
|
||||
JOINT_RIGHT_HEEL,
|
||||
JOINT_RIGHT_MIDDLE_FOOT,
|
||||
|
||||
JOINT_MAX,
|
||||
};
|
||||
|
||||
enum JointFlags {
|
||||
JOINT_FLAG_ORIENTATION_VALID = 1,
|
||||
JOINT_FLAG_ORIENTATION_TRACKED = 2,
|
||||
JOINT_FLAG_POSITION_VALID = 4,
|
||||
JOINT_FLAG_POSITION_TRACKED = 8,
|
||||
};
|
||||
|
||||
void set_tracker_type(XRServer::TrackerType p_type) override;
|
||||
void set_tracker_hand(const XRPositionalTracker::TrackerHand p_hand) override;
|
||||
|
||||
void set_has_tracking_data(bool p_has_tracking_data);
|
||||
bool get_has_tracking_data() const;
|
||||
|
||||
void set_body_flags(BitField<BodyFlags> p_body_flags);
|
||||
BitField<BodyFlags> get_body_flags() const;
|
||||
|
||||
void set_joint_flags(Joint p_joint, BitField<JointFlags> p_flags);
|
||||
BitField<JointFlags> get_joint_flags(Joint p_joint) const;
|
||||
|
||||
void set_joint_transform(Joint p_joint, const Transform3D &p_transform);
|
||||
Transform3D get_joint_transform(Joint p_joint) const;
|
||||
|
||||
XRBodyTracker();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
private:
|
||||
bool has_tracking_data = false;
|
||||
BitField<BodyFlags> body_flags = {};
|
||||
|
||||
BitField<JointFlags> joint_flags[JOINT_MAX];
|
||||
Transform3D joint_transforms[JOINT_MAX];
|
||||
};
|
||||
|
||||
VARIANT_BITFIELD_CAST(XRBodyTracker::BodyFlags)
|
||||
VARIANT_ENUM_CAST(XRBodyTracker::Joint)
|
||||
VARIANT_BITFIELD_CAST(XRBodyTracker::JointFlags)
|
39
servers/xr/xr_controller_tracker.cpp
Normal file
39
servers/xr/xr_controller_tracker.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/**************************************************************************/
|
||||
/* xr_controller_tracker.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "xr_controller_tracker.h"
|
||||
|
||||
#include "core/input/input.h"
|
||||
|
||||
void XRControllerTracker::_bind_methods() {}
|
||||
|
||||
XRControllerTracker::XRControllerTracker() {
|
||||
type = XRServer::TRACKER_CONTROLLER;
|
||||
}
|
49
servers/xr/xr_controller_tracker.h
Normal file
49
servers/xr/xr_controller_tracker.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/**************************************************************************/
|
||||
/* xr_controller_tracker.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/os/thread_safe.h"
|
||||
#include "servers/xr/xr_positional_tracker.h"
|
||||
|
||||
/**
|
||||
The controller tracker object as an object that represents the position and orientation of a controller.
|
||||
*/
|
||||
|
||||
class XRControllerTracker : public XRPositionalTracker {
|
||||
GDCLASS(XRControllerTracker, XRPositionalTracker);
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
XRControllerTracker();
|
||||
};
|
230
servers/xr/xr_face_tracker.cpp
Normal file
230
servers/xr/xr_face_tracker.cpp
Normal file
@@ -0,0 +1,230 @@
|
||||
/**************************************************************************/
|
||||
/* xr_face_tracker.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "xr_face_tracker.h"
|
||||
|
||||
void XRFaceTracker::_bind_methods() {
|
||||
// Base Shapes
|
||||
BIND_ENUM_CONSTANT(FT_EYE_LOOK_OUT_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_LOOK_IN_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_LOOK_UP_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_LOOK_DOWN_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_LOOK_OUT_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_LOOK_IN_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_LOOK_UP_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_LOOK_DOWN_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_CLOSED_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_CLOSED_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_SQUINT_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_SQUINT_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_WIDE_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_WIDE_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_DILATION_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_DILATION_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_CONSTRICT_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_CONSTRICT_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_BROW_PINCH_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_BROW_PINCH_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_BROW_LOWERER_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_BROW_LOWERER_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_BROW_INNER_UP_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_BROW_INNER_UP_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_BROW_OUTER_UP_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_BROW_OUTER_UP_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_NOSE_SNEER_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_NOSE_SNEER_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_NASAL_DILATION_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_NASAL_DILATION_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_NASAL_CONSTRICT_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_NASAL_CONSTRICT_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_CHEEK_SQUINT_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_CHEEK_SQUINT_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_CHEEK_PUFF_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_CHEEK_PUFF_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_CHEEK_SUCK_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_CHEEK_SUCK_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_JAW_OPEN);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_CLOSED);
|
||||
BIND_ENUM_CONSTANT(FT_JAW_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_JAW_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_JAW_FORWARD);
|
||||
BIND_ENUM_CONSTANT(FT_JAW_BACKWARD);
|
||||
BIND_ENUM_CONSTANT(FT_JAW_CLENCH);
|
||||
BIND_ENUM_CONSTANT(FT_JAW_MANDIBLE_RAISE);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_SUCK_UPPER_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_SUCK_UPPER_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_SUCK_LOWER_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_SUCK_LOWER_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_SUCK_CORNER_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_SUCK_CORNER_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_FUNNEL_UPPER_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_FUNNEL_UPPER_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_FUNNEL_LOWER_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_FUNNEL_LOWER_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_PUCKER_UPPER_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_PUCKER_UPPER_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_PUCKER_LOWER_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_PUCKER_LOWER_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_UPPER_UP_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_UPPER_UP_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_LOWER_DOWN_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_LOWER_DOWN_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_UPPER_DEEPEN_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_UPPER_DEEPEN_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_UPPER_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_UPPER_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_LOWER_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_LOWER_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_CORNER_PULL_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_CORNER_PULL_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_CORNER_SLANT_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_CORNER_SLANT_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_FROWN_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_FROWN_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_STRETCH_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_STRETCH_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_DIMPLE_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_DIMPLE_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_RAISER_UPPER);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_RAISER_LOWER);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_PRESS_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_PRESS_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_TIGHTENER_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_TIGHTENER_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_TONGUE_OUT);
|
||||
BIND_ENUM_CONSTANT(FT_TONGUE_UP);
|
||||
BIND_ENUM_CONSTANT(FT_TONGUE_DOWN);
|
||||
BIND_ENUM_CONSTANT(FT_TONGUE_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_TONGUE_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_TONGUE_ROLL);
|
||||
BIND_ENUM_CONSTANT(FT_TONGUE_BLEND_DOWN);
|
||||
BIND_ENUM_CONSTANT(FT_TONGUE_CURL_UP);
|
||||
BIND_ENUM_CONSTANT(FT_TONGUE_SQUISH);
|
||||
BIND_ENUM_CONSTANT(FT_TONGUE_FLAT);
|
||||
BIND_ENUM_CONSTANT(FT_TONGUE_TWIST_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_TONGUE_TWIST_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_SOFT_PALATE_CLOSE);
|
||||
BIND_ENUM_CONSTANT(FT_THROAT_SWALLOW);
|
||||
BIND_ENUM_CONSTANT(FT_NECK_FLEX_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_NECK_FLEX_LEFT);
|
||||
// Blended Shapes
|
||||
BIND_ENUM_CONSTANT(FT_EYE_CLOSED);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_WIDE);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_SQUINT);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_DILATION);
|
||||
BIND_ENUM_CONSTANT(FT_EYE_CONSTRICT);
|
||||
BIND_ENUM_CONSTANT(FT_BROW_DOWN_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_BROW_DOWN_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_BROW_DOWN);
|
||||
BIND_ENUM_CONSTANT(FT_BROW_UP_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_BROW_UP_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_BROW_UP);
|
||||
BIND_ENUM_CONSTANT(FT_NOSE_SNEER);
|
||||
BIND_ENUM_CONSTANT(FT_NASAL_DILATION);
|
||||
BIND_ENUM_CONSTANT(FT_NASAL_CONSTRICT);
|
||||
BIND_ENUM_CONSTANT(FT_CHEEK_PUFF);
|
||||
BIND_ENUM_CONSTANT(FT_CHEEK_SUCK);
|
||||
BIND_ENUM_CONSTANT(FT_CHEEK_SQUINT);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_SUCK_UPPER);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_SUCK_LOWER);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_SUCK);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_FUNNEL_UPPER);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_FUNNEL_LOWER);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_FUNNEL);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_PUCKER_UPPER);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_PUCKER_LOWER);
|
||||
BIND_ENUM_CONSTANT(FT_LIP_PUCKER);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_UPPER_UP);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_LOWER_DOWN);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_OPEN);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_SMILE_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_SMILE_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_SMILE);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_SAD_RIGHT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_SAD_LEFT);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_SAD);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_STRETCH);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_DIMPLE);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_TIGHTENER);
|
||||
BIND_ENUM_CONSTANT(FT_MOUTH_PRESS);
|
||||
BIND_ENUM_CONSTANT(FT_MAX);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_blend_shape", "blend_shape"), &XRFaceTracker::get_blend_shape);
|
||||
ClassDB::bind_method(D_METHOD("set_blend_shape", "blend_shape", "weight"), &XRFaceTracker::set_blend_shape);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_blend_shapes"), &XRFaceTracker::get_blend_shapes);
|
||||
ClassDB::bind_method(D_METHOD("set_blend_shapes", "weights"), &XRFaceTracker::set_blend_shapes);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT32_ARRAY, "blend_shapes"), "set_blend_shapes", "get_blend_shapes");
|
||||
ADD_PROPERTY_DEFAULT("blend_shapes", PackedFloat32Array()); // To prevent ludicrously large default values.
|
||||
}
|
||||
|
||||
void XRFaceTracker::set_tracker_type(XRServer::TrackerType p_type) {
|
||||
ERR_FAIL_COND_MSG(p_type != XRServer::TRACKER_FACE, "XRFaceTracker must be of type TRACKER_FACE.");
|
||||
}
|
||||
|
||||
float XRFaceTracker::get_blend_shape(BlendShapeEntry p_blend_shape) const {
|
||||
// Fail if the blend shape index is out of range.
|
||||
ERR_FAIL_INDEX_V(p_blend_shape, FT_MAX, 0.0f);
|
||||
|
||||
// Return the blend shape value.
|
||||
return blend_shape_values[p_blend_shape];
|
||||
}
|
||||
|
||||
void XRFaceTracker::set_blend_shape(BlendShapeEntry p_blend_shape, float p_value) {
|
||||
// Fail if the blend shape index is out of range.
|
||||
ERR_FAIL_INDEX(p_blend_shape, FT_MAX);
|
||||
|
||||
// Save the new blend shape value.
|
||||
blend_shape_values[p_blend_shape] = p_value;
|
||||
}
|
||||
|
||||
PackedFloat32Array XRFaceTracker::get_blend_shapes() const {
|
||||
// Create a packed float32 array and copy the blend shape values into it.
|
||||
PackedFloat32Array data;
|
||||
data.resize(FT_MAX);
|
||||
memcpy(data.ptrw(), blend_shape_values, sizeof(blend_shape_values));
|
||||
|
||||
// Return the blend shape array.
|
||||
return data;
|
||||
}
|
||||
|
||||
void XRFaceTracker::set_blend_shapes(const PackedFloat32Array &p_blend_shapes) {
|
||||
// Fail if the blend shape array is not the correct size.
|
||||
ERR_FAIL_COND(p_blend_shapes.size() != FT_MAX);
|
||||
|
||||
// Copy the blend shape values into the blend shape array.
|
||||
memcpy(blend_shape_values, p_blend_shapes.ptr(), sizeof(blend_shape_values));
|
||||
}
|
||||
|
||||
XRFaceTracker::XRFaceTracker() {
|
||||
type = XRServer::TRACKER_FACE;
|
||||
}
|
214
servers/xr/xr_face_tracker.h
Normal file
214
servers/xr/xr_face_tracker.h
Normal file
@@ -0,0 +1,214 @@
|
||||
/**************************************************************************/
|
||||
/* xr_face_tracker.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "servers/xr/xr_tracker.h"
|
||||
|
||||
/**
|
||||
The XRFaceTracker class provides face blend shape weights.
|
||||
|
||||
The supported blend shapes are based on the Unified Expressions
|
||||
standard, and as such have a well defined mapping to ARKit, SRanipal,
|
||||
and Meta Movement standards.
|
||||
*/
|
||||
|
||||
class XRFaceTracker : public XRTracker {
|
||||
GDCLASS(XRFaceTracker, XRTracker);
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
public:
|
||||
enum BlendShapeEntry {
|
||||
// Base Shapes
|
||||
FT_EYE_LOOK_OUT_RIGHT, // Right eye looks outwards.
|
||||
FT_EYE_LOOK_IN_RIGHT, // Right eye looks inwards.
|
||||
FT_EYE_LOOK_UP_RIGHT, // Right eye looks upwards.
|
||||
FT_EYE_LOOK_DOWN_RIGHT, // Right eye looks downwards.
|
||||
FT_EYE_LOOK_OUT_LEFT, // Left eye looks outwards.
|
||||
FT_EYE_LOOK_IN_LEFT, // Left eye looks inwards.
|
||||
FT_EYE_LOOK_UP_LEFT, // Left eye looks upwards.
|
||||
FT_EYE_LOOK_DOWN_LEFT, // Left eye looks downwards.
|
||||
FT_EYE_CLOSED_RIGHT, // Closes the right eyelid.
|
||||
FT_EYE_CLOSED_LEFT, // Closes the left eyelid.
|
||||
FT_EYE_SQUINT_RIGHT, // Squeezes the right eye socket muscles.
|
||||
FT_EYE_SQUINT_LEFT, // Squeezes the left eye socket muscles.
|
||||
FT_EYE_WIDE_RIGHT, // Right eyelid widens beyond relaxed.
|
||||
FT_EYE_WIDE_LEFT, // Left eyelid widens beyond relaxed.
|
||||
FT_EYE_DILATION_RIGHT, // Dilates the right eye pupil.
|
||||
FT_EYE_DILATION_LEFT, // Dilates the left eye pupil.
|
||||
FT_EYE_CONSTRICT_RIGHT, // Constricts the right eye pupil.
|
||||
FT_EYE_CONSTRICT_LEFT, // Constricts the left eye pupil.
|
||||
FT_BROW_PINCH_RIGHT, // Right eyebrow pinches in.
|
||||
FT_BROW_PINCH_LEFT, // Left eyebrow pinches in.
|
||||
FT_BROW_LOWERER_RIGHT, // Outer right eyebrow pulls down.
|
||||
FT_BROW_LOWERER_LEFT, // Outer left eyebrow pulls down.
|
||||
FT_BROW_INNER_UP_RIGHT, // Inner right eyebrow pulls up.
|
||||
FT_BROW_INNER_UP_LEFT, // Inner left eyebrow pulls up.
|
||||
FT_BROW_OUTER_UP_RIGHT, // Outer right eyebrow pulls up.
|
||||
FT_BROW_OUTER_UP_LEFT, // Outer left eyebrow pulls up.
|
||||
FT_NOSE_SNEER_RIGHT, // Right side face sneers.
|
||||
FT_NOSE_SNEER_LEFT, // Left side face sneers.
|
||||
FT_NASAL_DILATION_RIGHT, // Right side nose canal dilates.
|
||||
FT_NASAL_DILATION_LEFT, // Left side nose canal dilates.
|
||||
FT_NASAL_CONSTRICT_RIGHT, // Right side nose canal constricts.
|
||||
FT_NASAL_CONSTRICT_LEFT, // Left side nose canal constricts.
|
||||
FT_CHEEK_SQUINT_RIGHT, // Raises the right side cheek.
|
||||
FT_CHEEK_SQUINT_LEFT, // Raises the left side cheek.
|
||||
FT_CHEEK_PUFF_RIGHT, // Puffs the right side cheek.
|
||||
FT_CHEEK_PUFF_LEFT, // Puffs the left side cheek.
|
||||
FT_CHEEK_SUCK_RIGHT, // Sucks in the right side cheek.
|
||||
FT_CHEEK_SUCK_LEFT, // Sucks in the left side cheek.
|
||||
FT_JAW_OPEN, // Opens jawbone.
|
||||
FT_MOUTH_CLOSED, // Closes the mouth.
|
||||
FT_JAW_RIGHT, // Pushes jawbone right.
|
||||
FT_JAW_LEFT, // Pushes jawbone left.
|
||||
FT_JAW_FORWARD, // Pushes jawbone forward.
|
||||
FT_JAW_BACKWARD, // Pushes jawbone backward.
|
||||
FT_JAW_CLENCH, // Flexes jaw muscles.
|
||||
FT_JAW_MANDIBLE_RAISE, // Raises the jawbone.
|
||||
FT_LIP_SUCK_UPPER_RIGHT, // Upper right lip part tucks in the mouth.
|
||||
FT_LIP_SUCK_UPPER_LEFT, // Upper left lip part tucks in the mouth.
|
||||
FT_LIP_SUCK_LOWER_RIGHT, // Lower right lip part tucks in the mouth.
|
||||
FT_LIP_SUCK_LOWER_LEFT, // Lower left lip part tucks in the mouth.
|
||||
FT_LIP_SUCK_CORNER_RIGHT, // Right lip corner folds into the mouth.
|
||||
FT_LIP_SUCK_CORNER_LEFT, // Left lip corner folds into the mouth.
|
||||
FT_LIP_FUNNEL_UPPER_RIGHT, // Upper right lip part pushes into a funnel.
|
||||
FT_LIP_FUNNEL_UPPER_LEFT, // Upper left lip part pushes into a funnel.
|
||||
FT_LIP_FUNNEL_LOWER_RIGHT, // Lower right lip part pushes into a funnel.
|
||||
FT_LIP_FUNNEL_LOWER_LEFT, // Lower left lip part pushes into a funnel.
|
||||
FT_LIP_PUCKER_UPPER_RIGHT, // Upper right lip part pushes outwards.
|
||||
FT_LIP_PUCKER_UPPER_LEFT, // Upper left lip part pushes outwards.
|
||||
FT_LIP_PUCKER_LOWER_RIGHT, // Lower right lip part pushes outwards.
|
||||
FT_LIP_PUCKER_LOWER_LEFT, // Lower left lip part pushes outwards.
|
||||
FT_MOUTH_UPPER_UP_RIGHT, // Upper right part of the lip pulls up.
|
||||
FT_MOUTH_UPPER_UP_LEFT, // Upper left part of the lip pulls up.
|
||||
FT_MOUTH_LOWER_DOWN_RIGHT, // Lower right part of the lip pulls up.
|
||||
FT_MOUTH_LOWER_DOWN_LEFT, // Lower left part of the lip pulls up.
|
||||
FT_MOUTH_UPPER_DEEPEN_RIGHT, // Upper right lip part pushes in the cheek.
|
||||
FT_MOUTH_UPPER_DEEPEN_LEFT, // Upper left lip part pushes in the cheek.
|
||||
FT_MOUTH_UPPER_RIGHT, // Moves upper lip right.
|
||||
FT_MOUTH_UPPER_LEFT, // Moves upper lip left.
|
||||
FT_MOUTH_LOWER_RIGHT, // Moves lower lip right.
|
||||
FT_MOUTH_LOWER_LEFT, // Moves lower lip left.
|
||||
FT_MOUTH_CORNER_PULL_RIGHT, // Right lip corner pulls diagonally up and out.
|
||||
FT_MOUTH_CORNER_PULL_LEFT, // Left lip corner pulls diagonally up and out.
|
||||
FT_MOUTH_CORNER_SLANT_RIGHT, // Right corner lip slants up.
|
||||
FT_MOUTH_CORNER_SLANT_LEFT, // Left corner lip slants up.
|
||||
FT_MOUTH_FROWN_RIGHT, // Right corner lip pulls down.
|
||||
FT_MOUTH_FROWN_LEFT, // Left corner lip pulls down.
|
||||
FT_MOUTH_STRETCH_RIGHT, // Mouth corner lip pulls out and down.
|
||||
FT_MOUTH_STRETCH_LEFT, // Mouth corner lip pulls out and down.
|
||||
FT_MOUTH_DIMPLE_RIGHT, // Right lip corner is pushed backwards.
|
||||
FT_MOUTH_DIMPLE_LEFT, // Left lip corner is pushed backwards.
|
||||
FT_MOUTH_RAISER_UPPER, // Raises and slightly pushes out the upper mouth.
|
||||
FT_MOUTH_RAISER_LOWER, // Raises and slightly pushes out the lower mouth.
|
||||
FT_MOUTH_PRESS_RIGHT, // Right side lips press and flatten together vertically.
|
||||
FT_MOUTH_PRESS_LEFT, // Left side lips press and flatten together vertically.
|
||||
FT_MOUTH_TIGHTENER_RIGHT, // Right side lips squeeze together horizontally.
|
||||
FT_MOUTH_TIGHTENER_LEFT, // Left side lips squeeze together horizontally.
|
||||
FT_TONGUE_OUT, // Tongue visibly sticks out of the mouth.
|
||||
FT_TONGUE_UP, // Tongue points upwards.
|
||||
FT_TONGUE_DOWN, // Tongue points downwards.
|
||||
FT_TONGUE_RIGHT, // Tongue points right.
|
||||
FT_TONGUE_LEFT, // Tongue points left.
|
||||
FT_TONGUE_ROLL, // Sides of the tongue funnel, creating a roll.
|
||||
FT_TONGUE_BLEND_DOWN, // Tongue arches up then down inside the mouth.
|
||||
FT_TONGUE_CURL_UP, // Tongue arches down then up inside the mouth.
|
||||
FT_TONGUE_SQUISH, // Tongue squishes together and thickens.
|
||||
FT_TONGUE_FLAT, // Tongue flattens and thins out.
|
||||
FT_TONGUE_TWIST_RIGHT, // Tongue tip rotates clockwise, with the rest following gradually.
|
||||
FT_TONGUE_TWIST_LEFT, // Tongue tip rotates counter-clockwise, with the rest following gradually.
|
||||
FT_SOFT_PALATE_CLOSE, // Inner mouth throat closes.
|
||||
FT_THROAT_SWALLOW, // The Adam's apple visibly swallows.
|
||||
FT_NECK_FLEX_RIGHT, // Right side neck visibly flexes.
|
||||
FT_NECK_FLEX_LEFT, // Left side neck visibly flexes.
|
||||
// Blended Shapes
|
||||
FT_EYE_CLOSED, // Closes both eye lids.
|
||||
FT_EYE_WIDE, // Widens both eye lids.
|
||||
FT_EYE_SQUINT, // Squints both eye lids.
|
||||
FT_EYE_DILATION, // Dilates both pupils.
|
||||
FT_EYE_CONSTRICT, // Constricts both pupils.
|
||||
FT_BROW_DOWN_RIGHT, // Pulls the right eyebrow down and in.
|
||||
FT_BROW_DOWN_LEFT, // Pulls the left eyebrow down and in.
|
||||
FT_BROW_DOWN, // Pulls both eyebrows down and in.
|
||||
FT_BROW_UP_RIGHT, // Right brow appears worried.
|
||||
FT_BROW_UP_LEFT, // Left brow appears worried.
|
||||
FT_BROW_UP, // Both brows appear worried.
|
||||
FT_NOSE_SNEER, // Entire face sneers.
|
||||
FT_NASAL_DILATION, // Both nose canals dilate.
|
||||
FT_NASAL_CONSTRICT, // Both nose canals constrict.
|
||||
FT_CHEEK_PUFF, // Puffs both cheeks.
|
||||
FT_CHEEK_SUCK, // Sucks in both cheeks.
|
||||
FT_CHEEK_SQUINT, // Raises both cheeks.
|
||||
FT_LIP_SUCK_UPPER, // Tucks in the upper lips.
|
||||
FT_LIP_SUCK_LOWER, // Tucks in the lower lips.
|
||||
FT_LIP_SUCK, // Tucks in both lips.
|
||||
FT_LIP_FUNNEL_UPPER, // Funnels in the upper lips.
|
||||
FT_LIP_FUNNEL_LOWER, // Funnels in the lower lips.
|
||||
FT_LIP_FUNNEL, // Funnels in both lips.
|
||||
FT_LIP_PUCKER_UPPER, // Upper lip part pushes outwards.
|
||||
FT_LIP_PUCKER_LOWER, // Lower lip part pushes outwards.
|
||||
FT_LIP_PUCKER, // Lips push outwards.
|
||||
FT_MOUTH_UPPER_UP, // Raises the upper lips.
|
||||
FT_MOUTH_LOWER_DOWN, // Lowers the lower lips.
|
||||
FT_MOUTH_OPEN, // Mouth opens, revealing teeth.
|
||||
FT_MOUTH_RIGHT, // Moves mouth right.
|
||||
FT_MOUTH_LEFT, // Moves mouth left.
|
||||
FT_MOUTH_SMILE_RIGHT, // Right side of the mouth smiles.
|
||||
FT_MOUTH_SMILE_LEFT, // Left side of the mouth smiles.
|
||||
FT_MOUTH_SMILE, // Mouth expresses a smile.
|
||||
FT_MOUTH_SAD_RIGHT, // Right side of the mouth expresses sadness.
|
||||
FT_MOUTH_SAD_LEFT, // Left side of the mouth expresses sadness.
|
||||
FT_MOUTH_SAD, // Mouth expresses sadness.
|
||||
FT_MOUTH_STRETCH, // Mouth stretches.
|
||||
FT_MOUTH_DIMPLE, // Lip corners dimple.
|
||||
FT_MOUTH_TIGHTENER, // Mouth tightens.
|
||||
FT_MOUTH_PRESS, // Mouth presses together.
|
||||
FT_MAX // Maximum blend shape.
|
||||
};
|
||||
|
||||
void set_tracker_type(XRServer::TrackerType p_type) override;
|
||||
|
||||
float get_blend_shape(BlendShapeEntry p_blend_shape) const;
|
||||
void set_blend_shape(BlendShapeEntry p_blend_shape, float p_value);
|
||||
|
||||
PackedFloat32Array get_blend_shapes() const;
|
||||
void set_blend_shapes(const PackedFloat32Array &p_blend_shapes);
|
||||
|
||||
XRFaceTracker();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
private:
|
||||
float blend_shape_values[FT_MAX] = {};
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(XRFaceTracker::BlendShapeEntry);
|
178
servers/xr/xr_hand_tracker.cpp
Normal file
178
servers/xr/xr_hand_tracker.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
/**************************************************************************/
|
||||
/* xr_hand_tracker.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "xr_hand_tracker.h"
|
||||
|
||||
void XRHandTracker::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_has_tracking_data", "has_data"), &XRHandTracker::set_has_tracking_data);
|
||||
ClassDB::bind_method(D_METHOD("get_has_tracking_data"), &XRHandTracker::get_has_tracking_data);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_hand_tracking_source", "source"), &XRHandTracker::set_hand_tracking_source);
|
||||
ClassDB::bind_method(D_METHOD("get_hand_tracking_source"), &XRHandTracker::get_hand_tracking_source);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_hand_joint_flags", "joint", "flags"), &XRHandTracker::set_hand_joint_flags);
|
||||
ClassDB::bind_method(D_METHOD("get_hand_joint_flags", "joint"), &XRHandTracker::get_hand_joint_flags);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_hand_joint_transform", "joint", "transform"), &XRHandTracker::set_hand_joint_transform);
|
||||
ClassDB::bind_method(D_METHOD("get_hand_joint_transform", "joint"), &XRHandTracker::get_hand_joint_transform);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_hand_joint_radius", "joint", "radius"), &XRHandTracker::set_hand_joint_radius);
|
||||
ClassDB::bind_method(D_METHOD("get_hand_joint_radius", "joint"), &XRHandTracker::get_hand_joint_radius);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_hand_joint_linear_velocity", "joint", "linear_velocity"), &XRHandTracker::set_hand_joint_linear_velocity);
|
||||
ClassDB::bind_method(D_METHOD("get_hand_joint_linear_velocity", "joint"), &XRHandTracker::get_hand_joint_linear_velocity);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_hand_joint_angular_velocity", "joint", "angular_velocity"), &XRHandTracker::set_hand_joint_angular_velocity);
|
||||
ClassDB::bind_method(D_METHOD("get_hand_joint_angular_velocity", "joint"), &XRHandTracker::get_hand_joint_angular_velocity);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "has_tracking_data", PROPERTY_HINT_NONE), "set_has_tracking_data", "get_has_tracking_data");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "hand_tracking_source", PROPERTY_HINT_ENUM, "Unknown,Unobstructed,Controller"), "set_hand_tracking_source", "get_hand_tracking_source");
|
||||
|
||||
BIND_ENUM_CONSTANT(HAND_TRACKING_SOURCE_UNKNOWN);
|
||||
BIND_ENUM_CONSTANT(HAND_TRACKING_SOURCE_UNOBSTRUCTED);
|
||||
BIND_ENUM_CONSTANT(HAND_TRACKING_SOURCE_CONTROLLER);
|
||||
BIND_ENUM_CONSTANT(HAND_TRACKING_SOURCE_NOT_TRACKED);
|
||||
BIND_ENUM_CONSTANT(HAND_TRACKING_SOURCE_MAX);
|
||||
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_PALM);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_WRIST);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_THUMB_METACARPAL);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_THUMB_PHALANX_PROXIMAL);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_THUMB_PHALANX_DISTAL);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_THUMB_TIP);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_INDEX_FINGER_METACARPAL);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_INDEX_FINGER_PHALANX_PROXIMAL);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_INDEX_FINGER_PHALANX_INTERMEDIATE);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_INDEX_FINGER_PHALANX_DISTAL);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_INDEX_FINGER_TIP);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_MIDDLE_FINGER_METACARPAL);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_MIDDLE_FINGER_PHALANX_PROXIMAL);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_MIDDLE_FINGER_PHALANX_INTERMEDIATE);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_MIDDLE_FINGER_PHALANX_DISTAL);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_MIDDLE_FINGER_TIP);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_RING_FINGER_METACARPAL);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_RING_FINGER_PHALANX_PROXIMAL);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_RING_FINGER_PHALANX_INTERMEDIATE);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_RING_FINGER_PHALANX_DISTAL);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_RING_FINGER_TIP);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_PINKY_FINGER_METACARPAL);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_PINKY_FINGER_PHALANX_PROXIMAL);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_PINKY_FINGER_PHALANX_INTERMEDIATE);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_PINKY_FINGER_PHALANX_DISTAL);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_PINKY_FINGER_TIP);
|
||||
BIND_ENUM_CONSTANT(HAND_JOINT_MAX);
|
||||
|
||||
BIND_BITFIELD_FLAG(HAND_JOINT_FLAG_ORIENTATION_VALID);
|
||||
BIND_BITFIELD_FLAG(HAND_JOINT_FLAG_ORIENTATION_TRACKED);
|
||||
BIND_BITFIELD_FLAG(HAND_JOINT_FLAG_POSITION_VALID);
|
||||
BIND_BITFIELD_FLAG(HAND_JOINT_FLAG_POSITION_TRACKED);
|
||||
BIND_BITFIELD_FLAG(HAND_JOINT_FLAG_LINEAR_VELOCITY_VALID);
|
||||
BIND_BITFIELD_FLAG(HAND_JOINT_FLAG_ANGULAR_VELOCITY_VALID);
|
||||
}
|
||||
|
||||
void XRHandTracker::set_tracker_type(XRServer::TrackerType p_type) {
|
||||
ERR_FAIL_COND_MSG(p_type != XRServer::TRACKER_HAND, "XRHandTracker must be of type TRACKER_HAND.");
|
||||
}
|
||||
|
||||
void XRHandTracker::set_tracker_hand(const XRPositionalTracker::TrackerHand p_hand) {
|
||||
ERR_FAIL_COND_MSG(p_hand != TRACKER_HAND_LEFT && p_hand != TRACKER_HAND_RIGHT, "XRHandTracker must specify hand.");
|
||||
tracker_hand = p_hand;
|
||||
}
|
||||
|
||||
void XRHandTracker::set_has_tracking_data(bool p_has_tracking_data) {
|
||||
has_tracking_data = p_has_tracking_data;
|
||||
}
|
||||
|
||||
bool XRHandTracker::get_has_tracking_data() const {
|
||||
return has_tracking_data;
|
||||
}
|
||||
|
||||
void XRHandTracker::set_hand_tracking_source(XRHandTracker::HandTrackingSource p_source) {
|
||||
hand_tracking_source = p_source;
|
||||
}
|
||||
|
||||
XRHandTracker::HandTrackingSource XRHandTracker::get_hand_tracking_source() const {
|
||||
return hand_tracking_source;
|
||||
}
|
||||
|
||||
void XRHandTracker::set_hand_joint_flags(XRHandTracker::HandJoint p_joint, BitField<XRHandTracker::HandJointFlags> p_flags) {
|
||||
ERR_FAIL_INDEX(p_joint, HAND_JOINT_MAX);
|
||||
hand_joint_flags[p_joint] = p_flags;
|
||||
}
|
||||
|
||||
BitField<XRHandTracker::HandJointFlags> XRHandTracker::get_hand_joint_flags(XRHandTracker::HandJoint p_joint) const {
|
||||
ERR_FAIL_INDEX_V(p_joint, HAND_JOINT_MAX, BitField<HandJointFlags>());
|
||||
return hand_joint_flags[p_joint];
|
||||
}
|
||||
|
||||
void XRHandTracker::set_hand_joint_transform(XRHandTracker::HandJoint p_joint, const Transform3D &p_transform) {
|
||||
ERR_FAIL_INDEX(p_joint, HAND_JOINT_MAX);
|
||||
hand_joint_transforms[p_joint] = p_transform;
|
||||
}
|
||||
|
||||
Transform3D XRHandTracker::get_hand_joint_transform(XRHandTracker::HandJoint p_joint) const {
|
||||
ERR_FAIL_INDEX_V(p_joint, HAND_JOINT_MAX, Transform3D());
|
||||
return hand_joint_transforms[p_joint];
|
||||
}
|
||||
|
||||
void XRHandTracker::set_hand_joint_radius(XRHandTracker::HandJoint p_joint, float p_radius) {
|
||||
ERR_FAIL_INDEX(p_joint, HAND_JOINT_MAX);
|
||||
hand_joint_radii[p_joint] = p_radius;
|
||||
}
|
||||
|
||||
float XRHandTracker::get_hand_joint_radius(XRHandTracker::HandJoint p_joint) const {
|
||||
ERR_FAIL_INDEX_V(p_joint, HAND_JOINT_MAX, 0.0);
|
||||
return hand_joint_radii[p_joint];
|
||||
}
|
||||
|
||||
void XRHandTracker::set_hand_joint_linear_velocity(XRHandTracker::HandJoint p_joint, const Vector3 &p_velocity) {
|
||||
ERR_FAIL_INDEX(p_joint, HAND_JOINT_MAX);
|
||||
hand_joint_linear_velocities[p_joint] = p_velocity;
|
||||
}
|
||||
|
||||
Vector3 XRHandTracker::get_hand_joint_linear_velocity(XRHandTracker::HandJoint p_joint) const {
|
||||
ERR_FAIL_INDEX_V(p_joint, HAND_JOINT_MAX, Vector3());
|
||||
return hand_joint_linear_velocities[p_joint];
|
||||
}
|
||||
|
||||
void XRHandTracker::set_hand_joint_angular_velocity(XRHandTracker::HandJoint p_joint, const Vector3 &p_velocity) {
|
||||
ERR_FAIL_INDEX(p_joint, HAND_JOINT_MAX);
|
||||
hand_joint_angular_velocities[p_joint] = p_velocity;
|
||||
}
|
||||
|
||||
Vector3 XRHandTracker::get_hand_joint_angular_velocity(XRHandTracker::HandJoint p_joint) const {
|
||||
ERR_FAIL_INDEX_V(p_joint, HAND_JOINT_MAX, Vector3());
|
||||
return hand_joint_angular_velocities[p_joint];
|
||||
}
|
||||
|
||||
XRHandTracker::XRHandTracker() {
|
||||
type = XRServer::TRACKER_HAND;
|
||||
tracker_hand = TRACKER_HAND_LEFT;
|
||||
}
|
129
servers/xr/xr_hand_tracker.h
Normal file
129
servers/xr/xr_hand_tracker.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/**************************************************************************/
|
||||
/* xr_hand_tracker.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "servers/xr/xr_positional_tracker.h"
|
||||
|
||||
class XRHandTracker : public XRPositionalTracker {
|
||||
GDCLASS(XRHandTracker, XRPositionalTracker);
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
public:
|
||||
enum HandTrackingSource {
|
||||
HAND_TRACKING_SOURCE_UNKNOWN,
|
||||
HAND_TRACKING_SOURCE_UNOBSTRUCTED,
|
||||
HAND_TRACKING_SOURCE_CONTROLLER,
|
||||
HAND_TRACKING_SOURCE_NOT_TRACKED,
|
||||
HAND_TRACKING_SOURCE_MAX
|
||||
};
|
||||
|
||||
enum HandJoint {
|
||||
HAND_JOINT_PALM,
|
||||
HAND_JOINT_WRIST,
|
||||
HAND_JOINT_THUMB_METACARPAL,
|
||||
HAND_JOINT_THUMB_PHALANX_PROXIMAL,
|
||||
HAND_JOINT_THUMB_PHALANX_DISTAL,
|
||||
HAND_JOINT_THUMB_TIP,
|
||||
HAND_JOINT_INDEX_FINGER_METACARPAL,
|
||||
HAND_JOINT_INDEX_FINGER_PHALANX_PROXIMAL,
|
||||
HAND_JOINT_INDEX_FINGER_PHALANX_INTERMEDIATE,
|
||||
HAND_JOINT_INDEX_FINGER_PHALANX_DISTAL,
|
||||
HAND_JOINT_INDEX_FINGER_TIP,
|
||||
HAND_JOINT_MIDDLE_FINGER_METACARPAL,
|
||||
HAND_JOINT_MIDDLE_FINGER_PHALANX_PROXIMAL,
|
||||
HAND_JOINT_MIDDLE_FINGER_PHALANX_INTERMEDIATE,
|
||||
HAND_JOINT_MIDDLE_FINGER_PHALANX_DISTAL,
|
||||
HAND_JOINT_MIDDLE_FINGER_TIP,
|
||||
HAND_JOINT_RING_FINGER_METACARPAL,
|
||||
HAND_JOINT_RING_FINGER_PHALANX_PROXIMAL,
|
||||
HAND_JOINT_RING_FINGER_PHALANX_INTERMEDIATE,
|
||||
HAND_JOINT_RING_FINGER_PHALANX_DISTAL,
|
||||
HAND_JOINT_RING_FINGER_TIP,
|
||||
HAND_JOINT_PINKY_FINGER_METACARPAL,
|
||||
HAND_JOINT_PINKY_FINGER_PHALANX_PROXIMAL,
|
||||
HAND_JOINT_PINKY_FINGER_PHALANX_INTERMEDIATE,
|
||||
HAND_JOINT_PINKY_FINGER_PHALANX_DISTAL,
|
||||
HAND_JOINT_PINKY_FINGER_TIP,
|
||||
HAND_JOINT_MAX,
|
||||
};
|
||||
|
||||
enum HandJointFlags {
|
||||
HAND_JOINT_FLAG_ORIENTATION_VALID = 1,
|
||||
HAND_JOINT_FLAG_ORIENTATION_TRACKED = 2,
|
||||
HAND_JOINT_FLAG_POSITION_VALID = 4,
|
||||
HAND_JOINT_FLAG_POSITION_TRACKED = 8,
|
||||
HAND_JOINT_FLAG_LINEAR_VELOCITY_VALID = 16,
|
||||
HAND_JOINT_FLAG_ANGULAR_VELOCITY_VALID = 32,
|
||||
};
|
||||
|
||||
void set_tracker_type(XRServer::TrackerType p_type) override;
|
||||
void set_tracker_hand(const XRPositionalTracker::TrackerHand p_hand) override;
|
||||
|
||||
void set_has_tracking_data(bool p_has_tracking_data);
|
||||
bool get_has_tracking_data() const;
|
||||
|
||||
void set_hand_tracking_source(HandTrackingSource p_source);
|
||||
HandTrackingSource get_hand_tracking_source() const;
|
||||
|
||||
void set_hand_joint_flags(HandJoint p_joint, BitField<HandJointFlags> p_flags);
|
||||
BitField<HandJointFlags> get_hand_joint_flags(HandJoint p_joint) const;
|
||||
|
||||
void set_hand_joint_transform(HandJoint p_joint, const Transform3D &p_transform);
|
||||
Transform3D get_hand_joint_transform(HandJoint p_joint) const;
|
||||
|
||||
void set_hand_joint_radius(HandJoint p_joint, float p_radius);
|
||||
float get_hand_joint_radius(HandJoint p_joint) const;
|
||||
|
||||
void set_hand_joint_linear_velocity(HandJoint p_joint, const Vector3 &p_velocity);
|
||||
Vector3 get_hand_joint_linear_velocity(HandJoint p_joint) const;
|
||||
|
||||
void set_hand_joint_angular_velocity(HandJoint p_joint, const Vector3 &p_velocity);
|
||||
Vector3 get_hand_joint_angular_velocity(HandJoint p_joint) const;
|
||||
|
||||
XRHandTracker();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
private:
|
||||
bool has_tracking_data = false;
|
||||
HandTrackingSource hand_tracking_source = HAND_TRACKING_SOURCE_UNKNOWN;
|
||||
|
||||
BitField<HandJointFlags> hand_joint_flags[HAND_JOINT_MAX];
|
||||
Transform3D hand_joint_transforms[HAND_JOINT_MAX];
|
||||
float hand_joint_radii[HAND_JOINT_MAX] = {};
|
||||
Vector3 hand_joint_linear_velocities[HAND_JOINT_MAX];
|
||||
Vector3 hand_joint_angular_velocities[HAND_JOINT_MAX];
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(XRHandTracker::HandTrackingSource)
|
||||
VARIANT_ENUM_CAST(XRHandTracker::HandJoint)
|
||||
VARIANT_BITFIELD_CAST(XRHandTracker::HandJointFlags)
|
228
servers/xr/xr_interface.cpp
Normal file
228
servers/xr/xr_interface.cpp
Normal file
@@ -0,0 +1,228 @@
|
||||
/**************************************************************************/
|
||||
/* xr_interface.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "xr_interface.h"
|
||||
|
||||
void XRInterface::_bind_methods() {
|
||||
ADD_SIGNAL(MethodInfo("play_area_changed", PropertyInfo(Variant::INT, "mode")));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_name"), &XRInterface::get_name);
|
||||
ClassDB::bind_method(D_METHOD("get_capabilities"), &XRInterface::get_capabilities);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_primary"), &XRInterface::is_primary);
|
||||
ClassDB::bind_method(D_METHOD("set_primary", "primary"), &XRInterface::set_primary);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_initialized"), &XRInterface::is_initialized);
|
||||
ClassDB::bind_method(D_METHOD("initialize"), &XRInterface::initialize);
|
||||
ClassDB::bind_method(D_METHOD("uninitialize"), &XRInterface::uninitialize);
|
||||
ClassDB::bind_method(D_METHOD("get_system_info"), &XRInterface::get_system_info);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_tracking_status"), &XRInterface::get_tracking_status);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_render_target_size"), &XRInterface::get_render_target_size);
|
||||
ClassDB::bind_method(D_METHOD("get_view_count"), &XRInterface::get_view_count);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("trigger_haptic_pulse", "action_name", "tracker_name", "frequency", "amplitude", "duration_sec", "delay_sec"), &XRInterface::trigger_haptic_pulse);
|
||||
|
||||
ADD_GROUP("Interface", "interface_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interface_is_primary"), "set_primary", "is_primary");
|
||||
|
||||
// methods and properties specific to VR...
|
||||
ClassDB::bind_method(D_METHOD("supports_play_area_mode", "mode"), &XRInterface::supports_play_area_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_play_area_mode"), &XRInterface::get_play_area_mode);
|
||||
ClassDB::bind_method(D_METHOD("set_play_area_mode", "mode"), &XRInterface::set_play_area_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_play_area"), &XRInterface::get_play_area);
|
||||
|
||||
ADD_GROUP("XR", "xr_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "xr_play_area_mode", PROPERTY_HINT_ENUM, "Unknown,3DOF,Sitting,Roomscale,Stage"), "set_play_area_mode", "get_play_area_mode");
|
||||
|
||||
// methods and properties specific to AR....
|
||||
ClassDB::bind_method(D_METHOD("get_anchor_detection_is_enabled"), &XRInterface::get_anchor_detection_is_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_anchor_detection_is_enabled", "enable"), &XRInterface::set_anchor_detection_is_enabled);
|
||||
ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &XRInterface::get_camera_feed_id);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_passthrough_supported"), &XRInterface::is_passthrough_supported);
|
||||
ClassDB::bind_method(D_METHOD("is_passthrough_enabled"), &XRInterface::is_passthrough_enabled);
|
||||
ClassDB::bind_method(D_METHOD("start_passthrough"), &XRInterface::start_passthrough);
|
||||
ClassDB::bind_method(D_METHOD("stop_passthrough"), &XRInterface::stop_passthrough);
|
||||
ClassDB::bind_method(D_METHOD("get_transform_for_view", "view", "cam_transform"), &XRInterface::get_transform_for_view);
|
||||
ClassDB::bind_method(D_METHOD("get_projection_for_view", "view", "aspect", "near", "far"), &XRInterface::get_projection_for_view);
|
||||
|
||||
/** environment blend mode. */
|
||||
ClassDB::bind_method(D_METHOD("get_supported_environment_blend_modes"), &XRInterface::get_supported_environment_blend_modes);
|
||||
ClassDB::bind_method(D_METHOD("set_environment_blend_mode", "mode"), &XRInterface::set_environment_blend_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_environment_blend_mode"), &XRInterface::get_environment_blend_mode);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "environment_blend_mode"), "set_environment_blend_mode", "get_environment_blend_mode");
|
||||
|
||||
ADD_GROUP("AR", "ar_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ar_is_anchor_detection_enabled"), "set_anchor_detection_is_enabled", "get_anchor_detection_is_enabled");
|
||||
|
||||
BIND_ENUM_CONSTANT(XR_NONE);
|
||||
BIND_ENUM_CONSTANT(XR_MONO);
|
||||
BIND_ENUM_CONSTANT(XR_STEREO);
|
||||
BIND_ENUM_CONSTANT(XR_QUAD);
|
||||
BIND_ENUM_CONSTANT(XR_VR);
|
||||
BIND_ENUM_CONSTANT(XR_AR);
|
||||
BIND_ENUM_CONSTANT(XR_EXTERNAL);
|
||||
|
||||
BIND_ENUM_CONSTANT(XR_NORMAL_TRACKING);
|
||||
BIND_ENUM_CONSTANT(XR_EXCESSIVE_MOTION);
|
||||
BIND_ENUM_CONSTANT(XR_INSUFFICIENT_FEATURES);
|
||||
BIND_ENUM_CONSTANT(XR_UNKNOWN_TRACKING);
|
||||
BIND_ENUM_CONSTANT(XR_NOT_TRACKING);
|
||||
|
||||
BIND_ENUM_CONSTANT(XR_PLAY_AREA_UNKNOWN);
|
||||
BIND_ENUM_CONSTANT(XR_PLAY_AREA_3DOF);
|
||||
BIND_ENUM_CONSTANT(XR_PLAY_AREA_SITTING);
|
||||
BIND_ENUM_CONSTANT(XR_PLAY_AREA_ROOMSCALE);
|
||||
BIND_ENUM_CONSTANT(XR_PLAY_AREA_STAGE);
|
||||
BIND_ENUM_CONSTANT(XR_PLAY_AREA_CUSTOM);
|
||||
|
||||
BIND_ENUM_CONSTANT(XR_ENV_BLEND_MODE_OPAQUE);
|
||||
BIND_ENUM_CONSTANT(XR_ENV_BLEND_MODE_ADDITIVE);
|
||||
BIND_ENUM_CONSTANT(XR_ENV_BLEND_MODE_ALPHA_BLEND);
|
||||
|
||||
BIND_ENUM_CONSTANT(XR_VRS_TEXTURE_FORMAT_UNIFIED);
|
||||
BIND_ENUM_CONSTANT(XR_VRS_TEXTURE_FORMAT_FRAGMENT_SHADING_RATE);
|
||||
BIND_ENUM_CONSTANT(XR_VRS_TEXTURE_FORMAT_FRAGMENT_DENSITY_MAP);
|
||||
}
|
||||
|
||||
bool XRInterface::is_primary() {
|
||||
XRServer *xr_server = XRServer::get_singleton();
|
||||
ERR_FAIL_NULL_V(xr_server, false);
|
||||
|
||||
return xr_server->get_primary_interface() == this;
|
||||
}
|
||||
|
||||
void XRInterface::set_primary(bool p_primary) {
|
||||
XRServer *xr_server = XRServer::get_singleton();
|
||||
ERR_FAIL_NULL(xr_server);
|
||||
|
||||
if (p_primary) {
|
||||
ERR_FAIL_COND(!is_initialized());
|
||||
|
||||
xr_server->set_primary_interface(this);
|
||||
} else if (xr_server->get_primary_interface() == this) {
|
||||
xr_server->set_primary_interface(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
XRInterface::XRInterface() {}
|
||||
|
||||
XRInterface::~XRInterface() {}
|
||||
|
||||
// query if this interface supports this play area mode
|
||||
bool XRInterface::supports_play_area_mode(XRInterface::PlayAreaMode p_mode) {
|
||||
return p_mode == XR_PLAY_AREA_UNKNOWN;
|
||||
}
|
||||
|
||||
// get the current play area mode
|
||||
XRInterface::PlayAreaMode XRInterface::get_play_area_mode() const {
|
||||
return XR_PLAY_AREA_UNKNOWN;
|
||||
}
|
||||
|
||||
// change the play area mode, note that this should return false if the mode is not available
|
||||
bool XRInterface::set_play_area_mode(XRInterface::PlayAreaMode p_mode) {
|
||||
return p_mode == XR_PLAY_AREA_UNKNOWN;
|
||||
}
|
||||
|
||||
// if available, returns an array of vectors denoting the play area the player can move around in
|
||||
PackedVector3Array XRInterface::get_play_area() const {
|
||||
// Return an empty array by default.
|
||||
// Note implementation is responsible for applying our reference frame and world scale to the raw data.
|
||||
// `play_area_changed` should be emitted if play area data is available and either the reference frame or world scale changes.
|
||||
return PackedVector3Array();
|
||||
}
|
||||
|
||||
/** these will only be implemented on AR interfaces, so we want dummies for VR **/
|
||||
bool XRInterface::get_anchor_detection_is_enabled() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void XRInterface::set_anchor_detection_is_enabled(bool p_enable) {
|
||||
}
|
||||
|
||||
int XRInterface::get_camera_feed_id() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
RID XRInterface::get_vrs_texture() {
|
||||
return RID();
|
||||
}
|
||||
|
||||
/** these are optional, so we want dummies **/
|
||||
|
||||
RID XRInterface::get_color_texture() {
|
||||
return RID();
|
||||
}
|
||||
|
||||
RID XRInterface::get_depth_texture() {
|
||||
return RID();
|
||||
}
|
||||
|
||||
RID XRInterface::get_velocity_texture() {
|
||||
return RID();
|
||||
}
|
||||
|
||||
RID XRInterface::get_velocity_depth_texture() {
|
||||
return RID();
|
||||
}
|
||||
|
||||
Size2i XRInterface::get_velocity_target_size() {
|
||||
return Size2i();
|
||||
}
|
||||
|
||||
Rect2i XRInterface::get_render_region() {
|
||||
return Rect2i();
|
||||
}
|
||||
|
||||
PackedStringArray XRInterface::get_suggested_tracker_names() const {
|
||||
PackedStringArray arr;
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
PackedStringArray XRInterface::get_suggested_pose_names(const StringName &p_tracker_name) const {
|
||||
PackedStringArray arr;
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
XRInterface::TrackingStatus XRInterface::get_tracking_status() const {
|
||||
return XR_UNKNOWN_TRACKING;
|
||||
}
|
||||
|
||||
void XRInterface::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) {
|
||||
}
|
||||
|
||||
Array XRInterface::get_supported_environment_blend_modes() {
|
||||
Array default_blend_modes = { XR_ENV_BLEND_MODE_OPAQUE };
|
||||
return default_blend_modes;
|
||||
}
|
178
servers/xr/xr_interface.h
Normal file
178
servers/xr/xr_interface.h
Normal file
@@ -0,0 +1,178 @@
|
||||
/**************************************************************************/
|
||||
/* xr_interface.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/math/projection.h"
|
||||
#include "core/os/thread_safe.h"
|
||||
#include "servers/xr_server.h"
|
||||
#include "xr_vrs.h"
|
||||
|
||||
// forward declaration
|
||||
struct BlitToScreen;
|
||||
|
||||
/**
|
||||
The XR interface is a template class on top of which we build interface to different AR, VR and tracking SDKs.
|
||||
The idea is that we subclass this class, implement the logic, and then instantiate a singleton of each interface
|
||||
when Godot starts. These instances do not initialize themselves but register themselves with the AR/VR server.
|
||||
|
||||
If the user wants to enable AR/VR, they can choose the interface they want to use and initialize it.
|
||||
|
||||
Note that we may make this into a fully instantiable class for GDExtension support.
|
||||
*/
|
||||
|
||||
class XRInterface : public RefCounted {
|
||||
GDCLASS(XRInterface, RefCounted);
|
||||
|
||||
public:
|
||||
enum Capabilities { /* purely metadata, provides some info about what this interface supports */
|
||||
XR_NONE = 0, /* no capabilities */
|
||||
XR_MONO = 1, /* can be used with mono output */
|
||||
XR_STEREO = 2, /* can be used with stereo output */
|
||||
XR_QUAD = 4, /* can be used with quad output (not currently supported) */
|
||||
XR_VR = 8, /* offers VR support */
|
||||
XR_AR = 16, /* offers AR support */
|
||||
XR_EXTERNAL = 32 /* renders to external device */
|
||||
};
|
||||
|
||||
enum TrackingStatus { /* tracking status currently based on AR but we can start doing more with this for VR as well */
|
||||
XR_NORMAL_TRACKING,
|
||||
XR_EXCESSIVE_MOTION,
|
||||
XR_INSUFFICIENT_FEATURES,
|
||||
XR_UNKNOWN_TRACKING,
|
||||
XR_NOT_TRACKING
|
||||
};
|
||||
|
||||
enum PlayAreaMode { /* defines the mode used by the XR interface for tracking */
|
||||
XR_PLAY_AREA_UNKNOWN, /* Area mode not set or not available */
|
||||
XR_PLAY_AREA_3DOF, /* Only support orientation tracking, no positional tracking, area will center around player */
|
||||
XR_PLAY_AREA_SITTING, /* Player is in seated position, limited positional tracking, fixed guardian around player */
|
||||
XR_PLAY_AREA_ROOMSCALE, /* Player is free to move around, full positional tracking */
|
||||
XR_PLAY_AREA_STAGE, /* Same as roomscale but origin point is fixed to the center of the physical space */
|
||||
XR_PLAY_AREA_CUSTOM = 0x7FFFFFFF, /* Used to denote that a custom, possibly non-standard, play area is being used */
|
||||
};
|
||||
|
||||
enum EnvironmentBlendMode {
|
||||
XR_ENV_BLEND_MODE_OPAQUE, /* You cannot see the real world, VR like */
|
||||
XR_ENV_BLEND_MODE_ADDITIVE, /* You can see the real world, AR like */
|
||||
XR_ENV_BLEND_MODE_ALPHA_BLEND, /* Real world is passed through where alpha channel is 0.0 and gradually blends to opaque for value 1.0. */
|
||||
};
|
||||
|
||||
enum VRSTextureFormat {
|
||||
XR_VRS_TEXTURE_FORMAT_UNIFIED,
|
||||
XR_VRS_TEXTURE_FORMAT_FRAGMENT_SHADING_RATE,
|
||||
XR_VRS_TEXTURE_FORMAT_FRAGMENT_DENSITY_MAP,
|
||||
};
|
||||
|
||||
protected:
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
/** general interface information **/
|
||||
virtual StringName get_name() const = 0;
|
||||
virtual uint32_t get_capabilities() const = 0;
|
||||
|
||||
bool is_primary();
|
||||
void set_primary(bool p_is_primary);
|
||||
|
||||
virtual bool is_initialized() const = 0; /* returns true if we've initialized this interface */
|
||||
virtual bool initialize() = 0; /* initialize this interface, if this has an HMD it becomes the primary interface */
|
||||
virtual void uninitialize() = 0; /* deinitialize this interface */
|
||||
virtual Dictionary get_system_info() = 0; /* return a dictionary with info about our system */
|
||||
|
||||
/** input and output **/
|
||||
|
||||
virtual PackedStringArray get_suggested_tracker_names() const; /* return a list of likely/suggested tracker names */
|
||||
virtual PackedStringArray get_suggested_pose_names(const StringName &p_tracker_name) const; /* return a list of likely/suggested action names for this tracker */
|
||||
virtual TrackingStatus get_tracking_status() const; /* get the status of our current tracking */
|
||||
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); /* trigger a haptic pulse */
|
||||
|
||||
/** specific to VR **/
|
||||
virtual bool supports_play_area_mode(XRInterface::PlayAreaMode p_mode); /* query if this interface supports this play area mode */
|
||||
virtual XRInterface::PlayAreaMode get_play_area_mode() const; /* get the current play area mode */
|
||||
virtual bool set_play_area_mode(XRInterface::PlayAreaMode p_mode); /* change the play area mode, note that this should return false if the mode is not available */
|
||||
virtual PackedVector3Array get_play_area() const; /* if available, returns an array of vectors denoting the play area the player can move around in */
|
||||
|
||||
/** specific to AR **/
|
||||
virtual bool get_anchor_detection_is_enabled() const;
|
||||
virtual void set_anchor_detection_is_enabled(bool p_enable);
|
||||
virtual int get_camera_feed_id();
|
||||
|
||||
/** rendering and internal **/
|
||||
|
||||
// These methods are called from the main thread.
|
||||
virtual Transform3D get_camera_transform() = 0; /* returns the position of our camera, only used for updating reference frame. For monoscopic this is equal to the views transform, for stereoscopic this should be an average */
|
||||
virtual void process() = 0;
|
||||
|
||||
// These methods can be called from both main and render thread.
|
||||
virtual Size2 get_render_target_size() = 0; /* returns the recommended render target size per eye for this device */
|
||||
virtual uint32_t get_view_count() = 0; /* returns the view count we need (1 is monoscopic, 2 is stereoscopic but can be more) */
|
||||
|
||||
// These methods are called from the rendering thread.
|
||||
virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) = 0; /* get each views transform */
|
||||
virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) = 0; /* get each view projection matrix */
|
||||
virtual RID get_color_texture(); /* obtain color output texture (if applicable) */
|
||||
virtual RID get_depth_texture(); /* obtain depth output texture (if applicable, used for reprojection) */
|
||||
virtual RID get_velocity_texture(); /* obtain velocity output texture (if applicable, used for spacewarp) */
|
||||
virtual RID get_velocity_depth_texture();
|
||||
virtual Size2i get_velocity_target_size();
|
||||
virtual Rect2i get_render_region();
|
||||
virtual void pre_render() {}
|
||||
virtual bool pre_draw_viewport(RID p_render_target) { return true; } /* inform XR interface we are about to start our viewport draw process */
|
||||
virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) = 0; /* inform XR interface we finished our viewport draw process */
|
||||
virtual void end_frame() {}
|
||||
|
||||
/** passthrough **/
|
||||
|
||||
virtual bool is_passthrough_supported() { return false; }
|
||||
virtual bool is_passthrough_enabled() { return false; }
|
||||
virtual bool start_passthrough() { return false; }
|
||||
virtual void stop_passthrough() {}
|
||||
|
||||
/** environment blend mode **/
|
||||
virtual Array get_supported_environment_blend_modes();
|
||||
virtual XRInterface::EnvironmentBlendMode get_environment_blend_mode() const { return XR_ENV_BLEND_MODE_OPAQUE; }
|
||||
virtual bool set_environment_blend_mode(EnvironmentBlendMode mode) { return false; }
|
||||
|
||||
/** VRS **/
|
||||
virtual RID get_vrs_texture(); /* obtain VRS texture */
|
||||
virtual VRSTextureFormat get_vrs_texture_format() { return XR_VRS_TEXTURE_FORMAT_UNIFIED; }
|
||||
|
||||
XRInterface();
|
||||
~XRInterface();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(XRInterface::Capabilities);
|
||||
VARIANT_ENUM_CAST(XRInterface::TrackingStatus);
|
||||
VARIANT_ENUM_CAST(XRInterface::PlayAreaMode);
|
||||
VARIANT_ENUM_CAST(XRInterface::EnvironmentBlendMode);
|
||||
VARIANT_ENUM_CAST(XRInterface::VRSTextureFormat);
|
339
servers/xr/xr_interface_extension.cpp
Normal file
339
servers/xr/xr_interface_extension.cpp
Normal file
@@ -0,0 +1,339 @@
|
||||
/**************************************************************************/
|
||||
/* xr_interface_extension.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "xr_interface_extension.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
||||
|
||||
void XRInterfaceExtension::_bind_methods() {
|
||||
GDVIRTUAL_BIND(_get_name);
|
||||
GDVIRTUAL_BIND(_get_capabilities);
|
||||
|
||||
GDVIRTUAL_BIND(_is_initialized);
|
||||
GDVIRTUAL_BIND(_initialize);
|
||||
GDVIRTUAL_BIND(_uninitialize);
|
||||
GDVIRTUAL_BIND(_get_system_info);
|
||||
|
||||
GDVIRTUAL_BIND(_supports_play_area_mode, "mode");
|
||||
GDVIRTUAL_BIND(_get_play_area_mode);
|
||||
GDVIRTUAL_BIND(_set_play_area_mode, "mode");
|
||||
GDVIRTUAL_BIND(_get_play_area);
|
||||
|
||||
GDVIRTUAL_BIND(_get_render_target_size);
|
||||
GDVIRTUAL_BIND(_get_view_count);
|
||||
GDVIRTUAL_BIND(_get_camera_transform);
|
||||
GDVIRTUAL_BIND(_get_transform_for_view, "view", "cam_transform");
|
||||
GDVIRTUAL_BIND(_get_projection_for_view, "view", "aspect", "z_near", "z_far");
|
||||
GDVIRTUAL_BIND(_get_vrs_texture);
|
||||
GDVIRTUAL_BIND(_get_vrs_texture_format);
|
||||
|
||||
GDVIRTUAL_BIND(_process);
|
||||
GDVIRTUAL_BIND(_pre_render);
|
||||
GDVIRTUAL_BIND(_pre_draw_viewport, "render_target");
|
||||
GDVIRTUAL_BIND(_post_draw_viewport, "render_target", "screen_rect");
|
||||
GDVIRTUAL_BIND(_end_frame);
|
||||
|
||||
/** input and output **/
|
||||
|
||||
GDVIRTUAL_BIND(_get_suggested_tracker_names);
|
||||
GDVIRTUAL_BIND(_get_suggested_pose_names, "tracker_name");
|
||||
GDVIRTUAL_BIND(_get_tracking_status);
|
||||
GDVIRTUAL_BIND(_trigger_haptic_pulse, "action_name", "tracker_name", "frequency", "amplitude", "duration_sec", "delay_sec");
|
||||
|
||||
// we don't have any properties specific to VR yet....
|
||||
|
||||
// but we do have properties specific to AR....
|
||||
GDVIRTUAL_BIND(_get_anchor_detection_is_enabled);
|
||||
GDVIRTUAL_BIND(_set_anchor_detection_is_enabled, "enabled");
|
||||
GDVIRTUAL_BIND(_get_camera_feed_id);
|
||||
|
||||
// override output methods
|
||||
GDVIRTUAL_BIND(_get_color_texture);
|
||||
GDVIRTUAL_BIND(_get_depth_texture);
|
||||
GDVIRTUAL_BIND(_get_velocity_texture);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_color_texture"), &XRInterfaceExtension::get_color_texture);
|
||||
ClassDB::bind_method(D_METHOD("get_depth_texture"), &XRInterfaceExtension::get_depth_texture);
|
||||
ClassDB::bind_method(D_METHOD("get_velocity_texture"), &XRInterfaceExtension::get_velocity_texture);
|
||||
|
||||
// helper methods
|
||||
ClassDB::bind_method(D_METHOD("add_blit", "render_target", "src_rect", "dst_rect", "use_layer", "layer", "apply_lens_distortion", "eye_center", "k1", "k2", "upscale", "aspect_ratio"), &XRInterfaceExtension::add_blit);
|
||||
ClassDB::bind_method(D_METHOD("get_render_target_texture", "render_target"), &XRInterfaceExtension::get_render_target_texture);
|
||||
// ClassDB::bind_method(D_METHOD("get_render_target_depth", "render_target"), &XRInterfaceExtension::get_render_target_depth);
|
||||
}
|
||||
|
||||
StringName XRInterfaceExtension::get_name() const {
|
||||
StringName name;
|
||||
|
||||
if (GDVIRTUAL_CALL(_get_name, name)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
uint32_t XRInterfaceExtension::get_capabilities() const {
|
||||
uint32_t capabilities = 0;
|
||||
GDVIRTUAL_CALL(_get_capabilities, capabilities);
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
bool XRInterfaceExtension::is_initialized() const {
|
||||
bool initialized = false;
|
||||
GDVIRTUAL_CALL(_is_initialized, initialized);
|
||||
return initialized;
|
||||
}
|
||||
|
||||
bool XRInterfaceExtension::initialize() {
|
||||
bool initialized = false;
|
||||
GDVIRTUAL_CALL(_initialize, initialized);
|
||||
return initialized;
|
||||
}
|
||||
|
||||
void XRInterfaceExtension::uninitialize() {
|
||||
GDVIRTUAL_CALL(_uninitialize);
|
||||
}
|
||||
|
||||
Dictionary XRInterfaceExtension::get_system_info() {
|
||||
Dictionary dict;
|
||||
GDVIRTUAL_CALL(_get_system_info, dict);
|
||||
return dict;
|
||||
}
|
||||
|
||||
PackedStringArray XRInterfaceExtension::get_suggested_tracker_names() const {
|
||||
PackedStringArray arr;
|
||||
|
||||
GDVIRTUAL_CALL(_get_suggested_tracker_names, arr);
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
PackedStringArray XRInterfaceExtension::get_suggested_pose_names(const StringName &p_tracker_name) const {
|
||||
PackedStringArray arr;
|
||||
|
||||
GDVIRTUAL_CALL(_get_suggested_pose_names, p_tracker_name, arr);
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
XRInterface::TrackingStatus XRInterfaceExtension::get_tracking_status() const {
|
||||
XRInterface::TrackingStatus status = XR_UNKNOWN_TRACKING;
|
||||
GDVIRTUAL_CALL(_get_tracking_status, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
void XRInterfaceExtension::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) {
|
||||
GDVIRTUAL_CALL(_trigger_haptic_pulse, p_action_name, p_tracker_name, p_frequency, p_amplitude, p_duration_sec, p_delay_sec);
|
||||
}
|
||||
|
||||
bool XRInterfaceExtension::supports_play_area_mode(XRInterface::PlayAreaMode p_mode) {
|
||||
bool is_supported = false;
|
||||
GDVIRTUAL_CALL(_supports_play_area_mode, p_mode, is_supported);
|
||||
return is_supported;
|
||||
}
|
||||
|
||||
XRInterface::PlayAreaMode XRInterfaceExtension::get_play_area_mode() const {
|
||||
XRInterface::PlayAreaMode mode = XR_PLAY_AREA_UNKNOWN;
|
||||
GDVIRTUAL_CALL(_get_play_area_mode, mode);
|
||||
return mode;
|
||||
}
|
||||
|
||||
bool XRInterfaceExtension::set_play_area_mode(XRInterface::PlayAreaMode p_mode) {
|
||||
bool success = false;
|
||||
GDVIRTUAL_CALL(_set_play_area_mode, p_mode, success);
|
||||
return success;
|
||||
}
|
||||
|
||||
PackedVector3Array XRInterfaceExtension::get_play_area() const {
|
||||
PackedVector3Array arr;
|
||||
GDVIRTUAL_CALL(_get_play_area, arr);
|
||||
return arr;
|
||||
}
|
||||
|
||||
/** these will only be implemented on AR interfaces, so we want dummies for VR **/
|
||||
bool XRInterfaceExtension::get_anchor_detection_is_enabled() const {
|
||||
bool enabled = false;
|
||||
GDVIRTUAL_CALL(_get_anchor_detection_is_enabled, enabled);
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void XRInterfaceExtension::set_anchor_detection_is_enabled(bool p_enable) {
|
||||
// don't do anything here, this needs to be implemented on AR interface to enable/disable things like plane detection etc.
|
||||
GDVIRTUAL_CALL(_set_anchor_detection_is_enabled, p_enable);
|
||||
}
|
||||
|
||||
int XRInterfaceExtension::get_camera_feed_id() {
|
||||
int feed_id = 0;
|
||||
GDVIRTUAL_CALL(_get_camera_feed_id, feed_id);
|
||||
return feed_id;
|
||||
}
|
||||
|
||||
Size2 XRInterfaceExtension::get_render_target_size() {
|
||||
Size2 size;
|
||||
GDVIRTUAL_CALL(_get_render_target_size, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32_t XRInterfaceExtension::get_view_count() {
|
||||
uint32_t view_count = 1;
|
||||
GDVIRTUAL_CALL(_get_view_count, view_count);
|
||||
return view_count;
|
||||
}
|
||||
|
||||
Transform3D XRInterfaceExtension::get_camera_transform() {
|
||||
Transform3D transform;
|
||||
GDVIRTUAL_CALL(_get_camera_transform, transform);
|
||||
return transform;
|
||||
}
|
||||
|
||||
Transform3D XRInterfaceExtension::get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) {
|
||||
Transform3D transform;
|
||||
GDVIRTUAL_CALL(_get_transform_for_view, p_view, p_cam_transform, transform);
|
||||
return transform;
|
||||
}
|
||||
|
||||
Projection XRInterfaceExtension::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) {
|
||||
Projection cm;
|
||||
PackedFloat64Array arr;
|
||||
|
||||
if (GDVIRTUAL_CALL(_get_projection_for_view, p_view, p_aspect, p_z_near, p_z_far, arr)) {
|
||||
ERR_FAIL_COND_V_MSG(arr.size() != 16, Projection(), "Projection matrix must contain 16 floats");
|
||||
real_t *m = (real_t *)cm.columns;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
m[i] = arr[i];
|
||||
}
|
||||
return cm;
|
||||
}
|
||||
|
||||
return Projection();
|
||||
}
|
||||
|
||||
RID XRInterfaceExtension::get_vrs_texture() {
|
||||
RID vrs_texture;
|
||||
if (GDVIRTUAL_CALL(_get_vrs_texture, vrs_texture)) {
|
||||
return vrs_texture;
|
||||
} else {
|
||||
return XRInterface::get_vrs_texture();
|
||||
}
|
||||
}
|
||||
|
||||
XRInterface::VRSTextureFormat XRInterfaceExtension::get_vrs_texture_format() {
|
||||
VRSTextureFormat vrs_texture_format = XR_VRS_TEXTURE_FORMAT_UNIFIED;
|
||||
if (GDVIRTUAL_CALL(_get_vrs_texture_format, vrs_texture_format)) {
|
||||
return vrs_texture_format;
|
||||
}
|
||||
return vrs_texture_format;
|
||||
}
|
||||
|
||||
RID XRInterfaceExtension::get_color_texture() {
|
||||
RID texture;
|
||||
GDVIRTUAL_CALL(_get_color_texture, texture);
|
||||
return texture;
|
||||
}
|
||||
|
||||
RID XRInterfaceExtension::get_depth_texture() {
|
||||
RID texture;
|
||||
GDVIRTUAL_CALL(_get_depth_texture, texture);
|
||||
return texture;
|
||||
}
|
||||
|
||||
RID XRInterfaceExtension::get_velocity_texture() {
|
||||
RID texture;
|
||||
GDVIRTUAL_CALL(_get_velocity_texture, texture);
|
||||
return texture;
|
||||
}
|
||||
|
||||
void XRInterfaceExtension::add_blit(RID p_render_target, Rect2 p_src_rect, Rect2i p_dst_rect, bool p_use_layer, uint32_t p_layer, bool p_apply_lens_distortion, Vector2 p_eye_center, double p_k1, double p_k2, double p_upscale, double p_aspect_ratio) {
|
||||
BlitToScreen blit;
|
||||
|
||||
ERR_FAIL_COND_MSG(!can_add_blits, "add_blit can only be called from an XR plugin from within _post_draw_viewport!");
|
||||
|
||||
blit.render_target = p_render_target;
|
||||
blit.src_rect = p_src_rect;
|
||||
blit.dst_rect = p_dst_rect;
|
||||
|
||||
blit.multi_view.use_layer = p_use_layer;
|
||||
blit.multi_view.layer = p_layer;
|
||||
|
||||
blit.lens_distortion.apply = p_apply_lens_distortion;
|
||||
blit.lens_distortion.eye_center = p_eye_center;
|
||||
blit.lens_distortion.k1 = p_k1;
|
||||
blit.lens_distortion.k2 = p_k2;
|
||||
blit.lens_distortion.upscale = p_upscale;
|
||||
blit.lens_distortion.aspect_ratio = p_aspect_ratio;
|
||||
|
||||
blits.push_back(blit);
|
||||
}
|
||||
|
||||
void XRInterfaceExtension::process() {
|
||||
GDVIRTUAL_CALL(_process);
|
||||
}
|
||||
|
||||
void XRInterfaceExtension::pre_render() {
|
||||
GDVIRTUAL_CALL(_pre_render);
|
||||
}
|
||||
|
||||
bool XRInterfaceExtension::pre_draw_viewport(RID p_render_target) {
|
||||
bool do_render = true;
|
||||
GDVIRTUAL_CALL(_pre_draw_viewport, p_render_target, do_render);
|
||||
return do_render; // If not implemented we're returning true.
|
||||
}
|
||||
|
||||
Vector<BlitToScreen> XRInterfaceExtension::post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) {
|
||||
// This is just so our XR plugin can add blits...
|
||||
blits.clear();
|
||||
can_add_blits = true;
|
||||
|
||||
if (GDVIRTUAL_CALL(_post_draw_viewport, p_render_target, p_screen_rect)) {
|
||||
return blits;
|
||||
}
|
||||
|
||||
can_add_blits = false;
|
||||
return blits;
|
||||
}
|
||||
|
||||
void XRInterfaceExtension::end_frame() {
|
||||
GDVIRTUAL_CALL(_end_frame);
|
||||
}
|
||||
|
||||
RID XRInterfaceExtension::get_render_target_texture(RID p_render_target) {
|
||||
// In due time this will need to be enhance to return the correct INTERNAL RID for the chosen rendering engine.
|
||||
// So once a GLES driver is implemented we'll return that and the implemented plugin needs to handle this correctly too.
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
ERR_FAIL_NULL_V_MSG(texture_storage, RID(), "Texture storage not setup");
|
||||
|
||||
return texture_storage->render_target_get_rd_texture(p_render_target);
|
||||
}
|
||||
|
||||
/*
|
||||
RID XRInterfaceExtension::get_render_target_depth(RID p_render_target) {
|
||||
// TODO implement this, the problem is that our depth texture isn't part of our render target as it is used for 3D rendering only
|
||||
// but we don't have access to our render buffers from here....
|
||||
}
|
||||
*/
|
139
servers/xr/xr_interface_extension.h
Normal file
139
servers/xr/xr_interface_extension.h
Normal file
@@ -0,0 +1,139 @@
|
||||
/**************************************************************************/
|
||||
/* xr_interface_extension.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "servers/xr/xr_interface.h"
|
||||
|
||||
class XRInterfaceExtension : public XRInterface {
|
||||
GDCLASS(XRInterfaceExtension, XRInterface);
|
||||
|
||||
public:
|
||||
private:
|
||||
bool can_add_blits = false;
|
||||
Vector<BlitToScreen> blits;
|
||||
|
||||
protected:
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
/** general interface information **/
|
||||
virtual StringName get_name() const override;
|
||||
virtual uint32_t get_capabilities() const override;
|
||||
|
||||
GDVIRTUAL0RC(StringName, _get_name);
|
||||
GDVIRTUAL0RC(uint32_t, _get_capabilities);
|
||||
|
||||
virtual bool is_initialized() const override;
|
||||
virtual bool initialize() override;
|
||||
virtual void uninitialize() override;
|
||||
virtual Dictionary get_system_info() override;
|
||||
|
||||
GDVIRTUAL0RC(bool, _is_initialized);
|
||||
GDVIRTUAL0R(bool, _initialize);
|
||||
GDVIRTUAL0(_uninitialize);
|
||||
GDVIRTUAL0RC(Dictionary, _get_system_info);
|
||||
|
||||
/** input and output **/
|
||||
|
||||
virtual PackedStringArray get_suggested_tracker_names() const override; /* return a list of likely/suggested tracker names */
|
||||
virtual PackedStringArray get_suggested_pose_names(const StringName &p_tracker_name) const override; /* return a list of likely/suggested action names for this tracker */
|
||||
virtual TrackingStatus get_tracking_status() const override;
|
||||
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;
|
||||
|
||||
GDVIRTUAL0RC(PackedStringArray, _get_suggested_tracker_names);
|
||||
GDVIRTUAL1RC(PackedStringArray, _get_suggested_pose_names, const StringName &);
|
||||
GDVIRTUAL0RC(XRInterface::TrackingStatus, _get_tracking_status);
|
||||
GDVIRTUAL6(_trigger_haptic_pulse, const String &, const StringName &, double, double, double, double);
|
||||
|
||||
/** specific to VR **/
|
||||
virtual bool supports_play_area_mode(XRInterface::PlayAreaMode p_mode) override; /* query if this interface supports this play area mode */
|
||||
virtual XRInterface::PlayAreaMode get_play_area_mode() const override; /* get the current play area mode */
|
||||
virtual bool set_play_area_mode(XRInterface::PlayAreaMode p_mode) override; /* change the play area mode, note that this should return false if the mode is not available */
|
||||
virtual PackedVector3Array get_play_area() const override; /* if available, returns an array of vectors denoting the play area the player can move around in */
|
||||
|
||||
GDVIRTUAL1RC(bool, _supports_play_area_mode, XRInterface::PlayAreaMode);
|
||||
GDVIRTUAL0RC(XRInterface::PlayAreaMode, _get_play_area_mode);
|
||||
GDVIRTUAL1RC(bool, _set_play_area_mode, XRInterface::PlayAreaMode);
|
||||
GDVIRTUAL0RC(PackedVector3Array, _get_play_area);
|
||||
|
||||
/** specific to AR **/
|
||||
virtual bool get_anchor_detection_is_enabled() const override;
|
||||
virtual void set_anchor_detection_is_enabled(bool p_enable) override;
|
||||
virtual int get_camera_feed_id() override;
|
||||
|
||||
GDVIRTUAL0RC(bool, _get_anchor_detection_is_enabled);
|
||||
GDVIRTUAL1(_set_anchor_detection_is_enabled, bool);
|
||||
GDVIRTUAL0RC(int, _get_camera_feed_id);
|
||||
|
||||
/** rendering and internal **/
|
||||
|
||||
virtual Size2 get_render_target_size() override;
|
||||
virtual uint32_t get_view_count() override;
|
||||
virtual Transform3D get_camera_transform() override;
|
||||
virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override;
|
||||
virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override;
|
||||
virtual RID get_vrs_texture() override;
|
||||
virtual VRSTextureFormat get_vrs_texture_format() override;
|
||||
virtual RID get_color_texture() override;
|
||||
virtual RID get_depth_texture() override;
|
||||
virtual RID get_velocity_texture() override;
|
||||
|
||||
GDVIRTUAL0R(Size2, _get_render_target_size);
|
||||
GDVIRTUAL0R(uint32_t, _get_view_count);
|
||||
GDVIRTUAL0R(Transform3D, _get_camera_transform);
|
||||
GDVIRTUAL2R(Transform3D, _get_transform_for_view, uint32_t, const Transform3D &);
|
||||
GDVIRTUAL4R(PackedFloat64Array, _get_projection_for_view, uint32_t, double, double, double);
|
||||
GDVIRTUAL0R(RID, _get_vrs_texture);
|
||||
GDVIRTUAL0R(VRSTextureFormat, _get_vrs_texture_format);
|
||||
GDVIRTUAL0R(RID, _get_color_texture);
|
||||
GDVIRTUAL0R(RID, _get_depth_texture);
|
||||
GDVIRTUAL0R(RID, _get_velocity_texture);
|
||||
|
||||
void add_blit(RID p_render_target, Rect2 p_src_rect, Rect2i p_dst_rect, bool p_use_layer = false, uint32_t p_layer = 0, bool p_apply_lens_distortion = false, Vector2 p_eye_center = Vector2(), double p_k1 = 0.0, double p_k2 = 0.0, double p_upscale = 1.0, double p_aspect_ratio = 1.0);
|
||||
|
||||
virtual void process() override;
|
||||
virtual void pre_render() override;
|
||||
virtual bool pre_draw_viewport(RID p_render_target) override;
|
||||
virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override;
|
||||
virtual void end_frame() override;
|
||||
|
||||
GDVIRTUAL0(_process);
|
||||
GDVIRTUAL0(_pre_render);
|
||||
GDVIRTUAL1R(bool, _pre_draw_viewport, RID);
|
||||
GDVIRTUAL2(_post_draw_viewport, RID, const Rect2 &);
|
||||
GDVIRTUAL0(_end_frame);
|
||||
|
||||
/* access to some internals we need */
|
||||
RID get_render_target_texture(RID p_render_target);
|
||||
// RID get_render_target_depth(RID p_render_target);
|
||||
};
|
126
servers/xr/xr_pose.cpp
Normal file
126
servers/xr/xr_pose.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/**************************************************************************/
|
||||
/* xr_pose.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "xr_pose.h"
|
||||
|
||||
#include "servers/xr_server.h"
|
||||
|
||||
void XRPose::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(XR_TRACKING_CONFIDENCE_NONE);
|
||||
BIND_ENUM_CONSTANT(XR_TRACKING_CONFIDENCE_LOW);
|
||||
BIND_ENUM_CONSTANT(XR_TRACKING_CONFIDENCE_HIGH);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_has_tracking_data", "has_tracking_data"), &XRPose::set_has_tracking_data);
|
||||
ClassDB::bind_method(D_METHOD("get_has_tracking_data"), &XRPose::get_has_tracking_data);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "has_tracking_data"), "set_has_tracking_data", "get_has_tracking_data");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_name", "name"), &XRPose::set_name);
|
||||
ClassDB::bind_method(D_METHOD("get_name"), &XRPose::get_name);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "name"), "set_name", "get_name");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_transform", "transform"), &XRPose::set_transform);
|
||||
ClassDB::bind_method(D_METHOD("get_transform"), &XRPose::get_transform);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "transform"), "set_transform", "get_transform");
|
||||
ClassDB::bind_method(D_METHOD("get_adjusted_transform"), &XRPose::get_adjusted_transform);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_linear_velocity", "velocity"), &XRPose::set_linear_velocity);
|
||||
ClassDB::bind_method(D_METHOD("get_linear_velocity"), &XRPose::get_linear_velocity);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_angular_velocity", "velocity"), &XRPose::set_angular_velocity);
|
||||
ClassDB::bind_method(D_METHOD("get_angular_velocity"), &XRPose::get_angular_velocity);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "angular_velocity"), "set_angular_velocity", "get_angular_velocity");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_tracking_confidence", "tracking_confidence"), &XRPose::set_tracking_confidence);
|
||||
ClassDB::bind_method(D_METHOD("get_tracking_confidence"), &XRPose::get_tracking_confidence);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "tracking_confidence"), "set_tracking_confidence", "get_tracking_confidence");
|
||||
}
|
||||
|
||||
void XRPose::set_has_tracking_data(const bool p_has_tracking_data) {
|
||||
has_tracking_data = p_has_tracking_data;
|
||||
}
|
||||
bool XRPose::get_has_tracking_data() const {
|
||||
return has_tracking_data;
|
||||
}
|
||||
|
||||
void XRPose::set_name(const StringName &p_name) {
|
||||
name = p_name;
|
||||
}
|
||||
|
||||
StringName XRPose::get_name() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
void XRPose::set_transform(const Transform3D p_transform) {
|
||||
transform = p_transform;
|
||||
}
|
||||
|
||||
Transform3D XRPose::get_transform() const {
|
||||
return transform;
|
||||
}
|
||||
|
||||
Transform3D XRPose::get_adjusted_transform() const {
|
||||
Transform3D adjusted_transform = transform;
|
||||
|
||||
XRServer *xr_server = XRServer::get_singleton();
|
||||
ERR_FAIL_NULL_V(xr_server, transform);
|
||||
|
||||
// apply world scale
|
||||
adjusted_transform.origin *= xr_server->get_world_scale();
|
||||
|
||||
// apply reference frame
|
||||
adjusted_transform = xr_server->get_reference_frame() * adjusted_transform;
|
||||
|
||||
return adjusted_transform;
|
||||
}
|
||||
|
||||
void XRPose::set_linear_velocity(const Vector3 p_velocity) {
|
||||
linear_velocity = p_velocity;
|
||||
}
|
||||
|
||||
Vector3 XRPose::get_linear_velocity() const {
|
||||
return linear_velocity;
|
||||
}
|
||||
|
||||
void XRPose::set_angular_velocity(const Vector3 p_velocity) {
|
||||
angular_velocity = p_velocity;
|
||||
}
|
||||
|
||||
Vector3 XRPose::get_angular_velocity() const {
|
||||
return angular_velocity;
|
||||
}
|
||||
|
||||
void XRPose::set_tracking_confidence(const XRPose::TrackingConfidence p_tracking_confidence) {
|
||||
tracking_confidence = p_tracking_confidence;
|
||||
}
|
||||
|
||||
XRPose::TrackingConfidence XRPose::get_tracking_confidence() const {
|
||||
return tracking_confidence;
|
||||
}
|
78
servers/xr/xr_pose.h
Normal file
78
servers/xr/xr_pose.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/**************************************************************************/
|
||||
/* xr_pose.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/object/ref_counted.h"
|
||||
|
||||
class XRPose : public RefCounted {
|
||||
GDCLASS(XRPose, RefCounted);
|
||||
|
||||
public:
|
||||
// TrackingConfidence gives an indication of how reliable our transform data is.
|
||||
enum TrackingConfidence {
|
||||
XR_TRACKING_CONFIDENCE_NONE, // No tracking information is available for this pose.
|
||||
XR_TRACKING_CONFIDENCE_LOW, // Tracking information may be inaccurate or estimated.
|
||||
XR_TRACKING_CONFIDENCE_HIGH // Tracking information is deemed accurate and up to date.
|
||||
};
|
||||
|
||||
private:
|
||||
bool has_tracking_data = false;
|
||||
StringName name;
|
||||
Transform3D transform;
|
||||
Vector3 linear_velocity;
|
||||
Vector3 angular_velocity;
|
||||
TrackingConfidence tracking_confidence = XR_TRACKING_CONFIDENCE_NONE;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_has_tracking_data(const bool p_has_tracking_data);
|
||||
bool get_has_tracking_data() const;
|
||||
|
||||
void set_name(const StringName &p_name);
|
||||
StringName get_name() const;
|
||||
|
||||
void set_transform(const Transform3D p_transform);
|
||||
Transform3D get_transform() const;
|
||||
Transform3D get_adjusted_transform() const;
|
||||
|
||||
void set_linear_velocity(const Vector3 p_velocity);
|
||||
Vector3 get_linear_velocity() const;
|
||||
|
||||
void set_angular_velocity(const Vector3 p_velocity);
|
||||
Vector3 get_angular_velocity() const;
|
||||
|
||||
void set_tracking_confidence(const TrackingConfidence p_tracking_confidence);
|
||||
TrackingConfidence get_tracking_confidence() const;
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(XRPose::TrackingConfidence);
|
191
servers/xr/xr_positional_tracker.cpp
Normal file
191
servers/xr/xr_positional_tracker.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
/**************************************************************************/
|
||||
/* xr_positional_tracker.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "xr_positional_tracker.h"
|
||||
|
||||
#include "xr_controller_tracker.h"
|
||||
|
||||
void XRPositionalTracker::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(TRACKER_HAND_UNKNOWN);
|
||||
BIND_ENUM_CONSTANT(TRACKER_HAND_LEFT);
|
||||
BIND_ENUM_CONSTANT(TRACKER_HAND_RIGHT);
|
||||
BIND_ENUM_CONSTANT(TRACKER_HAND_MAX);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_tracker_profile"), &XRPositionalTracker::get_tracker_profile);
|
||||
ClassDB::bind_method(D_METHOD("set_tracker_profile", "profile"), &XRPositionalTracker::set_tracker_profile);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "profile"), "set_tracker_profile", "get_tracker_profile");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_tracker_hand"), &XRPositionalTracker::get_tracker_hand);
|
||||
ClassDB::bind_method(D_METHOD("set_tracker_hand", "hand"), &XRPositionalTracker::set_tracker_hand);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "hand", PROPERTY_HINT_ENUM, "Unknown,Left,Right"), "set_tracker_hand", "get_tracker_hand");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("has_pose", "name"), &XRPositionalTracker::has_pose);
|
||||
ClassDB::bind_method(D_METHOD("get_pose", "name"), &XRPositionalTracker::get_pose);
|
||||
ClassDB::bind_method(D_METHOD("invalidate_pose", "name"), &XRPositionalTracker::invalidate_pose);
|
||||
ClassDB::bind_method(D_METHOD("set_pose", "name", "transform", "linear_velocity", "angular_velocity", "tracking_confidence"), &XRPositionalTracker::set_pose);
|
||||
ADD_SIGNAL(MethodInfo("pose_changed", PropertyInfo(Variant::OBJECT, "pose", PROPERTY_HINT_RESOURCE_TYPE, "XRPose")));
|
||||
ADD_SIGNAL(MethodInfo("pose_lost_tracking", PropertyInfo(Variant::OBJECT, "pose", PROPERTY_HINT_RESOURCE_TYPE, "XRPose")));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_input", "name"), &XRPositionalTracker::get_input);
|
||||
ClassDB::bind_method(D_METHOD("set_input", "name", "value"), &XRPositionalTracker::set_input);
|
||||
ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::STRING, "name")));
|
||||
ADD_SIGNAL(MethodInfo("button_released", PropertyInfo(Variant::STRING, "name")));
|
||||
ADD_SIGNAL(MethodInfo("input_float_changed", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::FLOAT, "value")));
|
||||
ADD_SIGNAL(MethodInfo("input_vector2_changed", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::VECTOR2, "vector")));
|
||||
ADD_SIGNAL(MethodInfo("profile_changed", PropertyInfo(Variant::STRING, "role")));
|
||||
}
|
||||
|
||||
void XRPositionalTracker::set_tracker_profile(const String &p_profile) {
|
||||
if (profile != p_profile) {
|
||||
profile = p_profile;
|
||||
|
||||
emit_signal("profile_changed", profile);
|
||||
}
|
||||
}
|
||||
|
||||
String XRPositionalTracker::get_tracker_profile() const {
|
||||
return profile;
|
||||
}
|
||||
|
||||
XRPositionalTracker::TrackerHand XRPositionalTracker::get_tracker_hand() const {
|
||||
return tracker_hand;
|
||||
}
|
||||
|
||||
void XRPositionalTracker::set_tracker_hand(const XRPositionalTracker::TrackerHand p_hand) {
|
||||
ERR_FAIL_INDEX(p_hand, TRACKER_HAND_MAX);
|
||||
tracker_hand = p_hand;
|
||||
}
|
||||
|
||||
bool XRPositionalTracker::has_pose(const StringName &p_action_name) const {
|
||||
return poses.has(p_action_name);
|
||||
}
|
||||
|
||||
Ref<XRPose> XRPositionalTracker::get_pose(const StringName &p_action_name) const {
|
||||
Ref<XRPose> pose;
|
||||
|
||||
if (poses.has(p_action_name)) {
|
||||
pose = poses[p_action_name];
|
||||
}
|
||||
|
||||
return pose;
|
||||
}
|
||||
|
||||
void XRPositionalTracker::invalidate_pose(const StringName &p_action_name) {
|
||||
// only update this if we were tracking this pose
|
||||
if (poses.has(p_action_name)) {
|
||||
// We just set tracking data as invalid, we leave our current transform and velocity data as is so controllers don't suddenly jump to origin.
|
||||
Ref<XRPose> pose = poses[p_action_name];
|
||||
pose->set_has_tracking_data(false);
|
||||
|
||||
emit_signal(SNAME("pose_lost_tracking"), pose);
|
||||
}
|
||||
}
|
||||
|
||||
void XRPositionalTracker::set_pose(const StringName &p_action_name, const Transform3D &p_transform, const Vector3 &p_linear_velocity, const Vector3 &p_angular_velocity, const XRPose::TrackingConfidence p_tracking_confidence) {
|
||||
Ref<XRPose> new_pose;
|
||||
|
||||
if (poses.has(p_action_name)) {
|
||||
new_pose = poses[p_action_name];
|
||||
} else {
|
||||
new_pose.instantiate();
|
||||
poses[p_action_name] = new_pose;
|
||||
}
|
||||
|
||||
new_pose->set_name(p_action_name);
|
||||
new_pose->set_has_tracking_data(true);
|
||||
new_pose->set_transform(p_transform);
|
||||
new_pose->set_linear_velocity(p_linear_velocity);
|
||||
new_pose->set_angular_velocity(p_angular_velocity);
|
||||
new_pose->set_tracking_confidence(p_tracking_confidence);
|
||||
|
||||
emit_signal(SNAME("pose_changed"), new_pose);
|
||||
|
||||
// TODO discuss whether we also want to create and emit an InputEventXRPose event
|
||||
}
|
||||
|
||||
Variant XRPositionalTracker::get_input(const StringName &p_action_name) const {
|
||||
// Complain if this method is called on a XRPositionalTracker instance.
|
||||
if (!dynamic_cast<const XRControllerTracker *>(this)) {
|
||||
WARN_DEPRECATED_MSG(R"*(The "get_input()" method is deprecated, use "XRControllerTracker" instead.)*");
|
||||
}
|
||||
|
||||
if (inputs.has(p_action_name)) {
|
||||
return inputs[p_action_name];
|
||||
} else {
|
||||
return Variant();
|
||||
}
|
||||
}
|
||||
|
||||
void XRPositionalTracker::set_input(const StringName &p_action_name, const Variant &p_value) {
|
||||
// Complain if this method is called on a XRPositionalTracker instance.
|
||||
if (!dynamic_cast<XRControllerTracker *>(this)) {
|
||||
WARN_DEPRECATED_MSG(R"*(The "set_input()" method is deprecated, use "XRControllerTracker" instead.)*");
|
||||
}
|
||||
|
||||
// XR inputs
|
||||
bool changed;
|
||||
if (inputs.has(p_action_name)) {
|
||||
changed = inputs[p_action_name] != p_value;
|
||||
} else {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
// store the new value
|
||||
inputs[p_action_name] = p_value;
|
||||
|
||||
// emit signals to let the rest of the world know
|
||||
switch (p_value.get_type()) {
|
||||
case Variant::BOOL: {
|
||||
bool pressed = p_value;
|
||||
if (pressed) {
|
||||
emit_signal(SNAME("button_pressed"), p_action_name);
|
||||
} else {
|
||||
emit_signal(SNAME("button_released"), p_action_name);
|
||||
}
|
||||
|
||||
// TODO discuss whether we also want to create and emit an InputEventXRButton event
|
||||
} break;
|
||||
case Variant::FLOAT: {
|
||||
emit_signal(SNAME("input_float_changed"), p_action_name, p_value);
|
||||
|
||||
// TODO discuss whether we also want to create and emit an InputEventXRValue event
|
||||
} break;
|
||||
case Variant::VECTOR2: {
|
||||
emit_signal(SNAME("input_vector2_changed"), p_action_name, p_value);
|
||||
|
||||
// TODO discuss whether we also want to create and emit an InputEventXRAxis event
|
||||
} break;
|
||||
default: {
|
||||
// ???
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
81
servers/xr/xr_positional_tracker.h
Normal file
81
servers/xr/xr_positional_tracker.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/**************************************************************************/
|
||||
/* xr_positional_tracker.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/os/thread_safe.h"
|
||||
#include "servers/xr/xr_pose.h"
|
||||
#include "servers/xr/xr_tracker.h"
|
||||
#include "servers/xr_server.h"
|
||||
|
||||
/**
|
||||
The positional tracker object as an object that represents the position and orientation of a tracked object like a controller or headset.
|
||||
An AR/VR Interface will registered the trackers it manages with our AR/VR server and update its position and orientation.
|
||||
This is where potentially additional AR/VR interfaces may be active as there are AR/VR SDKs that solely deal with positional tracking.
|
||||
*/
|
||||
|
||||
class XRPositionalTracker : public XRTracker {
|
||||
GDCLASS(XRPositionalTracker, XRTracker);
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
public:
|
||||
enum TrackerHand {
|
||||
TRACKER_HAND_UNKNOWN, /* unknown or not applicable */
|
||||
TRACKER_HAND_LEFT, /* controller is the left hand controller */
|
||||
TRACKER_HAND_RIGHT, /* controller is the right hand controller */
|
||||
TRACKER_HAND_MAX
|
||||
};
|
||||
|
||||
protected:
|
||||
String profile; // this is interface dependent, for OpenXR this will be the interaction profile bound for to the tracker
|
||||
TrackerHand tracker_hand = TRACKER_HAND_UNKNOWN; // if known, the hand this tracker is held in
|
||||
|
||||
HashMap<StringName, Ref<XRPose>> poses;
|
||||
HashMap<StringName, Variant> inputs;
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_tracker_profile(const String &p_profile);
|
||||
String get_tracker_profile() const;
|
||||
|
||||
XRPositionalTracker::TrackerHand get_tracker_hand() const;
|
||||
virtual void set_tracker_hand(const XRPositionalTracker::TrackerHand p_hand);
|
||||
|
||||
bool has_pose(const StringName &p_action_name) const;
|
||||
Ref<XRPose> get_pose(const StringName &p_action_name) const;
|
||||
void invalidate_pose(const StringName &p_action_name);
|
||||
void set_pose(const StringName &p_action_name, const Transform3D &p_transform, const Vector3 &p_linear_velocity, const Vector3 &p_angular_velocity, const XRPose::TrackingConfidence p_tracking_confidence = XRPose::XR_TRACKING_CONFIDENCE_HIGH);
|
||||
|
||||
Variant get_input(const StringName &p_action_name) const;
|
||||
void set_input(const StringName &p_action_name, const Variant &p_value);
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(XRPositionalTracker::TrackerHand);
|
70
servers/xr/xr_tracker.cpp
Normal file
70
servers/xr/xr_tracker.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/**************************************************************************/
|
||||
/* xr_tracker.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "xr_tracker.h"
|
||||
|
||||
void XRTracker::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_tracker_type"), &XRTracker::get_tracker_type);
|
||||
ClassDB::bind_method(D_METHOD("set_tracker_type", "type"), &XRTracker::set_tracker_type);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "type"), "set_tracker_type", "get_tracker_type");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_tracker_name"), &XRTracker::get_tracker_name);
|
||||
ClassDB::bind_method(D_METHOD("set_tracker_name", "name"), &XRTracker::set_tracker_name);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "name"), "set_tracker_name", "get_tracker_name");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_tracker_desc"), &XRTracker::get_tracker_desc);
|
||||
ClassDB::bind_method(D_METHOD("set_tracker_desc", "description"), &XRTracker::set_tracker_desc);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "description"), "set_tracker_desc", "get_tracker_desc");
|
||||
}
|
||||
|
||||
void XRTracker::set_tracker_type(XRServer::TrackerType p_type) {
|
||||
type = p_type;
|
||||
}
|
||||
|
||||
XRServer::TrackerType XRTracker::get_tracker_type() const {
|
||||
return type;
|
||||
}
|
||||
|
||||
void XRTracker::set_tracker_name(const StringName &p_name) {
|
||||
// Note: this should not be changed after the tracker is registered with the XRServer!
|
||||
name = p_name;
|
||||
}
|
||||
|
||||
StringName XRTracker::get_tracker_name() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
void XRTracker::set_tracker_desc(const String &p_desc) {
|
||||
description = p_desc;
|
||||
}
|
||||
|
||||
String XRTracker::get_tracker_desc() const {
|
||||
return description;
|
||||
}
|
58
servers/xr/xr_tracker.h
Normal file
58
servers/xr/xr_tracker.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/**************************************************************************/
|
||||
/* xr_tracker.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/os/thread_safe.h"
|
||||
#include "servers/xr_server.h"
|
||||
|
||||
/**
|
||||
The XR tracker object is a common base for all different types of XR trackers.
|
||||
*/
|
||||
|
||||
class XRTracker : public RefCounted {
|
||||
GDCLASS(XRTracker, RefCounted);
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
protected:
|
||||
XRServer::TrackerType type = XRServer::TRACKER_UNKNOWN; // type of tracker
|
||||
StringName name = "Unknown"; // (unique) name of the tracker
|
||||
String description; // description of the tracker
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
virtual void set_tracker_type(XRServer::TrackerType p_type);
|
||||
XRServer::TrackerType get_tracker_type() const;
|
||||
void set_tracker_name(const StringName &p_name);
|
||||
StringName get_tracker_name() const;
|
||||
void set_tracker_desc(const String &p_desc);
|
||||
String get_tracker_desc() const;
|
||||
};
|
179
servers/xr/xr_vrs.cpp
Normal file
179
servers/xr/xr_vrs.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
/**************************************************************************/
|
||||
/* xr_vrs.cpp */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#include "xr_vrs.h"
|
||||
|
||||
#include "servers/rendering/renderer_scene_render.h"
|
||||
#include "servers/rendering_server.h"
|
||||
|
||||
void XRVRS::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_vrs_min_radius"), &XRVRS::get_vrs_min_radius);
|
||||
ClassDB::bind_method(D_METHOD("set_vrs_min_radius", "radius"), &XRVRS::set_vrs_min_radius);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_vrs_strength"), &XRVRS::get_vrs_strength);
|
||||
ClassDB::bind_method(D_METHOD("set_vrs_strength", "strength"), &XRVRS::set_vrs_strength);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_vrs_render_region"), &XRVRS::get_vrs_render_region);
|
||||
ClassDB::bind_method(D_METHOD("set_vrs_render_region", "render_region"), &XRVRS::set_vrs_render_region);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "vrs_min_radius", PROPERTY_HINT_RANGE, "1.0,100.0,1.0"), "set_vrs_min_radius", "get_vrs_min_radius");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "vrs_strength", PROPERTY_HINT_RANGE, "0.1,10.0,0.1"), "set_vrs_strength", "get_vrs_strength");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::RECT2I, "vrs_render_region"), "set_vrs_render_region", "get_vrs_render_region");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("make_vrs_texture", "target_size", "eye_foci"), &XRVRS::make_vrs_texture);
|
||||
}
|
||||
|
||||
XRVRS::~XRVRS() {
|
||||
if (vrs_texture.is_valid()) {
|
||||
ERR_FAIL_NULL(RS::get_singleton());
|
||||
RS::get_singleton()->free(vrs_texture);
|
||||
vrs_texture = RID();
|
||||
}
|
||||
}
|
||||
|
||||
float XRVRS::get_vrs_min_radius() const {
|
||||
return vrs_min_radius;
|
||||
}
|
||||
|
||||
void XRVRS::set_vrs_min_radius(float p_vrs_min_radius) {
|
||||
if (p_vrs_min_radius < 1.0) {
|
||||
WARN_PRINT_ONCE("VRS minimum radius can not be set below 1.0");
|
||||
vrs_min_radius = 1.0;
|
||||
} else if (p_vrs_min_radius > 100.0) {
|
||||
WARN_PRINT_ONCE("VRS minimum radius can not be set above 100.0");
|
||||
vrs_min_radius = 100.0;
|
||||
} else {
|
||||
vrs_min_radius = p_vrs_min_radius;
|
||||
vrs_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
float XRVRS::get_vrs_strength() const {
|
||||
return vrs_strength;
|
||||
}
|
||||
|
||||
void XRVRS::set_vrs_strength(float p_vrs_strength) {
|
||||
if (p_vrs_strength < 0.1) {
|
||||
WARN_PRINT_ONCE("VRS strength can not be set below 0.1");
|
||||
vrs_strength = 0.1;
|
||||
} else if (p_vrs_strength > 10.0) {
|
||||
WARN_PRINT_ONCE("VRS strength can not be set above 10.0");
|
||||
vrs_strength = 10.0;
|
||||
} else {
|
||||
vrs_strength = p_vrs_strength;
|
||||
vrs_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
Rect2i XRVRS::get_vrs_render_region() const {
|
||||
return vrs_render_region;
|
||||
}
|
||||
|
||||
void XRVRS::set_vrs_render_region(const Rect2i &p_vrs_render_region) {
|
||||
vrs_render_region = p_vrs_render_region;
|
||||
vrs_dirty = true;
|
||||
}
|
||||
|
||||
RID XRVRS::make_vrs_texture(const Size2 &p_target_size, const PackedVector2Array &p_eye_foci) {
|
||||
ERR_FAIL_COND_V(p_eye_foci.is_empty(), RID());
|
||||
|
||||
Size2i texel_size = RD::get_singleton()->vrs_get_texel_size();
|
||||
|
||||
// Should return sensible data or graphics API does not support VRS.
|
||||
ERR_FAIL_COND_V(texel_size.x < 1 || texel_size.y < 1, RID());
|
||||
|
||||
Size2 vrs_size = Size2(0.5 + p_target_size.x / texel_size.x, 0.5 + p_target_size.y / texel_size.y).floor();
|
||||
|
||||
// Make sure we have at least one pixel.
|
||||
vrs_size = vrs_size.maxf(1.0);
|
||||
|
||||
float max_radius = 0.5 * MIN(vrs_size.x, vrs_size.y); // Maximum radius that fits inside of our image
|
||||
float min_radius = vrs_min_radius * max_radius / 100.0; // Minimum radius as a percentage of our size
|
||||
real_t outer_radius = MAX(1.0, (max_radius - min_radius) / vrs_strength);
|
||||
Size2 vrs_sizei = vrs_size;
|
||||
|
||||
// Our density map is now unified, with a value of (0.0, 0.0) meaning a 1x1 texel size and (1.0, 1.0) an max texel size.
|
||||
// For our standard VRS extension on Vulkan this means a maximum of 8x8.
|
||||
// For the density map extension this scales depending on the max texel size.
|
||||
|
||||
if (target_size != vrs_sizei || eye_foci != p_eye_foci || vrs_dirty) {
|
||||
// Out with the old.
|
||||
if (vrs_texture.is_valid()) {
|
||||
RS::get_singleton()->free(vrs_texture);
|
||||
vrs_texture = RID();
|
||||
}
|
||||
|
||||
// In with the new.
|
||||
Vector<Ref<Image>> images;
|
||||
target_size = vrs_sizei;
|
||||
eye_foci = p_eye_foci;
|
||||
|
||||
Size2 region_ratio = Size2(1.0, 1.0);
|
||||
Point2i region_offset;
|
||||
if (vrs_render_region != Rect2i()) {
|
||||
region_ratio = (Size2)vrs_render_region.size / p_target_size;
|
||||
region_offset = (Point2)vrs_render_region.position / p_target_size * vrs_sizei;
|
||||
}
|
||||
|
||||
for (int i = 0; i < eye_foci.size() && i < RendererSceneRender::MAX_RENDER_VIEWS; i++) {
|
||||
PackedByteArray data;
|
||||
data.resize(vrs_sizei.x * vrs_sizei.y * 2);
|
||||
uint8_t *data_ptr = data.ptrw();
|
||||
|
||||
Vector2i view_center;
|
||||
view_center.x = int(vrs_size.x * (eye_foci[i].x + 1.0) * region_ratio.x * 0.5) + region_offset.x;
|
||||
view_center.y = int(vrs_size.y * (-eye_foci[i].y + 1.0) * region_ratio.y * 0.5) + region_offset.y;
|
||||
|
||||
int d = 0;
|
||||
for (int y = 0; y < vrs_sizei.y; y++) {
|
||||
for (int x = 0; x < vrs_sizei.x; x++) {
|
||||
// Generate a density map that represents the distance to the view focus point. While this leaves the opportunities
|
||||
// offered by the density map being different in each direction currently unused, it was found to give better tile
|
||||
// distribution on hardware that supports the feature natively. This area is open to improvements in the future.
|
||||
Vector2 offset = Vector2(x - view_center.x, y - view_center.y) / region_ratio;
|
||||
real_t density = MAX(offset.length() - min_radius, 0.0) / outer_radius;
|
||||
data_ptr[d++] = CLAMP(255.0 * density, 0, 255);
|
||||
data_ptr[d++] = CLAMP(255.0 * density, 0, 255);
|
||||
}
|
||||
}
|
||||
images.push_back(Image::create_from_data(vrs_sizei.x, vrs_sizei.y, false, Image::FORMAT_RG8, data));
|
||||
}
|
||||
|
||||
if (images.size() == 1) {
|
||||
vrs_texture = RS::get_singleton()->texture_2d_create(images[0]);
|
||||
} else {
|
||||
vrs_texture = RS::get_singleton()->texture_2d_layered_create(images, RS::TEXTURE_LAYERED_2D_ARRAY);
|
||||
}
|
||||
|
||||
vrs_dirty = false;
|
||||
}
|
||||
|
||||
return vrs_texture;
|
||||
}
|
67
servers/xr/xr_vrs.h
Normal file
67
servers/xr/xr_vrs.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/**************************************************************************/
|
||||
/* xr_vrs.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/object/class_db.h"
|
||||
#include "core/object/object.h"
|
||||
#include "core/templates/rid.h"
|
||||
#include "core/variant/variant.h"
|
||||
|
||||
/* This is a helper class for generating stereoscopic VRS images */
|
||||
|
||||
class XRVRS : public Object {
|
||||
GDCLASS(XRVRS, Object);
|
||||
|
||||
private:
|
||||
float vrs_min_radius = 20.0;
|
||||
float vrs_strength = 1.0;
|
||||
Rect2i vrs_render_region;
|
||||
bool vrs_dirty = true;
|
||||
|
||||
RID vrs_texture;
|
||||
Size2i target_size;
|
||||
PackedVector2Array eye_foci;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
~XRVRS();
|
||||
|
||||
float get_vrs_min_radius() const;
|
||||
void set_vrs_min_radius(float p_vrs_min_radius);
|
||||
float get_vrs_strength() const;
|
||||
void set_vrs_strength(float p_vrs_strength);
|
||||
Rect2i get_vrs_render_region() const;
|
||||
void set_vrs_render_region(const Rect2i &p_vrs_render_region);
|
||||
|
||||
RID make_vrs_texture(const Size2 &p_target_size, const PackedVector2Array &p_eye_foci);
|
||||
};
|
Reference in New Issue
Block a user