summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/input_map.cpp2
-rw-r--r--core/io/compression.cpp2
-rw-r--r--core/io/file_access_memory.cpp2
-rw-r--r--core/io/file_access_network.cpp2
-rw-r--r--core/io/packet_peer.cpp2
-rw-r--r--core/io/resource_format_binary.cpp2
-rw-r--r--core/io/resource_saver.cpp2
-rw-r--r--core/math/camera_matrix.cpp124
-rw-r--r--core/math/camera_matrix.h2
-rw-r--r--core/math/face3.h24
-rw-r--r--core/os/dir_access.cpp2
-rw-r--r--core/os/file_access.cpp2
-rw-r--r--core/os/input.cpp2
-rw-r--r--core/reference.h6
-rw-r--r--core/register_core_types.cpp2
-rw-r--r--core/script_debugger_remote.cpp2
-rw-r--r--core/translation.cpp2
-rw-r--r--editor/collada/collada.h2
-rw-r--r--editor/doc/doc_data.cpp2
-rw-r--r--editor/editor_autoload_settings.cpp2
-rw-r--r--editor/editor_data.cpp2
-rw-r--r--editor/editor_plugin_settings.cpp2
-rw-r--r--editor/editor_resource_preview.cpp2
-rw-r--r--editor/file_type_cache.cpp2
-rw-r--r--editor/filesystem_dock.cpp2
-rw-r--r--editor/import/editor_import_collada.cpp4
-rw-r--r--editor/io_plugins/editor_export_scene.cpp2
-rw-r--r--editor/io_plugins/editor_scene_import_plugin.cpp2
-rw-r--r--editor/io_plugins/editor_texture_import_plugin.cpp2
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp2
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.cpp2
-rw-r--r--editor/plugins/sample_editor_plugin.cpp2
-rw-r--r--editor/plugins/sample_library_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp2
-rw-r--r--editor/plugins/texture_editor_plugin.cpp2
-rw-r--r--editor/project_export.cpp2
-rw-r--r--editor/property_editor.cpp13
-rw-r--r--editor/script_create_dialog.cpp2
-rw-r--r--editor/script_editor_debugger.cpp2
-rw-r--r--editor/settings_config_dialog.cpp2
-rw-r--r--modules/gdnative/gdnative.cpp3
-rw-r--r--modules/gdnative/godot/gdnative.h1
-rw-r--r--modules/nativescript/nativescript.cpp10
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.cpp2
-rw-r--r--platform/iphone/gl_view.mm2
-rw-r--r--platform/iphone/ios.mm2
-rw-r--r--platform/osx/audio_driver_osx.cpp54
-rw-r--r--platform/osx/audio_driver_osx.h1
-rw-r--r--platform/osx/os_osx.h3
-rw-r--r--platform/osx/os_osx.mm114
-rw-r--r--scene/3d/arvr_nodes.cpp313
-rw-r--r--scene/3d/arvr_nodes.h126
-rw-r--r--scene/io/resource_format_image.cpp2
-rw-r--r--scene/main/node.h2
-rw-r--r--scene/main/viewport.cpp16
-rw-r--r--scene/main/viewport.h5
-rw-r--r--scene/register_scene_types.cpp7
-rw-r--r--scene/resources/packed_scene.cpp2
-rw-r--r--scene/resources/scene_format_text.cpp2
-rw-r--r--scene/resources/texture.h2
-rw-r--r--servers/SCsub3
-rw-r--r--servers/arvr/SCsub7
-rw-r--r--servers/arvr/arvr_interface.cpp82
-rw-r--r--servers/arvr/arvr_interface.h89
-rw-r--r--servers/arvr/arvr_positional_tracker.cpp142
-rw-r--r--servers/arvr/arvr_positional_tracker.h85
-rw-r--r--servers/arvr/arvr_script_interface.cpp127
-rw-r--r--servers/arvr/arvr_script_interface.h47
-rw-r--r--servers/arvr_server.cpp313
-rw-r--r--servers/arvr_server.h167
-rw-r--r--servers/register_server_types.cpp15
-rw-r--r--servers/visual/visual_server_raster.h1
-rw-r--r--servers/visual/visual_server_scene.cpp20
-rw-r--r--servers/visual/visual_server_scene.h2
-rw-r--r--servers/visual/visual_server_viewport.cpp82
-rw-r--r--servers/visual/visual_server_viewport.h8
-rw-r--r--servers/visual/visual_server_wrap_mt.h2
-rw-r--r--servers/visual_server.h1
79 files changed, 1927 insertions, 178 deletions
diff --git a/core/input_map.cpp b/core/input_map.cpp
index 1abe019167..24d0624e98 100644
--- a/core/input_map.cpp
+++ b/core/input_map.cpp
@@ -29,8 +29,8 @@
/*************************************************************************/
#include "input_map.h"
-#include "project_settings.h"
#include "os/keyboard.h"
+#include "project_settings.h"
InputMap *InputMap::singleton = NULL;
diff --git a/core/io/compression.cpp b/core/io/compression.cpp
index ca35ece8f5..139383710c 100644
--- a/core/io/compression.cpp
+++ b/core/io/compression.cpp
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "compression.h"
-#include "project_settings.h"
#include "os/copymem.h"
+#include "project_settings.h"
#include "zip_io.h"
#include "thirdparty/misc/fastlz.h"
diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp
index 2197b187eb..8e719568e5 100644
--- a/core/io/file_access_memory.cpp
+++ b/core/io/file_access_memory.cpp
@@ -29,10 +29,10 @@
/*************************************************************************/
#include "file_access_memory.h"
-#include "project_settings.h"
#include "map.h"
#include "os/copymem.h"
#include "os/dir_access.h"
+#include "project_settings.h"
static Map<String, Vector<uint8_t> > *files = NULL;
diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp
index 46457d1425..aa67479d7e 100644
--- a/core/io/file_access_network.cpp
+++ b/core/io/file_access_network.cpp
@@ -28,10 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "file_access_network.h"
-#include "project_settings.h"
#include "io/ip.h"
#include "marshalls.h"
#include "os/os.h"
+#include "project_settings.h"
//#define DEBUG_PRINT(m_p) print_line(m_p)
//#define DEBUG_TIME(m_what) printf("MS: %s - %lli\n",m_what,OS::get_singleton()->get_ticks_usec());
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index 81446a3886..a3d33593dd 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -29,8 +29,8 @@
/*************************************************************************/
#include "packet_peer.h"
-#include "project_settings.h"
#include "io/marshalls.h"
+#include "project_settings.h"
/* helpers / binders */
PacketPeer::PacketPeer() {
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index 602cbe6f30..9aa16ed7e7 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -28,11 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "resource_format_binary.h"
-#include "project_settings.h"
#include "image.h"
#include "io/file_access_compressed.h"
#include "io/marshalls.h"
#include "os/dir_access.h"
+#include "project_settings.h"
#include "version.h"
//#define print_bl(m_what) print_line(m_what)
#define print_bl(m_what)
diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp
index 58913b80cc..314259b2e9 100644
--- a/core/io/resource_saver.cpp
+++ b/core/io/resource_saver.cpp
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "resource_saver.h"
-#include "project_settings.h"
#include "os/file_access.h"
+#include "project_settings.h"
#include "resource_loader.h"
#include "script_language.h"
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index 33ad522315..a1666ccd8b 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -91,6 +91,72 @@ void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_
matrix[3][3] = 0;
}
+void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist) {
+ if (p_flip_fov) {
+ p_fovy_degrees = get_fovy(p_fovy_degrees, 1.0 / p_aspect);
+ }
+
+ real_t left, right, modeltranslation, ymax, xmax, frustumshift;
+
+ ymax = p_z_near * tan(p_fovy_degrees * Math_PI / 360.0f);
+ xmax = ymax * p_aspect;
+ frustumshift = (p_intraocular_dist / 2.0) * p_z_near / p_convergence_dist;
+
+ switch (p_eye) {
+ case 1: { // left eye
+ left = -xmax + frustumshift;
+ right = xmax + frustumshift;
+ modeltranslation = p_intraocular_dist / 2.0;
+ }; break;
+ case 2: { // right eye
+ left = -xmax - frustumshift;
+ right = xmax - frustumshift;
+ modeltranslation = -p_intraocular_dist / 2.0;
+ }; break;
+ default: { // mono, should give the same result as set_perspective(p_fovy_degrees,p_aspect,p_z_near,p_z_far,p_flip_fov)
+ left = -xmax;
+ right = xmax;
+ modeltranslation = 0.0;
+ }; break;
+ };
+
+ set_frustum(left, right, -ymax, ymax, p_z_near, p_z_far);
+
+ // translate matrix by (modeltranslation, 0.0, 0.0)
+ CameraMatrix cm;
+ cm.set_identity();
+ cm.matrix[3][0] = modeltranslation;
+ *this = *this * cm;
+}
+
+void CameraMatrix::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_dist, real_t p_display_width, real_t p_display_to_lens, real_t p_oversample, real_t p_z_near, real_t p_z_far) {
+ // we first calculate our base frustum on our values without taking our lens magnification into account.
+ real_t display_to_eye = 2.0 * p_display_to_lens;
+ real_t f1 = (p_intraocular_dist * 0.5) / p_display_to_lens;
+ real_t f2 = ((p_display_width - p_intraocular_dist) * 0.5) / p_display_to_lens;
+ real_t f3 = (p_display_width / 4.0) / p_display_to_lens;
+
+ // now we apply our oversample factor to increase our FOV. how much we oversample is always a balance we strike between performance and how much
+ // we're willing to sacrifice in FOV.
+ real_t add = ((f1 + f2) * (p_oversample - 1.0)) / 2.0;
+ f1 += add;
+ f2 += add;
+
+ // always apply KEEP_WIDTH aspect ratio
+ f3 *= p_aspect;
+
+ switch (p_eye) {
+ case 1: { // left eye
+ set_frustum(-f2 * p_z_near, f1 * p_z_near, -f3 * p_z_near, f3 * p_z_near, p_z_near, p_z_far);
+ }; break;
+ case 2: { // right eye
+ set_frustum(-f1 * p_z_near, f2 * p_z_near, -f3 * p_z_near, f3 * p_z_near, p_z_near, p_z_far);
+ }; break;
+ default: { // mono, does not apply here!
+ }; break;
+ };
+};
+
void CameraMatrix::set_orthogonal(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_znear, real_t p_zfar) {
set_identity();
@@ -243,23 +309,44 @@ bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8point
-matrix[15] + matrix[13]);
top_plane.normalize();
- Vector3 near_endpoint;
- Vector3 far_endpoint;
+ Vector3 near_endpoint_left, near_endpoint_right;
+ Vector3 far_endpoint_left, far_endpoint_right;
- bool res = near_plane.intersect_3(right_plane, top_plane, &near_endpoint);
+ bool res = near_plane.intersect_3(right_plane, top_plane, &near_endpoint_right);
ERR_FAIL_COND_V(!res, false);
- res = far_plane.intersect_3(right_plane, top_plane, &far_endpoint);
+ res = far_plane.intersect_3(right_plane, top_plane, &far_endpoint_right);
ERR_FAIL_COND_V(!res, false);
- p_8points[0] = p_transform.xform(Vector3(near_endpoint.x, near_endpoint.y, near_endpoint.z));
- p_8points[1] = p_transform.xform(Vector3(near_endpoint.x, -near_endpoint.y, near_endpoint.z));
- p_8points[2] = p_transform.xform(Vector3(-near_endpoint.x, near_endpoint.y, near_endpoint.z));
- p_8points[3] = p_transform.xform(Vector3(-near_endpoint.x, -near_endpoint.y, near_endpoint.z));
- p_8points[4] = p_transform.xform(Vector3(far_endpoint.x, far_endpoint.y, far_endpoint.z));
- p_8points[5] = p_transform.xform(Vector3(far_endpoint.x, -far_endpoint.y, far_endpoint.z));
- p_8points[6] = p_transform.xform(Vector3(-far_endpoint.x, far_endpoint.y, far_endpoint.z));
- p_8points[7] = p_transform.xform(Vector3(-far_endpoint.x, -far_endpoint.y, far_endpoint.z));
+ if ((matrix[8] == 0) && (matrix[9] == 0)) {
+ near_endpoint_left = near_endpoint_right;
+ near_endpoint_left.x = -near_endpoint_left.x;
+
+ far_endpoint_left = far_endpoint_right;
+ far_endpoint_left.x = -far_endpoint_left.x;
+ } else {
+ ///////--- Left Plane ---///////
+ Plane left_plane = Plane(matrix[0] + matrix[3],
+ matrix[4] + matrix[7],
+ matrix[8] + matrix[11],
+ -matrix[15] - matrix[12]);
+ left_plane.normalize();
+
+ res = near_plane.intersect_3(left_plane, top_plane, &near_endpoint_left);
+ ERR_FAIL_COND_V(!res, false);
+
+ res = far_plane.intersect_3(left_plane, top_plane, &far_endpoint_left);
+ ERR_FAIL_COND_V(!res, false);
+ }
+
+ p_8points[0] = p_transform.xform(Vector3(near_endpoint_right.x, near_endpoint_right.y, near_endpoint_right.z));
+ p_8points[1] = p_transform.xform(Vector3(near_endpoint_right.x, -near_endpoint_right.y, near_endpoint_right.z));
+ p_8points[2] = p_transform.xform(Vector3(near_endpoint_left.x, near_endpoint_left.y, near_endpoint_left.z));
+ p_8points[3] = p_transform.xform(Vector3(near_endpoint_left.x, -near_endpoint_left.y, near_endpoint_left.z));
+ p_8points[4] = p_transform.xform(Vector3(far_endpoint_right.x, far_endpoint_right.y, far_endpoint_right.z));
+ p_8points[5] = p_transform.xform(Vector3(far_endpoint_right.x, -far_endpoint_right.y, far_endpoint_right.z));
+ p_8points[6] = p_transform.xform(Vector3(far_endpoint_left.x, far_endpoint_left.y, far_endpoint_left.z));
+ p_8points[7] = p_transform.xform(Vector3(far_endpoint_left.x, -far_endpoint_left.y, far_endpoint_left.z));
return true;
}
@@ -546,7 +633,18 @@ real_t CameraMatrix::get_fov() const {
-matrix[15] + matrix[12]);
right_plane.normalize();
- return Math::rad2deg(Math::acos(Math::abs(right_plane.normal.x))) * 2.0;
+ if ((matrix[8] == 0) && (matrix[9] == 0)) {
+ return Math::rad2deg(Math::acos(Math::abs(right_plane.normal.x))) * 2.0;
+ } else {
+ // our frustum is asymetrical need to calculate the left planes angle seperately..
+ Plane left_plane = Plane(matrix[3] + matrix[0],
+ matrix[7] + matrix[4],
+ matrix[11] + matrix[8],
+ matrix[15] + matrix[12]);
+ left_plane.normalize();
+
+ return Math::rad2deg(Math::acos(Math::abs(left_plane.normal.x))) + Math::rad2deg(Math::acos(Math::abs(right_plane.normal.x)));
+ }
}
void CameraMatrix::make_scale(const Vector3 &p_scale) {
diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h
index af61e35993..4be8ffab8c 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -54,6 +54,8 @@ struct CameraMatrix {
void set_light_bias();
void set_light_atlas_rect(const Rect2 &p_rect);
void set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov = false);
+ void set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist);
+ void set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_dist, real_t p_display_width, real_t p_display_to_lens, real_t p_oversample, real_t p_z_near, real_t p_z_far);
void set_orthogonal(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_znear, real_t p_zfar);
void set_orthogonal(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov = false);
void set_frustum(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_near, real_t p_far);
diff --git a/core/math/face3.h b/core/math/face3.h
index 1cc94321c3..3d02ae4014 100644
--- a/core/math/face3.h
+++ b/core/math/face3.h
@@ -115,20 +115,20 @@ bool Face3::intersects_aabb2(const Rect3 &p_aabb) const {
if (dist_a * dist_b > 0)
return false; //does not intersect the plane
-#define TEST_AXIS(m_ax) \
- { \
+#define TEST_AXIS(m_ax) \
+ { \
real_t aabb_min = p_aabb.position.m_ax; \
real_t aabb_max = p_aabb.position.m_ax + p_aabb.size.m_ax; \
- real_t tri_min, tri_max; \
- for (int i = 0; i < 3; i++) { \
- if (i == 0 || vertex[i].m_ax > tri_max) \
- tri_max = vertex[i].m_ax; \
- if (i == 0 || vertex[i].m_ax < tri_min) \
- tri_min = vertex[i].m_ax; \
- } \
- \
- if (tri_max < aabb_min || aabb_max < tri_min) \
- return false; \
+ real_t tri_min, tri_max; \
+ for (int i = 0; i < 3; i++) { \
+ if (i == 0 || vertex[i].m_ax > tri_max) \
+ tri_max = vertex[i].m_ax; \
+ if (i == 0 || vertex[i].m_ax < tri_min) \
+ tri_min = vertex[i].m_ax; \
+ } \
+ \
+ if (tri_max < aabb_min || aabb_max < tri_min) \
+ return false; \
}
TEST_AXIS(x);
diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp
index 484942bad5..391ae78c85 100644
--- a/core/os/dir_access.cpp
+++ b/core/os/dir_access.cpp
@@ -28,10 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "dir_access.h"
-#include "project_settings.h"
#include "os/file_access.h"
#include "os/memory.h"
#include "os/os.h"
+#include "project_settings.h"
String DirAccess::_get_root_path() const {
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index 7f5a84843c..3bd5ac3f41 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -31,8 +31,8 @@
#include "core/io/file_access_pack.h"
#include "core/io/marshalls.h"
-#include "project_settings.h"
#include "os/os.h"
+#include "project_settings.h"
#include "thirdparty/misc/md5.h"
#include "thirdparty/misc/sha256.h"
diff --git a/core/os/input.cpp b/core/os/input.cpp
index 18d644668c..a90a552d1d 100644
--- a/core/os/input.cpp
+++ b/core/os/input.cpp
@@ -28,9 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "input.h"
-#include "project_settings.h"
#include "input_map.h"
#include "os/os.h"
+#include "project_settings.h"
Input *Input::singleton = NULL;
Input *Input::get_singleton() {
diff --git a/core/reference.h b/core/reference.h
index 4e2d6c36c0..90f2791f4b 100644
--- a/core/reference.h
+++ b/core/reference.h
@@ -330,7 +330,7 @@ struct PtrToArg<Ref<T> > {
_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
- return Ref<T>(reinterpret_cast<const T *>(p_ptr));
+ return Ref<T>(const_cast<T *>(reinterpret_cast<const T *>(p_ptr)));
}
_FORCE_INLINE_ static void encode(Ref<T> p_val, const void *p_ptr) {
@@ -355,7 +355,7 @@ struct PtrToArg<RefPtr> {
_FORCE_INLINE_ static RefPtr convert(const void *p_ptr) {
- return Ref<Reference>(reinterpret_cast<const Reference *>(p_ptr)).get_ref_ptr();
+ return Ref<Reference>(const_cast<Reference *>(reinterpret_cast<const Reference *>(p_ptr))).get_ref_ptr();
}
_FORCE_INLINE_ static void encode(RefPtr p_val, const void *p_ptr) {
@@ -370,7 +370,7 @@ struct PtrToArg<const RefPtr &> {
_FORCE_INLINE_ static RefPtr convert(const void *p_ptr) {
- return Ref<Reference>(reinterpret_cast<const Reference *>(p_ptr)).get_ref_ptr();
+ return Ref<Reference>(const_cast<Reference *>(reinterpret_cast<const Reference *>(p_ptr))).get_ref_ptr();
}
};
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index 07715f9718..43f781af55 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -36,7 +36,6 @@
#include "core_string_names.h"
#include "func_ref.h"
#include "geometry.h"
-#include "project_settings.h"
#include "input_map.h"
#include "io/config_file.h"
#include "io/http_client.h"
@@ -54,6 +53,7 @@
#include "os/main_loop.h"
#include "packed_data_container.h"
#include "path_remap.h"
+#include "project_settings.h"
#include "translation.h"
#include "undo_redo.h"
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index dec41e7976..d19fe213f6 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -29,10 +29,10 @@
/*************************************************************************/
#include "script_debugger_remote.h"
-#include "project_settings.h"
#include "io/ip.h"
#include "os/input.h"
#include "os/os.h"
+#include "project_settings.h"
void ScriptDebuggerRemote::_send_video_memory() {
diff --git a/core/translation.cpp b/core/translation.cpp
index d782006ddc..50694e4a2d 100644
--- a/core/translation.cpp
+++ b/core/translation.cpp
@@ -29,9 +29,9 @@
/*************************************************************************/
#include "translation.h"
-#include "project_settings.h"
#include "io/resource_loader.h"
#include "os/os.h"
+#include "project_settings.h"
static const char *locale_list[] = {
"aa", // Afar
diff --git a/editor/collada/collada.h b/editor/collada/collada.h
index 38e66a7e45..8945e14cce 100644
--- a/editor/collada/collada.h
+++ b/editor/collada/collada.h
@@ -32,9 +32,9 @@
#ifndef COLLADA_H
#define COLLADA_H
-#include "project_settings.h"
#include "io/xml_parser.h"
#include "map.h"
+#include "project_settings.h"
#include "scene/resources/material.h"
class Collada {
diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp
index fa90cd36b3..69d7475f4c 100644
--- a/editor/doc/doc_data.cpp
+++ b/editor/doc/doc_data.cpp
@@ -29,10 +29,10 @@
/*************************************************************************/
#include "doc_data.h"
-#include "project_settings.h"
#include "global_constants.h"
#include "io/compression.h"
#include "io/marshalls.h"
+#include "project_settings.h"
#include "scene/resources/theme.h"
#include "script_language.h"
#include "version.h"
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index 399c22bf2c..dde94cb334 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -30,8 +30,8 @@
#include "editor_autoload_settings.h"
#include "editor_node.h"
-#include "project_settings.h"
#include "global_constants.h"
+#include "project_settings.h"
#define PREVIEW_LIST_MAX_SIZE 10
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index f8dbd9abe5..c82e8f1226 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -31,10 +31,10 @@
#include "editor_node.h"
#include "editor_settings.h"
-#include "project_settings.h"
#include "io/resource_loader.h"
#include "os/dir_access.h"
#include "os/file_access.h"
+#include "project_settings.h"
#include "scene/resources/packed_scene.h"
void EditorHistory::_cleanup_history() {
diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp
index 6ab1468b1d..63bee33092 100644
--- a/editor/editor_plugin_settings.cpp
+++ b/editor/editor_plugin_settings.cpp
@@ -30,10 +30,10 @@
#include "editor_plugin_settings.h"
#include "editor_node.h"
-#include "project_settings.h"
#include "io/config_file.h"
#include "os/file_access.h"
#include "os/main_loop.h"
+#include "project_settings.h"
#include "scene/gui/margin_container.h"
void EditorPluginSettings::_notification(int p_what) {
diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp
index 3a6b34b7b4..89fa004eb1 100644
--- a/editor/editor_resource_preview.cpp
+++ b/editor/editor_resource_preview.cpp
@@ -31,11 +31,11 @@
#include "editor_scale.h"
#include "editor_settings.h"
-#include "project_settings.h"
#include "io/resource_loader.h"
#include "io/resource_saver.h"
#include "message_queue.h"
#include "os/file_access.h"
+#include "project_settings.h"
bool EditorResourcePreviewGenerator::handles(const String &p_type) const {
diff --git a/editor/file_type_cache.cpp b/editor/file_type_cache.cpp
index 100ebe21cd..728e80bba7 100644
--- a/editor/file_type_cache.cpp
+++ b/editor/file_type_cache.cpp
@@ -29,8 +29,8 @@
/*************************************************************************/
#include "file_type_cache.h"
-#include "project_settings.h"
#include "os/file_access.h"
+#include "project_settings.h"
FileTypeCache *FileTypeCache::singleton = NULL;
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index eacb1d2cd9..77ca1a5145 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -31,11 +31,11 @@
#include "editor_node.h"
#include "editor_settings.h"
-#include "project_settings.h"
#include "io/resource_loader.h"
#include "os/dir_access.h"
#include "os/file_access.h"
#include "os/os.h"
+#include "project_settings.h"
#include "scene/main/viewport.h"
bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir) {
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index 5bf2da9912..3626c6be59 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -554,10 +554,10 @@ static void _generate_tangents_and_binormals(const PoolVector<int> &p_indices, c
tangent = Vector3();
} else {
tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
- (t2 * z1 - t1 * z2) * r)
+ (t2 * z1 - t1 * z2) * r)
.normalized();
binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
- (s1 * z2 - s2 * z1) * r)
+ (s1 * z2 - s2 * z1) * r)
.normalized();
}
diff --git a/editor/io_plugins/editor_export_scene.cpp b/editor/io_plugins/editor_export_scene.cpp
index 390217053a..6392b4a715 100644
--- a/editor/io_plugins/editor_export_scene.cpp
+++ b/editor/io_plugins/editor_export_scene.cpp
@@ -30,11 +30,11 @@
#include "editor_export_scene.h"
#if 0
#include "editor/editor_settings.h"
-#include "project_settings.h"
#include "io/resource_loader.h"
#include "io/resource_saver.h"
#include "os/dir_access.h"
#include "os/file_access.h"
+#include "project_settings.h"
#include "scene/resources/packed_scene.h"
Vector<uint8_t> EditorSceneExportPlugin::custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) {
diff --git a/editor/io_plugins/editor_scene_import_plugin.cpp b/editor/io_plugins/editor_scene_import_plugin.cpp
index 5f0e928844..aa96f731ce 100644
--- a/editor/io_plugins/editor_scene_import_plugin.cpp
+++ b/editor/io_plugins/editor_scene_import_plugin.cpp
@@ -31,10 +31,10 @@
#if 0
#include "editor/create_dialog.h"
#include "editor/editor_node.h"
-#include "project_settings.h"
#include "io/resource_saver.h"
#include "os/file_access.h"
#include "os/os.h"
+#include "project_settings.h"
#include "scene/3d/body_shape.h"
#include "scene/3d/mesh_instance.h"
#include "scene/3d/navigation.h"
diff --git a/editor/io_plugins/editor_texture_import_plugin.cpp b/editor/io_plugins/editor_texture_import_plugin.cpp
index 842c43f4de..095bc02fa0 100644
--- a/editor/io_plugins/editor_texture_import_plugin.cpp
+++ b/editor/io_plugins/editor_texture_import_plugin.cpp
@@ -33,10 +33,10 @@
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "editor_atlas.h"
-#include "project_settings.h"
#include "io/image_loader.h"
#include "io/marshalls.h"
#include "io/resource_saver.h"
+#include "project_settings.h"
#include "scene/gui/button_group.h"
#include "scene/gui/check_button.h"
#include "scene/gui/margin_container.h"
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 82b03d3a19..c4e79bf263 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -31,10 +31,10 @@
#include "editor/animation_editor.h"
#include "editor/editor_settings.h"
-#include "project_settings.h"
#include "io/resource_loader.h"
#include "io/resource_saver.h"
#include "os/keyboard.h"
+#include "project_settings.h"
void AnimationPlayerEditor::_node_removed(Node *p_node) {
diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp
index 463b6360ad..2703da12fe 100644
--- a/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -30,8 +30,8 @@
#include "resource_preloader_editor_plugin.h"
#include "editor/editor_settings.h"
-#include "project_settings.h"
#include "io/resource_loader.h"
+#include "project_settings.h"
void ResourcePreloaderEditor::_gui_input(Ref<InputEvent> p_event) {
}
diff --git a/editor/plugins/sample_editor_plugin.cpp b/editor/plugins/sample_editor_plugin.cpp
index 0b99ab5460..739a8abb53 100644
--- a/editor/plugins/sample_editor_plugin.cpp
+++ b/editor/plugins/sample_editor_plugin.cpp
@@ -31,8 +31,8 @@
#if 0
#include "editor/editor_settings.h"
-#include "project_settings.h"
#include "io/resource_loader.h"
+#include "project_settings.h"
diff --git a/editor/plugins/sample_library_editor_plugin.cpp b/editor/plugins/sample_library_editor_plugin.cpp
index 04c805165f..5ccfde15ff 100644
--- a/editor/plugins/sample_library_editor_plugin.cpp
+++ b/editor/plugins/sample_library_editor_plugin.cpp
@@ -32,8 +32,8 @@
#include "sample_library_editor_plugin.h"
#include "editor/editor_settings.h"
-#include "project_settings.h"
#include "io/resource_loader.h"
+#include "project_settings.h"
#include "sample_editor_plugin.h"
#include "scene/main/viewport.h"
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index fef7f07abb..77c540b746 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -2229,7 +2229,7 @@ void ScriptEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_open_scripts"), &ScriptEditor::_get_open_scripts);
ADD_SIGNAL(MethodInfo("editor_script_changed", PropertyInfo(Variant::OBJECT, "script:Script")));
- ADD_SIGNAL(MethodInfo("script_close", PropertyInfo(Variant::STRING, "script:String")));
+ ADD_SIGNAL(MethodInfo("script_close", PropertyInfo(Variant::OBJECT, "script:Script")));
}
ScriptEditor::ScriptEditor(EditorNode *p_editor) {
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index fa80894f7b..6a010062f2 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -30,8 +30,8 @@
#include "sprite_frames_editor_plugin.h"
#include "editor/editor_settings.h"
-#include "project_settings.h"
#include "io/resource_loader.h"
+#include "project_settings.h"
#include "scene/3d/sprite_3d.h"
void SpriteFramesEditor::_gui_input(Ref<InputEvent> p_event) {
diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp
index 70a1227c52..125d906460 100644
--- a/editor/plugins/texture_editor_plugin.cpp
+++ b/editor/plugins/texture_editor_plugin.cpp
@@ -30,8 +30,8 @@
#include "texture_editor_plugin.h"
#include "editor/editor_settings.h"
-#include "project_settings.h"
#include "io/resource_loader.h"
+#include "project_settings.h"
void TextureEditor::_gui_input(Ref<InputEvent> p_event) {
}
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index b498044a65..b9694dffcb 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -32,7 +32,6 @@
#include "editor_data.h"
#include "editor_node.h"
#include "editor_settings.h"
-#include "project_settings.h"
#include "io/image_loader.h"
#include "io/resource_loader.h"
#include "io/resource_saver.h"
@@ -40,6 +39,7 @@
#include "os/dir_access.h"
#include "os/file_access.h"
#include "os/os.h"
+#include "project_settings.h"
#include "scene/gui/box_container.h"
#include "scene/gui/margin_container.h"
#include "scene/gui/scroll_container.h"
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 1d91d9a885..42485317c1 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -1957,11 +1957,6 @@ CustomPropertyEditor::CustomPropertyEditor() {
add_child(error);
//error->get_cancel()->hide();
- type_button = memnew(MenuButton);
- add_child(type_button);
- type_button->hide();
- type_button->get_popup()->connect("id_pressed", this, "_type_create_selected");
-
scene_tree = memnew(SceneTreeDialog);
add_child(scene_tree);
scene_tree->connect("selected", this, "_node_path_selected");
@@ -1979,6 +1974,11 @@ CustomPropertyEditor::CustomPropertyEditor() {
//easing_draw->emit_signal(SceneStringNames::get_singleton()->input_event,InputEvent());
easing_draw->set_default_cursor_shape(Control::CURSOR_MOVE);
+ type_button = memnew(MenuButton);
+ add_child(type_button);
+ type_button->hide();
+ type_button->get_popup()->connect("id_pressed", this, "_type_create_selected");
+
menu = memnew(PopupMenu);
add_child(menu);
menu->connect("id_pressed", this, "_menu_option");
@@ -2199,7 +2199,6 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String &p
case Variant::BOOL: {
p_item->set_checked(1, obj->get(p_name));
- p_item->set_text(1, obj->get(p_name) ? TTR("On") : TTR("Off"));
} break;
case Variant::REAL:
case Variant::INT: {
@@ -3142,7 +3141,7 @@ void PropertyEditor::update_tree() {
case Variant::BOOL: {
item->set_cell_mode(1, TreeItem::CELL_MODE_CHECK);
- item->set_text(1, obj->get(p.name) ? TTR("On") : TTR("Off"));
+ item->set_text(1, TTR("On"));
item->set_tooltip(1, obj->get(p.name) ? "True" : "False");
item->set_checked(1, obj->get(p.name));
if (show_type_icons)
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index c3a3410717..d81161ae94 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -31,9 +31,9 @@
#include "editor/editor_scale.h"
#include "editor_file_system.h"
-#include "project_settings.h"
#include "io/resource_saver.h"
#include "os/file_access.h"
+#include "project_settings.h"
#include "script_language.h"
void ScriptCreateDialog::_notification(int p_what) {
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 2af3bd5f31..f4ed430d3d 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -32,8 +32,8 @@
#include "editor_node.h"
#include "editor_profiler.h"
#include "editor_settings.h"
-#include "project_settings.h"
#include "main/performance.h"
+#include "project_settings.h"
#include "property_editor.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/label.h"
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index eec047cd9a..d455e0cea9 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -32,8 +32,8 @@
#include "editor_file_system.h"
#include "editor_node.h"
#include "editor_settings.h"
-#include "project_settings.h"
#include "os/keyboard.h"
+#include "project_settings.h"
#include "scene/gui/margin_container.h"
void EditorSettingsDialog::ok_pressed() {
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index e810c33f1c..158f7fd94d 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -185,6 +185,8 @@ void GDNative::_bind_methods() {
}
void GDNative::set_library(Ref<GDNativeLibrary> p_library) {
+ ERR_EXPLAIN("Tried to change library of GDNative when it is already set");
+ ERR_FAIL_COND(library.is_valid());
library = p_library;
}
@@ -229,6 +231,7 @@ bool GDNative::initialize() {
options.core_api_hash = ClassDB::get_api_hash(ClassDB::API_CORE);
options.editor_api_hash = ClassDB::get_api_hash(ClassDB::API_EDITOR);
options.no_api_hash = ClassDB::get_api_hash(ClassDB::API_NONE);
+ options.gd_native_library = (godot_object *)(get_library().ptr());
library_init_fpointer(&options);
diff --git a/modules/gdnative/godot/gdnative.h b/modules/gdnative/godot/gdnative.h
index 510bf36cd4..b0343272ef 100644
--- a/modules/gdnative/godot/gdnative.h
+++ b/modules/gdnative/godot/gdnative.h
@@ -265,6 +265,7 @@ typedef struct {
uint64_t core_api_hash;
uint64_t editor_api_hash;
uint64_t no_api_hash;
+ godot_object *gd_native_library; // pointer to GDNativeLibrary that is being initialized
} godot_gdnative_init_options;
typedef struct {
diff --git a/modules/nativescript/nativescript.cpp b/modules/nativescript/nativescript.cpp
index c4cbfcce51..e7445e6da9 100644
--- a/modules/nativescript/nativescript.cpp
+++ b/modules/nativescript/nativescript.cpp
@@ -288,9 +288,13 @@ ScriptLanguage *NativeScript::get_language() const {
bool NativeScript::has_script_signal(const StringName &p_signal) const {
NativeScriptDesc *script_data = get_script_desc();
- if (!script_data)
- return false;
- return script_data->signals_.has(p_signal);
+
+ while (script_data) {
+ if (script_data->signals_.has(p_signal))
+ return true;
+ script_data = script_data->base_data;
+ }
+ return false;
}
void NativeScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
index c645a55703..7b8b2abebb 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
@@ -39,7 +39,7 @@ void AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_fra
int todo = p_frames;
- while (todo) {
+ while (todo && active) {
int mixed = stb_vorbis_get_samples_float_interleaved(ogg_stream, 2, (float *)p_buffer, todo * 2);
todo -= mixed;
diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm
index 4b137b7ffa..f2778e8165 100644
--- a/platform/iphone/gl_view.mm
+++ b/platform/iphone/gl_view.mm
@@ -29,8 +29,8 @@
/*************************************************************************/
#import "gl_view.h"
-#include "core/project_settings.h"
#include "core/os/keyboard.h"
+#include "core/project_settings.h"
#include "os_iphone.h"
#include "servers/audio_server.h"
diff --git a/platform/iphone/ios.mm b/platform/iphone/ios.mm
index e9c164393b..6c95903241 100644
--- a/platform/iphone/ios.mm
+++ b/platform/iphone/ios.mm
@@ -36,7 +36,7 @@ void iOS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_rate_url", "app_id"), &iOS::get_rate_url);
};
-void iOS::alert(const char* p_alert, const char* p_title) {
+void iOS::alert(const char *p_alert, const char *p_title) {
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:[NSString stringWithUTF8String:p_title] message:[NSString stringWithUTF8String:p_alert] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] autorelease];
[alert show];
}
diff --git a/platform/osx/audio_driver_osx.cpp b/platform/osx/audio_driver_osx.cpp
index dabc7989c0..d7a91b1653 100644
--- a/platform/osx/audio_driver_osx.cpp
+++ b/platform/osx/audio_driver_osx.cpp
@@ -103,6 +103,7 @@ Error AudioDriverOSX::finishDevice() {
Error AudioDriverOSX::init() {
OSStatus result;
+ mutex = Mutex::create();
active = false;
channels = 2;
@@ -159,43 +160,30 @@ OSStatus AudioDriverOSX::output_callback(void *inRefCon,
UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData) {
- AudioBuffer *abuf;
AudioDriverOSX *ad = (AudioDriverOSX *)inRefCon;
- bool mix = true;
-
- if (!ad->active)
- mix = false;
- else if (ad->mutex) {
- mix = ad->mutex->try_lock() == OK;
- };
-
- if (!mix) {
+ if (!ad->active || !ad->try_lock()) {
for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) {
- abuf = &ioData->mBuffers[i];
+ AudioBuffer *abuf = &ioData->mBuffers[i];
zeromem(abuf->mData, abuf->mDataByteSize);
};
return 0;
};
- int frames_left;
-
for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) {
- abuf = &ioData->mBuffers[i];
- frames_left = inNumberFrames;
+ AudioBuffer *abuf = &ioData->mBuffers[i];
+ int frames_left = inNumberFrames;
int16_t *out = (int16_t *)abuf->mData;
while (frames_left) {
int frames = MIN(frames_left, ad->buffer_frames);
- //ad->lock();
ad->audio_server_process(frames, ad->samples_in);
- //ad->unlock();
- for (int i = 0; i < frames * ad->channels; i++) {
+ for (int j = 0; j < frames * ad->channels; j++) {
- out[i] = ad->samples_in[i] >> 16;
+ out[j] = ad->samples_in[j] >> 16;
}
frames_left -= frames;
@@ -203,8 +191,7 @@ OSStatus AudioDriverOSX::output_callback(void *inRefCon,
};
};
- if (ad->mutex)
- ad->mutex->unlock();
+ ad->unlock();
return 0;
};
@@ -232,11 +219,18 @@ void AudioDriverOSX::lock() {
if (mutex)
mutex->lock();
};
+
void AudioDriverOSX::unlock() {
if (mutex)
mutex->unlock();
};
+bool AudioDriverOSX::try_lock() {
+ if (mutex)
+ return mutex->try_lock() == OK;
+ return true;
+}
+
void AudioDriverOSX::finish() {
OSStatus result;
@@ -247,16 +241,22 @@ void AudioDriverOSX::finish() {
ERR_PRINT("AudioObjectRemovePropertyListener failed");
}
- memdelete_arr(samples_in);
+ if (mutex) {
+ memdelete(mutex);
+ mutex = NULL;
+ }
+
+ if (samples_in) {
+ memdelete_arr(samples_in);
+ samples_in = NULL;
+ }
};
AudioDriverOSX::AudioDriverOSX() {
-
- mutex = Mutex::create(); //NULL;
+ mutex = NULL;
+ samples_in = NULL;
};
-AudioDriverOSX::~AudioDriverOSX(){
-
-};
+AudioDriverOSX::~AudioDriverOSX(){};
#endif
diff --git a/platform/osx/audio_driver_osx.h b/platform/osx/audio_driver_osx.h
index d6d00b7970..287c9d6cbf 100644
--- a/platform/osx/audio_driver_osx.h
+++ b/platform/osx/audio_driver_osx.h
@@ -70,6 +70,7 @@ public:
virtual void unlock();
virtual void finish();
+ bool try_lock();
Error reopen();
AudioDriverOSX();
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index fc80088846..cb9dd1dd8e 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -101,9 +101,6 @@ public:
bool maximized;
bool zoomed;
- Vector<Rect2> screens;
- Vector<int> screen_dpi;
-
Size2 window_size;
Rect2 restore_rect;
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index fce38b6a8b..4a01532d89 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -162,6 +162,36 @@ static bool mouse_down_control = false;
}
#endif // MAC_OS_X_VERSION_MAX_ALLOWED
+- (void)windowDidChangeBackingProperties:(NSNotification *)notification {
+ if (!OS_OSX::singleton)
+ return;
+
+ NSWindow *window = (NSWindow *)[notification object];
+ CGFloat newBackingScaleFactor = [window backingScaleFactor];
+ CGFloat oldBackingScaleFactor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue];
+
+ if (newBackingScaleFactor != oldBackingScaleFactor) {
+ //Set new display scale and window size
+ OS_OSX::singleton->display_scale = newBackingScaleFactor;
+
+ const NSRect contentRect = [OS_OSX::singleton->window_view frame];
+ const NSRect fbRect = contentRect; //convertRectToBacking(contentRect);
+
+ OS_OSX::singleton->window_size.width = fbRect.size.width * OS_OSX::singleton->display_scale;
+ OS_OSX::singleton->window_size.height = fbRect.size.height * OS_OSX::singleton->display_scale;
+
+ //Update context
+ if (OS_OSX::singleton->main_loop) {
+ [OS_OSX::singleton->context update];
+
+ //Force window resize ???
+ NSRect frame = [OS_OSX::singleton->window_object frame];
+ [OS_OSX::singleton->window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, 1, 1) display:YES];
+ [OS_OSX::singleton->window_object setFrame:frame display:YES];
+ }
+ }
+}
+
- (void)windowDidResize:(NSNotification *)notification {
[OS_OSX::singleton->context update];
@@ -946,33 +976,6 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
_ensure_data_dir();
- NSArray *screenArray = [NSScreen screens];
- printf("nscreen count %i\n", (int)[screenArray count]);
- for (int i = 0; i < [screenArray count]; i++) {
-
- float displayScale = 1.0;
-
- if (display_scale > 1.0 && [[screenArray objectAtIndex:i] respondsToSelector:@selector(backingScaleFactor)]) {
- displayScale = [[screenArray objectAtIndex:i] backingScaleFactor];
- }
-
- // Note: Use frame to get the whole screen size
- NSRect nsrect = [[screenArray objectAtIndex:i] frame];
- Rect2 rect = Rect2(nsrect.origin.x, nsrect.origin.y, nsrect.size.width, nsrect.size.height);
- rect.position *= displayScale;
- rect.size *= displayScale;
- screens.push_back(rect);
-
- NSDictionary *description = [[screenArray objectAtIndex:i] deviceDescription];
- NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue];
- CGSize displayPhysicalSize = CGDisplayScreenSize(
- [[description objectForKey:@"NSScreenNumber"] unsignedIntValue]);
-
- //printf("width: %i pwidth %i rect width %i\n",int(displayPixelSize.width*displayScale),int(displayPhysicalSize.width*displayScale),int(nsrect.size.width));
- int dpi = (displayPixelSize.width * 25.4f / displayPhysicalSize.width) * displayScale;
-
- screen_dpi.push_back(dpi);
- };
restore_rect = Rect2(get_window_position(), get_window_size());
}
@@ -993,8 +996,6 @@ void OS_OSX::finalize() {
physics_2d_server->finish();
memdelete(physics_2d_server);
-
- screens.clear();
}
void OS_OSX::set_main_loop(MainLoop *p_main_loop) {
@@ -1244,8 +1245,8 @@ void OS_OSX::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) con
}
int OS_OSX::get_screen_count() const {
-
- return screens.size();
+ NSArray *screenArray = [NSScreen screens];
+ return [screenArray count];
};
int OS_OSX::get_current_screen() const {
@@ -1267,22 +1268,57 @@ void OS_OSX::set_current_screen(int p_screen) {
};
Point2 OS_OSX::get_screen_position(int p_screen) const {
+ NSArray *screenArray = [NSScreen screens];
+ if (p_screen < [screenArray count]) {
+ float displayScale = 1.0;
- ERR_FAIL_INDEX_V(p_screen, screens.size(), Point2());
- return screens[p_screen].position;
-};
+ if (display_scale > 1.0 && [[screenArray objectAtIndex:p_screen] respondsToSelector:@selector(backingScaleFactor)]) {
+ displayScale = [[screenArray objectAtIndex:p_screen] backingScaleFactor];
+ }
+
+ NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame];
+ return Point2(nsrect.origin.x, nsrect.origin.y) * displayScale;
+ }
+
+ return Point2();
+}
int OS_OSX::get_screen_dpi(int p_screen) const {
+ NSArray *screenArray = [NSScreen screens];
+ if (p_screen < [screenArray count]) {
+ float displayScale = 1.0;
+
+ if (display_scale > 1.0 && [[screenArray objectAtIndex:p_screen] respondsToSelector:@selector(backingScaleFactor)]) {
+ displayScale = [[screenArray objectAtIndex:p_screen] backingScaleFactor];
+ }
+
+ NSDictionary *description = [[screenArray objectAtIndex:p_screen] deviceDescription];
+ NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue];
+ CGSize displayPhysicalSize = CGDisplayScreenSize(
+ [[description objectForKey:@"NSScreenNumber"] unsignedIntValue]);
- ERR_FAIL_INDEX_V(p_screen, screens.size(), 72);
- return screen_dpi[p_screen];
+ return (displayPixelSize.width * 25.4f / displayPhysicalSize.width) * displayScale;
+ }
+
+ return 72;
}
Size2 OS_OSX::get_screen_size(int p_screen) const {
+ NSArray *screenArray = [NSScreen screens];
+ if (p_screen < [screenArray count]) {
+ float displayScale = 1.0;
- ERR_FAIL_INDEX_V(p_screen, screens.size(), Point2());
- return screens[p_screen].size;
-};
+ if (display_scale > 1.0 && [[screenArray objectAtIndex:p_screen] respondsToSelector:@selector(backingScaleFactor)]) {
+ displayScale = [[screenArray objectAtIndex:p_screen] backingScaleFactor];
+ }
+
+ // Note: Use frame to get the whole screen size
+ NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame];
+ return Size2(nsrect.size.width, nsrect.size.height) * displayScale;
+ }
+
+ return Size2();
+}
void OS_OSX::_update_window() {
bool borderless_full = false;
diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp
new file mode 100644
index 0000000000..5f2a720748
--- /dev/null
+++ b/scene/3d/arvr_nodes.cpp
@@ -0,0 +1,313 @@
+/*************************************************************************/
+/* arvr_nodes.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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 "arvr_nodes.h"
+#include "core/os/input.h"
+#include "servers/arvr/arvr_interface.h"
+#include "servers/arvr/arvr_positional_tracker.h"
+#include "servers/arvr_server.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void ARVRCamera::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ // need to find our ARVROrigin parent and let it know we're it's camera!
+ ARVROrigin *origin = get_parent()->cast_to<ARVROrigin>();
+ if (origin != NULL) {
+ origin->set_tracked_camera(this);
+ }
+ }; break;
+ case NOTIFICATION_EXIT_TREE: {
+ // need to find our ARVROrigin parent and let it know we're no longer it's camera!
+ ARVROrigin *origin = get_parent()->cast_to<ARVROrigin>();
+ if (origin != NULL) {
+ origin->clear_tracked_camera_if(this);
+ }
+ }; break;
+ };
+};
+
+String ARVRCamera::get_configuration_warning() const {
+ if (!is_visible() || !is_inside_tree())
+ return String();
+
+ // must be child node of ARVROrigin!
+ ARVROrigin *origin = get_parent()->cast_to<ARVROrigin>();
+ if (origin == NULL) {
+ return TTR("ARVRCamera must have an ARVROrigin node as its parent");
+ };
+
+ return String();
+};
+
+ARVRCamera::ARVRCamera(){
+ // nothing to do here yet for now..
+};
+
+ARVRCamera::~ARVRCamera(){
+ // nothing to do here yet for now..
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void ARVRController::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ set_process_internal(true);
+ }; break;
+ case NOTIFICATION_EXIT_TREE: {
+ set_process_internal(false);
+ }; break;
+ case NOTIFICATION_INTERNAL_PROCESS: {
+ // get our ARVRServer
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL(arvr_server);
+
+ // find the tracker for our controller
+ ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id);
+ if (tracker == NULL) {
+ // this controller is currently turned off
+ is_active = false;
+ button_states = 0;
+ } else {
+ set_transform(tracker->get_transform(true));
+
+ int joy_id = tracker->get_joy_id();
+ if (joy_id >= 0) {
+ int mask = 1;
+ // check button states
+ for (int i = 0; i < 16; i++) {
+ bool was_pressed = (button_states && mask) == mask;
+ bool is_pressed = Input::get_singleton()->is_joy_button_pressed(joy_id, i);
+
+ if (!was_pressed && is_pressed) {
+ emit_signal("button_pressed", i);
+ button_states += mask;
+ } else if (was_pressed && !is_pressed) {
+ emit_signal("button_release", i);
+ button_states -= mask;
+ };
+
+ mask = mask << 1;
+ };
+
+ } else {
+ button_states = 0;
+ };
+ };
+ }; break;
+ default:
+ break;
+ };
+};
+
+void ARVRController::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_controller_id", "controller_id"), &ARVRController::set_controller_id);
+ ClassDB::bind_method(D_METHOD("get_controller_id"), &ARVRController::get_controller_id);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_id"), "set_controller_id", "get_controller_id");
+ ClassDB::bind_method(D_METHOD("get_controller_name"), &ARVRController::get_controller_name);
+
+ // passthroughs to information about our related joystick
+ ClassDB::bind_method(D_METHOD("get_joystick_id"), &ARVRController::get_joystick_id);
+ ClassDB::bind_method(D_METHOD("is_button_pressed", "button"), &ARVRController::is_button_pressed);
+ ClassDB::bind_method(D_METHOD("get_joystick_axis", "axis"), &ARVRController::get_joystick_axis);
+
+ ClassDB::bind_method(D_METHOD("get_is_active"), &ARVRController::get_is_active);
+
+ ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::INT, "button")));
+ ADD_SIGNAL(MethodInfo("button_release", PropertyInfo(Variant::INT, "button")));
+};
+
+void ARVRController::set_controller_id(int p_controller_id) {
+ // we don't check any bounds here, this controller may not yet be active and just be a place holder until it is.
+ controller_id = p_controller_id;
+};
+
+int ARVRController::get_controller_id(void) const {
+ return controller_id;
+};
+
+String ARVRController::get_controller_name(void) const {
+ // get our ARVRServer
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL_V(arvr_server, String());
+
+ ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id);
+ if (tracker == NULL) {
+ return String("Not connected");
+ };
+
+ return tracker->get_name();
+};
+
+int ARVRController::get_joystick_id() const {
+ // get our ARVRServer
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL_V(arvr_server, 0);
+
+ ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id);
+ if (tracker == NULL) {
+ return 0;
+ };
+
+ return tracker->get_joy_id();
+};
+
+int ARVRController::is_button_pressed(int p_button) const {
+ int joy_id = get_joystick_id();
+ if (joy_id == 0) {
+ return false;
+ };
+
+ return Input::get_singleton()->is_joy_button_pressed(joy_id, p_button);
+};
+
+float ARVRController::get_joystick_axis(int p_axis) const {
+ int joy_id = get_joystick_id();
+ if (joy_id == 0) {
+ return 0.0;
+ };
+
+ return Input::get_singleton()->get_joy_axis(joy_id, p_axis);
+};
+
+bool ARVRController::get_is_active() const {
+ return is_active;
+};
+
+String ARVRController::get_configuration_warning() const {
+ if (!is_visible() || !is_inside_tree())
+ return String();
+
+ // must be child node of ARVROrigin!
+ ARVROrigin *origin = get_parent()->cast_to<ARVROrigin>();
+ if (origin == NULL) {
+ return TTR("ARVRController must have an ARVROrigin node as its parent");
+ };
+
+ if (controller_id == 0) {
+ return TTR("The controller id must not be 0 or this controller will not be bound to an actual controller");
+ };
+
+ return String();
+};
+
+ARVRController::ARVRController() {
+ controller_id = 0;
+ is_active = true;
+};
+
+ARVRController::~ARVRController(){
+ // nothing to do here yet for now..
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+String ARVROrigin::get_configuration_warning() const {
+ if (!is_visible() || !is_inside_tree())
+ return String();
+
+ if (tracked_camera == NULL)
+ return TTR("ARVROrigin requires an ARVRCamera child node");
+
+ return String();
+};
+
+void ARVROrigin::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_world_scale", "world_scale"), &ARVROrigin::set_world_scale);
+ ClassDB::bind_method(D_METHOD("get_world_scale"), &ARVROrigin::get_world_scale);
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "world_scale"), "set_world_scale", "get_world_scale");
+};
+
+void ARVROrigin::set_tracked_camera(ARVRCamera *p_tracked_camera) {
+ tracked_camera = p_tracked_camera;
+};
+
+void ARVROrigin::clear_tracked_camera_if(ARVRCamera *p_tracked_camera) {
+ if (tracked_camera == p_tracked_camera) {
+ tracked_camera = NULL;
+ };
+};
+
+float ARVROrigin::get_world_scale() const {
+ // get our ARVRServer
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL_V(arvr_server, 1.0);
+
+ return arvr_server->get_world_scale();
+};
+
+void ARVROrigin::set_world_scale(float p_world_scale) {
+ // get our ARVRServer
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL(arvr_server);
+
+ arvr_server->set_world_scale(p_world_scale);
+};
+
+void ARVROrigin::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ set_process_internal(true);
+ }; break;
+ case NOTIFICATION_EXIT_TREE: {
+ set_process_internal(false);
+ }; break;
+ case NOTIFICATION_INTERNAL_PROCESS: {
+ // get our ARVRServer
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL(arvr_server);
+
+ // set our world origin to our node transform
+ arvr_server->set_world_origin(get_global_transform());
+
+ // check if we have a primary interface
+ Ref<ARVRInterface> arvr_interface = arvr_server->get_primary_interface();
+ if (arvr_interface.is_valid() && tracked_camera != NULL) {
+ // get our positioning transform for our headset
+ Transform t = arvr_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, Transform());
+
+ // now apply this to our camera
+ tracked_camera->set_transform(t);
+ };
+ }; break;
+ default:
+ break;
+ };
+};
+
+ARVROrigin::ARVROrigin() {
+ tracked_camera = NULL;
+};
+
+ARVROrigin::~ARVROrigin(){
+ // nothing to do here yet for now..
+};
diff --git a/scene/3d/arvr_nodes.h b/scene/3d/arvr_nodes.h
new file mode 100644
index 0000000000..3dab263317
--- /dev/null
+++ b/scene/3d/arvr_nodes.h
@@ -0,0 +1,126 @@
+/*************************************************************************/
+/* arvr_nodes.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#ifndef ARVR_NODES_H
+#define ARVR_NODES_H
+
+#include "scene/3d/camera.h"
+#include "scene/3d/spatial.h"
+
+/**
+ @author Bastiaan Olij <mux213@gmail.com>
+**/
+
+/*
+ ARVRCamera is a subclass of camera which will register itself with its parent ARVROrigin and as a result is automatically positioned
+*/
+class ARVRCamera : public Camera {
+
+ GDCLASS(ARVRCamera, Camera);
+
+protected:
+ void _notification(int p_what);
+
+public:
+ String get_configuration_warning() const;
+
+ ARVRCamera();
+ ~ARVRCamera();
+};
+
+/*
+ ARVRController is a helper node that automatically updates it's position based on tracker data.
+
+ It must be a child node of our ARVROrigin node
+*/
+
+class ARVRController : public Spatial {
+
+ GDCLASS(ARVRController, Spatial);
+
+private:
+ int controller_id;
+ bool is_active;
+ int button_states;
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ void set_controller_id(int p_controller_id);
+ int get_controller_id(void) const;
+ String get_controller_name(void) const;
+
+ int get_joystick_id() const;
+ int is_button_pressed(int p_button) const;
+ float get_joystick_axis(int p_axis) const;
+
+ bool get_is_active() const;
+
+ String get_configuration_warning() const;
+
+ ARVRController();
+ ~ARVRController();
+};
+
+/*
+ ARVROrigin is special spatial node that acts as our origin point mapping our real world center of our tracking volume into our virtual world.
+
+ It is this point that you will move around the world as the player 'moves while standing still', i.e. the player moves through teleporting or controller inputs as opposed to physically moving.
+
+ Our camera and controllers will always be child nodes and thus place relative to this origin point.
+ This node will automatically locate any camera child nodes and update its position while our ARVRController node will handle tracked controllers.
+*/
+class ARVROrigin : public Spatial {
+
+ GDCLASS(ARVROrigin, Spatial);
+
+private:
+ ARVRCamera *tracked_camera;
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ String get_configuration_warning() const;
+
+ void set_tracked_camera(ARVRCamera *p_tracked_camera);
+ void clear_tracked_camera_if(ARVRCamera *p_tracked_camera);
+
+ float get_world_scale() const;
+ void set_world_scale(float p_world_scale);
+
+ ARVROrigin();
+ ~ARVROrigin();
+};
+
+#endif /* ARVR_NODES_H */
diff --git a/scene/io/resource_format_image.cpp b/scene/io/resource_format_image.cpp
index 8b3f939f1a..04b6177c3c 100644
--- a/scene/io/resource_format_image.cpp
+++ b/scene/io/resource_format_image.cpp
@@ -30,9 +30,9 @@
#include "resource_format_image.h"
#if 0
-#include "project_settings.h"
#include "io/image_loader.h"
#include "os/os.h"
+#include "project_settings.h"
#include "scene/resources/texture.h"
RES ResourceFormatLoaderImage::load(const String &p_path, const String& p_original_path, Error *r_error) {
diff --git a/scene/main/node.h b/scene/main/node.h
index cfd5c07921..1794cce9f6 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -31,10 +31,10 @@
#define NODE_H
#include "class_db.h"
-#include "project_settings.h"
#include "map.h"
#include "object.h"
#include "path_db.h"
+#include "project_settings.h"
#include "scene/main/scene_tree.h"
#include "script_language.h"
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 5ce347d79b..76b281ebac 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -701,6 +701,16 @@ RID Viewport::get_viewport_rid() const {
return viewport;
}
+void Viewport::set_use_arvr(bool p_use_arvr) {
+ arvr = p_use_arvr;
+
+ VS::get_singleton()->viewport_set_use_arvr(viewport, arvr);
+}
+
+bool Viewport::use_arvr() {
+ return arvr;
+}
+
void Viewport::set_size(const Size2 &p_size) {
if (size == p_size.floor())
@@ -2543,6 +2553,9 @@ int Viewport::get_render_info(RenderInfo p_info) {
void Viewport::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_use_arvr", "use"), &Viewport::set_use_arvr);
+ ClassDB::bind_method(D_METHOD("use_arvr"), &Viewport::use_arvr);
+
ClassDB::bind_method(D_METHOD("set_size", "size"), &Viewport::set_size);
ClassDB::bind_method(D_METHOD("get_size"), &Viewport::get_size);
ClassDB::bind_method(D_METHOD("set_world_2d", "world_2d:World2D"), &Viewport::set_world_2d);
@@ -2644,6 +2657,8 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shadow_atlas_quadrant_subdiv", "quadrant", "subdiv"), &Viewport::set_shadow_atlas_quadrant_subdiv);
ClassDB::bind_method(D_METHOD("get_shadow_atlas_quadrant_subdiv", "quadrant"), &Viewport::get_shadow_atlas_quadrant_subdiv);
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "arvr"), "set_use_arvr", "use_arvr");
+
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "size"), "set_size", "get_size");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world"), "set_use_own_world", "is_using_own_world");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world", PROPERTY_HINT_RESOURCE_TYPE, "World"), "set_world", "get_world");
@@ -2729,6 +2744,7 @@ Viewport::Viewport() {
parent = NULL;
listener = NULL;
camera = NULL;
+ arvr = false;
size_override = false;
size_override_stretch = false;
size_override_size = Size2(1, 1);
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index bd9747d878..83c989db54 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -148,6 +148,8 @@ private:
Listener *listener;
Set<Listener *> listeners;
+ bool arvr;
+
Camera *camera;
Set<Camera *> cameras;
@@ -349,6 +351,9 @@ public:
Listener *get_listener() const;
Camera *get_camera() const;
+ void set_use_arvr(bool p_use_arvr);
+ bool use_arvr();
+
void set_as_audio_listener(bool p_enable);
bool is_audio_listener() const;
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 74c556931c..f286bfb81a 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "register_scene_types.h"
-#include "project_settings.h"
#include "os/os.h"
+#include "project_settings.h"
#include "scene/io/resource_format_image.h"
#include "scene/io/resource_format_wav.h"
@@ -199,6 +199,8 @@
#include "scene/3d/camera.h"
#include "scene/3d/listener.h"
+#include "scene/3d/arvr_nodes.h"
+
#include "scene/3d/gi_probe.h"
#include "scene/3d/interpolated_camera.h"
#include "scene/3d/light.h"
@@ -405,6 +407,9 @@ void register_scene_types() {
ClassDB::register_virtual_class<VisualInstance>();
ClassDB::register_class<Camera>();
ClassDB::register_class<Listener>();
+ ClassDB::register_class<ARVRCamera>();
+ ClassDB::register_class<ARVRController>();
+ ClassDB::register_class<ARVROrigin>();
ClassDB::register_class<InterpolatedCamera>();
ClassDB::register_class<MeshInstance>();
ClassDB::register_class<ImmediateGeometry>();
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 01a8342fed..6bf3590c12 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -29,8 +29,8 @@
/*************************************************************************/
#include "packed_scene.h"
#include "core/core_string_names.h"
-#include "project_settings.h"
#include "io/resource_loader.h"
+#include "project_settings.h"
#include "scene/2d/node_2d.h"
#include "scene/3d/spatial.h"
#include "scene/gui/control.h"
diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp
index 585579aad5..03a862b744 100644
--- a/scene/resources/scene_format_text.cpp
+++ b/scene/resources/scene_format_text.cpp
@@ -29,8 +29,8 @@
/*************************************************************************/
#include "scene_format_text.h"
-#include "project_settings.h"
#include "os/dir_access.h"
+#include "project_settings.h"
#include "version.h"
//version 2: changed names for basis, rect3, poolvectors, etc.
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 9bbbd1d091..6c20c71af0 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -414,7 +414,7 @@ public:
void set_width(int p_width);
int get_width() const;
- void ensure_default_setup(float p_min=0, float p_max=1);
+ void ensure_default_setup(float p_min = 0, float p_max = 1);
void set_curve(Ref<Curve> p_curve);
Ref<Curve> get_curve() const;
diff --git a/servers/SCsub b/servers/SCsub
index eefa6278c4..df55010a36 100644
--- a/servers/SCsub
+++ b/servers/SCsub
@@ -7,12 +7,11 @@ env.add_source_files(env.servers_sources, "*.cpp")
Export('env')
+SConscript('arvr/SCsub')
SConscript('physics/SCsub')
SConscript('physics_2d/SCsub')
SConscript('visual/SCsub')
SConscript('audio/SCsub')
-SConscript('spatial_sound/SCsub')
-SConscript('spatial_sound_2d/SCsub')
lib = env.Library("servers", env.servers_sources)
diff --git a/servers/arvr/SCsub b/servers/arvr/SCsub
new file mode 100644
index 0000000000..ccc76e823f
--- /dev/null
+++ b/servers/arvr/SCsub
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+
+Import('env')
+
+env.add_source_files(env.servers_sources, "*.cpp")
+
+Export('env')
diff --git a/servers/arvr/arvr_interface.cpp b/servers/arvr/arvr_interface.cpp
new file mode 100644
index 0000000000..81eb011932
--- /dev/null
+++ b/servers/arvr/arvr_interface.cpp
@@ -0,0 +1,82 @@
+/*************************************************************************/
+/* arvr_interface.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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 "arvr_interface.h"
+
+void ARVRInterface::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_name"), &ARVRInterface::get_name);
+
+ ClassDB::bind_method(D_METHOD("is_primary"), &ARVRInterface::is_primary);
+ ClassDB::bind_method(D_METHOD("set_is_primary", "enable"), &ARVRInterface::set_is_primary);
+
+ ClassDB::bind_method(D_METHOD("is_installed"), &ARVRInterface::is_installed);
+ ClassDB::bind_method(D_METHOD("hmd_is_present"), &ARVRInterface::hmd_is_present);
+ ClassDB::bind_method(D_METHOD("supports_hmd"), &ARVRInterface::supports_hmd);
+ ClassDB::bind_method(D_METHOD("is_initialized"), &ARVRInterface::is_initialized);
+ ClassDB::bind_method(D_METHOD("initialize"), &ARVRInterface::initialize);
+ ClassDB::bind_method(D_METHOD("uninitialize"), &ARVRInterface::uninitialize);
+
+ ClassDB::bind_method(D_METHOD("get_recommended_render_targetsize"), &ARVRInterface::get_recommended_render_targetsize);
+
+ // These are now purely used internally, we may expose them again if we expose CameraMatrix through Variant but reduz is not a fan for good reasons :)
+ // ClassDB::bind_method(D_METHOD("get_transform_for_eye", "eye", "cam_transform"), &ARVRInterface::get_transform_for_eye);
+ // ClassDB::bind_method(D_METHOD("get_projection_for_eye", "eye"), &ARVRInterface::get_projection_for_eye);
+ // ClassDB::bind_method(D_METHOD("commit_for_eye", "node:viewport"), &ARVRInterface::commit_for_eye);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "primary"), "set_is_primary", "is_primary");
+
+ BIND_CONSTANT(EYE_MONO);
+ BIND_CONSTANT(EYE_LEFT);
+ BIND_CONSTANT(EYE_RIGHT);
+};
+
+StringName ARVRInterface::get_name() const {
+ return "Unknown";
+};
+
+bool ARVRInterface::is_primary() {
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL_V(arvr_server, false);
+
+ return arvr_server->get_primary_interface() == this;
+};
+
+void ARVRInterface::set_is_primary(bool p_is_primary) {
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL(arvr_server);
+
+ if (p_is_primary) {
+ ERR_FAIL_COND(!is_initialized());
+ ERR_FAIL_COND(!supports_hmd());
+
+ arvr_server->set_primary_interface(this);
+ } else {
+ arvr_server->clear_primary_interface_if(this);
+ };
+};
diff --git a/servers/arvr/arvr_interface.h b/servers/arvr/arvr_interface.h
new file mode 100644
index 0000000000..e405499fbb
--- /dev/null
+++ b/servers/arvr/arvr_interface.h
@@ -0,0 +1,89 @@
+/*************************************************************************/
+/* arvr_interface.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+#ifndef ARVR_INTERFACE_H
+#define ARVR_INTERFACE_H
+
+#include "core/math/camera_matrix.h"
+#include "os/thread_safe.h"
+#include "scene/main/viewport.h"
+#include "servers/arvr_server.h"
+
+/**
+ @author Bastiaan Olij <mux213@gmail.com>
+
+ The ARVR interface is a template class ontop of which we build interface to differt 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 the choose the interface they want to use and initialize it.
+
+ Note that we may make this into a fully instantiable class for GDNative support.
+*/
+
+class ARVRInterface : public Reference {
+ GDCLASS(ARVRInterface, Reference);
+
+protected:
+ _THREAD_SAFE_CLASS_
+
+ static void _bind_methods();
+
+public:
+ enum Eyes {
+ EYE_MONO, /* my son says we should call this EYE_CYCLOPS */
+ EYE_LEFT,
+ EYE_RIGHT
+ };
+
+ virtual StringName get_name() const;
+
+ bool is_primary();
+ void set_is_primary(bool p_is_primary);
+
+ virtual bool is_installed() = 0; /* returns true if the middle ware related to this interface has been installed */
+ virtual bool hmd_is_present() = 0; /* returns true if our HMD is connected */
+ virtual bool supports_hmd() = 0; /* returns true is this interface handles output to an HMD or only handles positioning */
+
+ virtual bool is_initialized() = 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 Size2 get_recommended_render_targetsize() = 0; /* returns the recommended render target size per eye for this device */
+ virtual bool is_stereo() = 0; /* returns true if this interface requires stereo rendering (for VR HMDs) or mono rendering (for mobile AR) */
+ virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) = 0; /* get each eyes camera transform, also implement EYE_MONO */
+ virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) = 0; /* get each eyes projection matrix */
+ virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) = 0; /* output the left or right eye */
+
+ virtual void process() = 0;
+};
+
+VARIANT_ENUM_CAST(ARVRInterface::Eyes);
+
+#endif
diff --git a/servers/arvr/arvr_positional_tracker.cpp b/servers/arvr/arvr_positional_tracker.cpp
new file mode 100644
index 0000000000..4215363d16
--- /dev/null
+++ b/servers/arvr/arvr_positional_tracker.cpp
@@ -0,0 +1,142 @@
+/*************************************************************************/
+/* arvr_postional_tracker.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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 "arvr_positional_tracker.h"
+#include "core/os/input.h"
+
+void ARVRPositionalTracker::_bind_methods() {
+ // this class is read only from GDScript, so we only have access to getters..
+ ClassDB::bind_method(D_METHOD("get_type"), &ARVRPositionalTracker::get_type);
+ ClassDB::bind_method(D_METHOD("get_name"), &ARVRPositionalTracker::get_name);
+ ClassDB::bind_method(D_METHOD("get_joy_id"), &ARVRPositionalTracker::get_joy_id);
+ ClassDB::bind_method(D_METHOD("get_tracks_orientation"), &ARVRPositionalTracker::get_tracks_orientation);
+ ClassDB::bind_method(D_METHOD("get_orientation"), &ARVRPositionalTracker::get_orientation);
+ ClassDB::bind_method(D_METHOD("get_tracks_position"), &ARVRPositionalTracker::get_tracks_position);
+ ClassDB::bind_method(D_METHOD("get_position"), &ARVRPositionalTracker::get_position);
+ ClassDB::bind_method(D_METHOD("get_transform", "adjust_by_reference_frame"), &ARVRPositionalTracker::get_transform);
+};
+
+void ARVRPositionalTracker::set_type(ARVRServer::TrackerType p_type) {
+ if (type != p_type) {
+ type = p_type;
+
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL(arvr_server);
+
+ // get a tracker id for our type
+ tracker_id = arvr_server->get_free_tracker_id_for_type(p_type);
+ }
+};
+
+ARVRServer::TrackerType ARVRPositionalTracker::get_type() const {
+ return type;
+};
+
+void ARVRPositionalTracker::set_name(const String p_name) {
+ name = p_name;
+};
+
+StringName ARVRPositionalTracker::get_name() const {
+ return name;
+};
+
+int ARVRPositionalTracker::get_tracker_id() const {
+ return tracker_id;
+};
+
+void ARVRPositionalTracker::set_joy_id(int p_joy_id) {
+ joy_id = p_joy_id;
+};
+
+int ARVRPositionalTracker::get_joy_id() const {
+ return joy_id;
+};
+
+bool ARVRPositionalTracker::get_tracks_orientation() const {
+ return tracks_orientation;
+};
+
+void ARVRPositionalTracker::set_orientation(const Basis &p_orientation) {
+ _THREAD_SAFE_METHOD_
+
+ tracks_orientation = true; // obviously we have this
+ orientation = p_orientation;
+};
+
+Basis ARVRPositionalTracker::get_orientation() const {
+ _THREAD_SAFE_METHOD_
+
+ return orientation;
+};
+
+bool ARVRPositionalTracker::get_tracks_position() const {
+ return tracks_position;
+};
+
+void ARVRPositionalTracker::set_position(const Vector3 &p_position) {
+ _THREAD_SAFE_METHOD_
+
+ tracks_position = true; // obviously we have this
+ position = p_position;
+};
+
+Vector3 ARVRPositionalTracker::get_position() const {
+ _THREAD_SAFE_METHOD_
+
+ return position;
+};
+
+Transform ARVRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const {
+ Transform new_transform;
+
+ new_transform.basis = get_orientation();
+ new_transform.origin = get_position();
+
+ if (p_adjust_by_reference_frame) {
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL_V(arvr_server, new_transform);
+
+ new_transform = arvr_server->get_reference_frame() * new_transform;
+ };
+
+ return new_transform;
+};
+
+ARVRPositionalTracker::ARVRPositionalTracker() {
+ type = ARVRServer::TRACKER_UNKNOWN;
+ name = "Unknown";
+ joy_id = -1;
+ tracker_id = 0;
+ tracks_orientation = false;
+ tracks_position = false;
+};
+
+ARVRPositionalTracker::~ARVRPositionalTracker(){
+
+};
diff --git a/servers/arvr/arvr_positional_tracker.h b/servers/arvr/arvr_positional_tracker.h
new file mode 100644
index 0000000000..e8c613b29d
--- /dev/null
+++ b/servers/arvr/arvr_positional_tracker.h
@@ -0,0 +1,85 @@
+/*************************************************************************/
+/* arvr_positional_tracker.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+#ifndef ARVR_POSITIONAL_TRACKER_H
+#define ARVR_POSITIONAL_TRACKER_H
+
+#include "os/thread_safe.h"
+#include "servers/arvr_server.h"
+
+/**
+ @author Bastiaan Olij <mux213@gmail.com>
+
+ 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.
+
+ @TODO:
+ - create subclass of spatial node that uses one of our positional trackers to automatically determine its position
+*/
+
+class ARVRPositionalTracker : public Object {
+ GDCLASS(ARVRPositionalTracker, Object);
+ _THREAD_SAFE_CLASS_
+
+private:
+ ARVRServer::TrackerType type; // type of tracker
+ StringName name; // (unique) name of the tracker
+ int tracker_id; // tracker index id that is unique per type
+ int joy_id; // if we also have a related joystick entity, the id of the joystick
+ bool tracks_orientation; // do we track orientation?
+ Basis orientation; // our orientation
+ bool tracks_position; // do we track position?
+ Vector3 position; // our position
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_type(ARVRServer::TrackerType p_type);
+ ARVRServer::TrackerType get_type() const;
+ void set_name(const String p_name);
+ StringName get_name() const;
+ int get_tracker_id() const;
+ void set_joy_id(int p_joy_id);
+ int get_joy_id() const;
+ bool get_tracks_orientation() const;
+ void set_orientation(const Basis &p_orientation);
+ Basis get_orientation() const;
+ bool get_tracks_position() const;
+ void set_position(const Vector3 &p_position);
+ Vector3 get_position() const;
+
+ Transform get_transform(bool p_adjust_by_reference_frame) const;
+
+ ARVRPositionalTracker();
+ ~ARVRPositionalTracker();
+};
+
+#endif
diff --git a/servers/arvr/arvr_script_interface.cpp b/servers/arvr/arvr_script_interface.cpp
new file mode 100644
index 0000000000..16e607920e
--- /dev/null
+++ b/servers/arvr/arvr_script_interface.cpp
@@ -0,0 +1,127 @@
+#include "arvr_script_interface.h"
+
+ARVRScriptInterface::ARVRScriptInterface() {
+ // testing
+ printf("Construct script interface");
+}
+
+ARVRScriptInterface::~ARVRScriptInterface() {
+ if (is_initialized()) {
+ uninitialize();
+ };
+
+ // testing
+ printf("Destruct script interface");
+}
+
+StringName ARVRScriptInterface::get_name() const {
+ if (get_script_instance() && get_script_instance()->has_method("get_name")) {
+ return get_script_instance()->call("get_name");
+ } else {
+ // just return something for now
+ return "ARVR Script interface";
+ }
+}
+
+bool ARVRScriptInterface::is_installed() {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("is_installed")), false);
+ return get_script_instance()->call("is_installed");
+}
+
+bool ARVRScriptInterface::hmd_is_present() {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("hmd_is_present")), false);
+ return get_script_instance()->call("hmd_is_present");
+}
+
+bool ARVRScriptInterface::supports_hmd() {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("supports_hmd")), false);
+ return get_script_instance()->call("supports_hmd");
+}
+
+bool ARVRScriptInterface::is_stereo() {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("is_stereo")), false);
+ return get_script_instance()->call("is_stereo");
+}
+
+bool ARVRScriptInterface::is_initialized() {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("is_initialized")), false);
+ return get_script_instance()->call("is_initialized");
+}
+
+bool ARVRScriptInterface::initialize() {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("initialize")), false);
+ return get_script_instance()->call("initialize");
+}
+
+void ARVRScriptInterface::uninitialize() {
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ if (arvr_server != NULL) {
+ // Whatever happens, make sure this is no longer our primary interface
+ arvr_server->clear_primary_interface_if(this);
+ }
+
+ ERR_FAIL_COND(!(get_script_instance() && get_script_instance()->has_method("uninitialize")));
+ get_script_instance()->call("uninitialize");
+}
+
+Size2 ARVRScriptInterface::get_recommended_render_targetsize() {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("get_recommended_render_targetsize")), Size2());
+ return get_script_instance()->call("get_recommended_render_targetsize");
+}
+
+Transform ARVRScriptInterface::get_transform_for_eye(Eyes p_eye, const Transform &p_cam_transform) {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("get_transform_for_eye")), Transform());
+ return get_script_instance()->call("get_transform_for_eye", p_eye, p_cam_transform);
+}
+
+// Suggestion from Reduz, as we can't return a CameraMatrix, return a PoolVector with our 16 floats
+PoolVector<float> ARVRScriptInterface::_get_projection_for_eye(Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("_get_projection_for_eye")), PoolVector<float>());
+ return get_script_instance()->call("_get_projection_for_eye", p_eye, p_aspect, p_z_near, p_z_far);
+}
+
+CameraMatrix ARVRScriptInterface::get_projection_for_eye(Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
+ CameraMatrix cm;
+ int i = 0;
+ int j = 0;
+
+ PoolVector<float> cm_as_floats = _get_projection_for_eye(p_eye, p_aspect, p_z_near, p_z_far);
+
+ for (int k = 0; k < cm_as_floats.size() && i < 4; k++) {
+ cm.matrix[i][j] = cm_as_floats[k];
+ j++;
+ if (j == 4) {
+ j = 0;
+ i++;
+ };
+ };
+
+ return cm;
+}
+
+void ARVRScriptInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
+ ERR_FAIL_COND(!(get_script_instance() && get_script_instance()->has_method("commit_for_eye")));
+ get_script_instance()->call("commit_for_eye");
+}
+
+void ARVRScriptInterface::process() {
+ ERR_FAIL_COND(!(get_script_instance() && get_script_instance()->has_method("process")));
+ get_script_instance()->call("process");
+}
+
+void ARVRScriptInterface::_bind_methods() {
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "is_installed"));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "hmd_is_present"));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "supports_hmd"));
+
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "is_initialized"));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "initialize"));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo("uninitialize"));
+
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "is_stereo"));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::VECTOR2, "get_recommended_render_targetsize"));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::TRANSFORM, "get_transform_for_eye", PropertyInfo(Variant::INT, "eye"), PropertyInfo(Variant::TRANSFORM, "cam_transform")));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo("_get_projection_for_eye"));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo("commit_for_eye", PropertyInfo(Variant::INT, "eye"), PropertyInfo(Variant::_RID, "render_target")));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo("process"));
+}
diff --git a/servers/arvr/arvr_script_interface.h b/servers/arvr/arvr_script_interface.h
new file mode 100644
index 0000000000..04ca33901a
--- /dev/null
+++ b/servers/arvr/arvr_script_interface.h
@@ -0,0 +1,47 @@
+#ifndef SCRIPT_INTERFACE_H
+#define SCRIPT_INTERFACE_H
+
+#include "arvr_interface.h"
+
+/**
+ @authors Hinsbart & Karroffel
+
+ This subclass of our AR/VR interface forms a bridge to GDNative.
+*/
+
+class ARVRScriptInterface : public ARVRInterface {
+ GDCLASS(ARVRScriptInterface, ARVRInterface);
+
+protected:
+ static void _bind_methods();
+
+public:
+ ARVRScriptInterface();
+ ~ARVRScriptInterface();
+
+ virtual StringName get_name() const;
+
+ virtual bool is_installed();
+ virtual bool hmd_is_present();
+ virtual bool supports_hmd();
+
+ virtual bool is_initialized();
+ virtual bool initialize();
+ virtual void uninitialize();
+
+ virtual Size2 get_recommended_render_targetsize();
+ virtual bool is_stereo();
+ virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform);
+
+ // we expose a PoolVector<float> version of this function to GDNative
+ PoolVector<float> _get_projection_for_eye(Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
+
+ // and a CameraMatrix version to ARVRServer
+ virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
+
+ virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
+
+ virtual void process();
+};
+
+#endif // SCRIPT_INTERFACE_H
diff --git a/servers/arvr_server.cpp b/servers/arvr_server.cpp
new file mode 100644
index 0000000000..78b3e514e6
--- /dev/null
+++ b/servers/arvr_server.cpp
@@ -0,0 +1,313 @@
+/*************************************************************************/
+/* arvr_server.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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 "arvr_server.h"
+#include "arvr/arvr_interface.h"
+#include "arvr/arvr_positional_tracker.h"
+#include "project_settings.h"
+
+ARVRServer *ARVRServer::singleton = NULL;
+
+ARVRServer *ARVRServer::get_singleton() {
+ return singleton;
+};
+
+void ARVRServer::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_world_scale"), &ARVRServer::get_world_scale);
+ ClassDB::bind_method(D_METHOD("set_world_scale"), &ARVRServer::set_world_scale);
+ ClassDB::bind_method(D_METHOD("get_reference_frame"), &ARVRServer::get_reference_frame);
+ ClassDB::bind_method(D_METHOD("request_reference_frame", "ignore_tilt", "keep_height"), &ARVRServer::request_reference_frame);
+
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "world_scale"), "set_world_scale", "get_world_scale");
+
+ ClassDB::bind_method(D_METHOD("get_interface_count"), &ARVRServer::get_interface_count);
+ ClassDB::bind_method(D_METHOD("get_interface:ARVRInterface", "idx"), &ARVRServer::get_interface);
+ ClassDB::bind_method(D_METHOD("find_interface:ARVRInterface", "name"), &ARVRServer::find_interface);
+ ClassDB::bind_method(D_METHOD("get_tracker_count"), &ARVRServer::get_tracker_count);
+ ClassDB::bind_method(D_METHOD("get_tracker:ARVRPositionalTracker", "idx"), &ARVRServer::get_tracker);
+
+ ClassDB::bind_method(D_METHOD("set_primary_interface"), &ARVRServer::set_primary_interface);
+
+ ClassDB::bind_method(D_METHOD("add_interface"), &ARVRServer::add_interface);
+ ClassDB::bind_method(D_METHOD("remove_interface"), &ARVRServer::remove_interface);
+
+ BIND_CONSTANT(TRACKER_CONTROLLER);
+ BIND_CONSTANT(TRACKER_BASESTATION);
+ BIND_CONSTANT(TRACKER_ANCHOR);
+ BIND_CONSTANT(TRACKER_UNKNOWN);
+ BIND_CONSTANT(TRACKER_ANY_KNOWN);
+ BIND_CONSTANT(TRACKER_ANY);
+
+ ADD_SIGNAL(MethodInfo("interface_added", PropertyInfo(Variant::STRING, "name")));
+ ADD_SIGNAL(MethodInfo("interface_removed", PropertyInfo(Variant::STRING, "name")));
+
+ ADD_SIGNAL(MethodInfo("tracker_added", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::INT, "type")));
+ ADD_SIGNAL(MethodInfo("tracker_removed", PropertyInfo(Variant::STRING, "name")));
+};
+
+real_t ARVRServer::get_world_scale() const {
+ return world_scale;
+};
+
+void ARVRServer::set_world_scale(real_t p_world_scale) {
+ if (world_scale < 0.01) {
+ world_scale = 0.01;
+ } else if (world_scale > 1000.0) {
+ world_scale = 1000.0;
+ };
+
+ world_scale = p_world_scale;
+};
+
+Transform ARVRServer::get_world_origin() const {
+ return world_origin;
+};
+
+void ARVRServer::set_world_origin(const Transform p_world_origin) {
+ world_origin = p_world_origin;
+};
+
+Transform ARVRServer::get_reference_frame() const {
+ return reference_frame;
+};
+
+void ARVRServer::request_reference_frame(bool p_ignore_tilt, bool p_keep_height) {
+ if (primary_interface != NULL) {
+ // clear our current reference frame or we'll end up double adjusting it
+ reference_frame = Transform();
+
+ // requesting our EYE_MONO transform should return our current HMD position
+ Transform new_reference_frame = primary_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, Transform());
+
+ // remove our tilt
+ if (p_ignore_tilt) {
+ // take the Y out of our Z
+ new_reference_frame.basis.set_axis(2, Vector3(new_reference_frame.basis.elements[0][2], 0.0, new_reference_frame.basis.elements[2][2]).normalized());
+
+ // Y is straight up
+ new_reference_frame.basis.set_axis(1, Vector3(0.0, 1.0, 0.0));
+
+ // and X is our cross reference
+ new_reference_frame.basis.set_axis(0, new_reference_frame.basis.get_axis(1).cross(new_reference_frame.basis.get_axis(2)).normalized());
+ };
+
+ // don't negate our height
+ if (p_keep_height) {
+ new_reference_frame.origin.y = 0.0;
+ };
+
+ reference_frame = new_reference_frame.inverse();
+ };
+};
+
+void ARVRServer::add_interface(const Ref<ARVRInterface> &p_interface) {
+ ERR_FAIL_COND(p_interface.is_null());
+
+ int idx = -1;
+ for (int i = 0; i < interfaces.size(); i++) {
+
+ if (interfaces[i] == p_interface) {
+ ERR_PRINT("Interface was already added");
+ return;
+ };
+ };
+
+ print_line("Registered interface " + p_interface->get_name());
+
+ interfaces.push_back(p_interface);
+ emit_signal("interface_added", p_interface->get_name());
+};
+
+void ARVRServer::remove_interface(const Ref<ARVRInterface> &p_interface) {
+ ERR_FAIL_COND(p_interface.is_null());
+
+ int idx = -1;
+ for (int i = 0; i < interfaces.size(); i++) {
+
+ if (interfaces[i] == p_interface) {
+
+ idx = i;
+ break;
+ };
+ };
+
+ ERR_FAIL_COND(idx == -1);
+
+ print_line("Removed interface" + p_interface->get_name());
+
+ emit_signal("interface_removed", p_interface->get_name());
+ interfaces.remove(idx);
+};
+
+int ARVRServer::get_interface_count() const {
+ return interfaces.size();
+};
+
+Ref<ARVRInterface> ARVRServer::get_interface(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, interfaces.size(), NULL);
+
+ return interfaces[p_index];
+};
+
+Ref<ARVRInterface> ARVRServer::find_interface(const String &p_name) const {
+ int idx = -1;
+ for (int i = 0; i < interfaces.size(); i++) {
+
+ if (interfaces[i]->get_name() == p_name) {
+
+ idx = i;
+ break;
+ };
+ };
+
+ ERR_FAIL_COND_V(idx == -1, NULL);
+
+ return interfaces[idx];
+};
+
+/*
+ A little extra info on the tracker ids, these are unique per tracker type so we get soem consistency in recognising our trackers, specifically controllers.
+
+ The first controller that is turned of will get ID 1, the second will get ID 2, etc.
+ The magic happens when one of the controllers is turned off, say controller 1 turns off, controller 2 will remain controller 2, controller 3 will remain controller 3.
+ If controller number 1 is turned on again it again gets ID 1 unless another new controller was turned on since.
+
+ The most likely scenario however is a controller that runs out of battery and another controller being used to replace it.
+ Because the controllers are often linked to physical objects, say you're holding a shield in controller 1, your left hand, and a gun in controller 2, your right hand, and controller 1 dies:
+ - using our tracker index would suddenly make the gun disappear and the shield jump into your right hand because controller 2 becomes controller 1.
+ - using this approach the shield disappears or is no longer tracked, but the gun stays firmly in your right hand because that is still controller 2, further more, if controller 1 is replaced the shield will return.
+*/
+
+bool ARVRServer::is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const {
+ for (int i = 0; i < trackers.size(); i++) {
+ if (trackers[i]->get_type() == p_tracker_type && trackers[i]->get_tracker_id() == p_tracker_id) {
+ return true;
+ };
+ };
+
+ // all good
+ return false;
+};
+
+int ARVRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) {
+ // we start checking at 1, 0 means that it's not a controller..
+ int tracker_id = 1;
+
+ while (is_tracker_id_in_use_for_type(p_tracker_type, tracker_id)) {
+ // try the next one
+ tracker_id++;
+ };
+
+ return tracker_id;
+};
+
+void ARVRServer::add_tracker(ARVRPositionalTracker *p_tracker) {
+ ERR_FAIL_NULL(p_tracker);
+
+ trackers.push_back(p_tracker);
+ emit_signal("tracker_added", p_tracker->get_name(), p_tracker->get_type());
+};
+
+void ARVRServer::remove_tracker(ARVRPositionalTracker *p_tracker) {
+ ERR_FAIL_NULL(p_tracker);
+
+ int idx = -1;
+ for (int i = 0; i < trackers.size(); i++) {
+
+ if (trackers[i] == p_tracker) {
+
+ idx = i;
+ break;
+ };
+ };
+
+ ERR_FAIL_COND(idx == -1);
+
+ emit_signal("tracker_removed", p_tracker->get_name());
+ trackers.remove(idx);
+};
+
+int ARVRServer::get_tracker_count() const {
+ return trackers.size();
+};
+
+ARVRPositionalTracker *ARVRServer::get_tracker(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, trackers.size(), NULL);
+
+ return trackers[p_index];
+};
+
+ARVRPositionalTracker *ARVRServer::find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const {
+ ERR_FAIL_COND_V(p_tracker_id == 0, NULL);
+
+ for (int i = 0; i < trackers.size(); i++) {
+ if (trackers[i]->get_type() == p_tracker_type && trackers[i]->get_tracker_id() == p_tracker_id) {
+ return trackers[i];
+ };
+ };
+
+ return NULL;
+};
+
+Ref<ARVRInterface> ARVRServer::get_primary_interface() const {
+ return primary_interface;
+};
+
+void ARVRServer::set_primary_interface(const Ref<ARVRInterface> &p_primary_interface) {
+ primary_interface = p_primary_interface;
+
+ print_line("Primary interface set to: " + primary_interface->get_name());
+};
+
+void ARVRServer::clear_primary_interface_if(const Ref<ARVRInterface> &p_primary_interface) {
+ if (primary_interface == p_primary_interface) {
+ print_line("Clearing primary interface");
+ primary_interface.unref();
+ };
+};
+
+ARVRServer::ARVRServer() {
+ singleton = this;
+ world_scale = 1.0;
+};
+
+ARVRServer::~ARVRServer() {
+ primary_interface.unref();
+
+ while (interfaces.size() > 0) {
+ interfaces.remove(0);
+ }
+
+ while (trackers.size() > 0) {
+ trackers.remove(0);
+ }
+
+ singleton = NULL;
+};
diff --git a/servers/arvr_server.h b/servers/arvr_server.h
new file mode 100644
index 0000000000..fd7c5470c3
--- /dev/null
+++ b/servers/arvr_server.h
@@ -0,0 +1,167 @@
+/*************************************************************************/
+/* arvr_server.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#ifndef ARVR_SERVER_H
+#define ARVR_SERVER_H
+
+#include "os/thread_safe.h"
+#include "reference.h"
+#include "rid.h"
+#include "variant.h"
+
+class ARVRInterface;
+class ARVRPositionalTracker;
+
+/**
+ @author Bastiaan Olij <mux213@gmail.com>
+
+ The ARVR server is a singleton object that gives access to the various
+ objects and SDKs that are available on the system.
+ Because there can be multiple SDKs active this is exposed as an array
+ and our ARVR server object acts as a pass through
+ Also each positioning tracker is accessible from here.
+
+ I've added some additional info into this header file that should move
+ into the documention, I will do so when we're close to accepting this PR
+ or as a separate PR once this has been merged into the master branch.
+**/
+
+class ARVRServer : public Object {
+ GDCLASS(ARVRServer, Object);
+ _THREAD_SAFE_CLASS_
+
+public:
+ enum TrackerType {
+ TRACKER_CONTROLLER = 0x01, /* tracks a controller */
+ TRACKER_BASESTATION = 0x02, /* tracks location of a base station */
+ TRACKER_ANCHOR = 0x04, /* tracks an anchor point, used in AR to track a real live location */
+ TRACKER_UNKNOWN = 0x80, /* unknown tracker */
+
+ TRACKER_ANY_KNOWN = 0x7f, /* all except unknown */
+ TRACKER_ANY = 0xff /* used by get_connected_trackers to return all types */
+ };
+
+private:
+ Vector<Ref<ARVRInterface> > interfaces;
+ Vector<ARVRPositionalTracker *> trackers;
+
+ Ref<ARVRInterface> primary_interface; /* we'll identify one interface as primary, this will be used by our viewports */
+
+ real_t world_scale; /* scale by which we multiply our tracker positions */
+ Transform world_origin; /* our world origin point, maps a location in our virtual world to the origin point in our real world tracking volume */
+ Transform reference_frame; /* our reference frame */
+
+ bool is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const;
+
+protected:
+ static ARVRServer *singleton;
+
+ static void _bind_methods();
+
+public:
+ static ARVRServer *get_singleton();
+
+ /*
+ World scale allows you to specify a scale factor that is applied to all positioning vectors in our VR world in essence scaling up, or scaling down the world.
+ For stereoscopic rendering specifically this is very important to give an accurate sense of scale.
+ Add controllers into the mix and an accurate mapping of real world movement to percieved virtual movement becomes very important.
+
+ Most VR platforms, and our assumption, is that 1 unit in our virtual world equates to 1 meter in the real mode.
+ This scale basically effects the unit size relationship to real world size.
+
+ I may remove access to this property in GDScript in favour of exposing it on the ARVROrigin node
+ */
+ real_t get_world_scale() const;
+ void set_world_scale(real_t p_world_scale);
+
+ /*
+ The world maps the 0,0,0 coordinate of our real world coordinate system for our tracking volume to a location in our
+ virtual world. It is this origin point that should be moved when the player is moved through the world by controller
+ actions be it straffing, teleporting, etc. Movement of the player by moving through the physical space is always tracked
+ in relation to this point.
+
+ Note that the ARVROrigin spatial node in your scene automatically updates this property and it should be used instead of
+ direct access to this property and it therefor is not available in GDScript
+
+ Note: this should not be used in AR and should be ignored by an AR based interface as it would throw what you're looking at in the real world
+ and in the virtual world out of sync
+ */
+ Transform get_world_origin() const;
+ void set_world_origin(const Transform p_origin);
+
+ /*
+ Requesting a reference frame results in a matrix being calculated that ensures the HMD is positioned to 0,0,0 facing 0,0,-1 (need to verify this direction)
+ in the virtual world.
+
+ Note: this should not be used in AR and should be ignored by an AR based interface as it would throw what you're looking at in the real world
+ and in the virtual world out of sync
+ */
+ Transform get_reference_frame() const;
+ void request_reference_frame(bool p_ignore_tilt, bool p_keep_height);
+
+ /*
+ Interfaces are objects that 'glue' Godot to an AR or VR SDK such as the Oculus SDK, OpenVR, OpenHMD, etc.
+ */
+ void add_interface(const Ref<ARVRInterface> &p_interface);
+ void remove_interface(const Ref<ARVRInterface> &p_interface);
+ int get_interface_count() const;
+ Ref<ARVRInterface> get_interface(int p_index) const;
+ Ref<ARVRInterface> find_interface(const String &p_name) const;
+
+ /*
+ note, more then one interface can technically be active, especially on mobile, but only one interface is used for
+ rendering. This interface identifies itself by calling set_primary_interface when it is initialized
+ */
+ Ref<ARVRInterface> get_primary_interface() const;
+ void set_primary_interface(const Ref<ARVRInterface> &p_primary_interface);
+ void clear_primary_interface_if(const Ref<ARVRInterface> &p_primary_interface); /* this is automatically called if an interface destructs */
+
+ /*
+ Our trackers are objects that expose the orientation and position of physical devices such as controller, anchor points, etc.
+ They are created and managed by our active AR/VR interfaces.
+
+ Note that for trackers that
+ */
+ int get_free_tracker_id_for_type(TrackerType p_tracker_type);
+ void add_tracker(ARVRPositionalTracker *p_tracker);
+ void remove_tracker(ARVRPositionalTracker *p_tracker);
+ int get_tracker_count() const;
+ ARVRPositionalTracker *get_tracker(int p_index) const;
+ ARVRPositionalTracker *find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const;
+
+ ARVRServer();
+ ~ARVRServer();
+};
+
+#define ARVR ARVRServer
+
+VARIANT_ENUM_CAST(ARVRServer::TrackerType);
+
+#endif
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index c5029d1e13..092f445c13 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -30,6 +30,10 @@
#include "register_server_types.h"
#include "project_settings.h"
+#include "arvr/arvr_interface.h"
+#include "arvr/arvr_positional_tracker.h"
+#include "arvr/arvr_script_interface.h"
+#include "arvr_server.h"
#include "audio/audio_effect.h"
#include "audio/audio_stream.h"
#include "audio/effects/audio_effect_amplify.h"
@@ -70,16 +74,23 @@ static void _debugger_get_resource_usage(List<ScriptDebuggerRemote::ResourceUsag
}
ShaderTypes *shader_types = NULL;
+ARVRServer *arvr_server = NULL;
void register_server_types() {
+ arvr_server = memnew(ARVRServer);
ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("VisualServer", VisualServer::get_singleton()));
ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("AudioServer", AudioServer::get_singleton()));
ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("PhysicsServer", PhysicsServer::get_singleton()));
ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("Physics2DServer", Physics2DServer::get_singleton()));
+ ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("ARVRServer", ARVRServer::get_singleton()));
shader_types = memnew(ShaderTypes);
+ ClassDB::register_virtual_class<ARVRInterface>();
+ ClassDB::register_class<ARVRPositionalTracker>();
+ ClassDB::register_class<ARVRScriptInterface>();
+
ClassDB::register_virtual_class<AudioStream>();
ClassDB::register_virtual_class<AudioStreamPlayback>();
ClassDB::register_class<AudioStreamRandomPitch>();
@@ -133,5 +144,9 @@ void register_server_types() {
void unregister_server_types() {
+ //@TODO move this into iPhone/Android implementation? just have this here for testing...
+ // mobile_interface = NULL;
+
memdelete(shader_types);
+ memdelete(arvr_server);
}
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 58481fc3f6..b13bb904ab 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -908,6 +908,7 @@ public:
BIND0R(RID, viewport_create)
+ BIND2(viewport_set_use_arvr, RID, bool)
BIND3(viewport_set_size, RID, int, int)
BIND2(viewport_set_active, RID, bool)
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index c383be549b..87431a2ce4 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -1658,6 +1658,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
}
void VisualServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) {
+ // render to mono camera
Camera *camera = camera_owner.getornull(p_camera);
ERR_FAIL_COND(!camera);
@@ -1697,6 +1698,25 @@ void VisualServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_view
_render_scene(camera->transform, camera_matrix, ortho, camera->env, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), -1);
}
+void VisualServerScene::render_camera(Ref<ARVRInterface> &p_interface, ARVRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) {
+ // render for AR/VR interface
+
+ Camera *camera = camera_owner.getornull(p_camera);
+ ERR_FAIL_COND(!camera);
+
+ /* SETUP CAMERA, we are ignoring type and FOV here */
+ bool ortho = false;
+ float aspect = p_viewport_size.width / (float)p_viewport_size.height;
+ CameraMatrix camera_matrix = p_interface->get_projection_for_eye(p_eye, aspect, camera->znear, camera->zfar);
+
+ // We also ignore our camera position, it will have been positioned with a slightly old tracking position.
+ // Instead we take our origin point and have our ar/vr interface add fresh tracking data! Whoohoo!
+ Transform world_origin = ARVRServer::get_singleton()->get_world_origin();
+ Transform cam_transform = p_interface->get_transform_for_eye(p_eye, world_origin);
+
+ _render_scene(cam_transform, camera_matrix, ortho, camera->env, camera->visible_layers, p_scenario, p_shadow_atlas, RID(), -1);
+};
+
void VisualServerScene::_render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
Scenario *scenario = scenario_owner.getornull(p_scenario);
diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h
index 168dfddfd4..17b95946b3 100644
--- a/servers/visual/visual_server_scene.h
+++ b/servers/visual/visual_server_scene.h
@@ -38,6 +38,7 @@
#include "os/semaphore.h"
#include "os/thread.h"
#include "self_list.h"
+#include "servers/arvr/arvr_interface.h"
class VisualServerScene {
public:
@@ -521,6 +522,7 @@ public:
void render_empty_scene(RID p_scenario, RID p_shadow_atlas);
void render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas);
+ void render_camera(Ref<ARVRInterface> &p_interface, ARVRInterface::Eyes p_eye, RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas);
void update_dirty_instances();
//probes
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index 2a37b64759..ad9dec090a 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -33,7 +33,7 @@
#include "visual_server_global.h"
#include "visual_server_scene.h"
-void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
+void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye) {
/* Camera should always be BEFORE any other 3D */
@@ -90,8 +90,13 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
}
if (!scenario_draw_canvas_bg && can_draw_3d) {
+ Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
- VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ if (p_viewport->use_arvr && arvr_interface.is_valid()) {
+ VSG::scene->render_camera(arvr_interface, p_eye, p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ } else {
+ VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ }
}
if (!p_viewport->hide_canvas) {
@@ -260,15 +265,19 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
}
void VisualServerViewport::draw_viewports() {
-
- //sort viewports
-
- //draw viewports
+ // get our arvr interface in case we need it
+ Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
+ if (arvr_interface.is_valid()) {
+ // update our positioning information as late as possible...
+ arvr_interface->process();
+ }
clear_color = GLOBAL_GET("rendering/environment/default_clear_color");
+ //sort viewports
active_viewports.sort_custom<ViewportSort>();
+ //draw viewports
for (int i = 0; i < active_viewports.size(); i++) {
Viewport *vp = active_viewports[i];
@@ -286,25 +295,47 @@ void VisualServerViewport::draw_viewports() {
VSG::storage->render_target_clear_used(vp->render_target);
- VSG::rasterizer->set_current_render_target(vp->render_target);
+ if (vp->use_arvr && arvr_interface.is_valid()) {
+ // override our size, make sure it matches our required size
+ Size2 size = arvr_interface->get_recommended_render_targetsize();
+ VSG::storage->render_target_set_size(vp->render_target, size.x, size.y);
- VSG::scene_render->set_debug_draw_mode(vp->debug_draw);
- VSG::storage->render_info_begin_capture();
+ // render mono or left eye first
+ ARVRInterface::Eyes leftOrMono = arvr_interface->is_stereo() ? ARVRInterface::EYE_LEFT : ARVRInterface::EYE_MONO;
+ VSG::rasterizer->set_current_render_target(vp->render_target);
+ _draw_viewport(vp, leftOrMono);
+ arvr_interface->commit_for_eye(leftOrMono, vp->render_target, vp->viewport_to_screen_rect);
- _draw_viewport(vp);
+ // render right eye
+ if (leftOrMono == ARVRInterface::EYE_LEFT) {
+ // commit for eye may have changed the render target
+ VSG::rasterizer->set_current_render_target(vp->render_target);
- VSG::storage->render_info_end_capture();
- vp->render_info[VS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_OBJECTS_IN_FRAME);
- vp->render_info[VS::VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_VERTICES_IN_FRAME);
- vp->render_info[VS::VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_MATERIAL_CHANGES_IN_FRAME);
- vp->render_info[VS::VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_SHADER_CHANGES_IN_FRAME);
- vp->render_info[VS::VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_SURFACE_CHANGES_IN_FRAME);
- vp->render_info[VS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_DRAW_CALLS_IN_FRAME);
-
- if (vp->viewport_to_screen_rect != Rect2()) {
- //copy to screen if set as such
- VSG::rasterizer->set_current_render_target(RID());
- VSG::rasterizer->blit_render_target_to_screen(vp->render_target, vp->viewport_to_screen_rect, vp->viewport_to_screen);
+ _draw_viewport(vp, ARVRInterface::EYE_RIGHT);
+ arvr_interface->commit_for_eye(ARVRInterface::EYE_RIGHT, vp->render_target, vp->viewport_to_screen_rect);
+ }
+ } else {
+ VSG::rasterizer->set_current_render_target(vp->render_target);
+
+ VSG::scene_render->set_debug_draw_mode(vp->debug_draw);
+ VSG::storage->render_info_begin_capture();
+
+ // render standard mono camera
+ _draw_viewport(vp);
+
+ VSG::storage->render_info_end_capture();
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_OBJECTS_IN_FRAME);
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_VERTICES_IN_FRAME);
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_MATERIAL_CHANGES_IN_FRAME);
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_SHADER_CHANGES_IN_FRAME);
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_SURFACE_CHANGES_IN_FRAME);
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_DRAW_CALLS_IN_FRAME);
+
+ if (vp->viewport_to_screen_rect != Rect2()) {
+ //copy to screen if set as such
+ VSG::rasterizer->set_current_render_target(RID());
+ VSG::rasterizer->blit_render_target_to_screen(vp->render_target, vp->viewport_to_screen_rect, vp->viewport_to_screen);
+ }
}
if (vp->update_mode == VS::VIEWPORT_UPDATE_ONCE) {
@@ -329,6 +360,13 @@ RID VisualServerViewport::viewport_create() {
return rid;
}
+void VisualServerViewport::viewport_set_use_arvr(RID p_viewport, bool p_use_arvr) {
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->use_arvr = p_use_arvr;
+}
+
void VisualServerViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) {
ERR_FAIL_COND(p_width < 0 && p_height < 0);
diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h
index f963ce4aa3..93227d1c31 100644
--- a/servers/visual/visual_server_viewport.h
+++ b/servers/visual/visual_server_viewport.h
@@ -32,6 +32,7 @@
#include "rasterizer.h"
#include "self_list.h"
+#include "servers/arvr/arvr_interface.h"
#include "servers/visual_server.h"
class VisualServerViewport {
@@ -44,6 +45,8 @@ public:
RID self;
RID parent;
+ bool use_arvr; /* use arvr interface to override camera positioning and projection matrices and control output */
+
Size2i size;
RID camera;
RID scenario;
@@ -107,6 +110,7 @@ public:
for (int i = 0; i < VS::VIEWPORT_RENDER_INFO_MAX; i++) {
render_info[i] = 0;
}
+ use_arvr = false;
}
};
@@ -131,11 +135,13 @@ public:
private:
Color clear_color;
- void _draw_viewport(Viewport *p_viewport);
+ void _draw_viewport(Viewport *p_viewport, ARVRInterface::Eyes p_eye = ARVRInterface::EYE_MONO);
public:
RID viewport_create();
+ void viewport_set_use_arvr(RID p_viewport, bool p_use_arvr);
+
void viewport_set_size(RID p_viewport, int p_width, int p_height);
void viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect = Rect2(), int p_screen = 0);
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 4567d87706..e6ce3f6a54 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -344,6 +344,8 @@ public:
FUNC0R(RID, viewport_create)
+ FUNC2(viewport_set_use_arvr, RID, bool)
+
FUNC3(viewport_set_size, RID, int, int)
FUNC2(viewport_set_active, RID, bool)
diff --git a/servers/visual_server.h b/servers/visual_server.h
index f515a7b990..5c9f4202f9 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -532,6 +532,7 @@ public:
virtual RID viewport_create() = 0;
+ virtual void viewport_set_use_arvr(RID p_viewport, bool p_use_arvr) = 0;
virtual void viewport_set_size(RID p_viewport, int p_width, int p_height) = 0;
virtual void viewport_set_active(RID p_viewport, bool p_active) = 0;
virtual void viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) = 0;