summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-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.cpp171
-rw-r--r--servers/arvr/arvr_positional_tracker.h87
-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/audio/audio_driver_dummy.cpp3
-rw-r--r--servers/audio/audio_driver_dummy.h1
-rw-r--r--servers/audio/audio_effect.cpp1
-rw-r--r--servers/audio/audio_effect.h1
-rw-r--r--servers/audio/audio_filter_sw.cpp38
-rw-r--r--servers/audio/audio_filter_sw.h34
-rw-r--r--servers/audio/audio_rb_resampler.cpp1
-rw-r--r--servers/audio/audio_rb_resampler.h1
-rw-r--r--servers/audio/audio_stream.cpp132
-rw-r--r--servers/audio/audio_stream.h58
-rw-r--r--servers/audio/effects/audio_effect_amplify.cpp1
-rw-r--r--servers/audio/effects/audio_effect_amplify.h1
-rw-r--r--servers/audio/effects/audio_effect_chorus.cpp1
-rw-r--r--servers/audio/effects/audio_effect_chorus.h1
-rw-r--r--servers/audio/effects/audio_effect_compressor.cpp21
-rw-r--r--servers/audio/effects/audio_effect_compressor.h7
-rw-r--r--servers/audio/effects/audio_effect_delay.cpp1
-rw-r--r--servers/audio/effects/audio_effect_delay.h1
-rw-r--r--servers/audio/effects/audio_effect_distortion.cpp1
-rw-r--r--servers/audio/effects/audio_effect_distortion.h9
-rw-r--r--servers/audio/effects/audio_effect_eq.cpp1
-rw-r--r--servers/audio/effects/audio_effect_eq.h1
-rw-r--r--servers/audio/effects/audio_effect_filter.cpp1
-rw-r--r--servers/audio/effects/audio_effect_filter.h1
-rw-r--r--servers/audio/effects/audio_effect_limiter.cpp21
-rw-r--r--servers/audio/effects/audio_effect_limiter.h7
-rw-r--r--servers/audio/effects/audio_effect_panner.cpp1
-rw-r--r--servers/audio/effects/audio_effect_panner.h3
-rw-r--r--servers/audio/effects/audio_effect_phaser.cpp1
-rw-r--r--servers/audio/effects/audio_effect_phaser.h1
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.cpp1
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.h1
-rw-r--r--servers/audio/effects/audio_effect_reverb.cpp1
-rw-r--r--servers/audio/effects/audio_effect_reverb.h1
-rw-r--r--servers/audio/effects/audio_effect_stereo_enhance.cpp1
-rw-r--r--servers/audio/effects/audio_effect_stereo_enhance.h1
-rw-r--r--servers/audio/effects/eq.cpp1
-rw-r--r--servers/audio/effects/eq.h1
-rw-r--r--servers/audio/effects/reverb.cpp1
-rw-r--r--servers/audio/effects/reverb.h1
-rw-r--r--servers/audio/reverb_sw.cpp1
-rw-r--r--servers/audio/reverb_sw.h1
-rw-r--r--servers/audio/voice_rb_sw.h1
-rw-r--r--servers/audio_server.cpp36
-rw-r--r--servers/audio_server.h4
-rw-r--r--servers/physics/area_pair_sw.cpp23
-rw-r--r--servers/physics/area_pair_sw.h1
-rw-r--r--servers/physics/area_sw.cpp1
-rw-r--r--servers/physics/area_sw.h2
-rw-r--r--servers/physics/body_pair_sw.cpp12
-rw-r--r--servers/physics/body_pair_sw.h1
-rw-r--r--servers/physics/body_sw.cpp10
-rw-r--r--servers/physics/body_sw.h2
-rw-r--r--servers/physics/broad_phase_basic.cpp25
-rw-r--r--servers/physics/broad_phase_basic.h2
-rw-r--r--servers/physics/broad_phase_octree.cpp8
-rw-r--r--servers/physics/broad_phase_octree.h4
-rw-r--r--servers/physics/broad_phase_sw.cpp1
-rw-r--r--servers/physics/broad_phase_sw.h2
-rw-r--r--servers/physics/collision_object_sw.cpp5
-rw-r--r--servers/physics/collision_object_sw.h19
-rw-r--r--servers/physics/collision_solver_sat.cpp3
-rw-r--r--servers/physics/collision_solver_sat.h1
-rw-r--r--servers/physics/collision_solver_sw.cpp7
-rw-r--r--servers/physics/collision_solver_sw.h1
-rw-r--r--servers/physics/constraint_sw.h1
-rw-r--r--servers/physics/gjk_epa.cpp26
-rw-r--r--servers/physics/gjk_epa.h1
-rw-r--r--servers/physics/joints/cone_twist_joint_sw.cpp30
-rw-r--r--servers/physics/joints/cone_twist_joint_sw.h5
-rw-r--r--servers/physics/joints/generic_6dof_joint_sw.cpp30
-rw-r--r--servers/physics/joints/generic_6dof_joint_sw.h5
-rw-r--r--servers/physics/joints/hinge_joint_sw.cpp17
-rw-r--r--servers/physics/joints/hinge_joint_sw.h1
-rw-r--r--servers/physics/joints/jacobian_entry_sw.h1
-rw-r--r--servers/physics/joints/pin_joint_sw.cpp17
-rw-r--r--servers/physics/joints/pin_joint_sw.h9
-rw-r--r--servers/physics/joints/slider_joint_sw.cpp23
-rw-r--r--servers/physics/joints/slider_joint_sw.h1
-rw-r--r--servers/physics/joints_sw.h1
-rw-r--r--servers/physics/physics_server_sw.cpp115
-rw-r--r--servers/physics/physics_server_sw.h42
-rw-r--r--servers/physics/shape_sw.cpp256
-rw-r--r--servers/physics/shape_sw.h27
-rw-r--r--servers/physics/space_sw.cpp458
-rw-r--r--servers/physics/space_sw.h23
-rw-r--r--servers/physics/step_sw.cpp1
-rw-r--r--servers/physics/step_sw.h1
-rw-r--r--servers/physics_2d/area_2d_sw.cpp1
-rw-r--r--servers/physics_2d/area_2d_sw.h2
-rw-r--r--servers/physics_2d/area_pair_2d_sw.cpp16
-rw-r--r--servers/physics_2d/area_pair_2d_sw.h1
-rw-r--r--servers/physics_2d/body_2d_sw.cpp5
-rw-r--r--servers/physics_2d/body_2d_sw.h17
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp16
-rw-r--r--servers/physics_2d/body_pair_2d_sw.h1
-rw-r--r--servers/physics_2d/broad_phase_2d_basic.cpp5
-rw-r--r--servers/physics_2d/broad_phase_2d_basic.h1
-rw-r--r--servers/physics_2d/broad_phase_2d_hash_grid.cpp23
-rw-r--r--servers/physics_2d/broad_phase_2d_hash_grid.h3
-rw-r--r--servers/physics_2d/broad_phase_2d_sw.cpp1
-rw-r--r--servers/physics_2d/broad_phase_2d_sw.h1
-rw-r--r--servers/physics_2d/collision_object_2d_sw.cpp8
-rw-r--r--servers/physics_2d/collision_object_2d_sw.h26
-rw-r--r--servers/physics_2d/collision_solver_2d_sat.cpp1
-rw-r--r--servers/physics_2d/collision_solver_2d_sat.h1
-rw-r--r--servers/physics_2d/collision_solver_2d_sw.cpp3
-rw-r--r--servers/physics_2d/collision_solver_2d_sw.h1
-rw-r--r--servers/physics_2d/constraint_2d_sw.h1
-rw-r--r--servers/physics_2d/joints_2d_sw.cpp1
-rw-r--r--servers/physics_2d/joints_2d_sw.h1
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp122
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h35
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.cpp19
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.h42
-rw-r--r--servers/physics_2d/shape_2d_sw.cpp25
-rw-r--r--servers/physics_2d/shape_2d_sw.h11
-rw-r--r--servers/physics_2d/space_2d_sw.cpp340
-rw-r--r--servers/physics_2d/space_2d_sw.h23
-rw-r--r--servers/physics_2d/step_2d_sw.cpp1
-rw-r--r--servers/physics_2d/step_2d_sw.h1
-rw-r--r--servers/physics_2d_server.cpp82
-rw-r--r--servers/physics_2d_server.h54
-rw-r--r--servers/physics_server.cpp71
-rw-r--r--servers/physics_server.h87
-rw-r--r--servers/register_server_types.cpp29
-rw-r--r--servers/register_server_types.h1
-rw-r--r--servers/server_wrap_mt_common.h151
-rw-r--r--servers/visual/rasterizer.cpp103
-rw-r--r--servers/visual/rasterizer.h232
-rw-r--r--servers/visual/shader_language.cpp397
-rw-r--r--servers/visual/shader_language.h22
-rw-r--r--servers/visual/shader_types.cpp57
-rw-r--r--servers/visual/shader_types.h4
-rw-r--r--servers/visual/visual_server_canvas.cpp149
-rw-r--r--servers/visual/visual_server_canvas.h24
-rw-r--r--servers/visual/visual_server_global.cpp1
-rw-r--r--servers/visual/visual_server_global.h1
-rw-r--r--servers/visual/visual_server_light_baker.cpp1
-rw-r--r--servers/visual/visual_server_light_baker.h1
-rw-r--r--servers/visual/visual_server_raster.cpp113
-rw-r--r--servers/visual/visual_server_raster.h106
-rw-r--r--servers/visual/visual_server_scene.cpp173
-rw-r--r--servers/visual/visual_server_scene.h11
-rw-r--r--servers/visual/visual_server_viewport.cpp215
-rw-r--r--servers/visual/visual_server_viewport.h25
-rw-r--r--servers/visual/visual_server_wrap_mt.cpp193
-rw-r--r--servers/visual/visual_server_wrap_mt.h590
-rw-r--r--servers/visual_server.cpp112
-rw-r--r--servers/visual_server.h139
160 files changed, 5243 insertions, 1375 deletions
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..9f3d01267b
--- /dev/null
+++ b/servers/arvr/arvr_positional_tracker.cpp
@@ -0,0 +1,171 @@
+/*************************************************************************/
+/* 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);
+
+ // these functions we don't want to expose to normal users but do need to be callable from GDNative
+ ClassDB::bind_method(D_METHOD("_set_type", "type"), &ARVRPositionalTracker::set_type);
+ ClassDB::bind_method(D_METHOD("_set_name", "name"), &ARVRPositionalTracker::set_name);
+ ClassDB::bind_method(D_METHOD("_set_joy_id", "joy_id"), &ARVRPositionalTracker::set_joy_id);
+ ClassDB::bind_method(D_METHOD("_set_orientation", "orientation"), &ARVRPositionalTracker::set_orientation);
+ ClassDB::bind_method(D_METHOD("_set_rw_position", "rw_position"), &ARVRPositionalTracker::set_rw_position);
+};
+
+void ARVRPositionalTracker::set_type(ARVRServer::TrackerType p_type) {
+ 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_
+
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL(arvr_server);
+ real_t world_scale = arvr_server->get_world_scale();
+ ERR_FAIL_COND(world_scale == 0);
+
+ tracks_position = true; // obviously we have this
+ rw_position = p_position / world_scale;
+};
+
+Vector3 ARVRPositionalTracker::get_position() const {
+ _THREAD_SAFE_METHOD_
+
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL_V(arvr_server, rw_position);
+ real_t world_scale = arvr_server->get_world_scale();
+
+ return rw_position * world_scale;
+};
+
+void ARVRPositionalTracker::set_rw_position(const Vector3 &p_rw_position) {
+ _THREAD_SAFE_METHOD_
+
+ tracks_position = true; // obviously we have this
+ rw_position = p_rw_position;
+};
+
+Vector3 ARVRPositionalTracker::get_rw_position() const {
+ _THREAD_SAFE_METHOD_
+
+ return rw_position;
+};
+
+Transform ARVRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const {
+ 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..dba203b73c
--- /dev/null
+++ b/servers/arvr/arvr_positional_tracker.h
@@ -0,0 +1,87 @@
+/*************************************************************************/
+/* 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 rw_position; // our position "in the real world, so without world_scale applied"
+
+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); // set position with world_scale applied
+ Vector3 get_position() const; // get position with world_scale applied
+ void set_rw_position(const Vector3 &p_rw_position);
+ Vector3 get_rw_position() const;
+
+ Transform get_transform(bool p_adjust_by_reference_frame) const;
+
+ 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..6398d87007
--- /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", "idx"), &ARVRServer::get_interface);
+ ClassDB::bind_method(D_METHOD("find_interface", "name"), &ARVRServer::find_interface);
+ ClassDB::bind_method(D_METHOD("get_tracker_count"), &ARVRServer::get_tracker_count);
+ ClassDB::bind_method(D_METHOD("get_tracker", "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..06e0a4561c
--- /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_world_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/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp
index e3022225a3..0f15b43b41 100644
--- a/servers/audio/audio_driver_dummy.cpp
+++ b/servers/audio/audio_driver_dummy.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -28,8 +29,8 @@
/*************************************************************************/
#include "audio_driver_dummy.h"
-#include "global_config.h"
#include "os/os.h"
+#include "project_settings.h"
Error AudioDriverDummy::init() {
diff --git a/servers/audio/audio_driver_dummy.h b/servers/audio/audio_driver_dummy.h
index 02f6a5407c..eadac44c5a 100644
--- a/servers/audio/audio_driver_dummy.h
+++ b/servers/audio/audio_driver_dummy.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/audio_effect.cpp b/servers/audio/audio_effect.cpp
index bb1179134c..edb79adb60 100644
--- a/servers/audio/audio_effect.cpp
+++ b/servers/audio/audio_effect.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/audio_effect.h b/servers/audio/audio_effect.h
index 6981cf0db7..570b2025b1 100644
--- a/servers/audio/audio_effect.h
+++ b/servers/audio/audio_effect.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/audio_filter_sw.cpp b/servers/audio/audio_filter_sw.cpp
index 4bfe31247b..4bf1cebf12 100644
--- a/servers/audio/audio_filter_sw.cpp
+++ b/servers/audio/audio_filter_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -241,28 +242,49 @@ AudioFilterSW::Processor::Processor() {
set_filter(NULL);
}
-void AudioFilterSW::Processor::set_filter(AudioFilterSW *p_filter) {
+void AudioFilterSW::Processor::set_filter(AudioFilterSW *p_filter, bool p_clear_history) {
- ha1 = ha2 = hb1 = hb2 = 0;
+ if (p_clear_history) {
+ ha1 = ha2 = hb1 = hb2 = 0;
+ }
filter = p_filter;
}
-void AudioFilterSW::Processor::update_coeffs() {
+void AudioFilterSW::Processor::update_coeffs(int p_interp_buffer_len) {
if (!filter)
return;
- filter->prepare_coefficients(&coeffs);
+ if (p_interp_buffer_len) { //interpolate
+ Coeffs old_coeffs = coeffs;
+ filter->prepare_coefficients(&coeffs);
+ incr_coeffs.a1 = (coeffs.a1 - old_coeffs.a1) / p_interp_buffer_len;
+ incr_coeffs.a2 = (coeffs.a2 - old_coeffs.a2) / p_interp_buffer_len;
+ incr_coeffs.b0 = (coeffs.b0 - old_coeffs.b0) / p_interp_buffer_len;
+ incr_coeffs.b1 = (coeffs.b1 - old_coeffs.b1) / p_interp_buffer_len;
+ incr_coeffs.b2 = (coeffs.b2 - old_coeffs.b2) / p_interp_buffer_len;
+ coeffs = old_coeffs;
+ } else {
+ filter->prepare_coefficients(&coeffs);
+ }
}
-void AudioFilterSW::Processor::process(float *p_samples, int p_amount, int p_stride) {
+void AudioFilterSW::Processor::process(float *p_samples, int p_amount, int p_stride, bool p_interpolate) {
if (!filter)
return;
- for (int i = 0; i < p_amount; i++) {
+ if (p_interpolate) {
+ for (int i = 0; i < p_amount; i++) {
+
+ process_one_interp(*p_samples);
+ p_samples += p_stride;
+ }
+ } else {
+ for (int i = 0; i < p_amount; i++) {
- process_one(*p_samples);
- p_samples += p_stride;
+ process_one(*p_samples);
+ p_samples += p_stride;
+ }
}
}
diff --git a/servers/audio/audio_filter_sw.h b/servers/audio/audio_filter_sw.h
index bbd006e525..caf735436a 100644
--- a/servers/audio/audio_filter_sw.h
+++ b/servers/audio/audio_filter_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -59,11 +60,14 @@ public:
AudioFilterSW *filter;
Coeffs coeffs;
float ha1, ha2, hb1, hb2; //history
+ Coeffs incr_coeffs;
+
public:
- void set_filter(AudioFilterSW *p_filter);
- void process(float *p_samples, int p_amount, int p_stride = 1);
- void update_coeffs();
+ void set_filter(AudioFilterSW *p_filter, bool p_clear_history = true);
+ void process(float *p_samples, int p_amount, int p_stride = 1, bool p_interpolate = false);
+ void update_coeffs(int p_interp_buffer_len = 0);
_ALWAYS_INLINE_ void process_one(float &p_sample);
+ _ALWAYS_INLINE_ void process_one_interp(float &p_sample);
Processor();
};
@@ -93,14 +97,30 @@ public:
/* inline methods */
-void AudioFilterSW::Processor::process_one(float &p_val) {
+void AudioFilterSW::Processor::process_one(float &p_sample) {
+
+ float pre = p_sample;
+ p_sample = (p_sample * coeffs.b0 + hb1 * coeffs.b1 + hb2 * coeffs.b2 + ha1 * coeffs.a1 + ha2 * coeffs.a2);
+ ha2 = ha1;
+ hb2 = hb1;
+ hb1 = pre;
+ ha1 = p_sample;
+}
+
+void AudioFilterSW::Processor::process_one_interp(float &p_sample) {
- float pre = p_val;
- p_val = (p_val * coeffs.b0 + hb1 * coeffs.b1 + hb2 * coeffs.b2 + ha1 * coeffs.a1 + ha2 * coeffs.a2);
+ float pre = p_sample;
+ p_sample = (p_sample * coeffs.b0 + hb1 * coeffs.b1 + hb2 * coeffs.b2 + ha1 * coeffs.a1 + ha2 * coeffs.a2);
ha2 = ha1;
hb2 = hb1;
hb1 = pre;
- ha1 = p_val;
+ ha1 = p_sample;
+
+ coeffs.b0 += incr_coeffs.b0;
+ coeffs.b1 += incr_coeffs.b1;
+ coeffs.b2 += incr_coeffs.b2;
+ coeffs.a1 += incr_coeffs.a1;
+ coeffs.a2 += incr_coeffs.a2;
}
#endif // AUDIO_FILTER_SW_H
diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp
index bf10f813a2..a5d0a53be6 100644
--- a/servers/audio/audio_rb_resampler.cpp
+++ b/servers/audio/audio_rb_resampler.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/audio_rb_resampler.h b/servers/audio/audio_rb_resampler.h
index d775aed0d9..a906f1bb20 100644
--- a/servers/audio/audio_rb_resampler.h
+++ b/servers/audio/audio_rb_resampler.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index 5f77eb54f6..aa498cccad 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -80,3 +81,134 @@ void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale,
}
}
}
+////////////////////////////////
+
+void AudioStreamRandomPitch::set_audio_stream(const Ref<AudioStream> &p_audio_stream) {
+
+ audio_stream = p_audio_stream;
+ if (audio_stream.is_valid()) {
+ for (Set<AudioStreamPlaybackRandomPitch *>::Element *E = playbacks.front(); E; E = E->next()) {
+ E->get()->playback = audio_stream->instance_playback();
+ }
+ }
+}
+
+Ref<AudioStream> AudioStreamRandomPitch::get_audio_stream() const {
+
+ return audio_stream;
+}
+
+void AudioStreamRandomPitch::set_random_pitch(float p_pitch) {
+
+ if (p_pitch < 1)
+ p_pitch = 1;
+ random_pitch = p_pitch;
+}
+
+float AudioStreamRandomPitch::get_random_pitch() const {
+ return random_pitch;
+}
+
+Ref<AudioStreamPlayback> AudioStreamRandomPitch::instance_playback() {
+ Ref<AudioStreamPlaybackRandomPitch> playback;
+ playback.instance();
+ if (audio_stream.is_valid())
+ playback->playback = audio_stream->instance_playback();
+
+ playbacks.insert(playback.ptr());
+ playback->random_pitch = Ref<AudioStreamRandomPitch>((AudioStreamRandomPitch *)this);
+ return playback;
+}
+
+String AudioStreamRandomPitch::get_stream_name() const {
+
+ if (audio_stream.is_valid()) {
+ return "Random: " + audio_stream->get_name();
+ }
+ return "RandomPitch";
+}
+
+void AudioStreamRandomPitch::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_audio_stream", "stream"), &AudioStreamRandomPitch::set_audio_stream);
+ ClassDB::bind_method(D_METHOD("get_audio_stream"), &AudioStreamRandomPitch::get_audio_stream);
+
+ ClassDB::bind_method(D_METHOD("set_random_pitch", "scale"), &AudioStreamRandomPitch::set_random_pitch);
+ ClassDB::bind_method(D_METHOD("get_random_pitch"), &AudioStreamRandomPitch::get_random_pitch);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "audio_stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_audio_stream", "get_audio_stream");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "random_pitch", PROPERTY_HINT_RANGE, "1,16,0.01"), "set_random_pitch", "get_random_pitch");
+}
+
+AudioStreamRandomPitch::AudioStreamRandomPitch() {
+ random_pitch = 1.1;
+}
+
+void AudioStreamPlaybackRandomPitch::start(float p_from_pos) {
+ playing = playback;
+ float range_from = 1.0 / random_pitch->random_pitch;
+ float range_to = random_pitch->random_pitch;
+
+ pitch_scale = range_from + Math::randf() * (range_to - range_from);
+
+ if (playing.is_valid()) {
+ playing->start(p_from_pos);
+ }
+}
+
+void AudioStreamPlaybackRandomPitch::stop() {
+ if (playing.is_valid()) {
+ playing->stop();
+ ;
+ }
+}
+bool AudioStreamPlaybackRandomPitch::is_playing() const {
+ if (playing.is_valid()) {
+ return playing->is_playing();
+ }
+
+ return false;
+}
+
+int AudioStreamPlaybackRandomPitch::get_loop_count() const {
+ if (playing.is_valid()) {
+ return playing->get_loop_count();
+ }
+
+ return 0;
+}
+
+float AudioStreamPlaybackRandomPitch::get_pos() const {
+ if (playing.is_valid()) {
+ return playing->get_pos();
+ }
+
+ return 0;
+}
+void AudioStreamPlaybackRandomPitch::seek_pos(float p_time) {
+ if (playing.is_valid()) {
+ playing->seek_pos(p_time);
+ }
+}
+
+void AudioStreamPlaybackRandomPitch::mix(AudioFrame *p_bufer, float p_rate_scale, int p_frames) {
+ if (playing.is_valid()) {
+ playing->mix(p_bufer, p_rate_scale * pitch_scale, p_frames);
+ } else {
+ for (int i = 0; i < p_frames; i++) {
+ p_bufer[i] = AudioFrame(0, 0);
+ }
+ }
+}
+
+float AudioStreamPlaybackRandomPitch::get_length() const {
+ if (playing.is_valid()) {
+ return playing->get_length();
+ }
+
+ return 0;
+}
+
+AudioStreamPlaybackRandomPitch::~AudioStreamPlaybackRandomPitch() {
+ random_pitch->playbacks.erase(this);
+}
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index 0d7b4adbfe..0d63e7af82 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -30,6 +31,7 @@
#define AUDIO_STREAM_H
#include "resource.h"
+#include "servers/audio/audio_filter_sw.h"
#include "servers/audio_server.h"
class AudioStreamPlayback : public Reference {
@@ -72,7 +74,7 @@ protected:
virtual float get_stream_sampling_rate() = 0;
public:
- virtual void mix(AudioFrame *p_bufer, float p_rate_scale, int p_frames);
+ virtual void mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames);
AudioStreamPlaybackResampled() { mix_offset = 0; }
};
@@ -87,4 +89,58 @@ public:
virtual String get_stream_name() const = 0;
};
+class AudioStreamPlaybackRandomPitch;
+
+class AudioStreamRandomPitch : public AudioStream {
+
+ GDCLASS(AudioStreamRandomPitch, AudioStream)
+ friend class AudioStreamPlaybackRandomPitch;
+
+ Set<AudioStreamPlaybackRandomPitch *> playbacks;
+ Ref<AudioStream> audio_stream;
+ float random_pitch;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_audio_stream(const Ref<AudioStream> &p_audio_stream);
+ Ref<AudioStream> get_audio_stream() const;
+
+ void set_random_pitch(float p_pitch);
+ float get_random_pitch() const;
+
+ virtual Ref<AudioStreamPlayback> instance_playback();
+ virtual String get_stream_name() const;
+
+ AudioStreamRandomPitch();
+};
+
+class AudioStreamPlaybackRandomPitch : public AudioStreamPlayback {
+
+ GDCLASS(AudioStreamPlaybackRandomPitch, AudioStreamPlayback)
+ friend class AudioStreamRandomPitch;
+
+ Ref<AudioStreamRandomPitch> random_pitch;
+ Ref<AudioStreamPlayback> playback;
+ Ref<AudioStreamPlayback> playing;
+ float pitch_scale;
+
+public:
+ virtual void start(float p_from_pos = 0.0);
+ virtual void stop();
+ virtual bool is_playing() const;
+
+ virtual int get_loop_count() const; //times it looped
+
+ virtual float get_pos() const;
+ virtual void seek_pos(float p_time);
+
+ virtual void mix(AudioFrame *p_bufer, float p_rate_scale, int p_frames);
+
+ virtual float get_length() const; //if supported, otherwise return 0
+
+ ~AudioStreamPlaybackRandomPitch();
+};
+
#endif // AUDIO_STREAM_H
diff --git a/servers/audio/effects/audio_effect_amplify.cpp b/servers/audio/effects/audio_effect_amplify.cpp
index 6a4d03e517..91d1e84182 100644
--- a/servers/audio/effects/audio_effect_amplify.cpp
+++ b/servers/audio/effects/audio_effect_amplify.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_amplify.h b/servers/audio/effects/audio_effect_amplify.h
index 0c75b43691..bba9e352b2 100644
--- a/servers/audio/effects/audio_effect_amplify.h
+++ b/servers/audio/effects/audio_effect_amplify.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_chorus.cpp b/servers/audio/effects/audio_effect_chorus.cpp
index 27b03351c8..8fb7ef2cd0 100644
--- a/servers/audio/effects/audio_effect_chorus.cpp
+++ b/servers/audio/effects/audio_effect_chorus.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_chorus.h b/servers/audio/effects/audio_effect_chorus.h
index 9af9ab1b9a..5db335e288 100644
--- a/servers/audio/effects/audio_effect_chorus.h
+++ b/servers/audio/effects/audio_effect_chorus.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_compressor.cpp b/servers/audio/effects/audio_effect_compressor.cpp
index 8b67353229..491e6ecc81 100644
--- a/servers/audio/effects/audio_effect_compressor.cpp
+++ b/servers/audio/effects/audio_effect_compressor.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -31,7 +32,7 @@
void AudioEffectCompressorInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
- float treshold = Math::db2linear(base->treshold);
+ float threshold = Math::db2linear(base->threshold);
float sample_rate = AudioServer::get_singleton()->get_mix_rate();
float ratatcoef = exp(-1 / (0.00001f * sample_rate));
@@ -65,7 +66,7 @@ void AudioEffectCompressorInstance::process(const AudioFrame *p_src_frames, Audi
float peak = MAX(s.l, s.r);
- float overdb = 2.08136898f * Math::linear2db(peak / treshold);
+ float overdb = 2.08136898f * Math::linear2db(peak / threshold);
if (overdb < 0.0) //we only care about what goes over to compress
overdb = 0.0;
@@ -124,14 +125,14 @@ Ref<AudioEffectInstance> AudioEffectCompressor::instance() {
return ins;
}
-void AudioEffectCompressor::set_treshold(float p_treshold) {
+void AudioEffectCompressor::set_threshold(float p_threshold) {
- treshold = p_treshold;
+ threshold = p_threshold;
}
-float AudioEffectCompressor::get_treshold() const {
+float AudioEffectCompressor::get_threshold() const {
- return treshold;
+ return threshold;
}
void AudioEffectCompressor::set_ratio(float p_ratio) {
@@ -207,8 +208,8 @@ void AudioEffectCompressor::_validate_property(PropertyInfo &property) const {
void AudioEffectCompressor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_treshold", "treshold"), &AudioEffectCompressor::set_treshold);
- ClassDB::bind_method(D_METHOD("get_treshold"), &AudioEffectCompressor::get_treshold);
+ ClassDB::bind_method(D_METHOD("set_threshold", "threshold"), &AudioEffectCompressor::set_threshold);
+ ClassDB::bind_method(D_METHOD("get_threshold"), &AudioEffectCompressor::get_threshold);
ClassDB::bind_method(D_METHOD("set_ratio", "ratio"), &AudioEffectCompressor::set_ratio);
ClassDB::bind_method(D_METHOD("get_ratio"), &AudioEffectCompressor::get_ratio);
@@ -228,7 +229,7 @@ void AudioEffectCompressor::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_sidechain", "sidechain"), &AudioEffectCompressor::set_sidechain);
ClassDB::bind_method(D_METHOD("get_sidechain"), &AudioEffectCompressor::get_sidechain);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "treshold", PROPERTY_HINT_RANGE, "-60,0,0.1"), "set_treshold", "get_treshold");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "threshold", PROPERTY_HINT_RANGE, "-60,0,0.1"), "set_threshold", "get_threshold");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ratio", PROPERTY_HINT_RANGE, "1,48,0.1"), "set_ratio", "get_ratio");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "gain", PROPERTY_HINT_RANGE, "-20,20,0.1"), "set_gain", "get_gain");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "attack_us", PROPERTY_HINT_RANGE, "20,2000,1"), "set_attack_us", "get_attack_us");
@@ -238,7 +239,7 @@ void AudioEffectCompressor::_bind_methods() {
}
AudioEffectCompressor::AudioEffectCompressor() {
- treshold = 0;
+ threshold = 0;
ratio = 4;
gain = 0;
attack_us = 20;
diff --git a/servers/audio/effects/audio_effect_compressor.h b/servers/audio/effects/audio_effect_compressor.h
index 34f80348db..550302056c 100644
--- a/servers/audio/effects/audio_effect_compressor.h
+++ b/servers/audio/effects/audio_effect_compressor.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -50,7 +51,7 @@ class AudioEffectCompressor : public AudioEffect {
GDCLASS(AudioEffectCompressor, AudioEffect)
friend class AudioEffectCompressorInstance;
- float treshold;
+ float threshold;
float ratio;
float gain;
float attack_us;
@@ -65,8 +66,8 @@ protected:
public:
Ref<AudioEffectInstance> instance();
- void set_treshold(float p_treshold);
- float get_treshold() const;
+ void set_threshold(float p_threshold);
+ float get_threshold() const;
void set_ratio(float p_ratio);
float get_ratio() const;
diff --git a/servers/audio/effects/audio_effect_delay.cpp b/servers/audio/effects/audio_effect_delay.cpp
index b643f801a7..de301fba6f 100644
--- a/servers/audio/effects/audio_effect_delay.cpp
+++ b/servers/audio/effects/audio_effect_delay.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_delay.h b/servers/audio/effects/audio_effect_delay.h
index 247fddac00..9d80c752d3 100644
--- a/servers/audio/effects/audio_effect_delay.h
+++ b/servers/audio/effects/audio_effect_delay.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_distortion.cpp b/servers/audio/effects/audio_effect_distortion.cpp
index e5430fcd21..87cf520e19 100644
--- a/servers/audio/effects/audio_effect_distortion.cpp
+++ b/servers/audio/effects/audio_effect_distortion.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_distortion.h b/servers/audio/effects/audio_effect_distortion.h
index 6cd92dea18..afeb6ac7ec 100644
--- a/servers/audio/effects/audio_effect_distortion.h
+++ b/servers/audio/effects/audio_effect_distortion.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -70,16 +71,16 @@ public:
void set_mode(Mode p_mode);
Mode get_mode() const;
- void set_pre_gain(float pre_gain);
+ void set_pre_gain(float p_pre_gain);
float get_pre_gain() const;
- void set_keep_hf_hz(float keep_hf_hz);
+ void set_keep_hf_hz(float p_keep_hf_hz);
float get_keep_hf_hz() const;
- void set_drive(float drive);
+ void set_drive(float p_drive);
float get_drive() const;
- void set_post_gain(float post_gain);
+ void set_post_gain(float p_post_gain);
float get_post_gain() const;
AudioEffectDistortion();
diff --git a/servers/audio/effects/audio_effect_eq.cpp b/servers/audio/effects/audio_effect_eq.cpp
index a103d34d0f..87f793f95e 100644
--- a/servers/audio/effects/audio_effect_eq.cpp
+++ b/servers/audio/effects/audio_effect_eq.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_eq.h b/servers/audio/effects/audio_effect_eq.h
index 917bf584c7..62041fe4f7 100644
--- a/servers/audio/effects/audio_effect_eq.h
+++ b/servers/audio/effects/audio_effect_eq.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_filter.cpp b/servers/audio/effects/audio_effect_filter.cpp
index 4c158ce44e..bcf1cc5756 100644
--- a/servers/audio/effects/audio_effect_filter.cpp
+++ b/servers/audio/effects/audio_effect_filter.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_filter.h b/servers/audio/effects/audio_effect_filter.h
index 4973630198..51932cdbf5 100644
--- a/servers/audio/effects/audio_effect_filter.h
+++ b/servers/audio/effects/audio_effect_filter.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_limiter.cpp b/servers/audio/effects/audio_effect_limiter.cpp
index 022d2d9aa4..9f39db0440 100644
--- a/servers/audio/effects/audio_effect_limiter.cpp
+++ b/servers/audio/effects/audio_effect_limiter.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -30,8 +31,8 @@
void AudioEffectLimiterInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
- float thresh = Math::db2linear(base->treshold);
- float threshdb = base->treshold;
+ float thresh = Math::db2linear(base->threshold);
+ float threshdb = base->threshold;
float ceiling = Math::db2linear(base->ceiling);
float ceildb = base->ceiling;
float makeup = Math::db2linear(ceildb - threshdb);
@@ -80,14 +81,14 @@ Ref<AudioEffectInstance> AudioEffectLimiter::instance() {
return ins;
}
-void AudioEffectLimiter::set_treshold_db(float p_treshold) {
+void AudioEffectLimiter::set_threshold_db(float p_threshold) {
- treshold = p_treshold;
+ threshold = p_threshold;
}
-float AudioEffectLimiter::get_treshold_db() const {
+float AudioEffectLimiter::get_threshold_db() const {
- return treshold;
+ return threshold;
}
void AudioEffectLimiter::set_ceiling_db(float p_ceiling) {
@@ -122,8 +123,8 @@ void AudioEffectLimiter::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_ceiling_db", "ceiling"), &AudioEffectLimiter::set_ceiling_db);
ClassDB::bind_method(D_METHOD("get_ceiling_db"), &AudioEffectLimiter::get_ceiling_db);
- ClassDB::bind_method(D_METHOD("set_treshold_db", "treshold"), &AudioEffectLimiter::set_treshold_db);
- ClassDB::bind_method(D_METHOD("get_treshold_db"), &AudioEffectLimiter::get_treshold_db);
+ ClassDB::bind_method(D_METHOD("set_threshold_db", "threshold"), &AudioEffectLimiter::set_threshold_db);
+ ClassDB::bind_method(D_METHOD("get_threshold_db"), &AudioEffectLimiter::get_threshold_db);
ClassDB::bind_method(D_METHOD("set_soft_clip_db", "soft_clip"), &AudioEffectLimiter::set_soft_clip_db);
ClassDB::bind_method(D_METHOD("get_soft_clip_db"), &AudioEffectLimiter::get_soft_clip_db);
@@ -132,13 +133,13 @@ void AudioEffectLimiter::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_soft_clip_ratio"), &AudioEffectLimiter::get_soft_clip_ratio);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ceiling_db", PROPERTY_HINT_RANGE, "-20,-0.1,0.1"), "set_ceiling_db", "get_ceiling_db");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "treshold_db", PROPERTY_HINT_RANGE, "-30,0,0.1"), "set_treshold_db", "get_treshold_db");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "threshold_db", PROPERTY_HINT_RANGE, "-30,0,0.1"), "set_threshold_db", "get_threshold_db");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "soft_clip_db", PROPERTY_HINT_RANGE, "0,6,0.1"), "set_soft_clip_db", "get_soft_clip_db");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "soft_clip_ratio", PROPERTY_HINT_RANGE, "3,20,0.1"), "set_soft_clip_ratio", "get_soft_clip_ratio");
}
AudioEffectLimiter::AudioEffectLimiter() {
- treshold = 0;
+ threshold = 0;
ceiling = -0.1;
soft_clip = 2;
soft_clip_ratio = 10;
diff --git a/servers/audio/effects/audio_effect_limiter.h b/servers/audio/effects/audio_effect_limiter.h
index 9863a788f5..e15ffe5b34 100644
--- a/servers/audio/effects/audio_effect_limiter.h
+++ b/servers/audio/effects/audio_effect_limiter.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -48,7 +49,7 @@ class AudioEffectLimiter : public AudioEffect {
GDCLASS(AudioEffectLimiter, AudioEffect)
friend class AudioEffectLimiterInstance;
- float treshold;
+ float threshold;
float ceiling;
float soft_clip;
float soft_clip_ratio;
@@ -57,8 +58,8 @@ protected:
static void _bind_methods();
public:
- void set_treshold_db(float p_treshold);
- float get_treshold_db() const;
+ void set_threshold_db(float p_threshold);
+ float get_threshold_db() const;
void set_ceiling_db(float p_ceiling);
float get_ceiling_db() const;
diff --git a/servers/audio/effects/audio_effect_panner.cpp b/servers/audio/effects/audio_effect_panner.cpp
index ec0ccab453..a6103f580a 100644
--- a/servers/audio/effects/audio_effect_panner.cpp
+++ b/servers/audio/effects/audio_effect_panner.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_panner.h b/servers/audio/effects/audio_effect_panner.h
index 19bef45f1e..8c3edfbde0 100644
--- a/servers/audio/effects/audio_effect_panner.h
+++ b/servers/audio/effects/audio_effect_panner.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -53,7 +54,7 @@ protected:
public:
Ref<AudioEffectInstance> instance();
- void set_pan(float p_volume);
+ void set_pan(float p_cpanume);
float get_pan() const;
AudioEffectPanner();
diff --git a/servers/audio/effects/audio_effect_phaser.cpp b/servers/audio/effects/audio_effect_phaser.cpp
index 72549009c8..9af344d876 100644
--- a/servers/audio/effects/audio_effect_phaser.cpp
+++ b/servers/audio/effects/audio_effect_phaser.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_phaser.h b/servers/audio/effects/audio_effect_phaser.h
index 70b3a3a4c4..c587ca8239 100644
--- a/servers/audio/effects/audio_effect_phaser.h
+++ b/servers/audio/effects/audio_effect_phaser.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_pitch_shift.cpp b/servers/audio/effects/audio_effect_pitch_shift.cpp
index 6a14ba7155..1889934f29 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.cpp
+++ b/servers/audio/effects/audio_effect_pitch_shift.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_pitch_shift.h b/servers/audio/effects/audio_effect_pitch_shift.h
index 610efdc0e1..08c8c59cc7 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.h
+++ b/servers/audio/effects/audio_effect_pitch_shift.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_reverb.cpp b/servers/audio/effects/audio_effect_reverb.cpp
index f01bd266b8..7049204645 100644
--- a/servers/audio/effects/audio_effect_reverb.cpp
+++ b/servers/audio/effects/audio_effect_reverb.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_reverb.h b/servers/audio/effects/audio_effect_reverb.h
index 2c665ca916..d8f13da8b7 100644
--- a/servers/audio/effects/audio_effect_reverb.h
+++ b/servers/audio/effects/audio_effect_reverb.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_stereo_enhance.cpp b/servers/audio/effects/audio_effect_stereo_enhance.cpp
index 9aed528bd3..ebd48c0546 100644
--- a/servers/audio/effects/audio_effect_stereo_enhance.cpp
+++ b/servers/audio/effects/audio_effect_stereo_enhance.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/audio_effect_stereo_enhance.h b/servers/audio/effects/audio_effect_stereo_enhance.h
index 21331692e9..bad55614c6 100644
--- a/servers/audio/effects/audio_effect_stereo_enhance.h
+++ b/servers/audio/effects/audio_effect_stereo_enhance.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/eq.cpp b/servers/audio/effects/eq.cpp
index 857f81e856..4dd5eb0ebe 100644
--- a/servers/audio/effects/eq.cpp
+++ b/servers/audio/effects/eq.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/eq.h b/servers/audio/effects/eq.h
index a6d471cc4a..90d19e6e91 100644
--- a/servers/audio/effects/eq.h
+++ b/servers/audio/effects/eq.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/reverb.cpp b/servers/audio/effects/reverb.cpp
index 26e6f50667..7bc8c5cac3 100644
--- a/servers/audio/effects/reverb.cpp
+++ b/servers/audio/effects/reverb.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/effects/reverb.h b/servers/audio/effects/reverb.h
index 33f11e59fe..d4ddb3902a 100644
--- a/servers/audio/effects/reverb.h
+++ b/servers/audio/effects/reverb.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/reverb_sw.cpp b/servers/audio/reverb_sw.cpp
index ea89f7e198..45fd7fd7de 100644
--- a/servers/audio/reverb_sw.cpp
+++ b/servers/audio/reverb_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/reverb_sw.h b/servers/audio/reverb_sw.h
index 06a14322a6..f912734e65 100644
--- a/servers/audio/reverb_sw.h
+++ b/servers/audio/reverb_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio/voice_rb_sw.h b/servers/audio/voice_rb_sw.h
index 117a62a436..a4a5ec3ddd 100644
--- a/servers/audio/voice_rb_sw.h
+++ b/servers/audio/voice_rb_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index 5f70f52576..3547f86eb3 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -27,10 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "audio_server.h"
-#include "global_config.h"
#include "io/resource_loader.h"
#include "os/file_access.h"
#include "os/os.h"
+#include "project_settings.h"
#include "servers/audio/effects/audio_effect_compressor.h"
#ifdef TOOLS_ENABLED
@@ -65,7 +66,8 @@ void AudioDriver::audio_server_process(int p_frames, int32_t *p_buffer, bool p_u
void AudioDriver::update_mix_time(int p_frames) {
_mix_amount += p_frames;
- _last_mix_time = OS::get_singleton()->get_ticks_usec();
+ if (OS::get_singleton())
+ _last_mix_time = OS::get_singleton()->get_ticks_usec();
}
double AudioDriver::get_mix_time() const {
@@ -251,7 +253,7 @@ void AudioServer::_mix_step() {
if (!bus->channels[k].used) {
//see if any audio is contained, because channel was not used
- if (MAX(peak.r, peak.l) > Math::db2linear(channel_disable_treshold_db)) {
+ if (MAX(peak.r, peak.l) > Math::db2linear(channel_disable_threshold_db)) {
bus->channels[k].last_mix_with_audio = mix_frames;
} else if (mix_frames - bus->channels[k].last_mix_with_audio > channel_disable_frames) {
bus->channels[k].active = false;
@@ -514,6 +516,15 @@ String AudioServer::get_bus_name(int p_bus) const {
return buses[p_bus]->name;
}
+int AudioServer::get_bus_index(const StringName &p_bus_name) const {
+ for (int i = 0; i < buses.size(); ++i) {
+ if (buses[i]->name == p_bus_name) {
+ return i;
+ }
+ }
+ return -1;
+}
+
void AudioServer::set_bus_volume_db(int p_bus, float p_volume_db) {
ERR_FAIL_INDEX(p_bus, buses.size());
@@ -712,7 +723,7 @@ bool AudioServer::is_bus_channel_active(int p_bus, int p_channel) const {
void AudioServer::init() {
- channel_disable_treshold_db = GLOBAL_DEF("audio/channel_disable_treshold_db", -60.0);
+ channel_disable_threshold_db = GLOBAL_DEF("audio/channel_disable_threshold_db", -60.0);
channel_disable_frames = float(GLOBAL_DEF("audio/channel_disable_time", 2.0)) * get_mix_rate();
buffer_size = 1024; //harcoded for now
switch (get_speaker_mode()) {
@@ -760,7 +771,12 @@ void AudioServer::finish() {
}
buses.clear();
+
+ for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
+ AudioDriverManager::get_driver(i)->finish();
+ }
}
+
void AudioServer::update() {
}
@@ -953,6 +969,7 @@ void AudioServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bus_name", "bus_idx", "name"), &AudioServer::set_bus_name);
ClassDB::bind_method(D_METHOD("get_bus_name", "bus_idx"), &AudioServer::get_bus_name);
+ ClassDB::bind_method(D_METHOD("get_bus_index", "bus_name"), &AudioServer::get_bus_index);
ClassDB::bind_method(D_METHOD("set_bus_volume_db", "bus_idx", "volume_db"), &AudioServer::set_bus_volume_db);
ClassDB::bind_method(D_METHOD("get_bus_volume_db", "bus_idx"), &AudioServer::get_bus_volume_db);
@@ -969,11 +986,11 @@ void AudioServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bus_bypass_effects", "bus_idx", "enable"), &AudioServer::set_bus_bypass_effects);
ClassDB::bind_method(D_METHOD("is_bus_bypassing_effects", "bus_idx"), &AudioServer::is_bus_bypassing_effects);
- ClassDB::bind_method(D_METHOD("add_bus_effect", "bus_idx", "effect:AudioEffect"), &AudioServer::add_bus_effect, DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("add_bus_effect", "bus_idx", "effect", "at_pos"), &AudioServer::add_bus_effect, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("remove_bus_effect", "bus_idx", "effect_idx"), &AudioServer::remove_bus_effect);
- ClassDB::bind_method(D_METHOD("get_bus_effect_count", "bus_idx"), &AudioServer::add_bus_effect);
- ClassDB::bind_method(D_METHOD("get_bus_effect:AudioEffect", "bus_idx", "effect_idx"), &AudioServer::get_bus_effect);
+ ClassDB::bind_method(D_METHOD("get_bus_effect_count", "bus_idx"), &AudioServer::get_bus_effect_count);
+ ClassDB::bind_method(D_METHOD("get_bus_effect", "bus_idx", "effect_idx"), &AudioServer::get_bus_effect);
ClassDB::bind_method(D_METHOD("swap_bus_effects", "bus_idx", "effect_idx", "by_effect_idx"), &AudioServer::swap_bus_effects);
ClassDB::bind_method(D_METHOD("set_bus_effect_enabled", "bus_idx", "effect_idx", "enabled"), &AudioServer::set_bus_effect_enabled);
@@ -988,8 +1005,8 @@ void AudioServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_speaker_mode"), &AudioServer::get_speaker_mode);
ClassDB::bind_method(D_METHOD("get_mix_rate"), &AudioServer::get_mix_rate);
- ClassDB::bind_method(D_METHOD("set_bus_layout", "bus_layout:AudioBusLayout"), &AudioServer::set_bus_layout);
- ClassDB::bind_method(D_METHOD("generate_bus_layout:AudioBusLayout"), &AudioServer::generate_bus_layout);
+ ClassDB::bind_method(D_METHOD("set_bus_layout", "bus_layout"), &AudioServer::set_bus_layout);
+ ClassDB::bind_method(D_METHOD("generate_bus_layout"), &AudioServer::generate_bus_layout);
ADD_SIGNAL(MethodInfo("bus_layout_changed"));
}
@@ -1007,6 +1024,7 @@ AudioServer::AudioServer() {
AudioServer::~AudioServer() {
memdelete(audio_data_lock);
+ singleton = NULL;
}
/////////////////////////////////
diff --git a/servers/audio_server.h b/servers/audio_server.h
index eed0a5e4c6..caa07891f7 100644
--- a/servers/audio_server.h
+++ b/servers/audio_server.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -112,7 +113,7 @@ private:
uint64_t mix_count;
uint64_t mix_frames;
- float channel_disable_treshold_db;
+ float channel_disable_threshold_db;
uint32_t channel_disable_frames;
int to_mix;
@@ -214,6 +215,7 @@ public:
void set_bus_name(int p_bus, const String &p_name);
String get_bus_name(int p_bus) const;
+ int get_bus_index(const StringName &p_bus_name) const;
void set_bus_volume_db(int p_bus, float p_volume_db);
float get_bus_volume_db(int p_bus) const;
diff --git a/servers/physics/area_pair_sw.cpp b/servers/physics/area_pair_sw.cpp
index d1040baa65..5c418c473f 100644
--- a/servers/physics/area_pair_sw.cpp
+++ b/servers/physics/area_pair_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -31,12 +32,13 @@
bool AreaPairSW::setup(real_t p_step) {
- if (!area->test_collision_mask(body)) {
- colliding = false;
- return false;
- }
+ bool result = false;
- bool result = CollisionSolverSW::solve_static(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), NULL, this);
+ if (area->is_shape_set_as_disabled(area_shape) || body->is_shape_set_as_disabled(body_shape)) {
+ result = false;
+ } else if (area->test_collision_mask(body) && CollisionSolverSW::solve_static(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), NULL, this)) {
+ result = true;
+ }
if (result != colliding) {
@@ -94,14 +96,13 @@ AreaPairSW::~AreaPairSW() {
bool Area2PairSW::setup(real_t p_step) {
- if (!area_a->test_collision_mask(area_b)) {
- colliding = false;
- return false;
+ bool result = false;
+ if (area_a->is_shape_set_as_disabled(shape_a) || area_b->is_shape_set_as_disabled(shape_b)) {
+ result = false;
+ } else if (area_a->test_collision_mask(area_b) && CollisionSolverSW::solve_static(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), NULL, this)) {
+ result = true;
}
- //bool result = area_a->test_collision_mask(area_b) && CollisionSolverSW::solve(area_a->get_shape(shape_a),area_a->get_transform() * area_a->get_shape_transform(shape_a),Vector2(),area_b->get_shape(shape_b),area_b->get_transform() * area_b->get_shape_transform(shape_b),Vector2(),NULL,this);
- bool result = CollisionSolverSW::solve_static(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), NULL, this);
-
if (result != colliding) {
if (result) {
diff --git a/servers/physics/area_pair_sw.h b/servers/physics/area_pair_sw.h
index 8fc7e7efaa..75df6043ea 100644
--- a/servers/physics/area_pair_sw.h
+++ b/servers/physics/area_pair_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics/area_sw.cpp b/servers/physics/area_sw.cpp
index dfb5d191bc..a310ed3411 100644
--- a/servers/physics/area_sw.cpp
+++ b/servers/physics/area_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics/area_sw.h b/servers/physics/area_sw.h
index 2c0cd8dbcd..3dae1db13f 100644
--- a/servers/physics/area_sw.h
+++ b/servers/physics/area_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -153,6 +154,7 @@ public:
_FORCE_INLINE_ void add_constraint(ConstraintSW *p_constraint) { constraints.insert(p_constraint); }
_FORCE_INLINE_ void remove_constraint(ConstraintSW *p_constraint) { constraints.erase(p_constraint); }
_FORCE_INLINE_ const Set<ConstraintSW *> &get_constraints() const { return constraints; }
+ _FORCE_INLINE_ void clear_constraints() { constraints.clear(); }
void set_monitorable(bool p_monitorable);
_FORCE_INLINE_ bool is_monitorable() const { return monitorable; }
diff --git a/servers/physics/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp
index 555d5f15c5..9ada1fbc50 100644
--- a/servers/physics/body_pair_sw.cpp
+++ b/servers/physics/body_pair_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -213,6 +214,11 @@ bool BodyPairSW::setup(real_t p_step) {
return false;
}
+ if (A->is_shape_set_as_disabled(shape_A) || B->is_shape_set_as_disabled(shape_B)) {
+ collided = false;
+ return false;
+ }
+
offset_B = B->get_transform().get_origin() - A->get_transform().get_origin();
validate_contacts();
@@ -312,12 +318,6 @@ bool BodyPairSW::setup(real_t p_step) {
B->add_contact(global_B, c.normal, depth, shape_B, global_A, shape_A, A->get_instance_id(), A->get_self(), crB);
}
- if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B) || (A->get_mode() <= PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode() <= PhysicsServer::BODY_MODE_KINEMATIC)) {
- c.active = false;
- collided = false;
- continue;
- }
-
c.active = true;
// Precompute normal mass, tangent mass, and bias.
diff --git a/servers/physics/body_pair_sw.h b/servers/physics/body_pair_sw.h
index fa426adafd..cb16849399 100644
--- a/servers/physics/body_pair_sw.h
+++ b/servers/physics/body_pair_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp
index 6b43ec31aa..e065fae2be 100644
--- a/servers/physics/body_sw.cpp
+++ b/servers/physics/body_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -494,7 +495,7 @@ void BodySW::integrate_forces(real_t p_step) {
Vector3 axis;
real_t angle;
- rot.get_axis_and_angle(axis, angle);
+ rot.get_axis_angle(axis, angle);
axis.normalize();
angular_velocity = axis.normalized() * (angle / p_step);
@@ -637,7 +638,7 @@ void BodySW::simulate_motion(const Transform& p_xform,real_t p_step) {
Vector3 axis;
real_t angle;
- rot.get_axis_and_angle(axis,angle);
+ rot.get_axis_angle(axis,angle);
axis.normalize();
angular_velocity=axis.normalized() * (angle/p_step);
linear_velocity = (p_xform.origin - get_transform().origin)/p_step;
@@ -705,7 +706,7 @@ bool BodySW::sleep_test(real_t p_step) {
else if (!can_sleep)
return false;
- if (Math::abs(angular_velocity.length()) < get_space()->get_body_angular_velocity_sleep_treshold() && Math::abs(linear_velocity.length_squared()) < get_space()->get_body_linear_velocity_sleep_treshold() * get_space()->get_body_linear_velocity_sleep_treshold()) {
+ if (Math::abs(angular_velocity.length()) < get_space()->get_body_angular_velocity_sleep_threshold() && Math::abs(linear_velocity.length_squared()) < get_space()->get_body_linear_velocity_sleep_threshold() * get_space()->get_body_linear_velocity_sleep_threshold()) {
still_time += p_step;
@@ -756,7 +757,8 @@ BodySW::BodySW()
contact_count = 0;
gravity_scale = 1.0;
-
+ linear_damp = -1;
+ angular_damp = -1;
area_angular_damp = 0;
area_linear_damp = 0;
diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h
index 4b1af6fca5..512b868570 100644
--- a/servers/physics/body_sw.h
+++ b/servers/physics/body_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -193,6 +194,7 @@ public:
_FORCE_INLINE_ void add_constraint(ConstraintSW *p_constraint, int p_pos) { constraint_map[p_constraint] = p_pos; }
_FORCE_INLINE_ void remove_constraint(ConstraintSW *p_constraint) { constraint_map.erase(p_constraint); }
const Map<ConstraintSW *, int> &get_constraint_map() const { return constraint_map; }
+ _FORCE_INLINE_ void clear_constraint_map() { constraint_map.clear(); }
_FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration = p_omit_force_integration; }
_FORCE_INLINE_ bool get_omit_force_integration() const { return omit_force_integration; }
diff --git a/servers/physics/broad_phase_basic.cpp b/servers/physics/broad_phase_basic.cpp
index ca9bb40842..05a2e1fdf8 100644
--- a/servers/physics/broad_phase_basic.cpp
+++ b/servers/physics/broad_phase_basic.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -104,6 +105,26 @@ int BroadPhaseBasic::get_subindex(ID p_id) const {
return E->get().subindex;
}
+int BroadPhaseBasic::cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) {
+
+ int rc = 0;
+
+ for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) {
+
+ const Rect3 aabb = E->get().aabb;
+ if (aabb.has_point(p_point)) {
+
+ p_results[rc] = E->get().owner;
+ p_result_indices[rc] = E->get().subindex;
+ rc++;
+ if (rc >= p_max_results)
+ break;
+ }
+ }
+
+ return rc;
+}
+
int BroadPhaseBasic::cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) {
int rc = 0;
@@ -148,10 +169,10 @@ void BroadPhaseBasic::set_pair_callback(PairCallback p_pair_callback, void *p_us
pair_userdata = p_userdata;
pair_callback = p_pair_callback;
}
-void BroadPhaseBasic::set_unpair_callback(UnpairCallback p_pair_callback, void *p_userdata) {
+void BroadPhaseBasic::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) {
unpair_userdata = p_userdata;
- unpair_callback = p_pair_callback;
+ unpair_callback = p_unpair_callback;
}
void BroadPhaseBasic::update() {
diff --git a/servers/physics/broad_phase_basic.h b/servers/physics/broad_phase_basic.h
index 2824af6b68..8dabf72f11 100644
--- a/servers/physics/broad_phase_basic.h
+++ b/servers/physics/broad_phase_basic.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -90,6 +91,7 @@ public:
virtual bool is_static(ID p_id) const;
virtual int get_subindex(ID p_id) const;
+ virtual int cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL);
virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL);
virtual int cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL);
diff --git a/servers/physics/broad_phase_octree.cpp b/servers/physics/broad_phase_octree.cpp
index cb64077d9a..e1aaf4e31a 100644
--- a/servers/physics/broad_phase_octree.cpp
+++ b/servers/physics/broad_phase_octree.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -65,6 +66,11 @@ int BroadPhaseOctree::get_subindex(ID p_id) const {
return octree.get_subindex(p_id);
}
+int BroadPhaseOctree::cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) {
+
+ return octree.cull_point(p_point, p_results, p_max_results, p_result_indices);
+}
+
int BroadPhaseOctree::cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) {
return octree.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices);
@@ -72,7 +78,7 @@ int BroadPhaseOctree::cull_segment(const Vector3 &p_from, const Vector3 &p_to, C
int BroadPhaseOctree::cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) {
- return octree.cull_AABB(p_aabb, p_results, p_max_results, p_result_indices);
+ return octree.cull_aabb(p_aabb, p_results, p_max_results, p_result_indices);
}
void *BroadPhaseOctree::_pair_callback(void *self, OctreeElementID p_A, CollisionObjectSW *p_object_A, int subindex_A, OctreeElementID p_B, CollisionObjectSW *p_object_B, int subindex_B) {
diff --git a/servers/physics/broad_phase_octree.h b/servers/physics/broad_phase_octree.h
index f9a8bd17ed..bd3ba6677a 100644
--- a/servers/physics/broad_phase_octree.h
+++ b/servers/physics/broad_phase_octree.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -46,7 +47,7 @@ class BroadPhaseOctree : public BroadPhaseSW {
public:
// 0 is an invalid ID
- virtual ID create(CollisionObjectSW *p_object_, int p_subindex = 0);
+ virtual ID create(CollisionObjectSW *p_object, int p_subindex = 0);
virtual void move(ID p_id, const Rect3 &p_aabb);
virtual void set_static(ID p_id, bool p_static);
virtual void remove(ID p_id);
@@ -55,6 +56,7 @@ public:
virtual bool is_static(ID p_id) const;
virtual int get_subindex(ID p_id) const;
+ virtual int cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL);
virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL);
virtual int cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL);
diff --git a/servers/physics/broad_phase_sw.cpp b/servers/physics/broad_phase_sw.cpp
index f9a19e558b..c3d42d4c2f 100644
--- a/servers/physics/broad_phase_sw.cpp
+++ b/servers/physics/broad_phase_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics/broad_phase_sw.h b/servers/physics/broad_phase_sw.h
index df6ea1cc73..5564cf5077 100644
--- a/servers/physics/broad_phase_sw.h
+++ b/servers/physics/broad_phase_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -56,6 +57,7 @@ public:
virtual bool is_static(ID p_id) const = 0;
virtual int get_subindex(ID p_id) const = 0;
+ virtual int cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0;
virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0;
virtual int cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0;
diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp
index 36704b6eb8..d673088304 100644
--- a/servers/physics/collision_object_sw.cpp
+++ b/servers/physics/collision_object_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -163,7 +164,7 @@ void CollisionObjectSW::_update_shapes_with_motion(const Vector3 &p_motion) {
Rect3 shape_aabb = s.shape->get_aabb();
Transform xform = transform * s.xform;
shape_aabb = xform.xform(shape_aabb);
- shape_aabb = shape_aabb.merge(Rect3(shape_aabb.pos + p_motion, shape_aabb.size)); //use motion
+ shape_aabb = shape_aabb.merge(Rect3(shape_aabb.position + p_motion, shape_aabb.size)); //use motion
s.aabb_cache = shape_aabb;
space->get_broadphase()->move(s.bpid, shape_aabb);
@@ -207,7 +208,7 @@ CollisionObjectSW::CollisionObjectSW(Type p_type) {
type = p_type;
space = NULL;
instance_id = 0;
- layer_mask = 1;
+ collision_layer = 1;
collision_mask = 1;
ray_pickable = true;
}
diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h
index 9a7626d583..44786829af 100644
--- a/servers/physics/collision_object_sw.h
+++ b/servers/physics/collision_object_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -52,7 +53,7 @@ private:
Type type;
RID self;
ObjectID instance_id;
- uint32_t layer_mask;
+ uint32_t collision_layer;
uint32_t collision_mask;
struct Shape {
@@ -63,9 +64,9 @@ private:
Rect3 aabb_cache; //for rayqueries
real_t area_cache;
ShapeSW *shape;
- bool trigger;
+ bool disabled;
- Shape() { trigger = false; }
+ Shape() { disabled = false; }
};
Vector<Shape> shapes;
@@ -97,7 +98,7 @@ protected:
void _set_static(bool p_static);
virtual void _shapes_changed() = 0;
- void _set_space(SpaceSW *space);
+ void _set_space(SpaceSW *p_space);
bool ray_pickable;
@@ -130,17 +131,17 @@ public:
_FORCE_INLINE_ void set_ray_pickable(bool p_enable) { ray_pickable = p_enable; }
_FORCE_INLINE_ bool is_ray_pickable() const { return ray_pickable; }
- _FORCE_INLINE_ void set_shape_as_trigger(int p_idx, bool p_enable) { shapes[p_idx].trigger = p_enable; }
- _FORCE_INLINE_ bool is_shape_set_as_trigger(int p_idx) const { return shapes[p_idx].trigger; }
+ _FORCE_INLINE_ void set_shape_as_disabled(int p_idx, bool p_enable) { shapes[p_idx].disabled = p_enable; }
+ _FORCE_INLINE_ bool is_shape_set_as_disabled(int p_idx) const { return shapes[p_idx].disabled; }
- _FORCE_INLINE_ void set_layer_mask(uint32_t p_mask) { layer_mask = p_mask; }
- _FORCE_INLINE_ uint32_t get_layer_mask() const { return layer_mask; }
+ _FORCE_INLINE_ void set_collision_layer(uint32_t p_layer) { collision_layer = p_layer; }
+ _FORCE_INLINE_ uint32_t get_collision_layer() const { return collision_layer; }
_FORCE_INLINE_ void set_collision_mask(uint32_t p_mask) { collision_mask = p_mask; }
_FORCE_INLINE_ uint32_t get_collision_mask() const { return collision_mask; }
_FORCE_INLINE_ bool test_collision_mask(CollisionObjectSW *p_other) const {
- return layer_mask & p_other->collision_mask || p_other->layer_mask & collision_mask;
+ return collision_layer & p_other->collision_mask || p_other->collision_layer & collision_mask;
}
void remove_shape(ShapeSW *p_shape);
diff --git a/servers/physics/collision_solver_sat.cpp b/servers/physics/collision_solver_sat.cpp
index 003e6b3257..128f78e46e 100644
--- a/servers/physics/collision_solver_sat.cpp
+++ b/servers/physics/collision_solver_sat.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -29,7 +30,7 @@
#include "collision_solver_sat.h"
#include "geometry.h"
-#define _EDGE_IS_VALID_SUPPORT_TRESHOLD 0.02
+#define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.02
struct _CollectorCallback {
diff --git a/servers/physics/collision_solver_sat.h b/servers/physics/collision_solver_sat.h
index 67ffb0b068..d5fae7798a 100644
--- a/servers/physics/collision_solver_sat.h
+++ b/servers/physics/collision_solver_sat.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics/collision_solver_sw.cpp b/servers/physics/collision_solver_sw.cpp
index 0f6e964359..32a42bcaf4 100644
--- a/servers/physics/collision_solver_sw.cpp
+++ b/servers/physics/collision_solver_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -165,7 +166,7 @@ bool CollisionSolverSW::solve_concave(const ShapeSW *p_shape_A, const Transform
smin *= axis_scale;
smax *= axis_scale;
- local_aabb.pos[i] = smin;
+ local_aabb.position[i] = smin;
local_aabb.size[i] = smax - smin;
}
@@ -331,7 +332,7 @@ bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A, const Transform
Rect3 cc_hint_aabb;
if (use_cc_hint) {
cc_hint_aabb = p_concave_hint;
- cc_hint_aabb.pos -= p_transform_B.origin;
+ cc_hint_aabb.position -= p_transform_B.origin;
}
Rect3 local_aabb;
@@ -352,7 +353,7 @@ bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A, const Transform
smin *= axis_scale;
smax *= axis_scale;
- local_aabb.pos[i] = smin;
+ local_aabb.position[i] = smin;
local_aabb.size[i] = smax - smin;
}
diff --git a/servers/physics/collision_solver_sw.h b/servers/physics/collision_solver_sw.h
index b0f18dc0ac..5a4e864eb5 100644
--- a/servers/physics/collision_solver_sw.h
+++ b/servers/physics/collision_solver_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics/constraint_sw.h b/servers/physics/constraint_sw.h
index 2cd0e1a420..d9f153a6a6 100644
--- a/servers/physics/constraint_sw.h
+++ b/servers/physics/constraint_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics/gjk_epa.cpp b/servers/physics/gjk_epa.cpp
index 2c5610ee89..ab2a9b507a 100644
--- a/servers/physics/gjk_epa.cpp
+++ b/servers/physics/gjk_epa.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -33,6 +34,31 @@
/*************** Bullet's GJK-EPA2 IMPLEMENTATION *******************/
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the
+use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+claim that you wrote the original software. If you use this software in a
+product, an acknowledgment in the product documentation would be appreciated
+but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+GJK-EPA collision solver by Nathanael Presson, 2008
+*/
+
// Config
/* GJK */
diff --git a/servers/physics/gjk_epa.h b/servers/physics/gjk_epa.h
index ae5db733b5..316b991477 100644
--- a/servers/physics/gjk_epa.h
+++ b/servers/physics/gjk_epa.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics/joints/cone_twist_joint_sw.cpp b/servers/physics/joints/cone_twist_joint_sw.cpp
index 8cab81de2c..d00eab53d3 100644
--- a/servers/physics/joints/cone_twist_joint_sw.cpp
+++ b/servers/physics/joints/cone_twist_joint_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -29,7 +30,23 @@
/*
Adapted to Godot from the Bullet library.
-See corresponding header file for licensing info.
+*/
+
+/*
+Bullet Continuous Collision Detection and Physics Library
+ConeTwistJointSW is Copyright (c) 2007 Starbreeze Studios
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Written by: Marcus Hennix
*/
#include "cone_twist_joint_sw.h"
@@ -83,6 +100,7 @@ ConeTwistJointSW::ConeTwistJointSW(BodySW *rbA, BodySW *rbB, const Transform &rb
m_biasFactor = 0.3f;
m_relaxationFactor = 1.0f;
+ m_angularOnly = false;
m_solveTwistLimit = false;
m_solveSwingLimit = false;
@@ -92,7 +110,7 @@ ConeTwistJointSW::ConeTwistJointSW(BodySW *rbA, BodySW *rbB, const Transform &rb
m_appliedImpulse = 0;
}
-bool ConeTwistJointSW::setup(real_t p_step) {
+bool ConeTwistJointSW::setup(real_t p_timestep) {
m_appliedImpulse = real_t(0.);
//set bias, sign, clear accumulator
@@ -219,7 +237,7 @@ bool ConeTwistJointSW::setup(real_t p_step) {
return true;
}
-void ConeTwistJointSW::solve(real_t timeStep) {
+void ConeTwistJointSW::solve(real_t p_timestep) {
Vector3 pivotAInW = A->get_transform().xform(m_rbAFrame.origin);
Vector3 pivotBInW = B->get_transform().xform(m_rbBFrame.origin);
@@ -243,7 +261,7 @@ void ConeTwistJointSW::solve(real_t timeStep) {
rel_vel = normal.dot(vel);
//positional error (zeroth order error)
real_t depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal
- real_t impulse = depth * tau / timeStep * jacDiagABInv - rel_vel * jacDiagABInv;
+ real_t impulse = depth * tau / p_timestep * jacDiagABInv - rel_vel * jacDiagABInv;
m_appliedImpulse += impulse;
Vector3 impulse_vector = normal * impulse;
A->apply_impulse(pivotAInW - A->get_transform().origin, impulse_vector);
@@ -258,7 +276,7 @@ void ConeTwistJointSW::solve(real_t timeStep) {
// solve swing limit
if (m_solveSwingLimit) {
- real_t amplitude = ((angVelB - angVelA).dot(m_swingAxis) * m_relaxationFactor * m_relaxationFactor + m_swingCorrection * (real_t(1.) / timeStep) * m_biasFactor);
+ real_t amplitude = ((angVelB - angVelA).dot(m_swingAxis) * m_relaxationFactor * m_relaxationFactor + m_swingCorrection * (real_t(1.) / p_timestep) * m_biasFactor);
real_t impulseMag = amplitude * m_kSwing;
// Clamp the accumulated impulse
@@ -274,7 +292,7 @@ void ConeTwistJointSW::solve(real_t timeStep) {
// solve twist limit
if (m_solveTwistLimit) {
- real_t amplitude = ((angVelB - angVelA).dot(m_twistAxis) * m_relaxationFactor * m_relaxationFactor + m_twistCorrection * (real_t(1.) / timeStep) * m_biasFactor);
+ real_t amplitude = ((angVelB - angVelA).dot(m_twistAxis) * m_relaxationFactor * m_relaxationFactor + m_twistCorrection * (real_t(1.) / p_timestep) * m_biasFactor);
real_t impulseMag = amplitude * m_kTwist;
// Clamp the accumulated impulse
diff --git a/servers/physics/joints/cone_twist_joint_sw.h b/servers/physics/joints/cone_twist_joint_sw.h
index c122c22258..f0e029712c 100644
--- a/servers/physics/joints/cone_twist_joint_sw.h
+++ b/servers/physics/joints/cone_twist_joint_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -103,8 +104,8 @@ public:
public:
virtual PhysicsServer::JointType get_type() const { return PhysicsServer::JOINT_CONE_TWIST; }
- virtual bool setup(real_t p_step);
- virtual void solve(real_t p_step);
+ virtual bool setup(real_t p_timestep);
+ virtual void solve(real_t p_timestep);
ConeTwistJointSW(BodySW *rbA, BodySW *rbB, const Transform &rbAFrame, const Transform &rbBFrame);
diff --git a/servers/physics/joints/generic_6dof_joint_sw.cpp b/servers/physics/joints/generic_6dof_joint_sw.cpp
index 1e07bc73fb..e1cd6ee7e5 100644
--- a/servers/physics/joints/generic_6dof_joint_sw.cpp
+++ b/servers/physics/joints/generic_6dof_joint_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -29,7 +30,28 @@
/*
Adapted to Godot from the Bullet library.
-See corresponding header file for licensing info.
+*/
+
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+2007-09-09
+Generic6DOFJointSW Refactored by Francisco Le?n
+email: projectileman@yahoo.com
+http://gimpact.sf.net
*/
#include "generic_6dof_joint_sw.h"
@@ -276,7 +298,7 @@ bool Generic6DOFJointSW::testAngularLimitMotor(int axis_index) {
return m_angularLimits[axis_index].needApplyTorques();
}
-bool Generic6DOFJointSW::setup(real_t p_step) {
+bool Generic6DOFJointSW::setup(real_t p_timestep) {
// Clear accumulated impulses for the next simulation step
m_linearLimits.m_accumulatedImpulse = Vector3(real_t(0.), real_t(0.), real_t(0.));
@@ -325,8 +347,8 @@ bool Generic6DOFJointSW::setup(real_t p_step) {
return true;
}
-void Generic6DOFJointSW::solve(real_t timeStep) {
- m_timeStep = timeStep;
+void Generic6DOFJointSW::solve(real_t p_timestep) {
+ m_timeStep = p_timestep;
//calculateTransforms();
diff --git a/servers/physics/joints/generic_6dof_joint_sw.h b/servers/physics/joints/generic_6dof_joint_sw.h
index bd9a1e5f0e..587a5850df 100644
--- a/servers/physics/joints/generic_6dof_joint_sw.h
+++ b/servers/physics/joints/generic_6dof_joint_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -263,8 +264,8 @@ public:
virtual PhysicsServer::JointType get_type() const { return PhysicsServer::JOINT_6DOF; }
- virtual bool setup(real_t p_step);
- virtual void solve(real_t p_step);
+ virtual bool setup(real_t p_timestep);
+ virtual void solve(real_t p_timestep);
//! Calcs global transform of the offsets
/*!
diff --git a/servers/physics/joints/hinge_joint_sw.cpp b/servers/physics/joints/hinge_joint_sw.cpp
index eaa57af873..3938427cea 100644
--- a/servers/physics/joints/hinge_joint_sw.cpp
+++ b/servers/physics/joints/hinge_joint_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -29,7 +30,21 @@
/*
Adapted to Godot from the Bullet library.
-See corresponding header file for licensing info.
+*/
+
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
*/
#include "hinge_joint_sw.h"
diff --git a/servers/physics/joints/hinge_joint_sw.h b/servers/physics/joints/hinge_joint_sw.h
index 013d9afdbf..5ebf0cb165 100644
--- a/servers/physics/joints/hinge_joint_sw.h
+++ b/servers/physics/joints/hinge_joint_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics/joints/jacobian_entry_sw.h b/servers/physics/joints/jacobian_entry_sw.h
index b0b31ed797..537a9a8f3d 100644
--- a/servers/physics/joints/jacobian_entry_sw.h
+++ b/servers/physics/joints/jacobian_entry_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics/joints/pin_joint_sw.cpp b/servers/physics/joints/pin_joint_sw.cpp
index e01514f4b6..0792ffeecd 100644
--- a/servers/physics/joints/pin_joint_sw.cpp
+++ b/servers/physics/joints/pin_joint_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -29,7 +30,21 @@
/*
Adapted to Godot from the Bullet library.
-See corresponding header file for licensing info.
+*/
+
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
*/
#include "pin_joint_sw.h"
diff --git a/servers/physics/joints/pin_joint_sw.h b/servers/physics/joints/pin_joint_sw.h
index 9500d4b46d..1d580b6c21 100644
--- a/servers/physics/joints/pin_joint_sw.h
+++ b/servers/physics/joints/pin_joint_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -82,11 +83,11 @@ public:
void set_param(PhysicsServer::PinJointParam p_param, real_t p_value);
real_t get_param(PhysicsServer::PinJointParam p_param) const;
- void set_pos_A(const Vector3 &p_pos) { m_pivotInA = p_pos; }
- void set_pos_B(const Vector3 &p_pos) { m_pivotInB = p_pos; }
+ void set_pos_a(const Vector3 &p_pos) { m_pivotInA = p_pos; }
+ void set_pos_b(const Vector3 &p_pos) { m_pivotInB = p_pos; }
- Vector3 get_pos_A() { return m_pivotInB; }
- Vector3 get_pos_B() { return m_pivotInA; }
+ Vector3 get_pos_a() { return m_pivotInB; }
+ Vector3 get_pos_b() { return m_pivotInA; }
PinJointSW(BodySW *p_body_a, const Vector3 &p_pos_a, BodySW *p_body_b, const Vector3 &p_pos_b);
~PinJointSW();
diff --git a/servers/physics/joints/slider_joint_sw.cpp b/servers/physics/joints/slider_joint_sw.cpp
index b8a6c1ecaf..947f46e960 100644
--- a/servers/physics/joints/slider_joint_sw.cpp
+++ b/servers/physics/joints/slider_joint_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -29,7 +30,27 @@
/*
Adapted to Godot from the Bullet library.
-See corresponding header file for licensing info.
+*/
+
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+Added by Roman Ponomarev (rponom@gmail.com)
+April 04, 2008
+
*/
#include "slider_joint_sw.h"
diff --git a/servers/physics/joints/slider_joint_sw.h b/servers/physics/joints/slider_joint_sw.h
index faf36bfe9e..7818ee2a5c 100644
--- a/servers/physics/joints/slider_joint_sw.h
+++ b/servers/physics/joints/slider_joint_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics/joints_sw.h b/servers/physics/joints_sw.h
index 0f637faf79..b25939d523 100644
--- a/servers/physics/joints_sw.h
+++ b/servers/physics/joints_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index 6fc983a739..151fc44476 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -221,12 +222,24 @@ void PhysicsServerSW::area_set_space(RID p_area, RID p_space) {
AreaSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
+
SpaceSW *space = NULL;
if (p_space.is_valid()) {
space = space_owner.get(p_space);
ERR_FAIL_COND(!space);
}
+ if (area->get_space() == space)
+ return; //pointless
+
+ for (Set<ConstraintSW *>::Element *E = area->get_constraints().front(); E; E = E->next()) {
+ RID self = E->get()->get_self();
+ if (!self.is_valid())
+ continue;
+ free(self);
+ }
+ area->clear_constraints();
+
area->set_space(space);
};
@@ -329,7 +342,15 @@ void PhysicsServerSW::area_clear_shapes(RID p_area) {
area->remove_shape(0);
}
-void PhysicsServerSW::area_attach_object_instance_ID(RID p_area, ObjectID p_ID) {
+void PhysicsServerSW::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) {
+
+ AreaSW *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+ ERR_FAIL_INDEX(p_shape_idx, area->get_shape_count());
+ area->set_shape_as_disabled(p_shape_idx, p_disabled);
+}
+
+void PhysicsServerSW::area_attach_object_instance_id(RID p_area, ObjectID p_ID) {
if (space_owner.owns(p_area)) {
SpaceSW *space = space_owner.get(p_area);
@@ -339,7 +360,7 @@ void PhysicsServerSW::area_attach_object_instance_ID(RID p_area, ObjectID p_ID)
ERR_FAIL_COND(!area);
area->set_instance_id(p_ID);
}
-ObjectID PhysicsServerSW::area_get_object_instance_ID(RID p_area) const {
+ObjectID PhysicsServerSW::area_get_object_instance_id(RID p_area) const {
if (space_owner.owns(p_area)) {
SpaceSW *space = space_owner.get(p_area);
@@ -388,12 +409,12 @@ Transform PhysicsServerSW::area_get_transform(RID p_area) const {
return area->get_transform();
};
-void PhysicsServerSW::area_set_layer_mask(RID p_area, uint32_t p_mask) {
+void PhysicsServerSW::area_set_collision_layer(RID p_area, uint32_t p_layer) {
AreaSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
- area->set_layer_mask(p_mask);
+ area->set_collision_layer(p_layer);
}
void PhysicsServerSW::area_set_collision_mask(RID p_area, uint32_t p_mask) {
@@ -417,7 +438,7 @@ void PhysicsServerSW::area_set_monitor_callback(RID p_area, Object *p_receiver,
AreaSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
- area->set_monitor_callback(p_receiver ? p_receiver->get_instance_ID() : 0, p_method);
+ area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : 0, p_method);
}
void PhysicsServerSW::area_set_ray_pickable(RID p_area, bool p_enable) {
@@ -441,7 +462,7 @@ void PhysicsServerSW::area_set_area_monitor_callback(RID p_area, Object *p_recei
AreaSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
- area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_ID() : 0, p_method);
+ area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : 0, p_method);
}
/* BODY API */
@@ -462,15 +483,23 @@ void PhysicsServerSW::body_set_space(RID p_body, RID p_space) {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
- SpaceSW *space = NULL;
+ SpaceSW *space = NULL;
if (p_space.is_valid()) {
space = space_owner.get(p_space);
ERR_FAIL_COND(!space);
}
if (body->get_space() == space)
- return; //pointles
+ return; //pointless
+
+ for (Map<ConstraintSW *, int>::Element *E = body->get_constraint_map().front(); E; E = E->next()) {
+ RID self = E->key()->get_self();
+ if (!self.is_valid())
+ continue;
+ free(self);
+ }
+ body->clear_constraint_map();
body->set_space(space);
};
@@ -550,21 +579,12 @@ RID PhysicsServerSW::body_get_shape(RID p_body, int p_shape_idx) const {
return shape->get_self();
}
-void PhysicsServerSW::body_set_shape_as_trigger(RID p_body, int p_shape_idx, bool p_enable) {
+void PhysicsServerSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
- body->set_shape_as_trigger(p_shape_idx, p_enable);
-}
-
-bool PhysicsServerSW::body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) const {
-
- BodySW *body = body_owner.get(p_body);
- ERR_FAIL_COND_V(!body, false);
- ERR_FAIL_INDEX_V(p_shape_idx, body->get_shape_count(), false);
-
- return body->is_shape_set_as_trigger(p_shape_idx);
+ body->set_shape_as_disabled(p_shape_idx, p_disabled);
}
Transform PhysicsServerSW::body_get_shape_transform(RID p_body, int p_shape_idx) const {
@@ -608,21 +628,21 @@ bool PhysicsServerSW::body_is_continuous_collision_detection_enabled(RID p_body)
return body->is_continuous_collision_detection_enabled();
}
-void PhysicsServerSW::body_set_layer_mask(RID p_body, uint32_t p_mask) {
+void PhysicsServerSW::body_set_collision_layer(RID p_body, uint32_t p_layer) {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
- body->set_layer_mask(p_mask);
+ body->set_collision_layer(p_layer);
body->wakeup();
}
-uint32_t PhysicsServerSW::body_get_layer_mask(RID p_body, uint32_t p_mask) const {
+uint32_t PhysicsServerSW::body_get_collision_layer(RID p_body) const {
const BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, 0);
- return body->get_layer_mask();
+ return body->get_collision_layer();
}
void PhysicsServerSW::body_set_collision_mask(RID p_body, uint32_t p_mask) {
@@ -634,7 +654,7 @@ void PhysicsServerSW::body_set_collision_mask(RID p_body, uint32_t p_mask) {
body->wakeup();
}
-uint32_t PhysicsServerSW::body_get_collision_mask(RID p_body, uint32_t p_mask) const {
+uint32_t PhysicsServerSW::body_get_collision_mask(RID p_body) const {
const BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -642,7 +662,7 @@ uint32_t PhysicsServerSW::body_get_collision_mask(RID p_body, uint32_t p_mask) c
return body->get_collision_mask();
}
-void PhysicsServerSW::body_attach_object_instance_ID(RID p_body, uint32_t p_ID) {
+void PhysicsServerSW::body_attach_object_instance_id(RID p_body, uint32_t p_ID) {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
@@ -650,7 +670,7 @@ void PhysicsServerSW::body_attach_object_instance_ID(RID p_body, uint32_t p_ID)
body->set_instance_id(p_ID);
};
-uint32_t PhysicsServerSW::body_get_object_instance_ID(RID p_body) const {
+uint32_t PhysicsServerSW::body_get_object_instance_id(RID p_body) const {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -664,7 +684,7 @@ void PhysicsServerSW::body_set_user_flags(RID p_body, uint32_t p_flags) {
ERR_FAIL_COND(!body);
};
-uint32_t PhysicsServerSW::body_get_user_flags(RID p_body, uint32_t p_flags) const {
+uint32_t PhysicsServerSW::body_get_user_flags(RID p_body) const {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -811,13 +831,13 @@ void PhysicsServerSW::body_get_collision_exceptions(RID p_body, List<RID> *p_exc
}
};
-void PhysicsServerSW::body_set_contacts_reported_depth_treshold(RID p_body, real_t p_treshold) {
+void PhysicsServerSW::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
};
-real_t PhysicsServerSW::body_get_contacts_reported_depth_treshold(RID p_body) const {
+real_t PhysicsServerSW::body_get_contacts_reported_depth_threshold(RID p_body) const {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -857,7 +877,7 @@ void PhysicsServerSW::body_set_force_integration_callback(RID p_body, Object *p_
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
- body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_ID() : ObjectID(0), p_method, p_udata);
+ body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(0), p_method, p_udata);
}
void PhysicsServerSW::body_set_ray_pickable(RID p_body, bool p_enable) {
@@ -874,6 +894,16 @@ bool PhysicsServerSW::body_is_ray_pickable(RID p_body) const {
return body->is_ray_pickable();
}
+bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, float p_margin, MotionResult *r_result) {
+
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, false);
+ ERR_FAIL_COND_V(!body->get_space(), false);
+ ERR_FAIL_COND_V(body->get_space()->is_locked(), false);
+
+ return body->get_space()->test_body_motion(body, p_from, p_motion, p_margin, r_result);
+}
+
/* JOINT API */
RID PhysicsServerSW::joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) {
@@ -914,38 +944,38 @@ real_t PhysicsServerSW::pin_joint_get_param(RID p_joint, PinJointParam p_param)
return pin_joint->get_param(p_param);
}
-void PhysicsServerSW::pin_joint_set_local_A(RID p_joint, const Vector3 &p_A) {
+void PhysicsServerSW::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) {
JointSW *joint = joint_owner.get(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_PIN);
PinJointSW *pin_joint = static_cast<PinJointSW *>(joint);
- pin_joint->set_pos_A(p_A);
+ pin_joint->set_pos_a(p_A);
}
-Vector3 PhysicsServerSW::pin_joint_get_local_A(RID p_joint) const {
+Vector3 PhysicsServerSW::pin_joint_get_local_a(RID p_joint) const {
JointSW *joint = joint_owner.get(p_joint);
ERR_FAIL_COND_V(!joint, Vector3());
ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3());
PinJointSW *pin_joint = static_cast<PinJointSW *>(joint);
- return pin_joint->get_pos_A();
+ return pin_joint->get_pos_a();
}
-void PhysicsServerSW::pin_joint_set_local_B(RID p_joint, const Vector3 &p_B) {
+void PhysicsServerSW::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) {
JointSW *joint = joint_owner.get(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_PIN);
PinJointSW *pin_joint = static_cast<PinJointSW *>(joint);
- pin_joint->set_pos_B(p_B);
+ pin_joint->set_pos_b(p_B);
}
-Vector3 PhysicsServerSW::pin_joint_get_local_B(RID p_joint) const {
+Vector3 PhysicsServerSW::pin_joint_get_local_b(RID p_joint) const {
JointSW *joint = joint_owner.get(p_joint);
ERR_FAIL_COND_V(!joint, Vector3());
ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3());
PinJointSW *pin_joint = static_cast<PinJointSW *>(joint);
- return pin_joint->get_pos_B();
+ return pin_joint->get_pos_b();
}
RID PhysicsServerSW::joint_create_hinge(RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) {
@@ -1319,12 +1349,6 @@ void PhysicsServerSW::free(RID p_rid) {
body->remove_shape(0);
}
- while (body->get_constraint_map().size()) {
- RID self = body->get_constraint_map().front()->key()->get_self();
- ERR_FAIL_COND(!self.is_valid());
- free(self);
- }
-
body_owner.free(p_rid);
memdelete(body);
@@ -1529,8 +1553,9 @@ void PhysicsServerSW::_shape_col_cbk(const Vector3 &p_point_A, const Vector3 &p_
}
}
+PhysicsServerSW *PhysicsServerSW::singleton = NULL;
PhysicsServerSW::PhysicsServerSW() {
-
+ singleton = this;
BroadPhaseSW::create_func = BroadPhaseOctree::_create;
island_count = 0;
active_objects = 0;
diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h
index cb5a339ee8..818922a989 100644
--- a/servers/physics/physics_server_sw.h
+++ b/servers/physics/physics_server_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -62,6 +63,8 @@ class PhysicsServerSW : public PhysicsServer {
//void _clear_query(QuerySW *p_query);
public:
+ static PhysicsServerSW *singleton;
+
struct CollCbkData {
int max;
@@ -116,20 +119,22 @@ public:
virtual void area_remove_shape(RID p_area, int p_shape_idx);
virtual void area_clear_shapes(RID p_area);
- virtual void area_attach_object_instance_ID(RID p_area, ObjectID p_ID);
- virtual ObjectID area_get_object_instance_ID(RID p_area) const;
+ virtual void area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled);
+
+ virtual void area_attach_object_instance_id(RID p_area, ObjectID p_ID);
+ virtual ObjectID area_get_object_instance_id(RID p_area) const;
virtual void area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value);
virtual void area_set_transform(RID p_area, const Transform &p_transform);
- virtual Variant area_get_param(RID p_parea, AreaParameter p_param) const;
+ virtual Variant area_get_param(RID p_area, AreaParameter p_param) const;
virtual Transform area_get_transform(RID p_area) const;
virtual void area_set_ray_pickable(RID p_area, bool p_enable);
virtual bool area_is_ray_pickable(RID p_area) const;
virtual void area_set_collision_mask(RID p_area, uint32_t p_mask);
- virtual void area_set_layer_mask(RID p_area, uint32_t p_mask);
+ virtual void area_set_collision_layer(RID p_area, uint32_t p_layer);
virtual void area_set_monitorable(RID p_area, bool p_monitorable);
@@ -155,26 +160,25 @@ public:
virtual RID body_get_shape(RID p_body, int p_shape_idx) const;
virtual Transform body_get_shape_transform(RID p_body, int p_shape_idx) const;
- virtual void body_set_shape_as_trigger(RID p_body, int p_shape_idx, bool p_enable);
- virtual bool body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) const;
+ virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled);
virtual void body_remove_shape(RID p_body, int p_shape_idx);
virtual void body_clear_shapes(RID p_body);
- virtual void body_attach_object_instance_ID(RID p_body, uint32_t p_ID);
- virtual uint32_t body_get_object_instance_ID(RID p_body) const;
+ virtual void body_attach_object_instance_id(RID p_body, uint32_t p_ID);
+ virtual uint32_t body_get_object_instance_id(RID p_body) const;
virtual void body_set_enable_continuous_collision_detection(RID p_body, bool p_enable);
virtual bool body_is_continuous_collision_detection_enabled(RID p_body) const;
- virtual void body_set_layer_mask(RID p_body, uint32_t p_mask);
- virtual uint32_t body_get_layer_mask(RID p_body, uint32_t p_mask) const;
+ virtual void body_set_collision_layer(RID p_body, uint32_t p_layer);
+ virtual uint32_t body_get_collision_layer(RID p_body) const;
virtual void body_set_collision_mask(RID p_body, uint32_t p_mask);
- virtual uint32_t body_get_collision_mask(RID p_body, uint32_t p_mask) const;
+ virtual uint32_t body_get_collision_mask(RID p_body) const;
virtual void body_set_user_flags(RID p_body, uint32_t p_flags);
- virtual uint32_t body_get_user_flags(RID p_body, uint32_t p_flags) const;
+ virtual uint32_t body_get_user_flags(RID p_body) const;
virtual void body_set_param(RID p_body, BodyParameter p_param, real_t p_value);
virtual real_t body_get_param(RID p_body, BodyParameter p_param) const;
@@ -199,8 +203,8 @@ public:
virtual void body_remove_collision_exception(RID p_body, RID p_body_b);
virtual void body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions);
- virtual void body_set_contacts_reported_depth_treshold(RID p_body, real_t p_treshold);
- virtual real_t body_get_contacts_reported_depth_treshold(RID p_body) const;
+ virtual void body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold);
+ virtual real_t body_get_contacts_reported_depth_threshold(RID p_body) const;
virtual void body_set_omit_force_integration(RID p_body, bool p_omit);
virtual bool body_is_omitting_force_integration(RID p_body) const;
@@ -213,6 +217,8 @@ public:
virtual void body_set_ray_pickable(RID p_body, bool p_enable);
virtual bool body_is_ray_pickable(RID p_body) const;
+ virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, float p_margin = 0.001, MotionResult *r_result = NULL);
+
/* JOINT API */
virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B);
@@ -220,11 +226,11 @@ public:
virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value);
virtual real_t pin_joint_get_param(RID p_joint, PinJointParam p_param) const;
- virtual void pin_joint_set_local_A(RID p_joint, const Vector3 &p_A);
- virtual Vector3 pin_joint_get_local_A(RID p_joint) const;
+ virtual void pin_joint_set_local_a(RID p_joint, const Vector3 &p_A);
+ virtual Vector3 pin_joint_get_local_a(RID p_joint) const;
- virtual void pin_joint_set_local_B(RID p_joint, const Vector3 &p_B);
- virtual Vector3 pin_joint_get_local_B(RID p_joint) const;
+ virtual void pin_joint_set_local_b(RID p_joint, const Vector3 &p_B);
+ virtual Vector3 pin_joint_get_local_b(RID p_joint) const;
virtual RID joint_create_hinge(RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B);
virtual RID joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B);
diff --git a/servers/physics/shape_sw.cpp b/servers/physics/shape_sw.cpp
index 4ce716c70a..b4004c8c94 100644
--- a/servers/physics/shape_sw.cpp
+++ b/servers/physics/shape_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -31,8 +32,8 @@
#include "quick_hull.h"
#include "sort.h"
#define _POINT_SNAP 0.001953125
-#define _EDGE_IS_VALID_SUPPORT_TRESHOLD 0.0002
-#define _FACE_IS_VALID_SUPPORT_TRESHOLD 0.9998
+#define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.0002
+#define _FACE_IS_VALID_SUPPORT_THRESHOLD 0.9998
void ShapeSW::configure(const Rect3 &p_aabb) {
aabb = p_aabb;
@@ -116,6 +117,20 @@ bool PlaneShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en
return inters;
}
+bool PlaneShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ return plane.distance_to(p_point) < 0;
+}
+
+Vector3 PlaneShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ if (plane.is_point_over(p_point)) {
+ return plane.project(p_point);
+ } else {
+ return p_point;
+ }
+}
+
Vector3 PlaneShapeSW::get_moment_of_inertia(real_t p_mass) const {
return Vector3(); //wtf
@@ -164,7 +179,7 @@ Vector3 RayShapeSW::get_support(const Vector3 &p_normal) const {
void RayShapeSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const {
- if (Math::abs(p_normal.z) < _EDGE_IS_VALID_SUPPORT_TRESHOLD) {
+ if (Math::abs(p_normal.z) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) {
r_amount = 2;
r_supports[0] = Vector3(0, 0, 0);
@@ -183,6 +198,21 @@ bool RayShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end,
return false; //simply not possible
}
+bool RayShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ return false; //simply not possible
+}
+
+Vector3 RayShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ Vector3 s[2] = {
+ Vector3(0, 0, 0),
+ Vector3(0, 0, length)
+ };
+
+ return Geometry::get_closest_point_to_segment(p_point, s);
+}
+
Vector3 RayShapeSW::get_moment_of_inertia(real_t p_mass) const {
return Vector3();
@@ -244,6 +274,20 @@ bool SphereShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_e
return Geometry::segment_intersects_sphere(p_begin, p_end, Vector3(), radius, &r_result, &r_normal);
}
+bool SphereShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ return p_point.length() < radius;
+}
+
+Vector3 SphereShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ Vector3 p = p_point;
+ float l = p.length();
+ if (l < radius)
+ return p_point;
+ return (p / l) * radius;
+}
+
Vector3 SphereShapeSW::get_moment_of_inertia(real_t p_mass) const {
real_t s = 0.4 * p_mass * radius * radius;
@@ -305,7 +349,7 @@ void BoxShapeSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_sup
Vector3 axis;
axis[i] = 1.0;
real_t dot = p_normal.dot(axis);
- if (Math::abs(dot) > _FACE_IS_VALID_SUPPORT_TRESHOLD) {
+ if (Math::abs(dot) > _FACE_IS_VALID_SUPPORT_THRESHOLD) {
//Vector3 axis_b;
@@ -349,7 +393,7 @@ void BoxShapeSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_sup
Vector3 axis;
axis[i] = 1.0;
- if (Math::abs(p_normal.dot(axis)) < _EDGE_IS_VALID_SUPPORT_TRESHOLD) {
+ if (Math::abs(p_normal.dot(axis)) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) {
r_amount = 2;
@@ -389,6 +433,62 @@ bool BoxShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end,
return aabb.intersects_segment(p_begin, p_end, &r_result, &r_normal);
}
+bool BoxShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ return (Math::abs(p_point.x) < half_extents.x && Math::abs(p_point.y) < half_extents.y && Math::abs(p_point.z) < half_extents.z);
+}
+
+Vector3 BoxShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ int outside = 0;
+ Vector3 min_point;
+
+ for (int i = 0; i < 3; i++) {
+
+ if (Math::abs(p_point[i]) > half_extents[i]) {
+ outside++;
+ if (outside == 1) {
+ //use plane if only one side matches
+ Vector3 n;
+ n[i] = SGN(p_point[i]);
+
+ Plane p(n, half_extents[i]);
+ min_point = p.project(p_point);
+ }
+ }
+ }
+
+ if (!outside)
+ return p_point; //it's inside, don't do anything else
+
+ if (outside == 1) //if only above one plane, this plane clearly wins
+ return min_point;
+
+ //check segments
+ float min_distance = 1e20;
+ Vector3 closest_vertex = half_extents * p_point.sign();
+ Vector3 s[2] = {
+ closest_vertex,
+ closest_vertex
+ };
+
+ for (int i = 0; i < 3; i++) {
+
+ s[1] = closest_vertex;
+ s[1][i] = -s[1][i]; //edge
+
+ Vector3 closest_edge = Geometry::get_closest_point_to_segment(p_point, s);
+
+ float d = p_point.distance_to(closest_edge);
+ if (d < min_distance) {
+ min_point = closest_edge;
+ min_distance = d;
+ }
+ }
+
+ return min_point;
+}
+
Vector3 BoxShapeSW::get_moment_of_inertia(real_t p_mass) const {
real_t lx = half_extents.x;
@@ -459,7 +559,7 @@ void CapsuleShapeSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r
real_t d = n.z;
- if (Math::abs(d) < _EDGE_IS_VALID_SUPPORT_TRESHOLD) {
+ if (Math::abs(d) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) {
// make it flat
n.z = 0.0;
@@ -541,6 +641,32 @@ bool CapsuleShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_
return collision;
}
+bool CapsuleShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ if (Math::abs(p_point.z) < height * 0.5) {
+ return Vector3(p_point.x, p_point.y, 0).length() < radius;
+ } else {
+ Vector3 p = p_point;
+ p.z = Math::abs(p.z) - height * 0.5;
+ return p.length() < radius;
+ }
+}
+
+Vector3 CapsuleShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ Vector3 s[2] = {
+ Vector3(0, 0, -height * 0.5),
+ Vector3(0, 0, height * 0.5),
+ };
+
+ Vector3 p = Geometry::get_closest_point_to_segment(p_point, s);
+
+ if (p.distance_to(p_point) < radius)
+ return p_point;
+
+ return p + (p_point - p).normalized() * radius;
+}
+
Vector3 CapsuleShapeSW::get_moment_of_inertia(real_t p_mass) const {
// use crappy AABB approximation
@@ -654,7 +780,7 @@ void ConvexPolygonShapeSW::get_supports(const Vector3 &p_normal, int p_max, Vect
for (int i = 0; i < fc; i++) {
- if (faces[i].plane.normal.dot(p_normal) > _FACE_IS_VALID_SUPPORT_TRESHOLD) {
+ if (faces[i].plane.normal.dot(p_normal) > _FACE_IS_VALID_SUPPORT_THRESHOLD) {
int ic = faces[i].indices.size();
const int *ind = faces[i].indices.ptr();
@@ -684,7 +810,7 @@ void ConvexPolygonShapeSW::get_supports(const Vector3 &p_normal, int p_max, Vect
real_t dot = (vertices[edges[i].a] - vertices[edges[i].b]).normalized().dot(p_normal);
dot = ABS(dot);
- if (dot < _EDGE_IS_VALID_SUPPORT_TRESHOLD && (edges[i].a == vtx || edges[i].b == vtx)) {
+ if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD && (edges[i].a == vtx || edges[i].b == vtx)) {
r_amount = 2;
r_supports[0] = vertices[edges[i].a];
@@ -737,6 +863,81 @@ bool ConvexPolygonShapeSW::intersect_segment(const Vector3 &p_begin, const Vecto
return col;
}
+bool ConvexPolygonShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ const Geometry::MeshData::Face *faces = mesh.faces.ptr();
+ int fc = mesh.faces.size();
+
+ for (int i = 0; i < fc; i++) {
+
+ if (faces[i].plane.distance_to(p_point) >= 0)
+ return false;
+ }
+
+ return true;
+}
+
+Vector3 ConvexPolygonShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ const Geometry::MeshData::Face *faces = mesh.faces.ptr();
+ int fc = mesh.faces.size();
+ const Vector3 *vertices = mesh.vertices.ptr();
+
+ bool all_inside = true;
+ for (int i = 0; i < fc; i++) {
+
+ if (!faces[i].plane.is_point_over(p_point))
+ continue;
+
+ all_inside = false;
+ bool is_inside = true;
+ int ic = faces[i].indices.size();
+ const int *indices = faces[i].indices.ptr();
+
+ for (int j = 0; j < ic; j++) {
+
+ Vector3 a = vertices[indices[j]];
+ Vector3 b = vertices[indices[(j + 1) % ic]];
+ Vector3 n = (a - b).cross(faces[i].plane.normal).normalized();
+ if (Plane(a, n).is_point_over(p_point)) {
+ is_inside = false;
+ break;
+ }
+ }
+
+ if (is_inside) {
+ return faces[i].plane.project(p_point);
+ }
+ }
+
+ if (all_inside) {
+ return p_point;
+ }
+
+ float min_distance = 1e20;
+ Vector3 min_point;
+
+ //check edges
+ const Geometry::MeshData::Edge *edges = mesh.edges.ptr();
+ int ec = mesh.edges.size();
+ for (int i = 0; i < ec; i++) {
+
+ Vector3 s[2] = {
+ vertices[edges[i].a],
+ vertices[edges[i].b]
+ };
+
+ Vector3 closest = Geometry::get_closest_point_to_segment(p_point, s);
+ float d = closest.distance_to(p_point);
+ if (d < min_distance) {
+ min_distance = d;
+ min_point = closest;
+ }
+ }
+
+ return min_point;
+}
+
Vector3 ConvexPolygonShapeSW::get_moment_of_inertia(real_t p_mass) const {
// use crappy AABB approximation
@@ -756,7 +957,7 @@ void ConvexPolygonShapeSW::_setup(const Vector<Vector3> &p_vertices) {
for (int i = 0; i < mesh.vertices.size(); i++) {
if (i == 0)
- _aabb.pos = mesh.vertices[i];
+ _aabb.position = mesh.vertices[i];
else
_aabb.expand_to(mesh.vertices[i]);
}
@@ -817,7 +1018,7 @@ void FaceShapeSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_su
Vector3 n = p_normal;
/** TEST FACE AS SUPPORT **/
- if (normal.dot(n) > _FACE_IS_VALID_SUPPORT_TRESHOLD) {
+ if (normal.dot(n) > _FACE_IS_VALID_SUPPORT_THRESHOLD) {
r_amount = 3;
for (int i = 0; i < 3; i++) {
@@ -853,7 +1054,7 @@ void FaceShapeSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_su
// check if edge is valid as a support
real_t dot = (vertex[i] - vertex[nx]).normalized().dot(n);
dot = ABS(dot);
- if (dot < _EDGE_IS_VALID_SUPPORT_TRESHOLD) {
+ if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD) {
r_amount = 2;
r_supports[0] = vertex[i];
@@ -879,6 +1080,16 @@ bool FaceShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end
return c;
}
+bool FaceShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ return false; //face is flat
+}
+
+Vector3 FaceShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ return Face3(vertex[0], vertex[1], vertex[2]).get_closest_point_to(p_point);
+}
+
Vector3 FaceShapeSW::get_moment_of_inertia(real_t p_mass) const {
return Vector3(); // Sorry, but i don't think anyone cares, FaceShape!
@@ -1045,6 +1256,16 @@ bool ConcavePolygonShapeSW::intersect_segment(const Vector3 &p_begin, const Vect
}
}
+bool ConcavePolygonShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ return false; //face is flat
+}
+
+Vector3 ConcavePolygonShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ return Vector3();
+}
+
void ConcavePolygonShapeSW::_cull(int p_idx, _CullParams *p_params) const {
const BVH *bvh = &p_params->bvh[p_idx];
@@ -1387,7 +1608,7 @@ void ConcavePolygonShapeSW::_setup(PoolVector<Vector3> p_faces) {
Face3 face(facesr[i * 3 + 0], facesr[i * 3 + 1], facesr[i * 3 + 2]);
bvh_arrayw[i].aabb = face.get_aabb();
- bvh_arrayw[i].center = bvh_arrayw[i].aabb.pos + bvh_arrayw[i].aabb.size * 0.5;
+ bvh_arrayw[i].center = bvh_arrayw[i].aabb.position + bvh_arrayw[i].aabb.size * 0.5;
bvh_arrayw[i].face_index = i;
facesw[i].indices[0] = i * 3 + 0;
facesw[i].indices[1] = i * 3 + 1;
@@ -1470,6 +1691,15 @@ bool HeightMapShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &
return false;
}
+bool HeightMapShapeSW::intersect_point(const Vector3 &p_point) const {
+ return false;
+}
+
+Vector3 HeightMapShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ return Vector3();
+}
+
void HeightMapShapeSW::cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const {
}
@@ -1503,7 +1733,7 @@ void HeightMapShapeSW::_setup(PoolVector<real_t> p_heights, int p_width, int p_d
Vector3 pos(j * cell_size, h, i * cell_size);
if (i == 0 || j == 0)
- aabb.pos = pos;
+ aabb.position = pos;
else
aabb.expand_to(pos);
}
diff --git a/servers/physics/shape_sw.h b/servers/physics/shape_sw.h
index 442cbc39eb..52623c019d 100644
--- a/servers/physics/shape_sw.h
+++ b/servers/physics/shape_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -86,8 +87,9 @@ public:
virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const = 0;
virtual Vector3 get_support(const Vector3 &p_normal) const;
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const = 0;
-
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const = 0;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const = 0;
+ virtual bool intersect_point(const Vector3 &p_point) const = 0;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const = 0;
virtual void set_data(const Variant &p_data) = 0;
@@ -133,7 +135,8 @@ public:
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; }
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
-
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
virtual void set_data(const Variant &p_data);
@@ -158,6 +161,8 @@ public:
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
@@ -184,6 +189,8 @@ public:
virtual Vector3 get_support(const Vector3 &p_normal) const;
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
@@ -208,6 +215,8 @@ public:
virtual Vector3 get_support(const Vector3 &p_normal) const;
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
@@ -236,6 +245,8 @@ public:
virtual Vector3 get_support(const Vector3 &p_normal) const;
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
@@ -260,6 +271,8 @@ public:
virtual Vector3 get_support(const Vector3 &p_normal) const;
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
@@ -337,6 +350,8 @@ public:
virtual Vector3 get_support(const Vector3 &p_normal) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual void cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const;
@@ -370,8 +385,10 @@ public:
virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const;
virtual Vector3 get_support(const Vector3 &p_normal) const;
- virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual void cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
@@ -396,6 +413,8 @@ struct FaceShapeSW : public ShapeSW {
Vector3 get_support(const Vector3 &p_normal) const;
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
Vector3 get_moment_of_inertia(real_t p_mass) const;
@@ -435,6 +454,8 @@ struct MotionShapeSW : public ShapeSW {
}
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; }
bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { return false; }
+ virtual bool intersect_point(const Vector3 &p_point) const { return false; }
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const { return p_point; }
Vector3 get_moment_of_inertia(real_t p_mass) const { return Vector3(); }
diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp
index 2043f9fed8..094cfa4656 100644
--- a/servers/physics/space_sw.cpp
+++ b/servers/physics/space_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -28,23 +29,67 @@
/*************************************************************************/
#include "space_sw.h"
#include "collision_solver_sw.h"
-#include "global_config.h"
#include "physics_server_sw.h"
+#include "project_settings.h"
-_FORCE_INLINE_ static bool _match_object_type_query(CollisionObjectSW *p_object, uint32_t p_layer_mask, uint32_t p_type_mask) {
+_FORCE_INLINE_ static bool _match_object_type_query(CollisionObjectSW *p_object, uint32_t p_collision_layer, uint32_t p_type_mask) {
+
+ if ((p_object->get_collision_layer() & p_collision_layer) == 0)
+ return false;
if (p_object->get_type() == CollisionObjectSW::TYPE_AREA)
return p_type_mask & PhysicsDirectSpaceState::TYPE_MASK_AREA;
- if ((p_object->get_layer_mask() & p_layer_mask) == 0)
- return false;
-
BodySW *body = static_cast<BodySW *>(p_object);
return (1 << body->get_mode()) & p_type_mask;
}
-bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask, bool p_pick_ray) {
+int PhysicsDirectSpaceStateSW::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
+
+ ERR_FAIL_COND_V(space->locked, false);
+ int amount = space->broadphase->cull_point(p_point, space->intersection_query_results, SpaceSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
+ int cc = 0;
+
+ //Transform ai = p_xform.affine_inverse();
+
+ for (int i = 0; i < amount; i++) {
+
+ if (cc >= p_result_max)
+ break;
+
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
+ continue;
+
+ //area can't be picked by ray (default)
+
+ if (p_exclude.has(space->intersection_query_results[i]->get_self()))
+ continue;
+
+ const CollisionObjectSW *col_obj = space->intersection_query_results[i];
+ int shape_idx = space->intersection_query_subindex_results[i];
+
+ Transform inv_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
+ inv_xform.affine_invert();
+
+ if (!col_obj->get_shape(shape_idx)->intersect_point(inv_xform.xform(p_point)))
+ continue;
+
+ r_results[cc].collider_id = col_obj->get_instance_id();
+ if (r_results[cc].collider_id != 0)
+ r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id);
+ else
+ r_results[cc].collider = NULL;
+ r_results[cc].rid = col_obj->get_self();
+ r_results[cc].shape = shape_idx;
+
+ cc++;
+ }
+
+ return cc;
+}
+
+bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask, bool p_pick_ray) {
ERR_FAIL_COND_V(space->locked, false);
@@ -66,7 +111,7 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vecto
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
if (p_pick_ray && !(static_cast<CollisionObjectSW *>(space->intersection_query_results[i])->is_ray_pickable()))
@@ -122,7 +167,7 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vecto
return true;
}
-int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
if (p_result_max <= 0)
return 0;
@@ -143,7 +188,7 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transfo
if (cc >= p_result_max)
break;
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
//area can't be picked by ray (default)
@@ -173,13 +218,13 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transfo
return cc;
}
-bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask, ShapeRestInfo *r_info) {
+bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask, ShapeRestInfo *r_info) {
ShapeSW *shape = static_cast<PhysicsServerSW *>(PhysicsServer::get_singleton())->shape_owner.get(p_shape);
ERR_FAIL_COND_V(!shape, false);
Rect3 aabb = p_xform.xform(shape->get_aabb());
- aabb = aabb.merge(Rect3(aabb.pos + p_motion, aabb.size)); //motion
+ aabb = aabb.merge(Rect3(aabb.position + p_motion, aabb.size)); //motion
aabb = aabb.grow(p_margin);
/*
@@ -203,7 +248,7 @@ bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
if (p_exclude.has(space->intersection_query_results[i]->get_self()))
@@ -294,7 +339,7 @@ bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform
return true;
}
-bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
if (p_result_max <= 0)
return 0;
@@ -324,7 +369,7 @@ bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform &p_sh
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
const CollisionObjectSW *col_obj = space->intersection_query_results[i];
@@ -373,7 +418,7 @@ static void _rest_cbk_result(const Vector3 &p_point_A, const Vector3 &p_point_B,
rd->best_object = rd->object;
rd->best_shape = rd->shape;
}
-bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
ShapeSW *shape = static_cast<PhysicsServerSW *>(PhysicsServer::get_singleton())->shape_owner.get(p_shape);
ERR_FAIL_COND_V(!shape, 0);
@@ -390,7 +435,7 @@ bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
const CollisionObjectSW *col_obj = space->intersection_query_results[i];
@@ -427,6 +472,48 @@ bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_
return true;
}
+Vector3 PhysicsDirectSpaceStateSW::get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const {
+
+ CollisionObjectSW *obj = NULL;
+ obj = PhysicsServerSW::singleton->area_owner.getornull(p_object);
+ if (!obj) {
+ obj = PhysicsServerSW::singleton->body_owner.getornull(p_object);
+ }
+ ERR_FAIL_COND_V(!obj, Vector3());
+
+ ERR_FAIL_COND_V(obj->get_space() != space, Vector3());
+
+ float min_distance = 1e20;
+ Vector3 min_point;
+
+ bool shapes_found = false;
+
+ for (int i = 0; i < obj->get_shape_count(); i++) {
+
+ if (obj->is_shape_set_as_disabled(i))
+ continue;
+
+ Transform shape_xform = obj->get_transform() * obj->get_shape_transform(i);
+ ShapeSW *shape = obj->get_shape(i);
+
+ Vector3 point = shape->get_closest_point_to(shape_xform.affine_inverse().xform(p_point));
+ point = shape_xform.xform(point);
+
+ float dist = point.distance_to(p_point);
+ if (dist < min_distance) {
+ min_distance = dist;
+ min_point = point;
+ }
+ shapes_found = true;
+ }
+
+ if (!shapes_found) {
+ return obj->get_transform().origin; //no shapes found, use distance to origin.
+ } else {
+ return min_point;
+ }
+}
+
PhysicsDirectSpaceStateSW::PhysicsDirectSpaceStateSW() {
space = NULL;
@@ -434,6 +521,337 @@ PhysicsDirectSpaceStateSW::PhysicsDirectSpaceStateSW() {
////////////////////////////////////////////////////////////////////////////////////////////////////////////
+int SpaceSW::_cull_aabb_for_body(BodySW *p_body, const Rect3 &p_aabb) {
+
+ int amount = broadphase->cull_aabb(p_aabb, intersection_query_results, INTERSECTION_QUERY_MAX, intersection_query_subindex_results);
+
+ for (int i = 0; i < amount; i++) {
+
+ bool keep = true;
+
+ if (intersection_query_results[i] == p_body)
+ keep = false;
+ else if (intersection_query_results[i]->get_type() == CollisionObjectSW::TYPE_AREA)
+ keep = false;
+ else if ((static_cast<BodySW *>(intersection_query_results[i])->test_collision_mask(p_body)) == 0)
+ keep = false;
+ else if (static_cast<BodySW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self()))
+ keep = false;
+ else if (static_cast<BodySW *>(intersection_query_results[i])->is_shape_set_as_disabled(intersection_query_subindex_results[i]))
+ keep = false;
+
+ if (!keep) {
+
+ if (i < amount - 1) {
+ SWAP(intersection_query_results[i], intersection_query_results[amount - 1]);
+ SWAP(intersection_query_subindex_results[i], intersection_query_subindex_results[amount - 1]);
+ }
+
+ amount--;
+ i--;
+ }
+ }
+
+ return amount;
+}
+
+bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Vector3 &p_motion, real_t p_margin, PhysicsServer::MotionResult *r_result) {
+
+ //give me back regular physics engine logic
+ //this is madness
+ //and most people using this function will think
+ //what it does is simpler than using physics
+ //this took about a week to get right..
+ //but is it right? who knows at this point..
+
+ if (r_result) {
+ r_result->collider_id = 0;
+ r_result->collider_shape = 0;
+ }
+ Rect3 body_aabb;
+
+ for (int i = 0; i < p_body->get_shape_count(); i++) {
+
+ if (i == 0)
+ body_aabb = p_body->get_shape_aabb(i);
+ else
+ body_aabb = body_aabb.merge(p_body->get_shape_aabb(i));
+ }
+
+ // Undo the currently transform the physics server is aware of and apply the provided one
+ body_aabb = p_from.xform(p_body->get_inv_transform().xform(body_aabb));
+ body_aabb = body_aabb.grow(p_margin);
+
+ Transform body_transform = p_from;
+
+ {
+ //STEP 1, FREE BODY IF STUCK
+
+ const int max_results = 32;
+ int recover_attempts = 4;
+ Vector3 sr[max_results * 2];
+
+ do {
+
+ PhysicsServerSW::CollCbkData cbk;
+ cbk.max = max_results;
+ cbk.amount = 0;
+ cbk.ptr = sr;
+
+ CollisionSolverSW::CallbackResult cbkres = NULL;
+
+ PhysicsServerSW::CollCbkData *cbkptr = NULL;
+ cbkptr = &cbk;
+ cbkres = PhysicsServerSW::_shape_col_cbk;
+
+ bool collided = false;
+
+ int amount = _cull_aabb_for_body(p_body, body_aabb);
+
+ for (int j = 0; j < p_body->get_shape_count(); j++) {
+ if (p_body->is_shape_set_as_disabled(j))
+ continue;
+
+ Transform body_shape_xform = body_transform * p_body->get_shape_transform(j);
+ ShapeSW *body_shape = p_body->get_shape(j);
+ for (int i = 0; i < amount; i++) {
+
+ const CollisionObjectSW *col_obj = intersection_query_results[i];
+ int shape_idx = intersection_query_subindex_results[i];
+
+ if (CollisionSolverSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, NULL, p_margin)) {
+ collided = cbk.amount > 0;
+ }
+ }
+ }
+
+ if (!collided) {
+ break;
+ }
+
+ Vector3 recover_motion;
+
+ for (int i = 0; i < cbk.amount; i++) {
+
+ Vector3 a = sr[i * 2 + 0];
+ Vector3 b = sr[i * 2 + 1];
+
+#if 0
+ Vector3 rel = b-a;
+ real_t d = rel.length();
+ if (d==0)
+ continue;
+
+ Vector3 n = rel/d;
+ real_t traveled = n.dot(recover_motion);
+ a+=n*traveled;
+
+ real_t d = a.distance_to(b);
+ if (d<margin)
+ continue;
+#endif
+ recover_motion += (b - a) * 0.4;
+ }
+
+ if (recover_motion == Vector3()) {
+ collided = false;
+ break;
+ }
+
+ body_transform.origin += recover_motion;
+ body_aabb.position += recover_motion;
+
+ recover_attempts--;
+
+ } while (recover_attempts);
+ }
+
+ real_t safe = 1.0;
+ real_t unsafe = 1.0;
+ int best_shape = -1;
+
+ {
+ // STEP 2 ATTEMPT MOTION
+
+ Rect3 motion_aabb = body_aabb;
+ motion_aabb.position += p_motion;
+ motion_aabb = motion_aabb.merge(body_aabb);
+
+ int amount = _cull_aabb_for_body(p_body, motion_aabb);
+
+ for (int j = 0; j < p_body->get_shape_count(); j++) {
+
+ if (p_body->is_shape_set_as_disabled(j))
+ continue;
+
+ Transform body_shape_xform = body_transform * p_body->get_shape_transform(j);
+ ShapeSW *body_shape = p_body->get_shape(j);
+
+ Transform body_shape_xform_inv = body_shape_xform.affine_inverse();
+ MotionShapeSW mshape;
+ mshape.shape = body_shape;
+ mshape.motion = body_shape_xform_inv.basis.xform(p_motion);
+
+ bool stuck = false;
+
+ real_t best_safe = 1;
+ real_t best_unsafe = 1;
+
+ for (int i = 0; i < amount; i++) {
+
+ const CollisionObjectSW *col_obj = intersection_query_results[i];
+ int shape_idx = intersection_query_subindex_results[i];
+
+ //test initial overlap, does it collide if going all the way?
+ Vector3 point_A, point_B;
+ Vector3 sep_axis = p_motion.normalized();
+
+ Transform col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
+ //test initial overlap, does it collide if going all the way?
+ if (CollisionSolverSW::solve_distance(&mshape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, motion_aabb, &sep_axis)) {
+ //print_line("failed motion cast (no collision)");
+ continue;
+ }
+ sep_axis = p_motion.normalized();
+
+ if (!CollisionSolverSW::solve_distance(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, motion_aabb, &sep_axis)) {
+ //print_line("failed motion cast (no collision)");
+ stuck = true;
+ break;
+ }
+
+ //just do kinematic solving
+ real_t low = 0;
+ real_t hi = 1;
+ Vector3 mnormal = p_motion.normalized();
+
+ for (int i = 0; i < 8; i++) { //steps should be customizable..
+
+ real_t ofs = (low + hi) * 0.5;
+
+ Vector3 sep = mnormal; //important optimization for this to work fast enough
+
+ mshape.motion = body_shape_xform_inv.basis.xform(p_motion * ofs);
+
+ Vector3 lA, lB;
+
+ bool collided = !CollisionSolverSW::solve_distance(&mshape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, lA, lB, motion_aabb, &sep);
+
+ if (collided) {
+
+ //print_line(itos(i)+": "+rtos(ofs));
+ hi = ofs;
+ } else {
+
+ point_A = lA;
+ point_B = lB;
+ low = ofs;
+ }
+ }
+
+ if (low < best_safe) {
+ best_safe = low;
+ best_unsafe = hi;
+ }
+ }
+
+ if (stuck) {
+
+ safe = 0;
+ unsafe = 0;
+ best_shape = j; //sadly it's the best
+ break;
+ }
+ if (best_safe == 1.0) {
+ continue;
+ }
+ if (best_safe < safe) {
+
+ safe = best_safe;
+ unsafe = best_unsafe;
+ best_shape = j;
+ }
+ }
+ }
+
+ bool collided = false;
+ if (safe >= 1) {
+ //not collided
+ collided = false;
+ if (r_result) {
+
+ r_result->motion = p_motion;
+ r_result->remainder = Vector3();
+ r_result->motion += (body_transform.get_origin() - p_from.get_origin());
+ }
+
+ } else {
+
+ //it collided, let's get the rest info in unsafe advance
+ Transform ugt = body_transform;
+ ugt.origin += p_motion * unsafe;
+
+ _RestCallbackData rcd;
+ rcd.best_len = 0;
+ rcd.best_object = NULL;
+ rcd.best_shape = 0;
+
+ Transform body_shape_xform = ugt * p_body->get_shape_transform(best_shape);
+ ShapeSW *body_shape = p_body->get_shape(best_shape);
+
+ body_aabb.position += p_motion * unsafe;
+
+ int amount = _cull_aabb_for_body(p_body, body_aabb);
+
+ for (int i = 0; i < amount; i++) {
+
+ const CollisionObjectSW *col_obj = intersection_query_results[i];
+ int shape_idx = intersection_query_subindex_results[i];
+
+ rcd.object = col_obj;
+ rcd.shape = shape_idx;
+ bool sc = CollisionSolverSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, NULL, p_margin);
+ if (!sc)
+ continue;
+ }
+
+ if (rcd.best_len != 0) {
+
+ if (r_result) {
+ r_result->collider = rcd.best_object->get_self();
+ r_result->collider_id = rcd.best_object->get_instance_id();
+ r_result->collider_shape = rcd.best_shape;
+ r_result->collision_local_shape = best_shape;
+ r_result->collision_normal = rcd.best_normal;
+ r_result->collision_point = rcd.best_contact;
+ //r_result->collider_metadata = rcd.best_object->get_shape_metadata(rcd.best_shape);
+
+ const BodySW *body = static_cast<const BodySW *>(rcd.best_object);
+ //Vector3 rel_vec = r_result->collision_point - body->get_transform().get_origin();
+ // r_result->collider_velocity = Vector3(-body->get_angular_velocity() * rel_vec.y, body->get_angular_velocity() * rel_vec.x) + body->get_linear_velocity();
+ r_result->collider_velocity = body->get_linear_velocity() + (body->get_angular_velocity()).cross(body->get_transform().origin - rcd.best_contact); // * mPos);
+
+ r_result->motion = safe * p_motion;
+ r_result->remainder = p_motion - safe * p_motion;
+ r_result->motion += (body_transform.get_origin() - p_from.get_origin());
+ }
+
+ collided = true;
+ } else {
+ if (r_result) {
+
+ r_result->motion = p_motion;
+ r_result->remainder = Vector3();
+ r_result->motion += (body_transform.get_origin() - p_from.get_origin());
+ }
+
+ collided = false;
+ }
+ }
+
+ return collided;
+}
+
void *SpaceSW::_broadphase_pair(CollisionObjectSW *A, int p_subindex_A, CollisionObjectSW *B, int p_subindex_B, void *p_self) {
CollisionObjectSW::Type type_A = A->get_type();
@@ -596,8 +1014,8 @@ void SpaceSW::set_param(PhysicsServer::SpaceParameter p_param, real_t p_value) {
case PhysicsServer::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: contact_recycle_radius = p_value; break;
case PhysicsServer::SPACE_PARAM_CONTACT_MAX_SEPARATION: contact_max_separation = p_value; break;
case PhysicsServer::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: contact_max_allowed_penetration = p_value; break;
- case PhysicsServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_TRESHOLD: body_linear_velocity_sleep_threshold = p_value; break;
- case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_TRESHOLD: body_angular_velocity_sleep_threshold = p_value; break;
+ case PhysicsServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: body_linear_velocity_sleep_threshold = p_value; break;
+ case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: body_angular_velocity_sleep_threshold = p_value; break;
case PhysicsServer::SPACE_PARAM_BODY_TIME_TO_SLEEP: body_time_to_sleep = p_value; break;
case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: body_angular_velocity_damp_ratio = p_value; break;
case PhysicsServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: constraint_bias = p_value; break;
@@ -611,8 +1029,8 @@ real_t SpaceSW::get_param(PhysicsServer::SpaceParameter p_param) const {
case PhysicsServer::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: return contact_recycle_radius;
case PhysicsServer::SPACE_PARAM_CONTACT_MAX_SEPARATION: return contact_max_separation;
case PhysicsServer::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: return contact_max_allowed_penetration;
- case PhysicsServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_TRESHOLD: return body_linear_velocity_sleep_threshold;
- case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_TRESHOLD: return body_angular_velocity_sleep_threshold;
+ case PhysicsServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: return body_linear_velocity_sleep_threshold;
+ case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: return body_angular_velocity_sleep_threshold;
case PhysicsServer::SPACE_PARAM_BODY_TIME_TO_SLEEP: return body_time_to_sleep;
case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: return body_angular_velocity_damp_ratio;
case PhysicsServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: return constraint_bias;
diff --git a/servers/physics/space_sw.h b/servers/physics/space_sw.h
index 06538265bb..dc7799d992 100644
--- a/servers/physics/space_sw.h
+++ b/servers/physics/space_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -35,8 +36,8 @@
#include "body_sw.h"
#include "broad_phase_sw.h"
#include "collision_object_sw.h"
-#include "global_config.h"
#include "hash_map.h"
+#include "project_settings.h"
#include "typedefs.h"
class PhysicsDirectSpaceStateSW : public PhysicsDirectSpaceState {
@@ -46,11 +47,13 @@ class PhysicsDirectSpaceStateSW : public PhysicsDirectSpaceState {
public:
SpaceSW *space;
- virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_ray = false);
- virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
- virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, ShapeRestInfo *r_info = NULL);
- virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
- virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_ray = false);
+ virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, ShapeRestInfo *r_info = NULL);
+ virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const;
PhysicsDirectSpaceStateSW();
};
@@ -119,6 +122,8 @@ private:
friend class PhysicsDirectSpaceStateSW;
+ int _cull_aabb_for_body(BodySW *p_body, const Rect3 &p_aabb);
+
public:
_FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; }
_FORCE_INLINE_ RID get_self() const { return self; }
@@ -151,8 +156,8 @@ public:
_FORCE_INLINE_ real_t get_contact_max_separation() const { return contact_max_separation; }
_FORCE_INLINE_ real_t get_contact_max_allowed_penetration() const { return contact_max_allowed_penetration; }
_FORCE_INLINE_ real_t get_constraint_bias() const { return constraint_bias; }
- _FORCE_INLINE_ real_t get_body_linear_velocity_sleep_treshold() const { return body_linear_velocity_sleep_threshold; }
- _FORCE_INLINE_ real_t get_body_angular_velocity_sleep_treshold() const { return body_angular_velocity_sleep_threshold; }
+ _FORCE_INLINE_ real_t get_body_linear_velocity_sleep_threshold() const { return body_linear_velocity_sleep_threshold; }
+ _FORCE_INLINE_ real_t get_body_angular_velocity_sleep_threshold() const { return body_angular_velocity_sleep_threshold; }
_FORCE_INLINE_ real_t get_body_time_to_sleep() const { return body_time_to_sleep; }
_FORCE_INLINE_ real_t get_body_angular_velocity_damp_ratio() const { return body_angular_velocity_damp_ratio; }
@@ -191,6 +196,8 @@ public:
void set_elapsed_time(ElapsedTime p_time, uint64_t p_msec) { elapsed_time[p_time] = p_msec; }
uint64_t get_elapsed_time(ElapsedTime p_time) const { return elapsed_time[p_time]; }
+ bool test_body_motion(BodySW *p_body, const Transform &p_from, const Vector3 &p_motion, real_t p_margin, PhysicsServer::MotionResult *r_result);
+
SpaceSW();
~SpaceSW();
};
diff --git a/servers/physics/step_sw.cpp b/servers/physics/step_sw.cpp
index c7b1be7a9b..5b5f5201db 100644
--- a/servers/physics/step_sw.cpp
+++ b/servers/physics/step_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics/step_sw.h b/servers/physics/step_sw.h
index 54f5fe9857..893bcfa6ad 100644
--- a/servers/physics/step_sw.h
+++ b/servers/physics/step_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp
index 885ede7cbf..fc5167c720 100644
--- a/servers/physics_2d/area_2d_sw.cpp
+++ b/servers/physics_2d/area_2d_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics_2d/area_2d_sw.h b/servers/physics_2d/area_2d_sw.h
index 8c52c96527..6d74a4b0f6 100644
--- a/servers/physics_2d/area_2d_sw.h
+++ b/servers/physics_2d/area_2d_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -152,6 +153,7 @@ public:
_FORCE_INLINE_ void add_constraint(Constraint2DSW *p_constraint) { constraints.insert(p_constraint); }
_FORCE_INLINE_ void remove_constraint(Constraint2DSW *p_constraint) { constraints.erase(p_constraint); }
_FORCE_INLINE_ const Set<Constraint2DSW *> &get_constraints() const { return constraints; }
+ _FORCE_INLINE_ void clear_constraints() { constraints.clear(); }
void set_monitorable(bool p_monitorable);
_FORCE_INLINE_ bool is_monitorable() const { return monitorable; }
diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp
index 769db8eb35..184db944da 100644
--- a/servers/physics_2d/area_pair_2d_sw.cpp
+++ b/servers/physics_2d/area_pair_2d_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -31,7 +32,13 @@
bool AreaPair2DSW::setup(real_t p_step) {
- bool result = area->test_collision_mask(body) && CollisionSolver2DSW::solve(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), Vector2(), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), Vector2(), NULL, this);
+ bool result = false;
+
+ if (area->is_shape_set_as_disabled(area_shape) || body->is_shape_set_as_disabled(body_shape)) {
+ result = false;
+ } else if (area->test_collision_mask(body) && CollisionSolver2DSW::solve(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), Vector2(), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), Vector2(), NULL, this)) {
+ result = true;
+ }
if (result != colliding) {
@@ -89,7 +96,12 @@ AreaPair2DSW::~AreaPair2DSW() {
bool Area2Pair2DSW::setup(real_t p_step) {
- bool result = area_a->test_collision_mask(area_b) && CollisionSolver2DSW::solve(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), Vector2(), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), Vector2(), NULL, this);
+ bool result = false;
+ if (area_a->is_shape_set_as_disabled(shape_a) || area_b->is_shape_set_as_disabled(shape_b)) {
+ result = false;
+ } else if (area_a->test_collision_mask(area_b) && CollisionSolver2DSW::solve(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), Vector2(), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), Vector2(), NULL, this)) {
+ result = true;
+ }
if (result != colliding) {
diff --git a/servers/physics_2d/area_pair_2d_sw.h b/servers/physics_2d/area_pair_2d_sw.h
index 78be9572bf..05954424f8 100644
--- a/servers/physics_2d/area_pair_2d_sw.h
+++ b/servers/physics_2d/area_pair_2d_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index 26f319559e..91b5646ef5 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -620,7 +621,7 @@ bool Body2DSW::sleep_test(real_t p_step) {
else if (!can_sleep)
return false;
- if (Math::abs(angular_velocity) < get_space()->get_body_angular_velocity_sleep_treshold() && Math::abs(linear_velocity.length_squared()) < get_space()->get_body_linear_velocity_sleep_treshold() * get_space()->get_body_linear_velocity_sleep_treshold()) {
+ if (Math::abs(angular_velocity) < get_space()->get_body_angular_velocity_sleep_threshold() && Math::abs(linear_velocity.length_squared()) < get_space()->get_body_linear_velocity_sleep_threshold() * get_space()->get_body_linear_velocity_sleep_threshold()) {
still_time += p_step;
@@ -675,8 +676,6 @@ Body2DSW::Body2DSW()
area_linear_damp = 0;
contact_count = 0;
gravity_scale = 1.0;
- using_one_way_cache = false;
- one_way_collision_max_depth = 0.1;
first_integration = false;
still_time = 0;
diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h
index 7e4fef8df3..412f2f51cd 100644
--- a/servers/physics_2d/body_2d_sw.h
+++ b/servers/physics_2d/body_2d_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -66,9 +67,6 @@ class Body2DSW : public CollisionObject2DSW {
Vector2 applied_force;
real_t applied_torque;
- Vector2 one_way_collision_direction;
- real_t one_way_collision_max_depth;
-
SelfList<Body2DSW> active_list;
SelfList<Body2DSW> inertia_update_list;
SelfList<Body2DSW> direct_state_query_list;
@@ -80,7 +78,6 @@ class Body2DSW : public CollisionObject2DSW {
bool can_sleep;
bool first_time_kinematic;
bool first_integration;
- bool using_one_way_cache;
void _update_inertia();
virtual void _shapes_changed();
Transform2D new_transform;
@@ -184,6 +181,7 @@ public:
_FORCE_INLINE_ void add_constraint(Constraint2DSW *p_constraint, int p_pos) { constraint_map[p_constraint] = p_pos; }
_FORCE_INLINE_ void remove_constraint(Constraint2DSW *p_constraint) { constraint_map.erase(p_constraint); }
const Map<Constraint2DSW *, int> &get_constraint_map() const { return constraint_map; }
+ _FORCE_INLINE_ void clear_constraint_map() { constraint_map.clear(); }
_FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration = p_omit_force_integration; }
_FORCE_INLINE_ bool get_omit_force_integration() const { return omit_force_integration; }
@@ -245,17 +243,6 @@ public:
_FORCE_INLINE_ void set_continuous_collision_detection_mode(Physics2DServer::CCDMode p_mode) { continuous_cd_mode = p_mode; }
_FORCE_INLINE_ Physics2DServer::CCDMode get_continuous_collision_detection_mode() const { return continuous_cd_mode; }
- void set_one_way_collision_direction(const Vector2 &p_dir) {
- one_way_collision_direction = p_dir;
- using_one_way_cache = one_way_collision_direction != Vector2();
- }
- Vector2 get_one_way_collision_direction() const { return one_way_collision_direction; }
-
- void set_one_way_collision_max_depth(real_t p_depth) { one_way_collision_max_depth = p_depth; }
- real_t get_one_way_collision_max_depth() const { return one_way_collision_max_depth; }
-
- _FORCE_INLINE_ bool is_using_one_way_collision() const { return using_one_way_cache; }
-
void set_space(Space2DSW *p_space);
void update_inertias();
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index ee94a7acec..484d4503d0 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -224,6 +225,11 @@ bool BodyPair2DSW::setup(real_t p_step) {
return false;
}
+ if (A->is_shape_set_as_disabled(shape_A) || B->is_shape_set_as_disabled(shape_B)) {
+ collided = false;
+ return false;
+ }
+
//use local A coordinates to avoid numerical issues on collision detection
offset_B = B->get_transform().get_origin() - A->get_transform().get_origin();
@@ -279,8 +285,8 @@ bool BodyPair2DSW::setup(real_t p_step) {
//if (!prev_collided) {
{
- if (A->is_using_one_way_collision()) {
- Vector2 direction = A->get_one_way_collision_direction();
+ if (A->is_shape_set_as_one_way_collision(shape_A)) {
+ Vector2 direction = xform_A.get_axis(1).normalized();
bool valid = false;
if (B->get_linear_velocity().dot(direction) >= 0) {
for (int i = 0; i < contact_count; i++) {
@@ -302,8 +308,8 @@ bool BodyPair2DSW::setup(real_t p_step) {
}
}
- if (B->is_using_one_way_collision()) {
- Vector2 direction = B->get_one_way_collision_direction();
+ if (B->is_shape_set_as_one_way_collision(shape_B)) {
+ Vector2 direction = xform_B.get_axis(1).normalized();
bool valid = false;
if (A->get_linear_velocity().dot(direction) >= 0) {
for (int i = 0; i < contact_count; i++) {
@@ -389,7 +395,7 @@ bool BodyPair2DSW::setup(real_t p_step) {
}
}
- if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B) || (A->get_mode() <= Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode() <= Physics2DServer::BODY_MODE_KINEMATIC)) {
+ if ((A->get_mode() <= Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode() <= Physics2DServer::BODY_MODE_KINEMATIC)) {
c.active = false;
collided = false;
continue;
diff --git a/servers/physics_2d/body_pair_2d_sw.h b/servers/physics_2d/body_pair_2d_sw.h
index 023c182c31..4d2b3b31f9 100644
--- a/servers/physics_2d/body_pair_2d_sw.h
+++ b/servers/physics_2d/body_pair_2d_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics_2d/broad_phase_2d_basic.cpp b/servers/physics_2d/broad_phase_2d_basic.cpp
index c282c0364e..76094ad98c 100644
--- a/servers/physics_2d/broad_phase_2d_basic.cpp
+++ b/servers/physics_2d/broad_phase_2d_basic.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -123,10 +124,10 @@ void BroadPhase2DBasic::set_pair_callback(PairCallback p_pair_callback, void *p_
pair_userdata = p_userdata;
pair_callback = p_pair_callback;
}
-void BroadPhase2DBasic::set_unpair_callback(UnpairCallback p_pair_callback, void *p_userdata) {
+void BroadPhase2DBasic::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) {
unpair_userdata = p_userdata;
- unpair_callback = p_pair_callback;
+ unpair_callback = p_unpair_callback;
}
void BroadPhase2DBasic::update() {
diff --git a/servers/physics_2d/broad_phase_2d_basic.h b/servers/physics_2d/broad_phase_2d_basic.h
index 7c5d799f9a..edd788266a 100644
--- a/servers/physics_2d/broad_phase_2d_basic.h
+++ b/servers/physics_2d/broad_phase_2d_basic.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.cpp b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
index 74c01e1220..0330bfa9f3 100644
--- a/servers/physics_2d/broad_phase_2d_hash_grid.cpp
+++ b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -27,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "broad_phase_2d_hash_grid.h"
-#include "global_config.h"
+#include "project_settings.h"
#define LARGE_ELEMENT_FI 1.01239812
@@ -115,8 +116,8 @@ void BroadPhase2DHashGrid::_enter_grid(Element *p_elem, const Rect2 &p_rect, boo
return;
}
- Point2i from = (p_rect.pos / cell_size).floor();
- Point2i to = ((p_rect.pos + p_rect.size) / cell_size).floor();
+ Point2i from = (p_rect.position / cell_size).floor();
+ Point2i to = ((p_rect.position + p_rect.size) / cell_size).floor();
for (int i = from.x; i <= to.x; i++) {
@@ -202,9 +203,11 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool
if (sz.width * sz.height > large_object_min_surface) {
//unpair all elements, instead of checking all, just check what is already paired, so we at least save from checking static vs static
- for (Map<Element *, PairData *>::Element *E = p_elem->paired.front(); E; E = E->next()) {
-
+ Map<Element *, PairData *>::Element *E = p_elem->paired.front();
+ while (E) {
+ Map<Element *, PairData *>::Element *next = E->next();
_unpair_attempt(p_elem, E->key());
+ E = next;
}
if (large_elements[p_elem].dec() == 0) {
@@ -213,8 +216,8 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool
return;
}
- Point2i from = (p_rect.pos / cell_size).floor();
- Point2i to = ((p_rect.pos + p_rect.size) / cell_size).floor();
+ Point2i from = (p_rect.position / cell_size).floor();
+ Point2i to = ((p_rect.position + p_rect.size) / cell_size).floor();
for (int i = from.x; i <= to.x; i++) {
@@ -573,8 +576,8 @@ int BroadPhase2DHashGrid::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p
pass++;
- Point2i from = (p_aabb.pos / cell_size).floor();
- Point2i to = ((p_aabb.pos + p_aabb.size) / cell_size).floor();
+ Point2i from = (p_aabb.position / cell_size).floor();
+ Point2i to = ((p_aabb.position + p_aabb.size) / cell_size).floor();
int cullcount = 0;
for (int i = from.x; i <= to.x; i++) {
@@ -635,7 +638,7 @@ BroadPhase2DHashGrid::BroadPhase2DHashGrid() {
hash_table = memnew_arr(PosBin *, hash_table_size);
cell_size = GLOBAL_DEF("physics/2d/cell_size", 128);
- large_object_min_surface = GLOBAL_DEF("physics/2d/large_object_surface_treshold_in_cells", 512);
+ large_object_min_surface = GLOBAL_DEF("physics/2d/large_object_surface_threshold_in_cells", 512);
for (int i = 0; i < hash_table_size; i++)
hash_table[i] = NULL;
diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.h b/servers/physics_2d/broad_phase_2d_hash_grid.h
index f30f72d6db..0cb3edb94f 100644
--- a/servers/physics_2d/broad_phase_2d_hash_grid.h
+++ b/servers/physics_2d/broad_phase_2d_hash_grid.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -166,7 +167,7 @@ class BroadPhase2DHashGrid : public BroadPhase2DSW {
void _check_motion(Element *p_elem);
public:
- virtual ID create(CollisionObject2DSW *p_object_, int p_subindex = 0);
+ virtual ID create(CollisionObject2DSW *p_object, int p_subindex = 0);
virtual void move(ID p_id, const Rect2 &p_aabb);
virtual void set_static(ID p_id, bool p_static);
virtual void remove(ID p_id);
diff --git a/servers/physics_2d/broad_phase_2d_sw.cpp b/servers/physics_2d/broad_phase_2d_sw.cpp
index 8cde46217b..a412f76567 100644
--- a/servers/physics_2d/broad_phase_2d_sw.cpp
+++ b/servers/physics_2d/broad_phase_2d_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics_2d/broad_phase_2d_sw.h b/servers/physics_2d/broad_phase_2d_sw.h
index a255cc6ba7..0309cbe730 100644
--- a/servers/physics_2d/broad_phase_2d_sw.h
+++ b/servers/physics_2d/broad_phase_2d_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp
index 30bb9f6b52..8f13f1130a 100644
--- a/servers/physics_2d/collision_object_2d_sw.cpp
+++ b/servers/physics_2d/collision_object_2d_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -36,7 +37,8 @@ void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_tra
s.xform = p_transform;
s.xform_inv = s.xform.affine_inverse();
s.bpid = 0; //needs update
- s.trigger = false;
+ s.disabled = false;
+ s.one_way_collision = false;
shapes.push_back(s);
p_shape->add_owner(this);
_update_shapes();
@@ -168,7 +170,7 @@ void CollisionObject2DSW::_update_shapes_with_motion(const Vector2 &p_motion) {
Rect2 shape_aabb = s.shape->get_aabb();
Transform2D xform = transform * s.xform;
shape_aabb = xform.xform(shape_aabb);
- shape_aabb = shape_aabb.merge(Rect2(shape_aabb.pos + p_motion, shape_aabb.size)); //use motion
+ shape_aabb = shape_aabb.merge(Rect2(shape_aabb.position + p_motion, shape_aabb.size)); //use motion
s.aabb_cache = shape_aabb;
space->get_broadphase()->move(s.bpid, shape_aabb);
@@ -213,6 +215,6 @@ CollisionObject2DSW::CollisionObject2DSW(Type p_type) {
space = NULL;
instance_id = 0;
collision_mask = 1;
- layer_mask = 1;
+ collision_layer = 1;
pickable = true;
}
diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h
index e6eec05f3d..ad8edb0b3d 100644
--- a/servers/physics_2d/collision_object_2d_sw.h
+++ b/servers/physics_2d/collision_object_2d_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -57,8 +58,12 @@ private:
Rect2 aabb_cache; //for rayqueries
Shape2DSW *shape;
Variant metadata;
- bool trigger;
- Shape() { trigger = false; }
+ bool disabled;
+ bool one_way_collision;
+ Shape() {
+ disabled = false;
+ one_way_collision = false;
+ }
};
Vector<Shape> shapes;
@@ -66,7 +71,7 @@ private:
Transform2D transform;
Transform2D inv_transform;
uint32_t collision_mask;
- uint32_t layer_mask;
+ uint32_t collision_layer;
bool _static;
void _update_shapes();
@@ -85,7 +90,7 @@ protected:
void _set_static(bool p_static);
virtual void _shapes_changed() = 0;
- void _set_space(Space2DSW *space);
+ void _set_space(Space2DSW *p_space);
CollisionObject2DSW(Type p_type);
@@ -115,14 +120,17 @@ public:
_FORCE_INLINE_ Transform2D get_inv_transform() const { return inv_transform; }
_FORCE_INLINE_ Space2DSW *get_space() const { return space; }
- _FORCE_INLINE_ void set_shape_as_trigger(int p_idx, bool p_enable) { shapes[p_idx].trigger = p_enable; }
- _FORCE_INLINE_ bool is_shape_set_as_trigger(int p_idx) const { return shapes[p_idx].trigger; }
+ _FORCE_INLINE_ void set_shape_as_disabled(int p_idx, bool p_disabled) { shapes[p_idx].disabled = p_disabled; }
+ _FORCE_INLINE_ bool is_shape_set_as_disabled(int p_idx) const { return shapes[p_idx].disabled; }
+
+ _FORCE_INLINE_ void set_shape_as_one_way_collision(int p_idx, bool p_one_way_collision) { shapes[p_idx].one_way_collision = p_one_way_collision; }
+ _FORCE_INLINE_ bool is_shape_set_as_one_way_collision(int p_idx) const { return shapes[p_idx].one_way_collision; }
void set_collision_mask(uint32_t p_mask) { collision_mask = p_mask; }
_FORCE_INLINE_ uint32_t get_collision_mask() const { return collision_mask; }
- void set_layer_mask(uint32_t p_mask) { layer_mask = p_mask; }
- _FORCE_INLINE_ uint32_t get_layer_mask() const { return layer_mask; }
+ void set_collision_layer(uint32_t p_layer) { collision_layer = p_layer; }
+ _FORCE_INLINE_ uint32_t get_collision_layer() const { return collision_layer; }
void remove_shape(Shape2DSW *p_shape);
void remove_shape(int p_index);
@@ -136,7 +144,7 @@ public:
_FORCE_INLINE_ bool test_collision_mask(CollisionObject2DSW *p_other) const {
- return layer_mask & p_other->collision_mask || p_other->layer_mask & collision_mask;
+ return collision_layer & p_other->collision_mask || p_other->collision_layer & collision_mask;
}
virtual ~CollisionObject2DSW() {}
diff --git a/servers/physics_2d/collision_solver_2d_sat.cpp b/servers/physics_2d/collision_solver_2d_sat.cpp
index f72a7ef0e4..a5a6cd7eac 100644
--- a/servers/physics_2d/collision_solver_2d_sat.cpp
+++ b/servers/physics_2d/collision_solver_2d_sat.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics_2d/collision_solver_2d_sat.h b/servers/physics_2d/collision_solver_2d_sat.h
index a13c3dd14d..2a075e2a30 100644
--- a/servers/physics_2d/collision_solver_2d_sat.h
+++ b/servers/physics_2d/collision_solver_2d_sat.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics_2d/collision_solver_2d_sw.cpp b/servers/physics_2d/collision_solver_2d_sw.cpp
index 6218af72a1..b482f826c2 100644
--- a/servers/physics_2d/collision_solver_2d_sw.cpp
+++ b/servers/physics_2d/collision_solver_2d_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -202,7 +203,7 @@ bool CollisionSolver2DSW::solve_concave(const Shape2DSW *p_shape_A, const Transf
smin *= axis_scale;
smax *= axis_scale;
- local_aabb.pos[i] = smin;
+ local_aabb.position[i] = smin;
local_aabb.size[i] = smax - smin;
}
diff --git a/servers/physics_2d/collision_solver_2d_sw.h b/servers/physics_2d/collision_solver_2d_sw.h
index 886cb90ace..aefd4d315d 100644
--- a/servers/physics_2d/collision_solver_2d_sw.h
+++ b/servers/physics_2d/collision_solver_2d_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics_2d/constraint_2d_sw.h b/servers/physics_2d/constraint_2d_sw.h
index 659b5b3219..7ff28b0cf4 100644
--- a/servers/physics_2d/constraint_2d_sw.h
+++ b/servers/physics_2d/constraint_2d_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics_2d/joints_2d_sw.cpp b/servers/physics_2d/joints_2d_sw.cpp
index 0277586495..449765621e 100644
--- a/servers/physics_2d/joints_2d_sw.cpp
+++ b/servers/physics_2d/joints_2d_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics_2d/joints_2d_sw.h b/servers/physics_2d/joints_2d_sw.h
index 8fe38f365a..548a8b778f 100644
--- a/servers/physics_2d/joints_2d_sw.h
+++ b/servers/physics_2d/joints_2d_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index 92555e26b6..3805075ac3 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -30,8 +31,8 @@
#include "broad_phase_2d_basic.h"
#include "broad_phase_2d_hash_grid.h"
#include "collision_solver_2d_sw.h"
-#include "global_config.h"
#include "os/os.h"
+#include "project_settings.h"
#include "script_language.h"
RID Physics2DServerSW::shape_create(ShapeType p_shape) {
@@ -285,12 +286,24 @@ void Physics2DServerSW::area_set_space(RID p_area, RID p_space) {
Area2DSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
+
Space2DSW *space = NULL;
if (p_space.is_valid()) {
space = space_owner.get(p_space);
ERR_FAIL_COND(!space);
}
+ if (area->get_space() == space)
+ return; //pointless
+
+ for (Set<Constraint2DSW *>::Element *E = area->get_constraints().front(); E; E = E->next()) {
+ RID self = E->get()->get_self();
+ if (!self.is_valid())
+ continue;
+ free(self);
+ }
+ area->clear_constraints();
+
area->set_space(space);
};
@@ -351,6 +364,15 @@ void Physics2DServerSW::area_set_shape_transform(RID p_area, int p_shape_idx, co
area->set_shape_transform(p_shape_idx, p_transform);
}
+void Physics2DServerSW::area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled) {
+
+ Area2DSW *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ ERR_FAIL_INDEX(p_shape, area->get_shape_count());
+ area->set_shape_as_disabled(p_shape, p_disabled);
+}
+
int Physics2DServerSW::area_get_shape_count(RID p_area) const {
Area2DSW *area = area_owner.get(p_area);
@@ -393,7 +415,7 @@ void Physics2DServerSW::area_clear_shapes(RID p_area) {
area->remove_shape(0);
}
-void Physics2DServerSW::area_attach_object_instance_ID(RID p_area, ObjectID p_ID) {
+void Physics2DServerSW::area_attach_object_instance_id(RID p_area, ObjectID p_ID) {
if (space_owner.owns(p_area)) {
Space2DSW *space = space_owner.get(p_area);
@@ -403,7 +425,7 @@ void Physics2DServerSW::area_attach_object_instance_ID(RID p_area, ObjectID p_ID
ERR_FAIL_COND(!area);
area->set_instance_id(p_ID);
}
-ObjectID Physics2DServerSW::area_get_object_instance_ID(RID p_area) const {
+ObjectID Physics2DServerSW::area_get_object_instance_id(RID p_area) const {
if (space_owner.owns(p_area)) {
Space2DSW *space = space_owner.get(p_area);
@@ -475,12 +497,12 @@ void Physics2DServerSW::area_set_collision_mask(RID p_area, uint32_t p_mask) {
area->set_collision_mask(p_mask);
}
-void Physics2DServerSW::area_set_layer_mask(RID p_area, uint32_t p_mask) {
+void Physics2DServerSW::area_set_collision_layer(RID p_area, uint32_t p_layer) {
Area2DSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
- area->set_layer_mask(p_mask);
+ area->set_collision_layer(p_layer);
}
void Physics2DServerSW::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
@@ -488,7 +510,7 @@ void Physics2DServerSW::area_set_monitor_callback(RID p_area, Object *p_receiver
Area2DSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
- area->set_monitor_callback(p_receiver ? p_receiver->get_instance_ID() : 0, p_method);
+ area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : 0, p_method);
}
void Physics2DServerSW::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
@@ -496,7 +518,7 @@ void Physics2DServerSW::area_set_area_monitor_callback(RID p_area, Object *p_rec
Area2DSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
- area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_ID() : 0, p_method);
+ area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : 0, p_method);
}
/* BODY API */
@@ -523,6 +545,17 @@ void Physics2DServerSW::body_set_space(RID p_body, RID p_space) {
ERR_FAIL_COND(!space);
}
+ if (body->get_space() == space)
+ return; //pointless
+
+ for (Map<Constraint2DSW *, int>::Element *E = body->get_constraint_map().front(); E; E = E->next()) {
+ RID self = E->key()->get_self();
+ if (!self.is_valid())
+ continue;
+ free(self);
+ }
+ body->clear_constraint_map();
+
body->set_space(space);
};
@@ -639,24 +672,23 @@ void Physics2DServerSW::body_clear_shapes(RID p_body) {
body->remove_shape(0);
}
-void Physics2DServerSW::body_set_shape_as_trigger(RID p_body, int p_shape_idx, bool p_enable) {
+void Physics2DServerSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
- body->set_shape_as_trigger(p_shape_idx, p_enable);
+ body->set_shape_as_disabled(p_shape_idx, p_disabled);
}
+void Physics2DServerSW::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable) {
-bool Physics2DServerSW::body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) const {
-
- const Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND_V(!body, false);
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
- ERR_FAIL_INDEX_V(p_shape_idx, body->get_shape_count(), false);
+ ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
- return body->is_shape_set_as_trigger(p_shape_idx);
+ body->set_shape_as_one_way_collision(p_shape_idx, p_enable);
}
void Physics2DServerSW::body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode) {
@@ -674,7 +706,7 @@ Physics2DServerSW::CCDMode Physics2DServerSW::body_get_continuous_collision_dete
return body->get_continuous_collision_detection_mode();
}
-void Physics2DServerSW::body_attach_object_instance_ID(RID p_body, uint32_t p_ID) {
+void Physics2DServerSW::body_attach_object_instance_id(RID p_body, uint32_t p_ID) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
@@ -682,7 +714,7 @@ void Physics2DServerSW::body_attach_object_instance_ID(RID p_body, uint32_t p_ID
body->set_instance_id(p_ID);
};
-uint32_t Physics2DServerSW::body_get_object_instance_ID(RID p_body) const {
+uint32_t Physics2DServerSW::body_get_object_instance_id(RID p_body) const {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -690,26 +722,26 @@ uint32_t Physics2DServerSW::body_get_object_instance_ID(RID p_body) const {
return body->get_instance_id();
};
-void Physics2DServerSW::body_set_layer_mask(RID p_body, uint32_t p_flags) {
+void Physics2DServerSW::body_set_collision_layer(RID p_body, uint32_t p_layer) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
- body->set_layer_mask(p_flags);
+ body->set_collision_layer(p_layer);
};
-uint32_t Physics2DServerSW::body_get_layer_mask(RID p_body) const {
+uint32_t Physics2DServerSW::body_get_collision_layer(RID p_body) const {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, 0);
- return body->get_layer_mask();
+ return body->get_collision_layer();
};
-void Physics2DServerSW::body_set_collision_mask(RID p_body, uint32_t p_flags) {
+void Physics2DServerSW::body_set_collision_mask(RID p_body, uint32_t p_mask) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
- body->set_collision_mask(p_flags);
+ body->set_collision_mask(p_mask);
};
uint32_t Physics2DServerSW::body_get_collision_mask(RID p_body) const {
@@ -844,13 +876,13 @@ void Physics2DServerSW::body_get_collision_exceptions(RID p_body, List<RID> *p_e
}
};
-void Physics2DServerSW::body_set_contacts_reported_depth_treshold(RID p_body, real_t p_treshold) {
+void Physics2DServerSW::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
};
-real_t Physics2DServerSW::body_get_contacts_reported_depth_treshold(RID p_body) const {
+real_t Physics2DServerSW::body_get_contacts_reported_depth_threshold(RID p_body) const {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -886,39 +918,11 @@ int Physics2DServerSW::body_get_max_contacts_reported(RID p_body) const {
return body->get_max_contacts_reported();
}
-void Physics2DServerSW::body_set_one_way_collision_direction(RID p_body, const Vector2 &p_direction) {
-
- Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND(!body);
- body->set_one_way_collision_direction(p_direction);
-}
-
-Vector2 Physics2DServerSW::body_get_one_way_collision_direction(RID p_body) const {
-
- Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND_V(!body, Vector2());
- return body->get_one_way_collision_direction();
-}
-
-void Physics2DServerSW::body_set_one_way_collision_max_depth(RID p_body, real_t p_max_depth) {
-
- Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND(!body);
- body->set_one_way_collision_max_depth(p_max_depth);
-}
-
-real_t Physics2DServerSW::body_get_one_way_collision_max_depth(RID p_body) const {
-
- Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND_V(!body, 0);
- return body->get_one_way_collision_max_depth();
-}
-
void Physics2DServerSW::body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
- body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_ID() : ObjectID(0), p_method, p_udata);
+ body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(0), p_method, p_udata);
}
bool Physics2DServerSW::body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) {
@@ -1092,19 +1096,13 @@ void Physics2DServerSW::free(RID p_rid) {
_clear_query(body->get_direct_state_query());
*/
- body->set_space(NULL);
+ body_set_space(p_rid, RID());
while (body->get_shape_count()) {
body->remove_shape(0);
}
- while (body->get_constraint_map().size()) {
- RID self = body->get_constraint_map().front()->key()->get_self();
- ERR_FAIL_COND(!self.is_valid());
- free(self);
- }
-
body_owner.free(p_rid);
memdelete(body);
@@ -1283,7 +1281,7 @@ Physics2DServerSW::Physics2DServerSW() {
island_count = 0;
active_objects = 0;
collision_pairs = 0;
- using_threads = int(GlobalConfig::get_singleton()->get("physics/2d/thread_model")) == 2;
+ using_threads = int(ProjectSettings::get_singleton()->get("physics/2d/thread_model")) == 2;
};
Physics2DServerSW::~Physics2DServerSW(){
diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h
index b49c37ab21..e767aad1da 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -122,20 +123,22 @@ public:
virtual RID area_get_shape(RID p_area, int p_shape_idx) const;
virtual Transform2D area_get_shape_transform(RID p_area, int p_shape_idx) const;
+ virtual void area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled);
+
virtual void area_remove_shape(RID p_area, int p_shape_idx);
virtual void area_clear_shapes(RID p_area);
- virtual void area_attach_object_instance_ID(RID p_area, ObjectID p_ID);
- virtual ObjectID area_get_object_instance_ID(RID p_area) const;
+ virtual void area_attach_object_instance_id(RID p_area, ObjectID p_ID);
+ virtual ObjectID area_get_object_instance_id(RID p_area) const;
virtual void area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value);
virtual void area_set_transform(RID p_area, const Transform2D &p_transform);
- virtual Variant area_get_param(RID p_parea, AreaParameter p_param) const;
+ virtual Variant area_get_param(RID p_area, AreaParameter p_param) const;
virtual Transform2D area_get_transform(RID p_area) const;
virtual void area_set_monitorable(RID p_area, bool p_monitorable);
virtual void area_set_collision_mask(RID p_area, uint32_t p_mask);
- virtual void area_set_layer_mask(RID p_area, uint32_t p_mask);
+ virtual void area_set_collision_layer(RID p_area, uint32_t p_layer);
virtual void area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method);
virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method);
@@ -166,20 +169,20 @@ public:
virtual void body_remove_shape(RID p_body, int p_shape_idx);
virtual void body_clear_shapes(RID p_body);
- virtual void body_set_shape_as_trigger(RID p_body, int p_shape_idx, bool p_enable);
- virtual bool body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) const;
+ virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled);
+ virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable);
- virtual void body_attach_object_instance_ID(RID p_body, uint32_t p_ID);
- virtual uint32_t body_get_object_instance_ID(RID p_body) const;
+ virtual void body_attach_object_instance_id(RID p_body, uint32_t p_ID);
+ virtual uint32_t body_get_object_instance_id(RID p_body) const;
virtual void body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode);
virtual CCDMode body_get_continuous_collision_detection_mode(RID p_body) const;
- virtual void body_set_layer_mask(RID p_body, uint32_t p_mask);
- virtual uint32_t body_get_layer_mask(RID p_body) const;
+ virtual void body_set_collision_layer(RID p_body, uint32_t p_layer);
+ virtual uint32_t body_get_collision_layer(RID p_body) const;
virtual void body_set_collision_mask(RID p_body, uint32_t p_mask);
- virtual uint32_t body_get_collision_mask(RID p_) const;
+ virtual uint32_t body_get_collision_mask(RID p_body) const;
virtual void body_set_param(RID p_body, BodyParameter p_param, real_t p_value);
virtual real_t body_get_param(RID p_body, BodyParameter p_param) const;
@@ -202,8 +205,8 @@ public:
virtual void body_remove_collision_exception(RID p_body, RID p_body_b);
virtual void body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions);
- virtual void body_set_contacts_reported_depth_treshold(RID p_body, real_t p_treshold);
- virtual real_t body_get_contacts_reported_depth_treshold(RID p_body) const;
+ virtual void body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold);
+ virtual real_t body_get_contacts_reported_depth_threshold(RID p_body) const;
virtual void body_set_omit_force_integration(RID p_body, bool p_omit);
virtual bool body_is_omitting_force_integration(RID p_body) const;
@@ -211,12 +214,6 @@ public:
virtual void body_set_max_contacts_reported(RID p_body, int p_contacts);
virtual int body_get_max_contacts_reported(RID p_body) const;
- virtual void body_set_one_way_collision_direction(RID p_body, const Vector2 &p_direction);
- virtual Vector2 body_get_one_way_collision_direction(RID p_body) const;
-
- virtual void body_set_one_way_collision_max_depth(RID p_body, real_t p_max_depth);
- virtual real_t body_get_one_way_collision_max_depth(RID p_body) const;
-
virtual void body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata = Variant());
virtual bool body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count);
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.cpp b/servers/physics_2d/physics_2d_server_wrap_mt.cpp
index ef1a5b333c..8d19153268 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.cpp
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -50,7 +51,7 @@ void Physics2DServerWrapMT::_thread_callback(void *_instance) {
void Physics2DServerWrapMT::thread_loop() {
- server_thread = Thread::get_caller_ID();
+ server_thread = Thread::get_caller_id();
OS::get_singleton()->make_rendering_thread();
@@ -160,20 +161,20 @@ Physics2DServerWrapMT::Physics2DServerWrapMT(Physics2DServer *p_contained, bool
step_thread_up = false;
alloc_mutex = Mutex::create();
- shape_pool_max_size = GLOBAL_GET("memory/multithread/thread_rid_pool_prealloc");
- area_pool_max_size = GLOBAL_GET("memory/multithread/thread_rid_pool_prealloc");
- body_pool_max_size = GLOBAL_GET("memory/multithread/thread_rid_pool_prealloc");
- pin_joint_pool_max_size = GLOBAL_GET("memory/multithread/thread_rid_pool_prealloc");
- groove_joint_pool_max_size = GLOBAL_GET("memory/multithread/thread_rid_pool_prealloc");
- damped_spring_joint_pool_max_size = GLOBAL_GET("memory/multithread/thread_rid_pool_prealloc");
+ shape_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
+ area_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
+ body_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
+ pin_joint_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
+ groove_joint_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
+ damped_spring_joint_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
if (!p_create_thread) {
- server_thread = Thread::get_caller_ID();
+ server_thread = Thread::get_caller_id();
} else {
server_thread = 0;
}
- main_thread = Thread::get_caller_ID();
+ main_thread = Thread::get_caller_id();
first_frame = true;
}
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h
index ff30b2df09..8058709c06 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.h
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -30,8 +31,8 @@
#define PHYSICS2DSERVERWRAPMT_H
#include "command_queue_mt.h"
-#include "global_config.h"
#include "os/thread.h"
+#include "project_settings.h"
#include "servers/physics_2d_server.h"
#ifdef DEBUG_SYNC
@@ -97,7 +98,7 @@ public:
//these work well, but should be used from the main thread only
bool shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_ID(), false);
+ ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
return physics_2d_server->shape_collide(p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, r_result_count);
}
@@ -113,20 +114,20 @@ public:
// this function only works on fixed process, errors and returns null otherwise
Physics2DDirectSpaceState *space_get_direct_state(RID p_space) {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_ID(), NULL);
+ ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), NULL);
return physics_2d_server->space_get_direct_state(p_space);
}
FUNC2(space_set_debug_contacts, RID, int);
virtual Vector<Vector2> space_get_contacts(RID p_space) const {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_ID(), Vector<Vector2>());
+ ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), Vector<Vector2>());
return physics_2d_server->space_get_contacts(p_space);
}
virtual int space_get_contact_count(RID p_space) const {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_ID(), 0);
+ ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), 0);
return physics_2d_server->space_get_contact_count(p_space);
}
@@ -144,6 +145,7 @@ public:
FUNC3(area_add_shape, RID, RID, const Transform2D &);
FUNC3(area_set_shape, RID, int, RID);
FUNC3(area_set_shape_transform, RID, int, const Transform2D &);
+ FUNC3(area_set_shape_disabled, RID, int, bool);
FUNC1RC(int, area_get_shape_count, RID);
FUNC2RC(RID, area_get_shape, RID, int);
@@ -151,8 +153,8 @@ public:
FUNC2(area_remove_shape, RID, int);
FUNC1(area_clear_shapes, RID);
- FUNC2(area_attach_object_instance_ID, RID, ObjectID);
- FUNC1RC(ObjectID, area_get_object_instance_ID, RID);
+ FUNC2(area_attach_object_instance_id, RID, ObjectID);
+ FUNC1RC(ObjectID, area_get_object_instance_id, RID);
FUNC3(area_set_param, RID, AreaParameter, const Variant &);
FUNC2(area_set_transform, RID, const Transform2D &);
@@ -161,7 +163,7 @@ public:
FUNC1RC(Transform2D, area_get_transform, RID);
FUNC2(area_set_collision_mask, RID, uint32_t);
- FUNC2(area_set_layer_mask, RID, uint32_t);
+ FUNC2(area_set_collision_layer, RID, uint32_t);
FUNC2(area_set_monitorable, RID, bool);
FUNC2(area_set_pickable, RID, bool);
@@ -190,20 +192,20 @@ public:
FUNC2RC(Variant, body_get_shape_metadata, RID, int);
FUNC2RC(RID, body_get_shape, RID, int);
- FUNC3(body_set_shape_as_trigger, RID, int, bool);
- FUNC2RC(bool, body_is_shape_set_as_trigger, RID, int);
+ FUNC3(body_set_shape_disabled, RID, int, bool);
+ FUNC3(body_set_shape_as_one_way_collision, RID, int, bool);
FUNC2(body_remove_shape, RID, int);
FUNC1(body_clear_shapes, RID);
- FUNC2(body_attach_object_instance_ID, RID, uint32_t);
- FUNC1RC(uint32_t, body_get_object_instance_ID, RID);
+ FUNC2(body_attach_object_instance_id, RID, uint32_t);
+ FUNC1RC(uint32_t, body_get_object_instance_id, RID);
FUNC2(body_set_continuous_collision_detection_mode, RID, CCDMode);
FUNC1RC(CCDMode, body_get_continuous_collision_detection_mode, RID);
- FUNC2(body_set_layer_mask, RID, uint32_t);
- FUNC1RC(uint32_t, body_get_layer_mask, RID);
+ FUNC2(body_set_collision_layer, RID, uint32_t);
+ FUNC1RC(uint32_t, body_get_collision_layer, RID);
FUNC2(body_set_collision_mask, RID, uint32_t);
FUNC1RC(uint32_t, body_get_collision_mask, RID);
@@ -231,14 +233,8 @@ public:
FUNC2(body_set_max_contacts_reported, RID, int);
FUNC1RC(int, body_get_max_contacts_reported, RID);
- FUNC2(body_set_one_way_collision_direction, RID, const Vector2 &);
- FUNC1RC(Vector2, body_get_one_way_collision_direction, RID);
-
- FUNC2(body_set_one_way_collision_max_depth, RID, real_t);
- FUNC1RC(real_t, body_get_one_way_collision_max_depth, RID);
-
- FUNC2(body_set_contacts_reported_depth_treshold, RID, real_t);
- FUNC1RC(real_t, body_get_contacts_reported_depth_treshold, RID);
+ FUNC2(body_set_contacts_reported_depth_threshold, RID, real_t);
+ FUNC1RC(real_t, body_get_contacts_reported_depth_threshold, RID);
FUNC2(body_set_omit_force_integration, RID, bool);
FUNC1RC(bool, body_is_omitting_force_integration, RID);
@@ -253,7 +249,7 @@ public:
bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, real_t p_margin = 0.001, MotionResult *r_result = NULL) {
- ERR_FAIL_COND_V(main_thread != Thread::get_caller_ID(), false);
+ ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_margin, r_result);
}
diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp
index 32d632453a..e153ee985c 100644
--- a/servers/physics_2d/shape_2d_sw.cpp
+++ b/servers/physics_2d/shape_2d_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -196,7 +197,7 @@ Variant RayShape2DSW::get_data() const {
void SegmentShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
- if (Math::abs(p_normal.dot(n)) > _SEGMENT_IS_VALID_SUPPORT_TRESHOLD) {
+ if (Math::abs(p_normal.dot(n)) > _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) {
r_supports[0] = a;
r_supports[1] = b;
r_amount = 2;
@@ -245,12 +246,12 @@ void SegmentShape2DSW::set_data(const Variant &p_data) {
ERR_FAIL_COND(p_data.get_type() != Variant::RECT2);
Rect2 r = p_data;
- a = r.pos;
+ a = r.position;
b = r.size;
n = (b - a).tangent();
Rect2 aabb;
- aabb.pos = a;
+ aabb.position = a;
aabb.expand_to(b);
if (aabb.size.x == 0)
aabb.size.x = 0.001;
@@ -262,7 +263,7 @@ void SegmentShape2DSW::set_data(const Variant &p_data) {
Variant SegmentShape2DSW::get_data() const {
Rect2 r;
- r.pos = a;
+ r.position = a;
r.size = b;
return r;
}
@@ -336,7 +337,7 @@ void RectangleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_suppor
Vector2 ag;
ag[i] = 1.0;
real_t dp = ag.dot(p_normal);
- if (Math::abs(dp) < _SEGMENT_IS_VALID_SUPPORT_TRESHOLD)
+ if (Math::abs(dp) < _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)
continue;
real_t sgn = dp > 0 ? 1.0 : -1.0;
@@ -399,7 +400,7 @@ void CapsuleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports
real_t d = n.y;
- if (Math::abs(d) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_TRESHOLD)) {
+ if (Math::abs(d) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) {
// make it flat
n.y = 0.0;
@@ -546,7 +547,7 @@ void ConvexPolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_su
}
//test segment
- if (points[i].normal.dot(p_normal) > _SEGMENT_IS_VALID_SUPPORT_TRESHOLD) {
+ if (points[i].normal.dot(p_normal) > _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) {
r_amount = 2;
r_supports[0] = points[i].pos;
@@ -620,13 +621,13 @@ bool ConvexPolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vec
real_t ConvexPolygonShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
Rect2 aabb;
- aabb.pos = points[0].pos * p_scale;
+ aabb.position = points[0].pos * p_scale;
for (int i = 0; i < point_count; i++) {
aabb.expand_to(points[i].pos * p_scale);
}
- return p_mass * aabb.size.dot(aabb.size) / 12.0 + p_mass * (aabb.pos + aabb.size * 0.5).length_squared();
+ return p_mass * aabb.size.dot(aabb.size) / 12.0 + p_mass * (aabb.position + aabb.size * 0.5).length_squared();
}
void ConvexPolygonShape2DSW::set_data(const Variant &p_data) {
@@ -676,7 +677,7 @@ void ConvexPolygonShape2DSW::set_data(const Variant &p_data) {
ERR_FAIL_COND(point_count == 0);
Rect2 aabb;
- aabb.pos = points[0].pos;
+ aabb.position = points[0].pos;
for (int i = 1; i < point_count; i++)
aabb.expand_to(points[i].pos);
@@ -941,7 +942,7 @@ void ConcavePolygonShape2DSW::set_data(const Variant &p_data) {
}
points.resize(pointmap.size());
- aabb.pos = pointmap.front()->key();
+ aabb.position = pointmap.front()->key();
for (Map<Point2, int>::Element *E = pointmap.front(); E; E = E->next()) {
aabb.expand_to(E->key());
@@ -952,7 +953,7 @@ void ConcavePolygonShape2DSW::set_data(const Variant &p_data) {
main_vbh.resize(segments.size());
for (int i = 0; i < main_vbh.size(); i++) {
- main_vbh[i].aabb.pos = points[segments[i].points[0]];
+ main_vbh[i].aabb.position = points[segments[i].points[0]];
main_vbh[i].aabb.expand_to(points[segments[i].points[1]]);
main_vbh[i].left = -1;
main_vbh[i].right = i;
diff --git a/servers/physics_2d/shape_2d_sw.h b/servers/physics_2d/shape_2d_sw.h
index 00d86da7fb..a75a4338e7 100644
--- a/servers/physics_2d/shape_2d_sw.h
+++ b/servers/physics_2d/shape_2d_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -30,7 +31,7 @@
#define SHAPE_2D_2DSW_H
#include "servers/physics_2d_server.h"
-#define _SEGMENT_IS_VALID_SUPPORT_TRESHOLD 0.99998
+#define _SEGMENT_IS_VALID_SUPPORT_THRESHOLD 0.99998
/*
@@ -105,7 +106,7 @@ public:
if (r_amount == 1) {
- if (Math::abs(p_normal.dot(p_cast.normalized())) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_TRESHOLD)) {
+ if (Math::abs(p_normal.dot(p_cast.normalized())) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) {
//make line because they are parallel
r_amount = 2;
r_supports[1] = r_supports[0] + p_cast;
@@ -116,7 +117,7 @@ public:
} else {
- if (Math::abs(p_normal.dot(p_cast.normalized())) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_TRESHOLD)) {
+ if (Math::abs(p_normal.dot(p_cast.normalized())) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) {
//optimize line and make it larger because they are parallel
if ((r_supports[1] - r_supports[0]).dot(p_cast) > 0) {
//larger towards 1
@@ -512,7 +513,7 @@ class ConcavePolygonShape2DSW : public ConcaveShape2DSW {
_FORCE_INLINE_ bool operator()(const BVH &a, const BVH &b) const {
- return (a.aabb.pos.x + a.aabb.size.x * 0.5) < (b.aabb.pos.x + b.aabb.size.x * 0.5);
+ return (a.aabb.position.x + a.aabb.size.x * 0.5) < (b.aabb.position.x + b.aabb.size.x * 0.5);
}
};
@@ -520,7 +521,7 @@ class ConcavePolygonShape2DSW : public ConcaveShape2DSW {
_FORCE_INLINE_ bool operator()(const BVH &a, const BVH &b) const {
- return (a.aabb.pos.y + a.aabb.size.y * 0.5) < (b.aabb.pos.y + b.aabb.size.y * 0.5);
+ return (a.aabb.position.y + a.aabb.size.y * 0.5) < (b.aabb.position.y + b.aabb.size.y * 0.5);
}
};
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index a858a20f2c..29f879d8e9 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -30,9 +31,9 @@
#include "collision_solver_2d_sw.h"
#include "physics_2d_server_sw.h"
-_FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_object, uint32_t p_layer_mask, uint32_t p_type_mask) {
+_FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_object, uint32_t p_collision_layer, uint32_t p_type_mask) {
- if ((p_object->get_layer_mask() & p_layer_mask) == 0)
+ if ((p_object->get_collision_layer() & p_collision_layer) == 0)
return false;
if (p_object->get_type() == CollisionObject2DSW::TYPE_AREA)
@@ -43,13 +44,13 @@ _FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_objec
return (1 << body->get_mode()) & p_type_mask;
}
-int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask, bool p_pick_point) {
+int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask, bool p_pick_point) {
if (p_result_max <= 0)
return 0;
Rect2 aabb;
- aabb.pos = p_point - Vector2(0.00001, 0.00001);
+ aabb.position = p_point - Vector2(0.00001, 0.00001);
aabb.size = Vector2(0.00002, 0.00002);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@@ -58,7 +59,7 @@ int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeRe
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
if (p_exclude.has(space->intersection_query_results[i]->get_self()))
@@ -94,7 +95,7 @@ int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeRe
return cc;
}
-bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
ERR_FAIL_COND_V(space->locked, false);
@@ -116,7 +117,7 @@ bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vec
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
if (p_exclude.has(space->intersection_query_results[i]->get_self()))
@@ -174,7 +175,7 @@ bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vec
return true;
}
-int Physics2DDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+int Physics2DDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
if (p_result_max <= 0)
return 0;
@@ -191,7 +192,7 @@ int Physics2DDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Trans
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
if (p_exclude.has(space->intersection_query_results[i]->get_self()))
@@ -216,13 +217,13 @@ int Physics2DDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Trans
return cc;
}
-bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
Shape2DSW *shape = Physics2DServerSW::singletonsw->shape_owner.get(p_shape);
ERR_FAIL_COND_V(!shape, false);
Rect2 aabb = p_xform.xform(shape->get_aabb());
- aabb = aabb.merge(Rect2(aabb.pos + p_motion, aabb.size)); //motion
+ aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion
aabb = aabb.grow(p_margin);
/*
@@ -237,7 +238,7 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transfor
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
if (p_exclude.has(space->intersection_query_results[i]->get_self()))
@@ -264,14 +265,6 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transfor
//test initial overlap
if (CollisionSolver2DSW::solve(shape, p_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, p_margin)) {
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
- //if one way collision direction ignore initial overlap
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- if (body->get_one_way_collision_direction() != Vector2()) {
- continue;
- }
- }
-
return false;
}
@@ -296,27 +289,6 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transfor
}
}
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
-
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- if (body->get_one_way_collision_direction() != Vector2()) {
-
- Vector2 cd[2];
- Physics2DServerSW::CollCbkData cbk;
- cbk.max = 1;
- cbk.amount = 0;
- cbk.ptr = cd;
- cbk.valid_dir = body->get_one_way_collision_direction();
- cbk.valid_depth = body->get_one_way_collision_max_depth();
-
- Vector2 sep = mnormal; //important optimization for this to work fast enough
- bool collided = CollisionSolver2DSW::solve(shape, p_xform, p_motion * (hi + space->contact_max_allowed_penetration), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), Physics2DServerSW::_shape_col_cbk, &cbk, &sep, p_margin);
- if (!collided || cbk.amount == 0) {
- continue;
- }
- }
- }
-
if (low < best_safe) {
best_safe = low;
best_unsafe = hi;
@@ -329,7 +301,7 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transfor
return true;
}
-bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
if (p_result_max <= 0)
return 0;
@@ -338,7 +310,7 @@ bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &
ERR_FAIL_COND_V(!shape, 0);
Rect2 aabb = p_shape_xform.xform(shape->get_aabb());
- aabb = aabb.merge(Rect2(aabb.pos + p_motion, aabb.size)); //motion
+ aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion
aabb = aabb.grow(p_margin);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@@ -360,7 +332,7 @@ bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
@@ -368,15 +340,9 @@ bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &
if (p_exclude.has(col_obj->get_self()))
continue;
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- cbk.valid_dir = body->get_one_way_collision_direction();
- cbk.valid_depth = body->get_one_way_collision_max_depth();
- } else {
- cbk.valid_dir = Vector2();
- cbk.valid_depth = 0;
- }
+ cbk.valid_dir = Vector2();
+ cbk.valid_depth = 0;
if (CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, NULL, p_margin)) {
collided = p_result_max == 0 || cbk.amount > 0;
@@ -406,13 +372,10 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B,
_RestCallbackData2D *rd = (_RestCallbackData2D *)p_userdata;
if (rd->valid_dir != Vector2()) {
-
- if (rd->valid_dir != Vector2()) {
- if (p_point_A.distance_squared_to(p_point_B) > rd->valid_depth * rd->valid_depth)
- return;
- if (rd->valid_dir.dot((p_point_A - p_point_B).normalized()) < Math_PI * 0.25)
- return;
- }
+ if (p_point_A.distance_squared_to(p_point_B) > rd->valid_depth * rd->valid_depth)
+ return;
+ if (rd->valid_dir.dot((p_point_A - p_point_B).normalized()) < Math_PI * 0.25)
+ return;
}
Vector2 contact_rel = p_point_B - p_point_A;
@@ -427,13 +390,13 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B,
rd->best_shape = rd->shape;
}
-bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
Shape2DSW *shape = Physics2DServerSW::singletonsw->shape_owner.get(p_shape);
ERR_FAIL_COND_V(!shape, 0);
Rect2 aabb = p_shape_xform.xform(shape->get_aabb());
- aabb = aabb.merge(Rect2(aabb.pos + p_motion, aabb.size)); //motion
+ aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion
aabb = aabb.grow(p_margin);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@@ -445,7 +408,7 @@ bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_sh
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
@@ -454,16 +417,8 @@ bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_sh
if (p_exclude.has(col_obj->get_self()))
continue;
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
-
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- rcd.valid_dir = body->get_one_way_collision_direction();
- rcd.valid_depth = body->get_one_way_collision_max_depth();
- } else {
- rcd.valid_dir = Vector2();
- rcd.valid_depth = 0;
- }
-
+ rcd.valid_dir = Vector2();
+ rcd.valid_depth = 0;
rcd.object = col_obj;
rcd.shape = shape_idx;
bool sc = CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, NULL, p_margin);
@@ -516,7 +471,7 @@ int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) {
keep = false;
else if (static_cast<Body2DSW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self()))
keep = false;
- else if (static_cast<Body2DSW *>(intersection_query_results[i])->is_shape_set_as_trigger(intersection_query_subindex_results[i]))
+ else if (static_cast<Body2DSW *>(intersection_query_results[i])->is_shape_set_as_disabled(intersection_query_subindex_results[i]))
keep = false;
if (!keep) {
@@ -588,7 +543,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
int amount = _cull_aabb_for_body(p_body, body_aabb);
for (int j = 0; j < p_body->get_shape_count(); j++) {
- if (p_body->is_shape_set_as_trigger(j))
+ if (p_body->is_shape_set_as_disabled(j))
continue;
Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j);
@@ -598,18 +553,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
const CollisionObject2DSW *col_obj = intersection_query_results[i];
int shape_idx = intersection_query_subindex_results[i];
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
-
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
+ if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
- Vector2 cdir = body->get_one_way_collision_direction();
- /*
- if (cdir!=Vector2() && p_motion.dot(cdir)<0)
- continue;
- */
-
- cbk.valid_dir = cdir;
- cbk.valid_depth = body->get_one_way_collision_max_depth();
+ cbk.valid_dir = body_shape_xform.get_axis(1).normalized();
+ cbk.valid_depth = p_margin; //only valid depth is the collision margin
} else {
cbk.valid_dir = Vector2();
cbk.valid_depth = 0;
@@ -655,7 +602,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
}
body_transform.elements[2] += recover_motion;
- body_aabb.pos += recover_motion;
+ body_aabb.position += recover_motion;
recover_attempts--;
@@ -670,14 +617,14 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
// STEP 2 ATTEMPT MOTION
Rect2 motion_aabb = body_aabb;
- motion_aabb.pos += p_motion;
+ motion_aabb.position += p_motion;
motion_aabb = motion_aabb.merge(body_aabb);
int amount = _cull_aabb_for_body(p_body, motion_aabb);
for (int j = 0; j < p_body->get_shape_count(); j++) {
- if (p_body->is_shape_set_as_trigger(j))
+ if (p_body->is_shape_set_as_disabled(j))
continue;
Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j);
@@ -702,12 +649,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
//test initial overlap
if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) {
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
- //if one way collision direction ignore initial overlap
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- if (body->get_one_way_collision_direction() != Vector2()) {
- continue;
- }
+ if (col_obj->is_shape_set_as_one_way_collision(j)) {
+ continue;
}
stuck = true;
@@ -719,7 +662,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
real_t hi = 1;
Vector2 mnormal = p_motion.normalized();
- for (int i = 0; i < 8; i++) { //steps should be customizable..
+ for (int k = 0; k < 8; k++) { //steps should be customizable..
real_t ofs = (low + hi) * 0.5;
@@ -735,24 +678,21 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
}
}
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
-
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- if (body->get_one_way_collision_direction() != Vector2()) {
+ if (col_obj->is_shape_set_as_one_way_collision(j)) {
- Vector2 cd[2];
- Physics2DServerSW::CollCbkData cbk;
- cbk.max = 1;
- cbk.amount = 0;
- cbk.ptr = cd;
- cbk.valid_dir = body->get_one_way_collision_direction();
- cbk.valid_depth = body->get_one_way_collision_max_depth();
+ Vector2 cd[2];
+ Physics2DServerSW::CollCbkData cbk;
+ cbk.max = 1;
+ cbk.amount = 0;
+ cbk.ptr = cd;
+ cbk.valid_dir = body_shape_xform.get_axis(1).normalized();
+ ;
+ cbk.valid_depth = 10e20;
- Vector2 sep = mnormal; //important optimization for this to work fast enough
- bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * (hi + contact_max_allowed_penetration), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), Physics2DServerSW::_shape_col_cbk, &cbk, &sep, 0);
- if (!collided || cbk.amount == 0) {
- continue;
- }
+ Vector2 sep = mnormal; //important optimization for this to work fast enough
+ bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * (hi + contact_max_allowed_penetration), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), Physics2DServerSW::_shape_col_cbk, &cbk, &sep, 0);
+ if (!collided || cbk.amount == 0) {
+ continue;
}
}
@@ -806,7 +746,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
Transform2D body_shape_xform = ugt * p_body->get_shape_transform(best_shape);
Shape2DSW *body_shape = p_body->get_shape(best_shape);
- body_aabb.pos += p_motion * unsafe;
+ body_aabb.position += p_motion * unsafe;
int amount = _cull_aabb_for_body(p_body, body_aabb);
@@ -815,11 +755,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
const CollisionObject2DSW *col_obj = intersection_query_results[i];
int shape_idx = intersection_query_subindex_results[i];
- if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
+ if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
- const Body2DSW *body = static_cast<const Body2DSW *>(col_obj);
- rcd.valid_dir = body->get_one_way_collision_direction();
- rcd.valid_depth = body->get_one_way_collision_max_depth();
+ rcd.valid_dir = body_shape_xform.get_axis(1).normalized();
+ rcd.valid_depth = 10e20;
} else {
rcd.valid_dir = Vector2();
rcd.valid_depth = 0;
@@ -838,6 +777,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
r_result->collider = rcd.best_object->get_self();
r_result->collider_id = rcd.best_object->get_instance_id();
r_result->collider_shape = rcd.best_shape;
+ r_result->collision_local_shape = best_shape;
r_result->collision_normal = rcd.best_normal;
r_result->collision_point = rcd.best_contact;
r_result->collider_metadata = rcd.best_object->get_shape_metadata(rcd.best_shape);
@@ -865,162 +805,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
}
return collided;
-
-#if 0
- //give me back regular physics engine logic
- //this is madness
- //and most people using this function will think
- //what it does is simpler than using physics
- //this took about a week to get right..
- //but is it right? who knows at this point..
-
-
- colliding=false;
- ERR_FAIL_COND_V(!is_inside_tree(),Vector2());
- Physics2DDirectSpaceState *dss = Physics2DServer::get_singleton()->space_get_direct_state(get_world_2d()->get_space());
- ERR_FAIL_COND_V(!dss,Vector2());
- const int max_shapes=32;
- Vector2 sr[max_shapes*2];
- int res_shapes;
-
- Set<RID> exclude;
- exclude.insert(get_rid());
-
-
- //recover first
- int recover_attempts=4;
-
- bool collided=false;
- uint32_t mask=0;
- if (collide_static)
- mask|=Physics2DDirectSpaceState::TYPE_MASK_STATIC_BODY;
- if (collide_kinematic)
- mask|=Physics2DDirectSpaceState::TYPE_MASK_KINEMATIC_BODY;
- if (collide_rigid)
- mask|=Physics2DDirectSpaceState::TYPE_MASK_RIGID_BODY;
- if (collide_character)
- mask|=Physics2DDirectSpaceState::TYPE_MASK_CHARACTER_BODY;
-
- //print_line("motion: "+p_motion+" margin: "+rtos(margin));
-
- //print_line("margin: "+rtos(margin));
- do {
-
- //motion recover
- for(int i=0;i<get_shape_count();i++) {
-
- if (is_shape_set_as_trigger(i))
- continue;
- if (dss->collide_shape(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i),Vector2(),margin,sr,max_shapes,res_shapes,exclude,get_layer_mask(),mask))
- collided=true;
-
- }
-
- if (!collided)
- break;
-
- Vector2 recover_motion;
-
- for(int i=0;i<res_shapes;i++) {
-
- Vector2 a = sr[i*2+0];
- Vector2 b = sr[i*2+1];
-
- real_t d = a.distance_to(b);
-
- /*
- if (d<margin)
- continue;
- */
- recover_motion+=(b-a)*0.4;
- }
-
- if (recover_motion==Vector2()) {
- collided=false;
- break;
- }
-
- Matrix32 gt = get_global_transform();
- gt.elements[2]+=recover_motion;
- set_global_transform(gt);
-
- recover_attempts--;
-
- } while (recover_attempts);
-
-
- //move second
- real_t safe = 1.0;
- real_t unsafe = 1.0;
- int best_shape=-1;
-
- for(int i=0;i<get_shape_count();i++) {
-
- if (is_shape_set_as_trigger(i))
- continue;
-
- real_t lsafe,lunsafe;
- bool valid = dss->cast_motion(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), p_motion, 0,lsafe,lunsafe,exclude,get_layer_mask(),mask);
- //print_line("shape: "+itos(i)+" travel:"+rtos(ltravel));
- if (!valid) {
-
- safe=0;
- unsafe=0;
- best_shape=i; //sadly it's the best
- break;
- }
- if (lsafe==1.0) {
- continue;
- }
- if (lsafe < safe) {
-
- safe=lsafe;
- unsafe=lunsafe;
- best_shape=i;
- }
- }
-
-
- //print_line("best shape: "+itos(best_shape)+" motion "+p_motion);
-
- if (safe>=1) {
- //not collided
- colliding=false;
- } else {
-
- //it collided, let's get the rest info in unsafe advance
- Matrix32 ugt = get_global_transform();
- ugt.elements[2]+=p_motion*unsafe;
- Physics2DDirectSpaceState::ShapeRestInfo rest_info;
- bool c2 = dss->rest_info(get_shape(best_shape)->get_rid(), ugt*get_shape_transform(best_shape), Vector2(), margin,&rest_info,exclude,get_layer_mask(),mask);
- if (!c2) {
- //should not happen, but floating point precision is so weird..
-
- colliding=false;
- } else {
-
-
- //print_line("Travel: "+rtos(travel));
- colliding=true;
- collision=rest_info.point;
- normal=rest_info.normal;
- collider=rest_info.collider_id;
- collider_vel=rest_info.linear_velocity;
- collider_shape=rest_info.shape;
- collider_metadata=rest_info.metadata;
- }
-
- }
-
- Vector2 motion=p_motion*safe;
- Matrix32 gt = get_global_transform();
- gt.elements[2]+=motion;
- set_global_transform(gt);
-
- return p_motion-motion;
-
-#endif
- return false;
}
void *Space2DSW::_broadphase_pair(CollisionObject2DSW *A, int p_subindex_A, CollisionObject2DSW *B, int p_subindex_B, void *p_self) {
@@ -1186,8 +970,8 @@ void Space2DSW::set_param(Physics2DServer::SpaceParameter p_param, real_t p_valu
case Physics2DServer::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: contact_recycle_radius = p_value; break;
case Physics2DServer::SPACE_PARAM_CONTACT_MAX_SEPARATION: contact_max_separation = p_value; break;
case Physics2DServer::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: contact_max_allowed_penetration = p_value; break;
- case Physics2DServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_TRESHOLD: body_linear_velocity_sleep_treshold = p_value; break;
- case Physics2DServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_TRESHOLD: body_angular_velocity_sleep_treshold = p_value; break;
+ case Physics2DServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: body_linear_velocity_sleep_threshold = p_value; break;
+ case Physics2DServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: body_angular_velocity_sleep_threshold = p_value; break;
case Physics2DServer::SPACE_PARAM_BODY_TIME_TO_SLEEP: body_time_to_sleep = p_value; break;
case Physics2DServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: constraint_bias = p_value; break;
}
@@ -1200,8 +984,8 @@ real_t Space2DSW::get_param(Physics2DServer::SpaceParameter p_param) const {
case Physics2DServer::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: return contact_recycle_radius;
case Physics2DServer::SPACE_PARAM_CONTACT_MAX_SEPARATION: return contact_max_separation;
case Physics2DServer::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: return contact_max_allowed_penetration;
- case Physics2DServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_TRESHOLD: return body_linear_velocity_sleep_treshold;
- case Physics2DServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_TRESHOLD: return body_angular_velocity_sleep_treshold;
+ case Physics2DServer::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: return body_linear_velocity_sleep_threshold;
+ case Physics2DServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: return body_angular_velocity_sleep_threshold;
case Physics2DServer::SPACE_PARAM_BODY_TIME_TO_SLEEP: return body_time_to_sleep;
case Physics2DServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: return constraint_bias;
}
@@ -1242,8 +1026,8 @@ Space2DSW::Space2DSW() {
contact_max_allowed_penetration = 0.3;
constraint_bias = 0.2;
- body_linear_velocity_sleep_treshold = GLOBAL_DEF("physics/2d/sleep_threashold_linear", 2.0);
- body_angular_velocity_sleep_treshold = GLOBAL_DEF("physics/2d/sleep_threshold_angular", (8.0 / 180.0 * Math_PI));
+ body_linear_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_linear", 2.0);
+ body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_angular", (8.0 / 180.0 * Math_PI));
body_time_to_sleep = GLOBAL_DEF("physics/2d/time_before_sleep", 0.5);
broadphase = BroadPhase2DSW::create_func();
diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h
index 103f328ed2..4bd81c054f 100644
--- a/servers/physics_2d/space_2d_sw.h
+++ b/servers/physics_2d/space_2d_sw.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -35,8 +36,8 @@
#include "body_pair_2d_sw.h"
#include "broad_phase_2d_sw.h"
#include "collision_object_2d_sw.h"
-#include "global_config.h"
#include "hash_map.h"
+#include "project_settings.h"
#include "typedefs.h"
class Physics2DDirectSpaceStateSW : public Physics2DDirectSpaceState {
@@ -46,12 +47,12 @@ class Physics2DDirectSpaceStateSW : public Physics2DDirectSpaceState {
public:
Space2DSW *space;
- virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_point = false);
- virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
- virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
- virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
- virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
- virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_point = false);
+ virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
Physics2DDirectSpaceStateSW();
};
@@ -102,8 +103,8 @@ private:
CollisionObject2DSW *intersection_query_results[INTERSECTION_QUERY_MAX];
int intersection_query_subindex_results[INTERSECTION_QUERY_MAX];
- real_t body_linear_velocity_sleep_treshold;
- real_t body_angular_velocity_sleep_treshold;
+ real_t body_linear_velocity_sleep_threshold;
+ real_t body_angular_velocity_sleep_threshold;
real_t body_time_to_sleep;
bool locked;
@@ -151,8 +152,8 @@ public:
_FORCE_INLINE_ real_t get_contact_max_separation() const { return contact_max_separation; }
_FORCE_INLINE_ real_t get_contact_max_allowed_penetration() const { return contact_max_allowed_penetration; }
_FORCE_INLINE_ real_t get_constraint_bias() const { return constraint_bias; }
- _FORCE_INLINE_ real_t get_body_linear_velocity_sleep_treshold() const { return body_linear_velocity_sleep_treshold; }
- _FORCE_INLINE_ real_t get_body_angular_velocity_sleep_treshold() const { return body_angular_velocity_sleep_treshold; }
+ _FORCE_INLINE_ real_t get_body_linear_velocity_sleep_threshold() const { return body_linear_velocity_sleep_threshold; }
+ _FORCE_INLINE_ real_t get_body_angular_velocity_sleep_threshold() const { return body_angular_velocity_sleep_threshold; }
_FORCE_INLINE_ real_t get_body_time_to_sleep() const { return body_time_to_sleep; }
void update();
diff --git a/servers/physics_2d/step_2d_sw.cpp b/servers/physics_2d/step_2d_sw.cpp
index 55bc62975f..f43fef4eef 100644
--- a/servers/physics_2d/step_2d_sw.cpp
+++ b/servers/physics_2d/step_2d_sw.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics_2d/step_2d_sw.h b/servers/physics_2d/step_2d_sw.h
index c743358b6a..bdcb34f3ae 100644
--- a/servers/physics_2d/step_2d_sw.h
+++ b/servers/physics_2d/step_2d_sw.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp
index f922b8f7a1..27732b9c29 100644
--- a/servers/physics_2d_server.cpp
+++ b/servers/physics_2d_server.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -99,11 +100,11 @@ void Physics2DDirectBodyState::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_contact_collider_id", "contact_idx"), &Physics2DDirectBodyState::get_contact_collider_id);
ClassDB::bind_method(D_METHOD("get_contact_collider_object", "contact_idx"), &Physics2DDirectBodyState::get_contact_collider_object);
ClassDB::bind_method(D_METHOD("get_contact_collider_shape", "contact_idx"), &Physics2DDirectBodyState::get_contact_collider_shape);
- ClassDB::bind_method(D_METHOD("get_contact_collider_shape_metadata:Variant", "contact_idx"), &Physics2DDirectBodyState::get_contact_collider_shape_metadata);
+ ClassDB::bind_method(D_METHOD("get_contact_collider_shape_metadata", "contact_idx"), &Physics2DDirectBodyState::get_contact_collider_shape_metadata);
ClassDB::bind_method(D_METHOD("get_contact_collider_velocity_at_pos", "contact_idx"), &Physics2DDirectBodyState::get_contact_collider_velocity_at_pos);
ClassDB::bind_method(D_METHOD("get_step"), &Physics2DDirectBodyState::get_step);
ClassDB::bind_method(D_METHOD("integrate_forces"), &Physics2DDirectBodyState::integrate_forces);
- ClassDB::bind_method(D_METHOD("get_space_state:Physics2DDirectSpaceState"), &Physics2DDirectBodyState::get_space_state);
+ ClassDB::bind_method(D_METHOD("get_space_state"), &Physics2DDirectBodyState::get_space_state);
}
Physics2DDirectBodyState::Physics2DDirectBodyState() {}
@@ -153,13 +154,13 @@ float Physics2DShapeQueryParameters::get_margin() const {
return margin;
}
-void Physics2DShapeQueryParameters::set_layer_mask(int p_layer_mask) {
+void Physics2DShapeQueryParameters::set_collision_layer(int p_collision_layer) {
- layer_mask = p_layer_mask;
+ collision_layer = p_collision_layer;
}
-int Physics2DShapeQueryParameters::get_layer_mask() const {
+int Physics2DShapeQueryParameters::get_collision_layer() const {
- return layer_mask;
+ return collision_layer;
}
void Physics2DShapeQueryParameters::set_object_type_mask(int p_object_type_mask) {
@@ -190,7 +191,7 @@ Vector<RID> Physics2DShapeQueryParameters::get_exclude() const {
void Physics2DShapeQueryParameters::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_shape", "shape:Shape2D"), &Physics2DShapeQueryParameters::set_shape);
+ ClassDB::bind_method(D_METHOD("set_shape", "shape"), &Physics2DShapeQueryParameters::set_shape);
ClassDB::bind_method(D_METHOD("set_shape_rid", "shape"), &Physics2DShapeQueryParameters::set_shape_rid);
ClassDB::bind_method(D_METHOD("get_shape_rid"), &Physics2DShapeQueryParameters::get_shape_rid);
@@ -203,8 +204,8 @@ void Physics2DShapeQueryParameters::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_margin", "margin"), &Physics2DShapeQueryParameters::set_margin);
ClassDB::bind_method(D_METHOD("get_margin"), &Physics2DShapeQueryParameters::get_margin);
- ClassDB::bind_method(D_METHOD("set_layer_mask", "layer_mask"), &Physics2DShapeQueryParameters::set_layer_mask);
- ClassDB::bind_method(D_METHOD("get_layer_mask"), &Physics2DShapeQueryParameters::get_layer_mask);
+ ClassDB::bind_method(D_METHOD("set_collision_layer", "collision_layer"), &Physics2DShapeQueryParameters::set_collision_layer);
+ ClassDB::bind_method(D_METHOD("get_collision_layer"), &Physics2DShapeQueryParameters::get_collision_layer);
ClassDB::bind_method(D_METHOD("set_object_type_mask", "object_type_mask"), &Physics2DShapeQueryParameters::set_object_type_mask);
ClassDB::bind_method(D_METHOD("get_object_type_mask"), &Physics2DShapeQueryParameters::get_object_type_mask);
@@ -216,7 +217,7 @@ void Physics2DShapeQueryParameters::_bind_methods() {
Physics2DShapeQueryParameters::Physics2DShapeQueryParameters() {
margin = 0;
- layer_mask = 0x7FFFFFFF;
+ collision_layer = 0x7FFFFFFF;
object_type_mask = Physics2DDirectSpaceState::TYPE_MASK_COLLISION;
}
@@ -244,11 +245,11 @@ Dictionary Physics2DDirectSpaceState::_intersect_ray(const Vector2 &p_from, cons
return d;
}
-Array Physics2DDirectSpaceState::_intersect_shape(const Ref<Physics2DShapeQueryParameters> &psq, int p_max_results) {
+Array Physics2DDirectSpaceState::_intersect_shape(const Ref<Physics2DShapeQueryParameters> &p_shape_query, int p_max_results) {
Vector<ShapeResult> sr;
sr.resize(p_max_results);
- int rc = intersect_shape(psq->shape, psq->transform, psq->motion, psq->margin, sr.ptr(), sr.size(), psq->exclude, psq->layer_mask, psq->object_type_mask);
+ int rc = intersect_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, sr.ptr(), sr.size(), p_shape_query->exclude, p_shape_query->collision_layer, p_shape_query->object_type_mask);
Array ret;
ret.resize(rc);
for (int i = 0; i < rc; i++) {
@@ -265,10 +266,10 @@ Array Physics2DDirectSpaceState::_intersect_shape(const Ref<Physics2DShapeQueryP
return ret;
}
-Array Physics2DDirectSpaceState::_cast_motion(const Ref<Physics2DShapeQueryParameters> &psq) {
+Array Physics2DDirectSpaceState::_cast_motion(const Ref<Physics2DShapeQueryParameters> &p_shape_query) {
float closest_safe, closest_unsafe;
- bool res = cast_motion(psq->shape, psq->transform, psq->motion, psq->margin, closest_safe, closest_unsafe, psq->exclude, psq->layer_mask, psq->object_type_mask);
+ bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_layer, p_shape_query->object_type_mask);
if (!res)
return Array();
Array ret;
@@ -306,12 +307,12 @@ Array Physics2DDirectSpaceState::_intersect_point(const Vector2 &p_point, int p_
return r;
}
-Array Physics2DDirectSpaceState::_collide_shape(const Ref<Physics2DShapeQueryParameters> &psq, int p_max_results) {
+Array Physics2DDirectSpaceState::_collide_shape(const Ref<Physics2DShapeQueryParameters> &p_shape_query, int p_max_results) {
Vector<Vector2> ret;
ret.resize(p_max_results * 2);
int rc = 0;
- bool res = collide_shape(psq->shape, psq->transform, psq->motion, psq->margin, ret.ptr(), p_max_results, rc, psq->exclude, psq->layer_mask, psq->object_type_mask);
+ bool res = collide_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, ret.ptr(), p_max_results, rc, p_shape_query->exclude, p_shape_query->collision_layer, p_shape_query->object_type_mask);
if (!res)
return Array();
Array r;
@@ -320,11 +321,11 @@ Array Physics2DDirectSpaceState::_collide_shape(const Ref<Physics2DShapeQueryPar
r[i] = ret[i];
return r;
}
-Dictionary Physics2DDirectSpaceState::_get_rest_info(const Ref<Physics2DShapeQueryParameters> &psq) {
+Dictionary Physics2DDirectSpaceState::_get_rest_info(const Ref<Physics2DShapeQueryParameters> &p_shape_query) {
ShapeRestInfo sri;
- bool res = rest_info(psq->shape, psq->transform, psq->motion, psq->margin, &sri, psq->exclude, psq->layer_mask, psq->object_type_mask);
+ bool res = rest_info(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, &sri, p_shape_query->exclude, p_shape_query->collision_layer, p_shape_query->object_type_mask);
Dictionary r;
if (!res)
return r;
@@ -345,12 +346,12 @@ Physics2DDirectSpaceState::Physics2DDirectSpaceState() {
void Physics2DDirectSpaceState::_bind_methods() {
- ClassDB::bind_method(D_METHOD("intersect_point", "point", "max_results", "exclude", "layer_mask", "type_mask"), &Physics2DDirectSpaceState::_intersect_point, DEFVAL(32), DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(TYPE_MASK_COLLISION));
- ClassDB::bind_method(D_METHOD("intersect_ray:Dictionary", "from", "to", "exclude", "layer_mask", "type_mask"), &Physics2DDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(TYPE_MASK_COLLISION));
- ClassDB::bind_method(D_METHOD("intersect_shape", "shape:Physics2DShapeQueryParameters", "max_results"), &Physics2DDirectSpaceState::_intersect_shape, DEFVAL(32));
- ClassDB::bind_method(D_METHOD("cast_motion", "shape:Physics2DShapeQueryParameters"), &Physics2DDirectSpaceState::_cast_motion);
- ClassDB::bind_method(D_METHOD("collide_shape", "shape:Physics2DShapeQueryParameters", "max_results"), &Physics2DDirectSpaceState::_collide_shape, DEFVAL(32));
- ClassDB::bind_method(D_METHOD("get_rest_info", "shape:Physics2DShapeQueryParameters"), &Physics2DDirectSpaceState::_get_rest_info);
+ ClassDB::bind_method(D_METHOD("intersect_point", "point", "max_results", "exclude", "collision_layer", "type_mask"), &Physics2DDirectSpaceState::_intersect_point, DEFVAL(32), DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(TYPE_MASK_COLLISION));
+ ClassDB::bind_method(D_METHOD("intersect_ray", "from", "to", "exclude", "collision_layer", "type_mask"), &Physics2DDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(TYPE_MASK_COLLISION));
+ ClassDB::bind_method(D_METHOD("intersect_shape", "shape", "max_results"), &Physics2DDirectSpaceState::_intersect_shape, DEFVAL(32));
+ ClassDB::bind_method(D_METHOD("cast_motion", "shape"), &Physics2DDirectSpaceState::_cast_motion);
+ ClassDB::bind_method(D_METHOD("collide_shape", "shape", "max_results"), &Physics2DDirectSpaceState::_collide_shape, DEFVAL(32));
+ ClassDB::bind_method(D_METHOD("get_rest_info", "shape"), &Physics2DDirectSpaceState::_get_rest_info);
//ClassDB::bind_method(D_METHOD("cast_motion","shape","xform","motion","exclude","umask"),&Physics2DDirectSpaceState::_intersect_shape,DEFVAL(Array()),DEFVAL(0));
BIND_CONSTANT(TYPE_MASK_STATIC_BODY);
@@ -483,7 +484,7 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("space_is_active", "space"), &Physics2DServer::space_is_active);
ClassDB::bind_method(D_METHOD("space_set_param", "space", "param", "value"), &Physics2DServer::space_set_param);
ClassDB::bind_method(D_METHOD("space_get_param", "space", "param"), &Physics2DServer::space_get_param);
- ClassDB::bind_method(D_METHOD("space_get_direct_state:Physics2DDirectSpaceState", "space"), &Physics2DServer::space_get_direct_state);
+ ClassDB::bind_method(D_METHOD("space_get_direct_state", "space"), &Physics2DServer::space_get_direct_state);
ClassDB::bind_method(D_METHOD("area_create"), &Physics2DServer::area_create);
ClassDB::bind_method(D_METHOD("area_set_space", "area", "space"), &Physics2DServer::area_set_space);
@@ -495,6 +496,7 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("area_add_shape", "area", "shape", "transform"), &Physics2DServer::area_add_shape, DEFVAL(Transform2D()));
ClassDB::bind_method(D_METHOD("area_set_shape", "area", "shape_idx", "shape"), &Physics2DServer::area_set_shape);
ClassDB::bind_method(D_METHOD("area_set_shape_transform", "area", "shape_idx", "transform"), &Physics2DServer::area_set_shape_transform);
+ ClassDB::bind_method(D_METHOD("area_set_shape_disabled", "area", "shape_idx", "disable"), &Physics2DServer::area_set_shape_disabled);
ClassDB::bind_method(D_METHOD("area_get_shape_count", "area"), &Physics2DServer::area_get_shape_count);
ClassDB::bind_method(D_METHOD("area_get_shape", "area", "shape_idx"), &Physics2DServer::area_get_shape);
@@ -503,7 +505,7 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("area_remove_shape", "area", "shape_idx"), &Physics2DServer::area_remove_shape);
ClassDB::bind_method(D_METHOD("area_clear_shapes", "area"), &Physics2DServer::area_clear_shapes);
- ClassDB::bind_method(D_METHOD("area_set_layer_mask", "area", "mask"), &Physics2DServer::area_set_layer_mask);
+ ClassDB::bind_method(D_METHOD("area_set_collision_layer", "area", "layer"), &Physics2DServer::area_set_collision_layer);
ClassDB::bind_method(D_METHOD("area_set_collision_mask", "area", "mask"), &Physics2DServer::area_set_collision_mask);
ClassDB::bind_method(D_METHOD("area_set_param", "area", "param", "value"), &Physics2DServer::area_set_param);
@@ -512,8 +514,8 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("area_get_param", "area", "param"), &Physics2DServer::area_get_param);
ClassDB::bind_method(D_METHOD("area_get_transform", "area"), &Physics2DServer::area_get_transform);
- ClassDB::bind_method(D_METHOD("area_attach_object_instance_ID", "area", "id"), &Physics2DServer::area_attach_object_instance_ID);
- ClassDB::bind_method(D_METHOD("area_get_object_instance_ID", "area"), &Physics2DServer::area_get_object_instance_ID);
+ ClassDB::bind_method(D_METHOD("area_attach_object_instance_id", "area", "id"), &Physics2DServer::area_attach_object_instance_id);
+ ClassDB::bind_method(D_METHOD("area_get_object_instance_id", "area"), &Physics2DServer::area_get_object_instance_id);
ClassDB::bind_method(D_METHOD("area_set_monitor_callback", "area", "receiver", "method"), &Physics2DServer::area_set_monitor_callback);
@@ -538,17 +540,17 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_remove_shape", "body", "shape_idx"), &Physics2DServer::body_remove_shape);
ClassDB::bind_method(D_METHOD("body_clear_shapes", "body"), &Physics2DServer::body_clear_shapes);
- ClassDB::bind_method(D_METHOD("body_set_shape_as_trigger", "body", "shape_idx", "enable"), &Physics2DServer::body_set_shape_as_trigger);
- ClassDB::bind_method(D_METHOD("body_is_shape_set_as_trigger", "body", "shape_idx"), &Physics2DServer::body_is_shape_set_as_trigger);
+ ClassDB::bind_method(D_METHOD("body_set_shape_disabled", "body", "shape_idx", "disable"), &Physics2DServer::body_set_shape_disabled);
+ ClassDB::bind_method(D_METHOD("body_set_shape_as_one_way_collision", "body", "shape_idx", "enable"), &Physics2DServer::body_set_shape_as_one_way_collision);
- ClassDB::bind_method(D_METHOD("body_attach_object_instance_ID", "body", "id"), &Physics2DServer::body_attach_object_instance_ID);
- ClassDB::bind_method(D_METHOD("body_get_object_instance_ID", "body"), &Physics2DServer::body_get_object_instance_ID);
+ ClassDB::bind_method(D_METHOD("body_attach_object_instance_id", "body", "id"), &Physics2DServer::body_attach_object_instance_id);
+ ClassDB::bind_method(D_METHOD("body_get_object_instance_id", "body"), &Physics2DServer::body_get_object_instance_id);
ClassDB::bind_method(D_METHOD("body_set_continuous_collision_detection_mode", "body", "mode"), &Physics2DServer::body_set_continuous_collision_detection_mode);
ClassDB::bind_method(D_METHOD("body_get_continuous_collision_detection_mode", "body"), &Physics2DServer::body_get_continuous_collision_detection_mode);
- ClassDB::bind_method(D_METHOD("body_set_layer_mask", "body", "mask"), &Physics2DServer::body_set_layer_mask);
- ClassDB::bind_method(D_METHOD("body_get_layer_mask", "body"), &Physics2DServer::body_get_layer_mask);
+ ClassDB::bind_method(D_METHOD("body_set_collision_layer", "body", "layer"), &Physics2DServer::body_set_collision_layer);
+ ClassDB::bind_method(D_METHOD("body_get_collision_layer", "body"), &Physics2DServer::body_get_collision_layer);
ClassDB::bind_method(D_METHOD("body_set_collision_mask", "body", "mask"), &Physics2DServer::body_set_collision_mask);
ClassDB::bind_method(D_METHOD("body_get_collision_mask", "body"), &Physics2DServer::body_get_collision_mask);
@@ -570,18 +572,12 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_set_max_contacts_reported", "body", "amount"), &Physics2DServer::body_set_max_contacts_reported);
ClassDB::bind_method(D_METHOD("body_get_max_contacts_reported", "body"), &Physics2DServer::body_get_max_contacts_reported);
- ClassDB::bind_method(D_METHOD("body_set_one_way_collision_direction", "body", "normal"), &Physics2DServer::body_set_one_way_collision_direction);
- ClassDB::bind_method(D_METHOD("body_get_one_way_collision_direction", "body"), &Physics2DServer::body_get_one_way_collision_direction);
-
- ClassDB::bind_method(D_METHOD("body_set_one_way_collision_max_depth", "body", "depth"), &Physics2DServer::body_set_one_way_collision_max_depth);
- ClassDB::bind_method(D_METHOD("body_get_one_way_collision_max_depth", "body"), &Physics2DServer::body_get_one_way_collision_max_depth);
-
ClassDB::bind_method(D_METHOD("body_set_omit_force_integration", "body", "enable"), &Physics2DServer::body_set_omit_force_integration);
ClassDB::bind_method(D_METHOD("body_is_omitting_force_integration", "body"), &Physics2DServer::body_is_omitting_force_integration);
ClassDB::bind_method(D_METHOD("body_set_force_integration_callback", "body", "receiver", "method", "userdata"), &Physics2DServer::body_set_force_integration_callback, DEFVAL(Variant()));
- ClassDB::bind_method(D_METHOD("body_test_motion", "body", "from", "motion", "margin", "result:Physics2DTestMotionResult"), &Physics2DServer::_body_test_motion, DEFVAL(0.08), DEFVAL(Variant()));
+ ClassDB::bind_method(D_METHOD("body_test_motion", "body", "from", "motion", "margin", "result"), &Physics2DServer::_body_test_motion, DEFVAL(0.08), DEFVAL(Variant()));
/* JOINT API */
@@ -611,8 +607,8 @@ void Physics2DServer::_bind_methods() {
BIND_CONSTANT(SPACE_PARAM_CONTACT_RECYCLE_RADIUS);
BIND_CONSTANT(SPACE_PARAM_CONTACT_MAX_SEPARATION);
BIND_CONSTANT(SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION);
- BIND_CONSTANT(SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_TRESHOLD);
- BIND_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_TRESHOLD);
+ BIND_CONSTANT(SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD);
+ BIND_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD);
BIND_CONSTANT(SPACE_PARAM_BODY_TIME_TO_SLEEP);
BIND_CONSTANT(SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS);
diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h
index 3c64d3df6a..f3acd8df18 100644
--- a/servers/physics_2d_server.h
+++ b/servers/physics_2d_server.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -96,7 +97,7 @@ class Physics2DShapeQueryParameters : public Reference {
Vector2 motion;
float margin;
Set<RID> exclude;
- uint32_t layer_mask;
+ uint32_t collision_layer;
uint32_t object_type_mask;
protected:
@@ -116,8 +117,8 @@ public:
void set_margin(float p_margin);
float get_margin() const;
- void set_layer_mask(int p_layer_mask);
- int get_layer_mask() const;
+ void set_collision_layer(int p_collision_layer);
+ int get_collision_layer() const;
void set_object_type_mask(int p_object_type_mask);
int get_object_type_mask() const;
@@ -165,7 +166,7 @@ public:
Variant metadata;
};
- virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
struct ShapeResult {
@@ -176,13 +177,13 @@ public:
Variant metadata;
};
- virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_point = false) = 0;
+ virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_point = false) = 0;
- virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
- virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
- virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
struct ShapeRestInfo {
@@ -195,7 +196,7 @@ public:
Variant metadata;
};
- virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
Physics2DDirectSpaceState();
};
@@ -271,8 +272,8 @@ public:
SPACE_PARAM_CONTACT_RECYCLE_RADIUS,
SPACE_PARAM_CONTACT_MAX_SEPARATION,
SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION,
- SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_TRESHOLD,
- SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_TRESHOLD,
+ SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD,
+ SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD,
SPACE_PARAM_BODY_TIME_TO_SLEEP,
SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS,
};
@@ -331,8 +332,10 @@ public:
virtual void area_remove_shape(RID p_area, int p_shape_idx) = 0;
virtual void area_clear_shapes(RID p_area) = 0;
- virtual void area_attach_object_instance_ID(RID p_area, ObjectID p_ID) = 0;
- virtual ObjectID area_get_object_instance_ID(RID p_area) const = 0;
+ virtual void area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled) = 0;
+
+ virtual void area_attach_object_instance_id(RID p_area, ObjectID p_ID) = 0;
+ virtual ObjectID area_get_object_instance_id(RID p_area) const = 0;
virtual void area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) = 0;
virtual void area_set_transform(RID p_area, const Transform2D &p_transform) = 0;
@@ -341,7 +344,7 @@ public:
virtual Transform2D area_get_transform(RID p_area) const = 0;
virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) = 0;
- virtual void area_set_layer_mask(RID p_area, uint32_t p_mask) = 0;
+ virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) = 0;
virtual void area_set_monitorable(RID p_area, bool p_monitorable) = 0;
virtual void area_set_pickable(RID p_area, bool p_pickable) = 0;
@@ -379,14 +382,14 @@ public:
virtual Transform2D body_get_shape_transform(RID p_body, int p_shape_idx) const = 0;
virtual Variant body_get_shape_metadata(RID p_body, int p_shape_idx) const = 0;
- virtual void body_set_shape_as_trigger(RID p_body, int p_shape_idx, bool p_enable) = 0;
- virtual bool body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) const = 0;
+ virtual void body_set_shape_disabled(RID p_body, int p_shape, bool p_disabled) = 0;
+ virtual void body_set_shape_as_one_way_collision(RID p_body, int p_shape, bool p_enabled) = 0;
virtual void body_remove_shape(RID p_body, int p_shape_idx) = 0;
virtual void body_clear_shapes(RID p_body) = 0;
- virtual void body_attach_object_instance_ID(RID p_body, uint32_t p_ID) = 0;
- virtual uint32_t body_get_object_instance_ID(RID p_body) const = 0;
+ virtual void body_attach_object_instance_id(RID p_body, uint32_t p_ID) = 0;
+ virtual uint32_t body_get_object_instance_id(RID p_body) const = 0;
enum CCDMode {
CCD_MODE_DISABLED,
@@ -397,8 +400,8 @@ public:
virtual void body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode) = 0;
virtual CCDMode body_get_continuous_collision_detection_mode(RID p_body) const = 0;
- virtual void body_set_layer_mask(RID p_body, uint32_t p_mask) = 0;
- virtual uint32_t body_get_layer_mask(RID p_body) const = 0;
+ virtual void body_set_collision_layer(RID p_body, uint32_t p_layer) = 0;
+ virtual uint32_t body_get_collision_layer(RID p_body) const = 0;
virtual void body_set_collision_mask(RID p_body, uint32_t p_mask) = 0;
virtual uint32_t body_get_collision_mask(RID p_body) const = 0;
@@ -450,15 +453,9 @@ public:
virtual void body_set_max_contacts_reported(RID p_body, int p_contacts) = 0;
virtual int body_get_max_contacts_reported(RID p_body) const = 0;
- virtual void body_set_one_way_collision_direction(RID p_body, const Vector2 &p_direction) = 0;
- virtual Vector2 body_get_one_way_collision_direction(RID p_body) const = 0;
-
- virtual void body_set_one_way_collision_max_depth(RID p_body, float p_max_depth) = 0;
- virtual float body_get_one_way_collision_max_depth(RID p_body) const = 0;
-
//missing remove
- virtual void body_set_contacts_reported_depth_treshold(RID p_body, float p_treshold) = 0;
- virtual float body_get_contacts_reported_depth_treshold(RID p_body) const = 0;
+ virtual void body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold) = 0;
+ virtual float body_get_contacts_reported_depth_threshold(RID p_body) const = 0;
virtual void body_set_omit_force_integration(RID p_body, bool p_omit) = 0;
virtual bool body_is_omitting_force_integration(RID p_body) const = 0;
@@ -477,6 +474,7 @@ public:
Vector2 collision_point;
Vector2 collision_normal;
Vector2 collider_velocity;
+ int collision_local_shape;
ObjectID collider_id;
RID collider;
int collider_shape;
diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp
index d8f77fbe0d..86bf6253ee 100644
--- a/servers/physics_server.cpp
+++ b/servers/physics_server.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -108,7 +109,7 @@ void PhysicsDirectBodyState::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_contact_collider_velocity_at_pos", "contact_idx"), &PhysicsDirectBodyState::get_contact_collider_velocity_at_pos);
ClassDB::bind_method(D_METHOD("get_step"), &PhysicsDirectBodyState::get_step);
ClassDB::bind_method(D_METHOD("integrate_forces"), &PhysicsDirectBodyState::integrate_forces);
- ClassDB::bind_method(D_METHOD("get_space_state:PhysicsDirectSpaceState"), &PhysicsDirectBodyState::get_space_state);
+ ClassDB::bind_method(D_METHOD("get_space_state"), &PhysicsDirectBodyState::get_space_state);
}
PhysicsDirectBodyState::PhysicsDirectBodyState() {}
@@ -150,13 +151,13 @@ float PhysicsShapeQueryParameters::get_margin() const {
return margin;
}
-void PhysicsShapeQueryParameters::set_layer_mask(int p_layer_mask) {
+void PhysicsShapeQueryParameters::set_collision_layer(int p_collision_layer) {
- layer_mask = p_layer_mask;
+ collision_layer = p_collision_layer;
}
-int PhysicsShapeQueryParameters::get_layer_mask() const {
+int PhysicsShapeQueryParameters::get_collision_layer() const {
- return layer_mask;
+ return collision_layer;
}
void PhysicsShapeQueryParameters::set_object_type_mask(int p_object_type_mask) {
@@ -187,7 +188,7 @@ Vector<RID> PhysicsShapeQueryParameters::get_exclude() const {
void PhysicsShapeQueryParameters::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_shape", "shape:Shape"), &PhysicsShapeQueryParameters::set_shape);
+ ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsShapeQueryParameters::set_shape);
ClassDB::bind_method(D_METHOD("set_shape_rid", "shape"), &PhysicsShapeQueryParameters::set_shape_rid);
ClassDB::bind_method(D_METHOD("get_shape_rid"), &PhysicsShapeQueryParameters::get_shape_rid);
@@ -197,8 +198,8 @@ void PhysicsShapeQueryParameters::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_margin", "margin"), &PhysicsShapeQueryParameters::set_margin);
ClassDB::bind_method(D_METHOD("get_margin"), &PhysicsShapeQueryParameters::get_margin);
- ClassDB::bind_method(D_METHOD("set_layer_mask", "layer_mask"), &PhysicsShapeQueryParameters::set_layer_mask);
- ClassDB::bind_method(D_METHOD("get_layer_mask"), &PhysicsShapeQueryParameters::get_layer_mask);
+ ClassDB::bind_method(D_METHOD("set_collision_layer", "collision_layer"), &PhysicsShapeQueryParameters::set_collision_layer);
+ ClassDB::bind_method(D_METHOD("get_collision_layer"), &PhysicsShapeQueryParameters::get_collision_layer);
ClassDB::bind_method(D_METHOD("set_object_type_mask", "object_type_mask"), &PhysicsShapeQueryParameters::set_object_type_mask);
ClassDB::bind_method(D_METHOD("get_object_type_mask"), &PhysicsShapeQueryParameters::get_object_type_mask);
@@ -210,7 +211,7 @@ void PhysicsShapeQueryParameters::_bind_methods() {
PhysicsShapeQueryParameters::PhysicsShapeQueryParameters() {
margin = 0;
- layer_mask = 0x7FFFFFFF;
+ collision_layer = 0x7FFFFFFF;
object_type_mask = PhysicsDirectSpaceState::TYPE_MASK_COLLISION;
}
@@ -269,11 +270,11 @@ Dictionary PhysicsDirectSpaceState::_intersect_ray(const Vector3 &p_from, const
return d;
}
-Array PhysicsDirectSpaceState::_intersect_shape(const Ref<PhysicsShapeQueryParameters> &psq, int p_max_results) {
+Array PhysicsDirectSpaceState::_intersect_shape(const Ref<PhysicsShapeQueryParameters> &p_shape_query, int p_max_results) {
Vector<ShapeResult> sr;
sr.resize(p_max_results);
- int rc = intersect_shape(psq->shape, psq->transform, psq->margin, sr.ptr(), sr.size(), psq->exclude, psq->layer_mask, psq->object_type_mask);
+ int rc = intersect_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, sr.ptr(), sr.size(), p_shape_query->exclude, p_shape_query->collision_layer, p_shape_query->object_type_mask);
Array ret;
ret.resize(rc);
for (int i = 0; i < rc; i++) {
@@ -289,10 +290,10 @@ Array PhysicsDirectSpaceState::_intersect_shape(const Ref<PhysicsShapeQueryParam
return ret;
}
-Array PhysicsDirectSpaceState::_cast_motion(const Ref<PhysicsShapeQueryParameters> &psq, const Vector3 &p_motion) {
+Array PhysicsDirectSpaceState::_cast_motion(const Ref<PhysicsShapeQueryParameters> &p_shape_query, const Vector3 &p_motion) {
float closest_safe, closest_unsafe;
- bool res = cast_motion(psq->shape, psq->transform, p_motion, psq->margin, closest_safe, closest_unsafe, psq->exclude, psq->layer_mask, psq->object_type_mask);
+ bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_layer, p_shape_query->object_type_mask);
if (!res)
return Array();
Array ret;
@@ -301,12 +302,12 @@ Array PhysicsDirectSpaceState::_cast_motion(const Ref<PhysicsShapeQueryParameter
ret[1] = closest_unsafe;
return ret;
}
-Array PhysicsDirectSpaceState::_collide_shape(const Ref<PhysicsShapeQueryParameters> &psq, int p_max_results) {
+Array PhysicsDirectSpaceState::_collide_shape(const Ref<PhysicsShapeQueryParameters> &p_shape_query, int p_max_results) {
Vector<Vector3> ret;
ret.resize(p_max_results * 2);
int rc = 0;
- bool res = collide_shape(psq->shape, psq->transform, psq->margin, ret.ptr(), p_max_results, rc, psq->exclude, psq->layer_mask, psq->object_type_mask);
+ bool res = collide_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, ret.ptr(), p_max_results, rc, p_shape_query->exclude, p_shape_query->collision_layer, p_shape_query->object_type_mask);
if (!res)
return Array();
Array r;
@@ -315,11 +316,11 @@ Array PhysicsDirectSpaceState::_collide_shape(const Ref<PhysicsShapeQueryParamet
r[i] = ret[i];
return r;
}
-Dictionary PhysicsDirectSpaceState::_get_rest_info(const Ref<PhysicsShapeQueryParameters> &psq) {
+Dictionary PhysicsDirectSpaceState::_get_rest_info(const Ref<PhysicsShapeQueryParameters> &p_shape_query) {
ShapeRestInfo sri;
- bool res = rest_info(psq->shape, psq->transform, psq->margin, &sri, psq->exclude, psq->layer_mask, psq->object_type_mask);
+ bool res = rest_info(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, &sri, p_shape_query->exclude, p_shape_query->collision_layer, p_shape_query->object_type_mask);
Dictionary r;
if (!res)
return r;
@@ -340,13 +341,13 @@ PhysicsDirectSpaceState::PhysicsDirectSpaceState() {
void PhysicsDirectSpaceState::_bind_methods() {
//ClassDB::bind_method(D_METHOD("intersect_ray","from","to","exclude","umask"),&PhysicsDirectSpaceState::_intersect_ray,DEFVAL(Array()),DEFVAL(0));
- //ClassDB::bind_method(D_METHOD("intersect_shape:PhysicsShapeQueryResult","shape","xform","result_max","exclude","umask"),&PhysicsDirectSpaceState::_intersect_shape,DEFVAL(Array()),DEFVAL(0));
+ //ClassDB::bind_method(D_METHOD("intersect_shape","shape","xform","result_max","exclude","umask"),&PhysicsDirectSpaceState::_intersect_shape,DEFVAL(Array()),DEFVAL(0));
- ClassDB::bind_method(D_METHOD("intersect_ray:Dictionary", "from", "to", "exclude", "layer_mask", "type_mask"), &PhysicsDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(TYPE_MASK_COLLISION));
- ClassDB::bind_method(D_METHOD("intersect_shape", "shape:PhysicsShapeQueryParameters", "max_results"), &PhysicsDirectSpaceState::_intersect_shape, DEFVAL(32));
- ClassDB::bind_method(D_METHOD("cast_motion", "shape:PhysicsShapeQueryParameters", "motion"), &PhysicsDirectSpaceState::_cast_motion);
- ClassDB::bind_method(D_METHOD("collide_shape", "shape:PhysicsShapeQueryParameters", "max_results"), &PhysicsDirectSpaceState::_collide_shape, DEFVAL(32));
- ClassDB::bind_method(D_METHOD("get_rest_info", "shape:PhysicsShapeQueryParameters"), &PhysicsDirectSpaceState::_get_rest_info);
+ ClassDB::bind_method(D_METHOD("intersect_ray", "from", "to", "exclude", "collision_layer", "type_mask"), &PhysicsDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(TYPE_MASK_COLLISION));
+ ClassDB::bind_method(D_METHOD("intersect_shape", "shape", "max_results"), &PhysicsDirectSpaceState::_intersect_shape, DEFVAL(32));
+ ClassDB::bind_method(D_METHOD("cast_motion", "shape", "motion"), &PhysicsDirectSpaceState::_cast_motion);
+ ClassDB::bind_method(D_METHOD("collide_shape", "shape", "max_results"), &PhysicsDirectSpaceState::_collide_shape, DEFVAL(32));
+ ClassDB::bind_method(D_METHOD("get_rest_info", "shape"), &PhysicsDirectSpaceState::_get_rest_info);
BIND_CONSTANT(TYPE_MASK_STATIC_BODY);
BIND_CONSTANT(TYPE_MASK_KINEMATIC_BODY);
@@ -404,7 +405,7 @@ void PhysicsServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("space_is_active", "space"), &PhysicsServer::space_is_active);
ClassDB::bind_method(D_METHOD("space_set_param", "space", "param", "value"), &PhysicsServer::space_set_param);
ClassDB::bind_method(D_METHOD("space_get_param", "space", "param"), &PhysicsServer::space_get_param);
- ClassDB::bind_method(D_METHOD("space_get_direct_state:PhysicsDirectSpaceState", "space"), &PhysicsServer::space_get_direct_state);
+ ClassDB::bind_method(D_METHOD("space_get_direct_state", "space"), &PhysicsServer::space_get_direct_state);
ClassDB::bind_method(D_METHOD("area_create"), &PhysicsServer::area_create);
ClassDB::bind_method(D_METHOD("area_set_space", "area", "space"), &PhysicsServer::area_set_space);
@@ -424,7 +425,7 @@ void PhysicsServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("area_remove_shape", "area", "shape_idx"), &PhysicsServer::area_remove_shape);
ClassDB::bind_method(D_METHOD("area_clear_shapes", "area"), &PhysicsServer::area_clear_shapes);
- ClassDB::bind_method(D_METHOD("area_set_layer_mask", "area", "mask"), &PhysicsServer::area_set_layer_mask);
+ ClassDB::bind_method(D_METHOD("area_set_collision_layer", "area", "layer"), &PhysicsServer::area_set_collision_layer);
ClassDB::bind_method(D_METHOD("area_set_collision_mask", "area", "mask"), &PhysicsServer::area_set_collision_mask);
ClassDB::bind_method(D_METHOD("area_set_param", "area", "param", "value"), &PhysicsServer::area_set_param);
@@ -433,8 +434,8 @@ void PhysicsServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("area_get_param", "area", "param"), &PhysicsServer::area_get_param);
ClassDB::bind_method(D_METHOD("area_get_transform", "area"), &PhysicsServer::area_get_transform);
- ClassDB::bind_method(D_METHOD("area_attach_object_instance_ID", "area", "id"), &PhysicsServer::area_attach_object_instance_ID);
- ClassDB::bind_method(D_METHOD("area_get_object_instance_ID", "area"), &PhysicsServer::area_get_object_instance_ID);
+ ClassDB::bind_method(D_METHOD("area_attach_object_instance_id", "area", "id"), &PhysicsServer::area_attach_object_instance_id);
+ ClassDB::bind_method(D_METHOD("area_get_object_instance_id", "area"), &PhysicsServer::area_get_object_instance_id);
ClassDB::bind_method(D_METHOD("area_set_monitor_callback", "area", "receiver", "method"), &PhysicsServer::area_set_monitor_callback);
@@ -449,8 +450,8 @@ void PhysicsServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_set_mode", "body", "mode"), &PhysicsServer::body_set_mode);
ClassDB::bind_method(D_METHOD("body_get_mode", "body"), &PhysicsServer::body_get_mode);
- ClassDB::bind_method(D_METHOD("body_set_layer_mask", "body", "mask"), &PhysicsServer::body_set_layer_mask);
- ClassDB::bind_method(D_METHOD("body_get_layer_mask", "body"), &PhysicsServer::body_get_layer_mask);
+ ClassDB::bind_method(D_METHOD("body_set_collision_layer", "body", "layer"), &PhysicsServer::body_set_collision_layer);
+ ClassDB::bind_method(D_METHOD("body_get_collision_layer", "body"), &PhysicsServer::body_get_collision_layer);
ClassDB::bind_method(D_METHOD("body_set_collision_mask", "body", "mask"), &PhysicsServer::body_set_collision_mask);
ClassDB::bind_method(D_METHOD("body_get_collision_mask", "body"), &PhysicsServer::body_get_collision_mask);
@@ -466,8 +467,8 @@ void PhysicsServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_remove_shape", "body", "shape_idx"), &PhysicsServer::body_remove_shape);
ClassDB::bind_method(D_METHOD("body_clear_shapes", "body"), &PhysicsServer::body_clear_shapes);
- ClassDB::bind_method(D_METHOD("body_attach_object_instance_ID", "body", "id"), &PhysicsServer::body_attach_object_instance_ID);
- ClassDB::bind_method(D_METHOD("body_get_object_instance_ID", "body"), &PhysicsServer::body_get_object_instance_ID);
+ ClassDB::bind_method(D_METHOD("body_attach_object_instance_id", "body", "id"), &PhysicsServer::body_attach_object_instance_id);
+ ClassDB::bind_method(D_METHOD("body_get_object_instance_id", "body"), &PhysicsServer::body_get_object_instance_id);
ClassDB::bind_method(D_METHOD("body_set_enable_continuous_collision_detection", "body", "enable"), &PhysicsServer::body_set_enable_continuous_collision_detection);
ClassDB::bind_method(D_METHOD("body_is_continuous_collision_detection_enabled", "body"), &PhysicsServer::body_is_continuous_collision_detection_enabled);
@@ -515,11 +516,11 @@ void PhysicsServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("pin_joint_set_param", "joint", "param", "value"), &PhysicsServer::pin_joint_set_param);
ClassDB::bind_method(D_METHOD("pin_joint_get_param", "joint", "param"), &PhysicsServer::pin_joint_get_param);
- ClassDB::bind_method(D_METHOD("pin_joint_set_local_A", "joint", "local_A"), &PhysicsServer::pin_joint_set_local_A);
- ClassDB::bind_method(D_METHOD("pin_joint_get_local_A", "joint"), &PhysicsServer::pin_joint_get_local_A);
+ ClassDB::bind_method(D_METHOD("pin_joint_set_local_a", "joint", "local_A"), &PhysicsServer::pin_joint_set_local_a);
+ ClassDB::bind_method(D_METHOD("pin_joint_get_local_a", "joint"), &PhysicsServer::pin_joint_get_local_a);
- ClassDB::bind_method(D_METHOD("pin_joint_set_local_B", "joint", "local_B"), &PhysicsServer::pin_joint_set_local_B);
- ClassDB::bind_method(D_METHOD("pin_joint_get_local_B", "joint"), &PhysicsServer::pin_joint_get_local_B);
+ ClassDB::bind_method(D_METHOD("pin_joint_set_local_b", "joint", "local_B"), &PhysicsServer::pin_joint_set_local_b);
+ ClassDB::bind_method(D_METHOD("pin_joint_get_local_b", "joint"), &PhysicsServer::pin_joint_get_local_b);
BIND_CONSTANT(PIN_JOINT_BIAS);
BIND_CONSTANT(PIN_JOINT_DAMPING);
diff --git a/servers/physics_server.h b/servers/physics_server.h
index dbd0c79f06..b38e14eb0c 100644
--- a/servers/physics_server.h
+++ b/servers/physics_server.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -99,7 +100,7 @@ class PhysicsShapeQueryParameters : public Reference {
Transform transform;
float margin;
Set<RID> exclude;
- uint32_t layer_mask;
+ uint32_t collision_layer;
uint32_t object_type_mask;
protected:
@@ -116,8 +117,8 @@ public:
void set_margin(float p_margin);
float get_margin() const;
- void set_layer_mask(int p_layer_mask);
- int get_layer_mask() const;
+ void set_collision_layer(int p_collision_layer);
+ int get_collision_layer() const;
void set_object_type_mask(int p_object_type_mask);
int get_object_type_mask() const;
@@ -155,27 +156,29 @@ protected:
static void _bind_methods();
public:
- struct RayResult {
+ struct ShapeResult {
- Vector3 position;
- Vector3 normal;
RID rid;
ObjectID collider_id;
Object *collider;
int shape;
};
- virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_ray = false) = 0;
+ virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
- struct ShapeResult {
+ struct RayResult {
+ Vector3 position;
+ Vector3 normal;
RID rid;
ObjectID collider_id;
Object *collider;
int shape;
};
- virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_ray = false) = 0;
+
+ virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
struct ShapeRestInfo {
@@ -187,11 +190,13 @@ public:
Vector3 linear_velocity; //velocity at contact point
};
- virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, ShapeRestInfo *r_info = NULL) = 0;
+ virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, ShapeRestInfo *r_info = NULL) = 0;
+
+ virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
- virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
- virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const = 0;
PhysicsDirectSpaceState();
};
@@ -260,8 +265,8 @@ public:
SPACE_PARAM_CONTACT_RECYCLE_RADIUS,
SPACE_PARAM_CONTACT_MAX_SEPARATION,
SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION,
- SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_TRESHOLD,
- SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_TRESHOLD,
+ SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD,
+ SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD,
SPACE_PARAM_BODY_TIME_TO_SLEEP,
SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO,
SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS,
@@ -321,8 +326,10 @@ public:
virtual void area_remove_shape(RID p_area, int p_shape_idx) = 0;
virtual void area_clear_shapes(RID p_area) = 0;
- virtual void area_attach_object_instance_ID(RID p_area, ObjectID p_ID) = 0;
- virtual ObjectID area_get_object_instance_ID(RID p_area) const = 0;
+ virtual void area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) = 0;
+
+ virtual void area_attach_object_instance_id(RID p_area, ObjectID p_ID) = 0;
+ virtual ObjectID area_get_object_instance_id(RID p_area) const = 0;
virtual void area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) = 0;
virtual void area_set_transform(RID p_area, const Transform &p_transform) = 0;
@@ -331,7 +338,7 @@ public:
virtual Transform area_get_transform(RID p_area) const = 0;
virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) = 0;
- virtual void area_set_layer_mask(RID p_area, uint32_t p_mask) = 0;
+ virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) = 0;
virtual void area_set_monitorable(RID p_area, bool p_monitorable) = 0;
@@ -369,26 +376,25 @@ public:
virtual RID body_get_shape(RID p_body, int p_shape_idx) const = 0;
virtual Transform body_get_shape_transform(RID p_body, int p_shape_idx) const = 0;
- virtual void body_set_shape_as_trigger(RID p_body, int p_shape_idx, bool p_enable) = 0;
- virtual bool body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) const = 0;
-
virtual void body_remove_shape(RID p_body, int p_shape_idx) = 0;
virtual void body_clear_shapes(RID p_body) = 0;
- virtual void body_attach_object_instance_ID(RID p_body, uint32_t p_ID) = 0;
- virtual uint32_t body_get_object_instance_ID(RID p_body) const = 0;
+ virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) = 0;
+
+ virtual void body_attach_object_instance_id(RID p_body, uint32_t p_ID) = 0;
+ virtual uint32_t body_get_object_instance_id(RID p_body) const = 0;
virtual void body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) = 0;
virtual bool body_is_continuous_collision_detection_enabled(RID p_body) const = 0;
- virtual void body_set_layer_mask(RID p_body, uint32_t p_mask) = 0;
- virtual uint32_t body_get_layer_mask(RID p_body, uint32_t p_mask) const = 0;
+ virtual void body_set_collision_layer(RID p_body, uint32_t p_layer) = 0;
+ virtual uint32_t body_get_collision_layer(RID p_body) const = 0;
virtual void body_set_collision_mask(RID p_body, uint32_t p_mask) = 0;
- virtual uint32_t body_get_collision_mask(RID p_body, uint32_t p_mask) const = 0;
+ virtual uint32_t body_get_collision_mask(RID p_body) const = 0;
virtual void body_set_user_flags(RID p_body, uint32_t p_flags) = 0;
- virtual uint32_t body_get_user_flags(RID p_body, uint32_t p_flags) const = 0;
+ virtual uint32_t body_get_user_flags(RID p_body) const = 0;
// common body variables
enum BodyParameter {
@@ -446,8 +452,8 @@ public:
virtual int body_get_max_contacts_reported(RID p_body) const = 0;
//missing remove
- virtual void body_set_contacts_reported_depth_treshold(RID p_body, float p_treshold) = 0;
- virtual float body_get_contacts_reported_depth_treshold(RID p_body) const = 0;
+ virtual void body_set_contacts_reported_depth_threshold(RID p_body, float p_threshold) = 0;
+ virtual float body_get_contacts_reported_depth_threshold(RID p_body) const = 0;
virtual void body_set_omit_force_integration(RID p_body, bool p_omit) = 0;
virtual bool body_is_omitting_force_integration(RID p_body) const = 0;
@@ -457,6 +463,23 @@ public:
virtual void body_set_ray_pickable(RID p_body, bool p_enable) = 0;
virtual bool body_is_ray_pickable(RID p_body) const = 0;
+ struct MotionResult {
+
+ Vector3 motion;
+ Vector3 remainder;
+
+ Vector3 collision_point;
+ Vector3 collision_normal;
+ Vector3 collider_velocity;
+ int collision_local_shape;
+ ObjectID collider_id;
+ RID collider;
+ int collider_shape;
+ Variant collider_metadata;
+ };
+
+ virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, float p_margin = 0.001, MotionResult *r_result = NULL) = 0;
+
/* JOINT API */
enum JointType {
@@ -485,11 +508,11 @@ public:
virtual void pin_joint_set_param(RID p_joint, PinJointParam p_param, float p_value) = 0;
virtual float pin_joint_get_param(RID p_joint, PinJointParam p_param) const = 0;
- virtual void pin_joint_set_local_A(RID p_joint, const Vector3 &p_A) = 0;
- virtual Vector3 pin_joint_get_local_A(RID p_joint) const = 0;
+ virtual void pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) = 0;
+ virtual Vector3 pin_joint_get_local_a(RID p_joint) const = 0;
- virtual void pin_joint_set_local_B(RID p_joint, const Vector3 &p_B) = 0;
- virtual Vector3 pin_joint_get_local_B(RID p_joint) const = 0;
+ virtual void pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) = 0;
+ virtual Vector3 pin_joint_get_local_b(RID p_joint) const = 0;
enum HingeJointParam {
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 06bcb642ad..092f445c13 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -27,8 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "register_server_types.h"
-#include "global_config.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"
@@ -69,20 +74,26 @@ 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);
- GLOBAL_DEF("memory/multithread/thread_rid_pool_prealloc", 20);
-
- GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("VisualServer", VisualServer::get_singleton()));
- GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("AudioServer", AudioServer::get_singleton()));
- GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("PhysicsServer", PhysicsServer::get_singleton()));
- GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("Physics2DServer", Physics2DServer::get_singleton()));
+ 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>();
ClassDB::register_virtual_class<AudioEffect>();
ClassDB::register_class<AudioBusLayout>();
@@ -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/register_server_types.h b/servers/register_server_types.h
index a3e7d3ee32..c183ccc8a4 100644
--- a/servers/register_server_types.h
+++ b/servers/register_server_types.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/server_wrap_mt_common.h b/servers/server_wrap_mt_common.h
index cfb65cf161..1ffa5ad14c 100644
--- a/servers/server_wrap_mt_common.h
+++ b/servers/server_wrap_mt_common.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -29,7 +30,7 @@
#define FUNC0R(m_r, m_type) \
virtual m_r m_type() { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret); \
SYNC_DEBUG \
@@ -40,8 +41,9 @@
}
#define FUNCRID(m_type) \
+ List<RID> m_type##_id_pool; \
int m_type##allocn() { \
- for (int i = 0; i < m_type##_pool_max_size; i++) { \
+ for (int i = 0; i < pool_max_size; i++) { \
m_type##_id_pool.push_back(server_name->m_type##_create()); \
} \
return 0; \
@@ -53,7 +55,7 @@
} \
} \
virtual RID m_type##_create() { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
RID rid; \
alloc_mutex->lock(); \
if (m_type##_id_pool.size() == 0) { \
@@ -83,7 +85,7 @@
} \
} \
virtual RID m_type##_create(m_arg1 p1) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
RID rid; \
alloc_mutex->lock(); \
if (m_type##_id_pool.size() == 0) { \
@@ -113,7 +115,7 @@
} \
} \
virtual RID m_type##_create(m_arg1 p1, m_arg2 p2) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
RID rid; \
alloc_mutex->lock(); \
if (m_type##_id_pool.size() == 0) { \
@@ -143,7 +145,7 @@
} \
} \
virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
RID rid; \
alloc_mutex->lock(); \
if (m_type##_id_pool.size() == 0) { \
@@ -173,7 +175,7 @@
} \
} \
virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
RID rid; \
alloc_mutex->lock(); \
if (m_type##_id_pool.size() == 0) { \
@@ -203,7 +205,7 @@
} \
} \
virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
RID rid; \
alloc_mutex->lock(); \
if (m_type##_id_pool.size() == 0) { \
@@ -221,7 +223,7 @@
#define FUNC0RC(m_r, m_type) \
virtual m_r m_type() const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, &ret); \
SYNC_DEBUG \
@@ -233,7 +235,7 @@
#define FUNC0(m_type) \
virtual void m_type() { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type); \
} else { \
server_name->m_type(); \
@@ -242,7 +244,7 @@
#define FUNC0C(m_type) \
virtual void m_type() const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type); \
} else { \
server_name->m_type(); \
@@ -251,7 +253,7 @@
#define FUNC0S(m_type) \
virtual void m_type() { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type); \
} else { \
server_name->m_type(); \
@@ -260,7 +262,7 @@
#define FUNC0SC(m_type) \
virtual void m_type() const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type); \
} else { \
server_name->m_type(); \
@@ -271,7 +273,7 @@
#define FUNC1R(m_r, m_type, m_arg1) \
virtual m_r m_type(m_arg1 p1) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \
SYNC_DEBUG \
@@ -283,7 +285,7 @@
#define FUNC1RC(m_r, m_type, m_arg1) \
virtual m_r m_type(m_arg1 p1) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, &ret); \
SYNC_DEBUG \
@@ -295,7 +297,7 @@
#define FUNC1S(m_type, m_arg1) \
virtual void m_type(m_arg1 p1) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1); \
} else { \
server_name->m_type(p1); \
@@ -304,7 +306,7 @@
#define FUNC1SC(m_type, m_arg1) \
virtual void m_type(m_arg1 p1) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1); \
} else { \
server_name->m_type(p1); \
@@ -313,7 +315,7 @@
#define FUNC1(m_type, m_arg1) \
virtual void m_type(m_arg1 p1) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1); \
} else { \
server_name->m_type(p1); \
@@ -322,7 +324,7 @@
#define FUNC1C(m_type, m_arg1) \
virtual void m_type(m_arg1 p1) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1); \
} else { \
server_name->m_type(p1); \
@@ -331,7 +333,7 @@
#define FUNC2R(m_r, m_type, m_arg1, m_arg2) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \
SYNC_DEBUG \
@@ -343,7 +345,7 @@
#define FUNC2RC(m_r, m_type, m_arg1, m_arg2) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, &ret); \
SYNC_DEBUG \
@@ -355,7 +357,7 @@
#define FUNC2S(m_type, m_arg1, m_arg2) \
virtual void m_type(m_arg1 p1, m_arg2 p2) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2); \
} else { \
server_name->m_type(p1, p2); \
@@ -364,7 +366,7 @@
#define FUNC2SC(m_type, m_arg1, m_arg2) \
virtual void m_type(m_arg1 p1, m_arg2 p2) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2); \
} else { \
server_name->m_type(p1, p2); \
@@ -373,7 +375,7 @@
#define FUNC2(m_type, m_arg1, m_arg2) \
virtual void m_type(m_arg1 p1, m_arg2 p2) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2); \
} else { \
server_name->m_type(p1, p2); \
@@ -382,7 +384,7 @@
#define FUNC2C(m_type, m_arg1, m_arg2) \
virtual void m_type(m_arg1 p1, m_arg2 p2) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2); \
} else { \
server_name->m_type(p1, p2); \
@@ -391,7 +393,7 @@
#define FUNC3R(m_r, m_type, m_arg1, m_arg2, m_arg3) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \
SYNC_DEBUG \
@@ -403,7 +405,7 @@
#define FUNC3RC(m_r, m_type, m_arg1, m_arg2, m_arg3) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, &ret); \
return ret; \
@@ -414,7 +416,7 @@
#define FUNC3S(m_type, m_arg1, m_arg2, m_arg3) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3); \
} else { \
server_name->m_type(p1, p2, p3); \
@@ -423,7 +425,7 @@
#define FUNC3SC(m_type, m_arg1, m_arg2, m_arg3) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3); \
} else { \
server_name->m_type(p1, p2, p3); \
@@ -432,7 +434,7 @@
#define FUNC3(m_type, m_arg1, m_arg2, m_arg3) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2, p3); \
} else { \
server_name->m_type(p1, p2, p3); \
@@ -441,7 +443,7 @@
#define FUNC3C(m_type, m_arg1, m_arg2, m_arg3) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2, p3); \
} else { \
server_name->m_type(p1, p2, p3); \
@@ -450,7 +452,7 @@
#define FUNC4R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \
SYNC_DEBUG \
@@ -462,7 +464,7 @@
#define FUNC4RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, &ret); \
SYNC_DEBUG \
@@ -474,7 +476,7 @@
#define FUNC4S(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4); \
} else { \
server_name->m_type(p1, p2, p3, p4); \
@@ -483,7 +485,7 @@
#define FUNC4SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4); \
} else { \
server_name->m_type(p1, p2, p3, p4); \
@@ -492,7 +494,7 @@
#define FUNC4(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4); \
} else { \
server_name->m_type(p1, p2, p3, p4); \
@@ -501,7 +503,7 @@
#define FUNC4C(m_type, m_arg1, m_arg2, m_arg3, m_arg4) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4); \
} else { \
server_name->m_type(p1, p2, p3, p4); \
@@ -510,7 +512,7 @@
#define FUNC5R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \
SYNC_DEBUG \
@@ -522,7 +524,7 @@
#define FUNC5RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, &ret); \
SYNC_DEBUG \
@@ -534,7 +536,7 @@
#define FUNC5S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5); \
@@ -543,7 +545,7 @@
#define FUNC5SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5); \
@@ -552,7 +554,7 @@
#define FUNC5(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5); \
@@ -561,7 +563,7 @@
#define FUNC5C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5); \
@@ -570,7 +572,7 @@
#define FUNC6R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \
SYNC_DEBUG \
@@ -582,7 +584,7 @@
#define FUNC6RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, &ret); \
return ret; \
@@ -593,7 +595,7 @@
#define FUNC6S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5, p6); \
@@ -602,7 +604,7 @@
#define FUNC6SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5, p6); \
@@ -611,7 +613,7 @@
#define FUNC6(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5, p6); \
@@ -620,7 +622,7 @@
#define FUNC6C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5, p6); \
@@ -629,7 +631,7 @@
#define FUNC7R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \
SYNC_DEBUG \
@@ -641,7 +643,7 @@
#define FUNC7RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, &ret); \
SYNC_DEBUG \
@@ -653,7 +655,7 @@
#define FUNC7S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
@@ -662,7 +664,7 @@
#define FUNC7SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
@@ -671,7 +673,7 @@
#define FUNC7(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
@@ -680,7 +682,7 @@
#define FUNC7C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5, p6, p7); \
@@ -689,7 +691,7 @@
#define FUNC8R(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \
SYNC_DEBUG \
@@ -701,7 +703,7 @@
#define FUNC8RC(m_r, m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
m_r ret; \
command_queue.push_and_ret(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, &ret); \
SYNC_DEBUG \
@@ -713,7 +715,7 @@
#define FUNC8S(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
@@ -722,7 +724,7 @@
#define FUNC8SC(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push_and_sync(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
@@ -731,7 +733,7 @@
#define FUNC8(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
@@ -740,9 +742,36 @@
#define FUNC8C(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8) \
virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \
- if (Thread::get_caller_ID() != server_thread) { \
+ if (Thread::get_caller_id() != server_thread) { \
command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8); \
} else { \
server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
} \
}
+
+#define FUNC9(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9) { \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9); \
+ } else { \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9); \
+ } \
+ }
+
+#define FUNC10(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10) { \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \
+ } else { \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \
+ } \
+ }
+
+#define FUNC11(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11) { \
+ if (Thread::get_caller_id() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \
+ } else { \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \
+ } \
+ }
diff --git a/servers/visual/rasterizer.cpp b/servers/visual/rasterizer.cpp
index 1be65be927..f7ea158646 100644
--- a/servers/visual/rasterizer.cpp
+++ b/servers/visual/rasterizer.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -37,11 +38,11 @@ Rasterizer *Rasterizer::create() {
return _create_func();
}
-RasterizerStorage *RasterizerStorage::base_signleton = NULL;
+RasterizerStorage *RasterizerStorage::base_singleton = NULL;
RasterizerStorage::RasterizerStorage() {
- base_signleton = this;
+ base_singleton = this;
}
#if 0
@@ -54,10 +55,10 @@ RID Rasterizer::create_default_material() {
/* Fixed MAterial SHADER API */
-RID Rasterizer::_create_shader(const FixedSpatialMaterialShaderKey& p_key) {
+RID Rasterizer::_create_shader(const SpatialMaterialShaderKey& p_key) {
ERR_FAIL_COND_V(!p_key.valid,RID());
- Map<FixedSpatialMaterialShaderKey,FixedSpatialMaterialShader>::Element *E=fixed_material_shaders.find(p_key);
+ Map<SpatialMaterialShaderKey,SpatialMaterialShader>::Element *E=fixed_material_shaders.find(p_key);
if (E) {
E->get().refcount++;
@@ -66,7 +67,7 @@ RID Rasterizer::_create_shader(const FixedSpatialMaterialShaderKey& p_key) {
uint64_t t = OS::get_singleton()->get_ticks_usec();
- FixedSpatialMaterialShader fms;
+ SpatialMaterialShader fms;
fms.refcount=1;
fms.shader=shader_create();
@@ -312,12 +313,12 @@ RID Rasterizer::_create_shader(const FixedSpatialMaterialShaderKey& p_key) {
return fms.shader;
}
-void Rasterizer::_free_shader(const FixedSpatialMaterialShaderKey& p_key) {
+void Rasterizer::_free_shader(const SpatialMaterialShaderKey& p_key) {
if (p_key.valid==0)
return; //not a valid key
- Map<FixedSpatialMaterialShaderKey,FixedSpatialMaterialShader>::Element *E=fixed_material_shaders.find(p_key);
+ Map<SpatialMaterialShaderKey,SpatialMaterialShader>::Element *E=fixed_material_shaders.find(p_key);
ERR_FAIL_COND(!E);
E->get().refcount--;
@@ -329,12 +330,12 @@ void Rasterizer::_free_shader(const FixedSpatialMaterialShaderKey& p_key) {
}
-void Rasterizer::fixed_material_set_flag(RID p_material, VS::FixedSpatialMaterialFlags p_flag, bool p_enabled) {
+void Rasterizer::fixed_material_set_flag(RID p_material, VS::SpatialMaterialFlags p_flag, bool p_enabled) {
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND(!E);
- FixedSpatialMaterial &fm=*E->get();
+ SpatialMaterial &fm=*E->get();
switch(p_flag) {
@@ -350,11 +351,11 @@ void Rasterizer::fixed_material_set_flag(RID p_material, VS::FixedSpatialMateria
}
-bool Rasterizer::fixed_material_get_flag(RID p_material, VS::FixedSpatialMaterialFlags p_flag) const{
+bool Rasterizer::fixed_material_get_flag(RID p_material, VS::SpatialMaterialFlags p_flag) const{
- const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND_V(!E,false);
- const FixedSpatialMaterial &fm=*E->get();
+ const SpatialMaterial &fm=*E->get();
switch(p_flag) {
case VS::FIXED_MATERIAL_FLAG_USE_ALPHA: return fm.use_alpha;; break;
@@ -373,8 +374,8 @@ bool Rasterizer::fixed_material_get_flag(RID p_material, VS::FixedSpatialMateria
RID Rasterizer::fixed_material_create() {
RID mat = material_create();
- fixed_materials[mat]=memnew( FixedSpatialMaterial() );
- FixedSpatialMaterial &fm=*fixed_materials[mat];
+ fixed_materials[mat]=memnew( SpatialMaterial() );
+ SpatialMaterial &fm=*fixed_materials[mat];
fm.self=mat;
fm.get_key();
material_set_flag(mat,VS::MATERIAL_FLAG_COLOR_ARRAY_SRGB,true);
@@ -390,11 +391,11 @@ RID Rasterizer::fixed_material_create() {
-void Rasterizer::fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant& p_value){
+void Rasterizer::fixed_material_set_parameter(RID p_material, VS::SpatialMaterialParam p_parameter, const Variant& p_value){
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND(!E);
- FixedSpatialMaterial &fm=*E->get();
+ SpatialMaterial &fm=*E->get();
RID material=E->key();
ERR_FAIL_INDEX(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX);
@@ -417,24 +418,24 @@ void Rasterizer::fixed_material_set_parameter(RID p_material, VS::FixedSpatialMa
}
-Variant Rasterizer::fixed_material_get_parameter(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const{
+Variant Rasterizer::fixed_material_get_parameter(RID p_material,VS::SpatialMaterialParam p_parameter) const{
- const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND_V(!E,Variant());
- const FixedSpatialMaterial &fm=*E->get();
+ const SpatialMaterial &fm=*E->get();
ERR_FAIL_INDEX_V(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX,Variant());
return fm.param[p_parameter];
}
-void Rasterizer::fixed_material_set_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter, RID p_texture){
+void Rasterizer::fixed_material_set_texture(RID p_material,VS::SpatialMaterialParam p_parameter, RID p_texture){
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
if (!E) {
print_line("Not found: "+itos(p_material.get_id()));
}
ERR_FAIL_COND(!E);
- FixedSpatialMaterial &fm=*E->get();
+ SpatialMaterial &fm=*E->get();
ERR_FAIL_INDEX(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX);
@@ -449,22 +450,22 @@ void Rasterizer::fixed_material_set_texture(RID p_material,VS::FixedSpatialMater
}
-RID Rasterizer::fixed_material_get_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const{
+RID Rasterizer::fixed_material_get_texture(RID p_material,VS::SpatialMaterialParam p_parameter) const{
- const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND_V(!E,RID());
- const FixedSpatialMaterial &fm=*E->get();
+ const SpatialMaterial &fm=*E->get();
ERR_FAIL_INDEX_V(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX,RID());
return fm.texture[p_parameter];
}
-void Rasterizer::fixed_material_set_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode) {
+void Rasterizer::fixed_material_set_texcoord_mode(RID p_material,VS::SpatialMaterialParam p_parameter, VS::SpatialMaterialTexCoordMode p_mode) {
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND(!E);
- FixedSpatialMaterial &fm=*E->get();
+ SpatialMaterial &fm=*E->get();
ERR_FAIL_INDEX(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX);
fm.get_key();
@@ -476,11 +477,11 @@ void Rasterizer::fixed_material_set_texcoord_mode(RID p_material,VS::FixedSpatia
}
-VS::FixedSpatialMaterialTexCoordMode Rasterizer::fixed_material_get_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const {
+VS::SpatialMaterialTexCoordMode Rasterizer::fixed_material_get_texcoord_mode(RID p_material,VS::SpatialMaterialParam p_parameter) const {
- const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND_V(!E,VS::FIXED_MATERIAL_TEXCOORD_UV);
- const FixedSpatialMaterial &fm=*E->get();
+ const SpatialMaterial &fm=*E->get();
ERR_FAIL_INDEX_V(p_parameter,VS::FIXED_MATERIAL_PARAM_MAX,VS::FIXED_MATERIAL_TEXCOORD_UV);
return fm.texture_tc[p_parameter];
@@ -488,9 +489,9 @@ VS::FixedSpatialMaterialTexCoordMode Rasterizer::fixed_material_get_texcoord_mod
void Rasterizer::fixed_material_set_uv_transform(RID p_material,const Transform& p_transform) {
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND(!E);
- FixedSpatialMaterial &fm=*E->get();
+ SpatialMaterial &fm=*E->get();
RID material=E->key();
VS::get_singleton()->material_set_param(material,_fixed_material_uv_xform_name,p_transform);
@@ -503,18 +504,18 @@ void Rasterizer::fixed_material_set_uv_transform(RID p_material,const Transform&
Transform Rasterizer::fixed_material_get_uv_transform(RID p_material) const {
- const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND_V(!E,Transform());
- const FixedSpatialMaterial &fm=*E->get();
+ const SpatialMaterial &fm=*E->get();
return fm.uv_xform;
}
-void Rasterizer::fixed_material_set_light_shader(RID p_material,VS::FixedSpatialMaterialLightShader p_shader) {
+void Rasterizer::fixed_material_set_light_shader(RID p_material,VS::SpatialMaterialLightShader p_shader) {
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND(!E);
- FixedSpatialMaterial &fm=*E->get();
+ SpatialMaterial &fm=*E->get();
fm.light_shader=p_shader;
@@ -523,20 +524,20 @@ void Rasterizer::fixed_material_set_light_shader(RID p_material,VS::FixedSpatial
}
-VS::FixedSpatialMaterialLightShader Rasterizer::fixed_material_get_light_shader(RID p_material) const {
+VS::SpatialMaterialLightShader Rasterizer::fixed_material_get_light_shader(RID p_material) const {
- const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND_V(!E,VS::FIXED_MATERIAL_LIGHT_SHADER_LAMBERT);
- const FixedSpatialMaterial &fm=*E->get();
+ const SpatialMaterial &fm=*E->get();
return fm.light_shader;
}
void Rasterizer::fixed_material_set_point_size(RID p_material,float p_size) {
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND(!E);
- FixedSpatialMaterial &fm=*E->get();
+ SpatialMaterial &fm=*E->get();
RID material=E->key();
VS::get_singleton()->material_set_param(material,_fixed_material_point_size_name,p_size);
@@ -548,9 +549,9 @@ void Rasterizer::fixed_material_set_point_size(RID p_material,float p_size) {
float Rasterizer::fixed_material_get_point_size(RID p_material) const{
- const Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ const Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
ERR_FAIL_COND_V(!E,1.0);
- const FixedSpatialMaterial &fm=*E->get();
+ const SpatialMaterial &fm=*E->get();
return fm.point_size;
@@ -561,9 +562,9 @@ void Rasterizer::_update_fixed_materials() {
while(fixed_material_dirty_list.first()) {
- FixedSpatialMaterial &fm=*fixed_material_dirty_list.first()->self();
+ SpatialMaterial &fm=*fixed_material_dirty_list.first()->self();
- FixedSpatialMaterialShaderKey new_key = fm.get_key();
+ SpatialMaterialShaderKey new_key = fm.get_key();
if (new_key.key!=fm.current_key.key) {
_free_shader(fm.current_key);
@@ -593,7 +594,7 @@ void Rasterizer::_update_fixed_materials() {
void Rasterizer::_free_fixed_material(const RID& p_material) {
- Map<RID,FixedSpatialMaterial*>::Element *E = fixed_materials.find(p_material);
+ Map<RID,SpatialMaterial*>::Element *E = fixed_materials.find(p_material);
if (E) {
@@ -636,7 +637,7 @@ Rasterizer::Rasterizer() {
draw_viewport_func=NULL;
- ERR_FAIL_COND( sizeof(FixedSpatialMaterialShaderKey)!=4);
+ ERR_FAIL_COND( sizeof(SpatialMaterialShaderKey)!=4);
}
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 838ddead75..9405f6e012 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -51,25 +52,33 @@ public:
virtual RID environment_create() = 0;
virtual void environment_set_background(RID p_env, VS::EnvironmentBG p_bg) = 0;
- virtual void environment_set_skybox(RID p_env, RID p_skybox) = 0;
- virtual void environment_set_skybox_scale(RID p_env, float p_scale) = 0;
+ virtual void environment_set_sky(RID p_env, RID p_sky) = 0;
+ virtual void environment_set_sky_scale(RID p_env, float p_scale) = 0;
virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0;
virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0;
virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0;
- virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_skybox_contribution = 0.0) = 0;
+ virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_sky_contribution = 0.0) = 0;
virtual void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) = 0;
virtual void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) = 0;
- virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_treshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) = 0;
+ virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) = 0;
virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) = 0;
- virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_accel, float p_fade, float p_depth_tolerance, bool p_smooth, bool p_roughness) = 0;
+ virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance, bool p_roughness) = 0;
virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, bool p_blur) = 0;
virtual void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0;
virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) = 0;
+ virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) = 0;
+ virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
+ virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0;
+
+ virtual bool is_environment(RID p_env) = 0;
+ virtual VS::EnvironmentBG environment_get_background(RID p_env) = 0;
+ virtual int environment_get_canvas_max_layer(RID p_env) = 0;
+
struct InstanceBase : RID_Data {
VS::InstanceType base_type;
@@ -98,41 +107,36 @@ public:
//int baked_lightmap_id;
bool mirror : 8;
- bool depth_scale : 8;
- bool billboard : 8;
- bool billboard_y : 8;
bool receive_shadows : 8;
bool visible : 8;
+ bool baked_light : 8; //this flag is only to know if it actually did use baked light
float depth; //used for sorting
SelfList<InstanceBase> dependency_item;
- InstanceBase *baked_light; //baked light to use
- SelfList<InstanceBase> baked_light_item;
+ //InstanceBase *baked_light; //baked light to use
+ //SelfList<InstanceBase> baked_light_item;
virtual void base_removed() = 0;
virtual void base_changed() = 0;
virtual void base_material_changed() = 0;
InstanceBase()
- : dependency_item(this), baked_light_item(this) {
+ : dependency_item(this) {
base_type = VS::INSTANCE_NONE;
cast_shadows = VS::SHADOW_CASTING_SETTING_ON;
receive_shadows = true;
- depth_scale = false;
- billboard = false;
- billboard_y = false;
visible = true;
depth_layer = 0;
layer_mask = 1;
- baked_light = NULL;
+ baked_light = false;
}
};
virtual RID light_instance_create(RID p_light) = 0;
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0;
- virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass) = 0;
+ virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0) = 0;
virtual void light_instance_mark_visible(RID p_light_instance) = 0;
virtual RID reflection_atlas_create() = 0;
@@ -156,6 +160,7 @@ public:
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) = 0;
virtual void set_scene_pass(uint64_t p_pass) = 0;
+ virtual void set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw) = 0;
virtual bool free(RID p_rid) = 0;
@@ -168,11 +173,12 @@ public:
virtual RID texture_create() = 0;
virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT) = 0;
- virtual void texture_set_data(RID p_texture, const Image &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) = 0;
- virtual Image texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const = 0;
+ virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) = 0;
+ virtual Ref<Image> texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const = 0;
virtual void texture_set_flags(RID p_texture, uint32_t p_flags) = 0;
virtual uint32_t texture_get_flags(RID p_texture) const = 0;
virtual Image::Format texture_get_format(RID p_texture) const = 0;
+ virtual uint32_t texture_get_texid(RID p_texture) const = 0;
virtual uint32_t texture_get_width(RID p_texture) const = 0;
virtual uint32_t texture_get_height(RID p_texture) const = 0;
virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) = 0;
@@ -188,20 +194,18 @@ public:
virtual void texture_set_detect_3d_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) = 0;
virtual void texture_set_detect_srgb_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) = 0;
+ virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) = 0;
virtual void textures_keep_original(bool p_enable) = 0;
- /* SKYBOX API */
+ /* SKY API */
- virtual RID skybox_create() = 0;
- virtual void skybox_set_texture(RID p_skybox, RID p_cube_map, int p_radiance_size) = 0;
+ virtual RID sky_create() = 0;
+ virtual void sky_set_texture(RID p_sky, RID p_cube_map, int p_radiance_size) = 0;
/* SHADER API */
- virtual RID shader_create(VS::ShaderMode p_mode = VS::SHADER_SPATIAL) = 0;
-
- virtual void shader_set_mode(RID p_shader, VS::ShaderMode p_mode) = 0;
- virtual VS::ShaderMode shader_get_mode(RID p_shader) const = 0;
+ virtual RID shader_create() = 0;
virtual void shader_set_code(RID p_shader, const String &p_code) = 0;
virtual String shader_get_code(RID p_shader) const = 0;
@@ -222,6 +226,8 @@ public:
virtual void material_set_line_width(RID p_material, float p_width) = 0;
+ virtual void material_set_next_pass(RID p_material, RID p_next_material) = 0;
+
virtual bool material_is_animated(RID p_material) = 0;
virtual bool material_casts_shadows(RID p_material) = 0;
@@ -417,6 +423,9 @@ public:
virtual void gi_probe_set_bias(RID p_probe, float p_range) = 0;
virtual float gi_probe_get_bias(RID p_probe) const = 0;
+ virtual void gi_probe_set_normal_bias(RID p_probe, float p_range) = 0;
+ virtual float gi_probe_get_normal_bias(RID p_probe) const = 0;
+
virtual void gi_probe_set_propagation(RID p_probe, float p_range) = 0;
virtual float gi_probe_get_propagation(RID p_probe) const = 0;
@@ -445,32 +454,38 @@ public:
virtual void particles_set_emitting(RID p_particles, bool p_emitting) = 0;
virtual void particles_set_amount(RID p_particles, int p_amount) = 0;
virtual void particles_set_lifetime(RID p_particles, float p_lifetime) = 0;
+ virtual void particles_set_one_shot(RID p_particles, bool p_one_shot) = 0;
virtual void particles_set_pre_process_time(RID p_particles, float p_time) = 0;
virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) = 0;
virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio) = 0;
virtual void particles_set_custom_aabb(RID p_particles, const Rect3 &p_aabb) = 0;
- virtual void particles_set_gravity(RID p_particles, const Vector3 &p_gravity) = 0;
+ virtual void particles_set_speed_scale(RID p_particles, float p_scale) = 0;
virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable) = 0;
virtual void particles_set_process_material(RID p_particles, RID p_material) = 0;
-
- virtual void particles_set_emission_shape(RID p_particles, VS::ParticlesEmissionShape p_shape) = 0;
- virtual void particles_set_emission_sphere_radius(RID p_particles, float p_radius) = 0;
- virtual void particles_set_emission_box_extents(RID p_particles, const Vector3 &p_extents) = 0;
- virtual void particles_set_emission_points(RID p_particles, const PoolVector<Vector3> &p_points) = 0;
+ virtual void particles_set_fixed_fps(RID p_particles, int p_fps) = 0;
+ virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) = 0;
+ virtual void particles_restart(RID p_particles) = 0;
virtual void particles_set_draw_order(RID p_particles, VS::ParticlesDrawOrder p_order) = 0;
virtual void particles_set_draw_passes(RID p_particles, int p_count) = 0;
- virtual void particles_set_draw_pass_material(RID p_particles, int p_pass, RID p_material) = 0;
virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) = 0;
+ virtual void particles_request_process(RID p_particles) = 0;
virtual Rect3 particles_get_current_aabb(RID p_particles) = 0;
+ virtual Rect3 particles_get_aabb(RID p_particles) const = 0;
+
+ virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0;
+
+ virtual int particles_get_draw_passes(RID p_particles) const = 0;
+ virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const = 0;
/* RENDER TARGET */
enum RenderTargetFlags {
RENDER_TARGET_VFLIP,
RENDER_TARGET_TRANSPARENT,
+ RENDER_TARGET_NO_3D_EFFECTS,
RENDER_TARGET_NO_3D,
RENDER_TARGET_NO_SAMPLING,
RENDER_TARGET_HDR,
@@ -481,7 +496,8 @@ public:
virtual void render_target_set_size(RID p_render_target, int p_width, int p_height) = 0;
virtual RID render_target_get_texture(RID p_render_target) const = 0;
virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) = 0;
- virtual bool render_target_renedered_in_frame(RID p_render_target) = 0;
+ virtual bool render_target_was_used(RID p_render_target) = 0;
+ virtual void render_target_clear_used(RID p_render_target) = 0;
virtual void render_target_set_msaa(RID p_render_target, VS::ViewportMSAA p_msaa) = 0;
/* CANVAS SHADOW */
@@ -500,7 +516,15 @@ public:
virtual void update_dirty_resources() = 0;
- static RasterizerStorage *base_signleton;
+ virtual void set_debug_generate_wireframes(bool p_generate) = 0;
+
+ virtual void render_info_begin_capture() = 0;
+ virtual void render_info_end_capture() = 0;
+ virtual int get_captured_render_info(VS::RenderInfo p_info) = 0;
+
+ virtual int get_render_info(VS::RenderInfo p_info) = 0;
+
+ static RasterizerStorage *base_singleton;
RasterizerStorage();
virtual ~RasterizerStorage() {}
};
@@ -513,7 +537,8 @@ public:
CANVAS_RECT_TILE = 2,
CANVAS_RECT_FLIP_H = 4,
CANVAS_RECT_FLIP_V = 8,
- CANVAS_RECT_TRANSPOSE = 16
+ CANVAS_RECT_TRANSPOSE = 16,
+ CANVAS_RECT_CLIP_UV = 32
};
struct Light : public RID_Data {
@@ -539,6 +564,7 @@ public:
float shadow_gradient_length;
VS::CanvasLightShadowFilter shadow_filter;
Color shadow_color;
+ float shadow_smooth;
void *texture_cache; // implementation dependent
Rect2 rect_cache;
@@ -577,6 +603,7 @@ public:
shadow_buffer_size = 256;
shadow_gradient_length = 0;
shadow_filter = VS::CANVAS_LIGHT_FILTER_NONE;
+ shadow_smooth = 0.0;
}
};
@@ -591,12 +618,14 @@ public:
enum Type {
TYPE_LINE,
+ TYPE_POLYLINE,
TYPE_RECT,
TYPE_NINEPATCH,
TYPE_PRIMITIVE,
TYPE_POLYGON,
TYPE_MESH,
TYPE_MULTIMESH,
+ TYPE_PARTICLES,
TYPE_CIRCLE,
TYPE_TRANSFORM,
TYPE_CLIP_IGNORE,
@@ -614,11 +643,24 @@ public:
bool antialiased;
CommandLine() { type = TYPE_LINE; }
};
+ struct CommandPolyLine : public Command {
+
+ bool antialiased;
+ Vector<Point2> triangles;
+ Vector<Color> triangle_colors;
+ Vector<Point2> lines;
+ Vector<Color> line_colors;
+ CommandPolyLine() {
+ type = TYPE_POLYLINE;
+ antialiased = false;
+ }
+ };
struct CommandRect : public Command {
Rect2 rect;
RID texture;
+ RID normal_map;
Color modulate;
Rect2 source;
uint8_t flags;
@@ -634,6 +676,7 @@ public:
Rect2 rect;
Rect2 source;
RID texture;
+ RID normal_map;
float margin[4];
bool draw_center;
Color color;
@@ -651,6 +694,7 @@ public:
Vector<Point2> uvs;
Vector<Color> colors;
RID texture;
+ RID normal_map;
float width;
CommandPrimitive() {
@@ -666,6 +710,7 @@ public:
Vector<Point2> uvs;
Vector<Color> colors;
RID texture;
+ RID normal_map;
int count;
CommandPolygon() {
@@ -688,6 +733,16 @@ public:
CommandMultiMesh() { type = TYPE_MULTIMESH; }
};
+ struct CommandParticles : public Command {
+
+ RID particles;
+ RID texture;
+ RID normal_map;
+ int h_frames;
+ int v_frames;
+ CommandParticles() { type = TYPE_PARTICLES; }
+ };
+
struct CommandCircle : public Command {
Point2 pos;
@@ -776,9 +831,34 @@ public:
case Item::Command::TYPE_LINE: {
const Item::CommandLine *line = static_cast<const Item::CommandLine *>(c);
- r.pos = line->from;
+ r.position = line->from;
r.expand_to(line->to);
} break;
+ case Item::Command::TYPE_POLYLINE: {
+
+ const Item::CommandPolyLine *pline = static_cast<const Item::CommandPolyLine *>(c);
+ if (pline->triangles.size()) {
+ for (int j = 0; j < pline->triangles.size(); j++) {
+
+ if (j == 0) {
+ r.position = pline->triangles[j];
+ } else {
+ r.expand_to(pline->triangles[j]);
+ }
+ }
+ } else {
+
+ for (int j = 0; j < pline->lines.size(); j++) {
+
+ if (j == 0) {
+ r.position = pline->lines[j];
+ } else {
+ r.expand_to(pline->lines[j]);
+ }
+ }
+ }
+
+ } break;
case Item::Command::TYPE_RECT: {
const Item::CommandRect *crect = static_cast<const Item::CommandRect *>(c);
@@ -793,7 +873,7 @@ public:
case Item::Command::TYPE_PRIMITIVE: {
const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c);
- r.pos = primitive->points[0];
+ r.position = primitive->points[0];
for (int i = 1; i < primitive->points.size(); i++) {
r.expand_to(primitive->points[i]);
@@ -804,7 +884,7 @@ public:
const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c);
int l = polygon->points.size();
const Point2 *pp = &polygon->points[0];
- r.pos = pp[0];
+ r.position = pp[0];
for (int i = 1; i < l; i++) {
r.expand_to(pp[i]);
@@ -813,23 +893,32 @@ public:
case Item::Command::TYPE_MESH: {
const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c);
- Rect3 aabb = RasterizerStorage::base_signleton->mesh_get_aabb(mesh->mesh, mesh->skeleton);
+ Rect3 aabb = RasterizerStorage::base_singleton->mesh_get_aabb(mesh->mesh, mesh->skeleton);
- r = Rect2(aabb.pos.x, aabb.pos.y, aabb.size.x, aabb.size.y);
+ r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
} break;
case Item::Command::TYPE_MULTIMESH: {
const Item::CommandMultiMesh *multimesh = static_cast<const Item::CommandMultiMesh *>(c);
- Rect3 aabb = RasterizerStorage::base_signleton->multimesh_get_aabb(multimesh->multimesh);
+ Rect3 aabb = RasterizerStorage::base_singleton->multimesh_get_aabb(multimesh->multimesh);
+
+ r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
+
+ } break;
+ case Item::Command::TYPE_PARTICLES: {
- r = Rect2(aabb.pos.x, aabb.pos.y, aabb.size.x, aabb.size.y);
+ const Item::CommandParticles *particles_cmd = static_cast<const Item::CommandParticles *>(c);
+ if (particles_cmd->particles.is_valid()) {
+ Rect3 aabb = RasterizerStorage::base_singleton->particles_get_aabb(particles_cmd->particles);
+ r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
+ }
} break;
case Item::Command::TYPE_CIRCLE: {
const Item::CommandCircle *circle = static_cast<const Item::CommandCircle *>(c);
- r.pos = Point2(-circle->radius, -circle->radius) + circle->pos;
+ r.position = Point2(-circle->radius, -circle->radius) + circle->pos;
r.size = Point2(circle->radius * 2.0, circle->radius * 2.0);
} break;
case Item::Command::TYPE_TRANSFORM: {
@@ -894,6 +983,7 @@ public:
};
virtual void canvas_begin() = 0;
+ virtual void canvas_end() = 0;
virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light) = 0;
virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) = 0;
@@ -924,6 +1014,8 @@ public:
virtual void reset_canvas() = 0;
+ virtual void draw_window_margins(int *p_margins, RID *p_margin_textures) = 0;
+
virtual ~RasterizerCanvas() {}
};
@@ -938,6 +1030,8 @@ public:
virtual RasterizerCanvas *get_canvas() = 0;
virtual RasterizerScene *get_scene() = 0;
+ virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale) = 0;
+
virtual void initialize() = 0;
virtual void begin_frame() = 0;
virtual void set_current_render_target(RID p_render_target) = 0;
@@ -971,7 +1065,7 @@ protected:
/* Fixed Material Shader API */
- union FixedSpatialMaterialShaderKey {
+ union SpatialMaterialShaderKey {
struct {
uint16_t texcoord_mask;
@@ -987,21 +1081,21 @@ protected:
uint32_t key;
- _FORCE_INLINE_ bool operator<(const FixedSpatialMaterialShaderKey& p_key) const { return key<p_key.key; }
+ _FORCE_INLINE_ bool operator<(const SpatialMaterialShaderKey& p_key) const { return key<p_key.key; }
};
- struct FixedSpatialMaterialShader {
+ struct SpatialMaterialShader {
int refcount;
RID shader;
};
- Map<FixedSpatialMaterialShaderKey,FixedSpatialMaterialShader> fixed_material_shaders;
+ Map<SpatialMaterialShaderKey,SpatialMaterialShader> fixed_material_shaders;
- RID _create_shader(const FixedSpatialMaterialShaderKey& p_key);
- void _free_shader(const FixedSpatialMaterialShaderKey& p_key);
+ RID _create_shader(const SpatialMaterialShaderKey& p_key);
+ void _free_shader(const SpatialMaterialShaderKey& p_key);
- struct FixedSpatialMaterial {
+ struct SpatialMaterial {
RID self;
@@ -1012,19 +1106,19 @@ protected:
bool use_xy_normalmap;
float point_size;
Transform uv_xform;
- VS::FixedSpatialMaterialLightShader light_shader;
+ VS::SpatialMaterialLightShader light_shader;
RID texture[VS::FIXED_MATERIAL_PARAM_MAX];
Variant param[VS::FIXED_MATERIAL_PARAM_MAX];
- VS::FixedSpatialMaterialTexCoordMode texture_tc[VS::FIXED_MATERIAL_PARAM_MAX];
+ VS::SpatialMaterialTexCoordMode texture_tc[VS::FIXED_MATERIAL_PARAM_MAX];
- SelfList<FixedSpatialMaterial> dirty_list;
+ SelfList<SpatialMaterial> dirty_list;
- FixedSpatialMaterialShaderKey current_key;
+ SpatialMaterialShaderKey current_key;
- _FORCE_INLINE_ FixedSpatialMaterialShaderKey get_key() const {
+ _FORCE_INLINE_ SpatialMaterialShaderKey get_key() const {
- FixedSpatialMaterialShaderKey k;
+ SpatialMaterialShaderKey k;
k.key=0;
k.use_alpha=use_alpha;
k.use_color_array=use_color_array;
@@ -1045,7 +1139,7 @@ protected:
}
- FixedSpatialMaterial() : dirty_list(this) {
+ SpatialMaterial() : dirty_list(this) {
use_alpha=false;
use_color_array=false;
@@ -1077,9 +1171,9 @@ protected:
StringName _fixed_material_uv_xform_name;
StringName _fixed_material_point_size_name;
- Map<RID,FixedSpatialMaterial*> fixed_materials;
+ Map<RID,SpatialMaterial*> fixed_materials;
- SelfList<FixedSpatialMaterial>::List fixed_material_dirty_list;
+ SelfList<SpatialMaterial>::List fixed_material_dirty_list;
protected:
void _update_fixed_materials();
@@ -1166,23 +1260,23 @@ public:
virtual RID fixed_material_create();
- virtual void fixed_material_set_flag(RID p_material, VS::FixedSpatialMaterialFlags p_flag, bool p_enabled);
- virtual bool fixed_material_get_flag(RID p_material, VS::FixedSpatialMaterialFlags p_flag) const;
+ virtual void fixed_material_set_flag(RID p_material, VS::SpatialMaterialFlags p_flag, bool p_enabled);
+ virtual bool fixed_material_get_flag(RID p_material, VS::SpatialMaterialFlags p_flag) const;
- virtual void fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant& p_value);
- virtual Variant fixed_material_get_parameter(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const;
+ virtual void fixed_material_set_parameter(RID p_material, VS::SpatialMaterialParam p_parameter, const Variant& p_value);
+ virtual Variant fixed_material_get_parameter(RID p_material,VS::SpatialMaterialParam p_parameter) const;
- virtual void fixed_material_set_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter, RID p_texture);
- virtual RID fixed_material_get_texture(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const;
+ virtual void fixed_material_set_texture(RID p_material,VS::SpatialMaterialParam p_parameter, RID p_texture);
+ virtual RID fixed_material_get_texture(RID p_material,VS::SpatialMaterialParam p_parameter) const;
- virtual void fixed_material_set_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode);
- virtual VS::FixedSpatialMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material,VS::FixedSpatialMaterialParam p_parameter) const;
+ virtual void fixed_material_set_texcoord_mode(RID p_material,VS::SpatialMaterialParam p_parameter, VS::SpatialMaterialTexCoordMode p_mode);
+ virtual VS::SpatialMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material,VS::SpatialMaterialParam p_parameter) const;
virtual void fixed_material_set_uv_transform(RID p_material,const Transform& p_transform);
virtual Transform fixed_material_get_uv_transform(RID p_material) const;
- virtual void fixed_material_set_light_shader(RID p_material,VS::FixedSpatialMaterialLightShader p_shader);
- virtual VS::FixedSpatialMaterialLightShader fixed_material_get_light_shader(RID p_material) const;
+ virtual void fixed_material_set_light_shader(RID p_material,VS::SpatialMaterialLightShader p_shader);
+ virtual VS::SpatialMaterialLightShader fixed_material_get_light_shader(RID p_material) const;
virtual void fixed_material_set_point_size(RID p_material,float p_size);
virtual float fixed_material_get_point_size(RID p_material) const;
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index bc4452d5a8..49f9e161fa 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -81,7 +82,8 @@ String ShaderLanguage::get_operator_text(Operator p_op) {
"++"
"--",
"()",
- "construct" };
+ "construct",
+ "index" };
return op_names[p_op];
}
@@ -176,6 +178,9 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"PERIOD",
"UNIFORM",
"VARYING",
+ "IN",
+ "OUT",
+ "INOUT",
"RENDER_MODE",
"HINT_WHITE_TEXTURE",
"HINT_BLACK_TEXTURE",
@@ -185,6 +190,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"HINT_BLACK_ALBEDO_TEXTURE",
"HINT_COLOR",
"HINT_RANGE",
+ "SHADER_TYPE",
"CURSOR",
"ERROR",
"EOF",
@@ -258,6 +264,9 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
{ TK_CF_RETURN, "return" },
{ TK_UNIFORM, "uniform" },
{ TK_VARYING, "varying" },
+ { TK_ARG_IN, "in" },
+ { TK_ARG_OUT, "out" },
+ { TK_ARG_INOUT, "inout" },
{ TK_RENDER_MODE, "render_mode" },
{ TK_HINT_WHITE_TEXTURE, "hint_white" },
{ TK_HINT_BLACK_TEXTURE, "hint_black" },
@@ -267,6 +276,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
{ TK_HINT_BLACK_ALBEDO_TEXTURE, "hint_black_albedo" },
{ TK_HINT_COLOR, "hint_color" },
{ TK_HINT_RANGE, "hint_range" },
+ { TK_SHADER_TYPE, "shader_type" },
{ TK_ERROR, NULL }
};
@@ -368,7 +378,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
if (GETCHAR(0) == '=') {
char_idx++;
return _make_token(TK_OP_GREATER_EQUAL);
- } else if (GETCHAR(0) == '<') {
+ } else if (GETCHAR(0) == '>') {
char_idx++;
if (GETCHAR(0) == '=') {
char_idx++;
@@ -871,7 +881,7 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
}
if (na == nb) {
- valid = (na > TYPE_BOOL && na < TYPE_MAT2) || (p_op->op == OP_MUL && na >= TYPE_MAT2 && na <= TYPE_MAT4);
+ valid = (na > TYPE_BOOL && na <= TYPE_MAT4);
ret_type = na;
} else if (na == TYPE_INT && nb == TYPE_IVEC2) {
valid = true;
@@ -900,15 +910,24 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
} else if (na == TYPE_FLOAT && nb == TYPE_VEC4) {
valid = true;
ret_type = TYPE_VEC4;
- } else if (p_op->op == OP_MUL && na == TYPE_VEC2 && nb == TYPE_MAT2) {
+ } else if (p_op->op == OP_MUL && na == TYPE_FLOAT && nb == TYPE_MAT2) {
valid = true;
ret_type = TYPE_MAT2;
- } else if (p_op->op == OP_MUL && na == TYPE_VEC3 && nb == TYPE_MAT3) {
+ } else if (p_op->op == OP_MUL && na == TYPE_FLOAT && nb == TYPE_MAT3) {
valid = true;
ret_type = TYPE_MAT3;
- } else if (p_op->op == OP_MUL && na == TYPE_VEC4 && nb == TYPE_MAT4) {
+ } else if (p_op->op == OP_MUL && na == TYPE_FLOAT && nb == TYPE_MAT4) {
valid = true;
ret_type = TYPE_MAT4;
+ } else if (p_op->op == OP_MUL && na == TYPE_VEC2 && nb == TYPE_MAT2) {
+ valid = true;
+ ret_type = TYPE_VEC2;
+ } else if (p_op->op == OP_MUL && na == TYPE_VEC3 && nb == TYPE_MAT3) {
+ valid = true;
+ ret_type = TYPE_VEC3;
+ } else if (p_op->op == OP_MUL && na == TYPE_VEC4 && nb == TYPE_MAT4) {
+ valid = true;
+ ret_type = TYPE_VEC4;
}
} break;
case OP_ASSIGN_MOD:
@@ -977,14 +996,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
DataType na = p_op->arguments[0]->get_datatype();
DataType nb = p_op->arguments[1]->get_datatype();
- if (na >= TYPE_UINT && na <= TYPE_UVEC4) {
- na = DataType(na - 4);
- }
-
- if (nb >= TYPE_UINT && nb <= TYPE_UVEC4) {
- nb = DataType(nb - 4);
- }
-
if (na == TYPE_INT && nb == TYPE_INT) {
valid = true;
ret_type = TYPE_INT;
@@ -1006,6 +1017,27 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
} else if (na == TYPE_IVEC4 && nb == TYPE_IVEC4) {
valid = true;
ret_type = TYPE_IVEC4;
+ } else if (na == TYPE_UINT && nb == TYPE_UINT) {
+ valid = true;
+ ret_type = TYPE_UINT;
+ } else if (na == TYPE_UVEC2 && nb == TYPE_UINT) {
+ valid = true;
+ ret_type = TYPE_UVEC2;
+ } else if (na == TYPE_UVEC3 && nb == TYPE_UINT) {
+ valid = true;
+ ret_type = TYPE_UVEC3;
+ } else if (na == TYPE_UVEC4 && nb == TYPE_UINT) {
+ valid = true;
+ ret_type = TYPE_UVEC4;
+ } else if (na == TYPE_UVEC2 && nb == TYPE_UVEC2) {
+ valid = true;
+ ret_type = TYPE_UVEC2;
+ } else if (na == TYPE_UVEC3 && nb == TYPE_UVEC3) {
+ valid = true;
+ ret_type = TYPE_UVEC3;
+ } else if (na == TYPE_UVEC4 && nb == TYPE_UVEC4) {
+ valid = true;
+ ret_type = TYPE_UVEC4;
}
} break;
case OP_ASSIGN: {
@@ -1325,11 +1357,8 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "tanh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
//builtins - exponential
{ "pow", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
- { "pow", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
{ "pow", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
- { "pow", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
{ "pow", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
- { "pow", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } },
{ "pow", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
{ "exp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
{ "exp", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } },
@@ -1651,25 +1680,19 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "not", TYPE_BOOL, { TYPE_BVEC4, TYPE_VOID } },
//builtins - texture
- { "textureSize", TYPE_VEC2, { TYPE_SAMPLER2D, TYPE_INT, TYPE_VOID } },
- { "textureSize", TYPE_VEC2, { TYPE_ISAMPLER2D, TYPE_INT, TYPE_VOID } },
- { "textureSize", TYPE_VEC2, { TYPE_USAMPLER2D, TYPE_INT, TYPE_VOID } },
- { "textureSize", TYPE_VEC2, { TYPE_SAMPLERCUBE, TYPE_INT, TYPE_VOID } },
+ { "textureSize", TYPE_IVEC2, { TYPE_SAMPLER2D, TYPE_INT, TYPE_VOID } },
+ { "textureSize", TYPE_IVEC2, { TYPE_ISAMPLER2D, TYPE_INT, TYPE_VOID } },
+ { "textureSize", TYPE_IVEC2, { TYPE_USAMPLER2D, TYPE_INT, TYPE_VOID } },
+ { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBE, TYPE_INT, TYPE_VOID } },
{ "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID } },
- { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_VOID } },
{ "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
- { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
{ "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VOID } },
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_VOID } },
{ "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
{ "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VOID } },
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_VOID } },
{ "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VOID } },
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
@@ -1689,9 +1712,9 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
{ "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } },
- { "textureLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
- { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
- { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
+ { "textureLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
+ { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
+ { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
{ "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
{ "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID } },
@@ -2308,9 +2331,17 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
bool ok = _parse_function_arguments(p_block, p_builtin_types, func, &carg);
+ //test if function was parsed first
for (int i = 0; i < shader->functions.size(); i++) {
if (shader->functions[i].name == name) {
- shader->functions[i].uses_function.insert(name);
+ //add to current function as dependency
+ for (int j = 0; j < shader->functions.size(); j++) {
+ if (shader->functions[j].name == current_function) {
+ shader->functions[j].uses_function.insert(name);
+ break;
+ }
+ }
+ break;
}
}
@@ -2514,24 +2545,15 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
} break;
- case TYPE_MAT2:
- ok = (ident == "x" || ident == "y");
- member_type = TYPE_VEC2;
- break;
- case TYPE_MAT3:
- ok = (ident == "x" || ident == "y" || ident == "z");
- member_type = TYPE_VEC3;
- break;
- case TYPE_MAT4:
- ok = (ident == "x" || ident == "y" || ident == "z" || ident == "w");
- member_type = TYPE_VEC4;
- break;
- default: {}
+
+ default: {
+ ok = false;
+ }
}
if (!ok) {
- _set_error("Invalid member for expression: ." + ident);
+ _set_error("Invalid member for " + get_datatype_name(dt) + " expression: ." + ident);
return NULL;
}
@@ -2552,6 +2574,116 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
//creates a subindexing expression in place
*/
+ } else if (tk.type == TK_BRACKET_OPEN) {
+
+ Node *index = _parse_and_reduce_expression(p_block, p_builtin_types);
+
+ if (index->get_datatype() != TYPE_INT && index->get_datatype() != TYPE_UINT) {
+ _set_error("Only integer datatypes are allowed for indexing");
+ return NULL;
+ }
+
+ bool index_valid = false;
+ DataType member_type;
+
+ switch (expr->get_datatype()) {
+ case TYPE_BVEC2:
+ case TYPE_VEC2:
+ case TYPE_IVEC2:
+ case TYPE_UVEC2:
+ case TYPE_MAT2:
+ if (index->type == Node::TYPE_CONSTANT) {
+ uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
+ if (index_constant >= 2) {
+ _set_error("Index out of range (0-1)");
+ return NULL;
+ }
+ } else {
+ _set_error("Only integer constants are allowed as index at the moment");
+ return NULL;
+ }
+ index_valid = true;
+ switch (expr->get_datatype()) {
+ case TYPE_BVEC2: member_type = TYPE_BOOL; break;
+ case TYPE_VEC2: member_type = TYPE_FLOAT; break;
+ case TYPE_IVEC2: member_type = TYPE_INT; break;
+ case TYPE_UVEC2: member_type = TYPE_UINT; break;
+ case TYPE_MAT2: member_type = TYPE_VEC2; break;
+ }
+
+ break;
+ case TYPE_BVEC3:
+ case TYPE_VEC3:
+ case TYPE_IVEC3:
+ case TYPE_UVEC3:
+ case TYPE_MAT3:
+ if (index->type == Node::TYPE_CONSTANT) {
+ uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
+ if (index_constant >= 3) {
+ _set_error("Index out of range (0-2)");
+ return NULL;
+ }
+ } else {
+ _set_error("Only integer constants are allowed as index at the moment");
+ return NULL;
+ }
+ index_valid = true;
+ switch (expr->get_datatype()) {
+ case TYPE_BVEC3: member_type = TYPE_BOOL; break;
+ case TYPE_VEC3: member_type = TYPE_FLOAT; break;
+ case TYPE_IVEC3: member_type = TYPE_INT; break;
+ case TYPE_UVEC3: member_type = TYPE_UINT; break;
+ case TYPE_MAT3: member_type = TYPE_VEC3; break;
+ }
+ break;
+ case TYPE_BVEC4:
+ case TYPE_VEC4:
+ case TYPE_IVEC4:
+ case TYPE_UVEC4:
+ case TYPE_MAT4:
+ if (index->type == Node::TYPE_CONSTANT) {
+ uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint;
+ if (index_constant >= 4) {
+ _set_error("Index out of range (0-3)");
+ return NULL;
+ }
+ } else {
+ _set_error("Only integer constants are allowed as index at the moment");
+ return NULL;
+ }
+ index_valid = true;
+ switch (expr->get_datatype()) {
+ case TYPE_BVEC4: member_type = TYPE_BOOL; break;
+ case TYPE_VEC4: member_type = TYPE_FLOAT; break;
+ case TYPE_IVEC4: member_type = TYPE_INT; break;
+ case TYPE_UVEC4: member_type = TYPE_UINT; break;
+ case TYPE_MAT4: member_type = TYPE_VEC4; break;
+ }
+ break;
+ default: {
+ _set_error("Object of type '" + get_datatype_name(expr->get_datatype()) + "' can't be indexed");
+ return NULL;
+ }
+ }
+
+ if (!index_valid) {
+ _set_error("Invalid index");
+ return NULL;
+ }
+
+ OperatorNode *op = alloc_node<OperatorNode>();
+ op->op = OP_INDEX;
+ op->return_cache = member_type;
+ op->arguments.push_back(expr);
+ op->arguments.push_back(index);
+ expr = op;
+
+ tk = _get_token();
+ if (tk.type != TK_BRACKET_CLOSE) {
+ _set_error("Expected ']' after indexing expression");
+ return NULL;
+ }
+
} else if (tk.type == TK_OP_INCREMENT || tk.type == TK_OP_DECREMENT) {
OperatorNode *op = alloc_node<OperatorNode>();
@@ -3052,7 +3184,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
tk = _get_token();
if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_error("Expected '(' after expression");
+ _set_error("Expected ')' after expression");
return ERR_PARSE_ERROR;
}
@@ -3063,6 +3195,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
p_block->statements.push_back(cf);
Error err = _parse_block(block, p_builtin_types, true, p_can_break, p_can_continue);
+ if (err)
+ return err;
pos = _get_tkpos();
tk = _get_token();
@@ -3076,6 +3210,81 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
} else {
_set_tkpos(pos); //rollback
}
+ } else if (tk.type == TK_CF_WHILE) {
+ //if () {}
+ tk = _get_token();
+ if (tk.type != TK_PARENTHESIS_OPEN) {
+ _set_error("Expected '(' after if");
+ return ERR_PARSE_ERROR;
+ }
+
+ ControlFlowNode *cf = alloc_node<ControlFlowNode>();
+ cf->flow_op = FLOW_OP_WHILE;
+ Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ if (!n)
+ return ERR_PARSE_ERROR;
+
+ tk = _get_token();
+ if (tk.type != TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ')' after expression");
+ return ERR_PARSE_ERROR;
+ }
+
+ BlockNode *block = alloc_node<BlockNode>();
+ block->parent_block = p_block;
+ cf->expressions.push_back(n);
+ cf->blocks.push_back(block);
+ p_block->statements.push_back(cf);
+
+ Error err = _parse_block(block, p_builtin_types, true, p_can_break, p_can_continue);
+ if (err)
+ return err;
+
+ } else if (tk.type == TK_CF_RETURN) {
+
+ //check return type
+ BlockNode *b = p_block;
+ while (b && !b->parent_function) {
+ b = b->parent_block;
+ }
+
+ if (!b) {
+ _set_error("Bug");
+ return ERR_BUG;
+ }
+
+ ControlFlowNode *flow = alloc_node<ControlFlowNode>();
+ flow->flow_op = FLOW_OP_RETURN;
+
+ pos = _get_tkpos();
+ tk = _get_token();
+ if (tk.type == TK_SEMICOLON) {
+ //all is good
+ if (b->parent_function->return_type != TYPE_VOID) {
+ _set_error("Expected return with expression of type '" + get_datatype_name(b->parent_function->return_type) + "'");
+ return ERR_PARSE_ERROR;
+ }
+ } else {
+ _set_tkpos(pos); //rollback, wants expression
+ Node *expr = _parse_and_reduce_expression(p_block, p_builtin_types);
+ if (!expr)
+ return ERR_PARSE_ERROR;
+
+ if (b->parent_function->return_type != expr->get_datatype()) {
+ _set_error("Expected return expression of type '" + get_datatype_name(b->parent_function->return_type) + "'");
+ return ERR_PARSE_ERROR;
+ }
+
+ tk = _get_token();
+ if (tk.type != TK_SEMICOLON) {
+ _set_error("Expected ';' after return expression");
+ return ERR_PARSE_ERROR;
+ }
+
+ flow->expressions.push_back(expr);
+ }
+
+ p_block->statements.push_back(flow);
} else {
@@ -3100,10 +3309,47 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
return OK;
}
-Error ShaderLanguage::_parse_shader(const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes) {
+Error ShaderLanguage::_parse_shader(const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types) {
Token tk = _get_token();
+ if (tk.type != TK_SHADER_TYPE) {
+ _set_error("Expected 'shader_type' at the begining of shader.");
+ return ERR_PARSE_ERROR;
+ }
+
+ tk = _get_token();
+
+ if (tk.type != TK_IDENTIFIER) {
+ _set_error("Expected identifier after 'shader_type', indicating type of shader.");
+ return ERR_PARSE_ERROR;
+ }
+
+ String shader_type_identifier;
+
+ shader_type_identifier = tk.text;
+
+ if (!p_shader_types.has(shader_type_identifier)) {
+
+ String valid;
+ for (Set<String>::Element *E = p_shader_types.front(); E; E = E->next()) {
+ if (valid != String()) {
+ valid += ", ";
+ }
+ valid += "'" + E->get() + "'";
+ }
+ _set_error("Invalid shader type, valid types are: " + valid);
+ return ERR_PARSE_ERROR;
+ }
+
+ tk = _get_token();
+
+ if (tk.type != TK_SEMICOLON) {
+ _set_error("Expected ';' after 'shader_type <type>'.");
+ }
+
+ tk = _get_token();
+
int texture_uniforms = 0;
int uniforms = 0;
@@ -3428,6 +3674,19 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, Map<StringName, DataTy
break;
}
+ ArgumentQualifier qualifier = ARGUMENT_QUALIFIER_IN;
+
+ if (tk.type == TK_ARG_IN) {
+ qualifier = ARGUMENT_QUALIFIER_IN;
+ tk = _get_token();
+ } else if (tk.type == TK_ARG_OUT) {
+ qualifier = ARGUMENT_QUALIFIER_OUT;
+ tk = _get_token();
+ } else if (tk.type == TK_ARG_INOUT) {
+ qualifier = ARGUMENT_QUALIFIER_INOUT;
+ tk = _get_token();
+ }
+
DataType ptype;
StringName pname;
DataPrecision pprecision = PRECISION_DEFAULT;
@@ -3466,6 +3725,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, Map<StringName, DataTy
arg.type = ptype;
arg.name = pname;
arg.precision = pprecision;
+ arg.qualifier = qualifier;
func_node->arguments.push_back(arg);
@@ -3515,7 +3775,42 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, Map<StringName, DataTy
return OK;
}
-Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes) {
+String ShaderLanguage::get_shader_type(const String &p_code) {
+
+ bool reading_type = false;
+
+ String cur_identifier;
+
+ for (int i = 0; i < p_code.length(); i++) {
+
+ if (p_code[i] == ';') {
+ break;
+
+ } else if (p_code[i] <= 32) {
+ if (cur_identifier != String()) {
+ if (!reading_type) {
+ if (cur_identifier != "shader_type") {
+ return String();
+ }
+
+ reading_type = true;
+ cur_identifier = String();
+ } else {
+ return cur_identifier;
+ }
+ }
+ } else {
+ cur_identifier += String::chr(p_code[i]);
+ }
+ }
+
+ if (reading_type)
+ return cur_identifier;
+
+ return String();
+}
+
+Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types) {
clear();
@@ -3524,7 +3819,7 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Map<St
nodes = NULL;
shader = alloc_node<ShaderNode>();
- Error err = _parse_shader(p_functions, p_render_modes);
+ Error err = _parse_shader(p_functions, p_render_modes, p_shader_types);
if (err != OK) {
return err;
@@ -3532,7 +3827,7 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Map<St
return OK;
}
-Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, List<String> *r_options, String &r_call_hint) {
+Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint) {
clear();
@@ -3541,7 +3836,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Map<S
nodes = NULL;
shader = alloc_node<ShaderNode>();
- Error err = _parse_shader(p_functions, p_render_modes);
+ Error err = _parse_shader(p_functions, p_render_modes, p_shader_types);
switch (completion_type) {
diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h
index a4757e3419..c92cbf2abb 100644
--- a/servers/visual/shader_language.h
+++ b/servers/visual/shader_language.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -130,6 +131,9 @@ public:
TK_PERIOD,
TK_UNIFORM,
TK_VARYING,
+ TK_ARG_IN,
+ TK_ARG_OUT,
+ TK_ARG_INOUT,
TK_RENDER_MODE,
TK_HINT_WHITE_TEXTURE,
TK_HINT_BLACK_TEXTURE,
@@ -139,6 +143,7 @@ public:
TK_HINT_BLACK_ALBEDO_TEXTURE,
TK_HINT_COLOR,
TK_HINT_RANGE,
+ TK_SHADER_TYPE,
TK_CURSOR,
TK_ERROR,
TK_EOF,
@@ -227,6 +232,7 @@ public:
OP_POST_DECREMENT,
OP_CALL,
OP_CONSTRUCT,
+ OP_INDEX,
OP_MAX
};
@@ -242,6 +248,13 @@ public:
};
+ enum ArgumentQualifier {
+ ARGUMENT_QUALIFIER_IN,
+ ARGUMENT_QUALIFIER_OUT,
+ ARGUMENT_QUALIFIER_INOUT,
+
+ };
+
struct Node {
Node *next;
@@ -363,6 +376,7 @@ public:
struct Argument {
+ ArgumentQualifier qualifier;
StringName name;
DataType type;
DataPrecision precision;
@@ -577,14 +591,16 @@ private:
Error _parse_block(BlockNode *p_block, const Map<StringName, DataType> &p_builtin_types, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false);
- Error _parse_shader(const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes);
+ Error _parse_shader(const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types);
public:
//static void get_keyword_list(ShaderType p_type,List<String> *p_keywords);
void clear();
- Error compile(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes);
- Error complete(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, List<String> *r_options, String &r_call_hint);
+
+ static String get_shader_type(const String &p_code);
+ Error compile(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types);
+ Error complete(const String &p_code, const Map<StringName, Map<StringName, DataType> > &p_functions, const Set<String> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint);
String get_error_text();
int get_error_line();
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index c5e31b235a..3f1403d532 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -38,6 +39,10 @@ const Set<String> &ShaderTypes::get_modes(VS::ShaderMode p_mode) {
return shader_modes[p_mode].modes;
}
+const Set<String> &ShaderTypes::get_types() {
+ return shader_types;
+}
+
ShaderTypes *ShaderTypes::singleton = NULL;
ShaderTypes::ShaderTypes() {
@@ -47,7 +52,6 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_VERTEX"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_NORMAL"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_TANGENT"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_BONES"] = ShaderLanguage::TYPE_IVEC4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_WEIGHTS"] = ShaderLanguage::TYPE_VEC4;
@@ -61,11 +65,15 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["POINT_SIZE"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["INSTANCE_ID"] = ShaderLanguage::TYPE_INT;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["INSTANCE_CUSTOM"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT;
//builtins
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["INV_CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["MODELVIEW_MATRIX"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["VIEWPORT_SIZE"] = ShaderLanguage::TYPE_VEC2;
@@ -83,7 +91,8 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["NORMAL"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ALBEDO"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ALPHA"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SPECULAR"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["METALLIC"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SPECULAR"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["RIM"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["RIM_TINT"] = ShaderLanguage::TYPE_FLOAT;
@@ -94,10 +103,13 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SSS_STRENGTH"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["AO"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["EMISSION"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SPECIAL"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["DISCARD"] = ShaderLanguage::TYPE_BOOL;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SCREEN_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["DEPTH_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["POINT_COORD"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SIDE"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ALPHA_SCISSOR"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["INV_CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
@@ -122,7 +134,22 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].modes.insert("unshaded");
shader_modes[VS::SHADER_SPATIAL].modes.insert("ontop");
- shader_modes[VS::SHADER_SPATIAL].modes.insert("skip_transform");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_lambert");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_half_lambert");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_oren_nayar");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_burley");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_toon");
+
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("specular_schlick_ggx");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("specular_blinn");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("specular_phong");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("specular_toon");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("specular_disabled");
+
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("skip_vertex_transform");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("world_vertex_coords");
+
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("vertex_lighting");
/************ CANVAS ITEM **************************/
@@ -136,9 +163,11 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["EXTRA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["PARTICLE_CUSTOM"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["AT_LIGHT_PASS"] = ShaderLanguage::TYPE_BOOL;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["SRC_COLOR"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["POSITION"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["FRAGCOORD"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["NORMAL"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["NORMALMAP"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["NORMALMAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
@@ -147,8 +176,12 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["TEXTURE_PIXEL_SIZE"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["SCREEN_PIXEL_SIZE"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["POINT_COORD"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["AT_LIGHT_PASS"] = ShaderLanguage::TYPE_BOOL;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["SCREEN_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["POSITION"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["NORMAL"] = ShaderLanguage::TYPE_VEC3;
@@ -156,8 +189,6 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["TEXTURE_PIXEL_SIZE"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["VAR1"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["VAR2"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["LIGHT_VEC"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["LIGHT_HEIGHT"] = ShaderLanguage::TYPE_FLOAT;
@@ -169,7 +200,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["POINT_COORD"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("skip_transform");
+ shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("skip_vertex_transform");
shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("blend_mix");
shader_modes[VS::SHADER_CANVAS_ITEM].modes.insert("blend_add");
@@ -192,11 +223,17 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["LIFETIME"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["DELTA"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["SEED"] = ShaderLanguage::TYPE_BOOL;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["ORIGIN"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["NUMBER"] = ShaderLanguage::TYPE_UINT;
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["INDEX"] = ShaderLanguage::TYPE_INT;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["EMISSION_TRANSFORM"] = ShaderLanguage::TYPE_MAT4;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["RANDOM_SEED"] = ShaderLanguage::TYPE_UINT;
shader_modes[VS::SHADER_PARTICLES].modes.insert("billboard");
shader_modes[VS::SHADER_PARTICLES].modes.insert("disable_force");
shader_modes[VS::SHADER_PARTICLES].modes.insert("disable_velocity");
+ shader_modes[VS::SHADER_PARTICLES].modes.insert("keep_data");
+
+ shader_types.insert("spatial");
+ shader_types.insert("canvas_item");
+ shader_types.insert("particles");
}
diff --git a/servers/visual/shader_types.h b/servers/visual/shader_types.h
index 1bddde8c82..b8cbabeec1 100644
--- a/servers/visual/shader_types.h
+++ b/servers/visual/shader_types.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -43,11 +44,14 @@ class ShaderTypes {
static ShaderTypes *singleton;
+ Set<String> shader_types;
+
public:
static ShaderTypes *get_singleton() { return singleton; }
const Map<StringName, Map<StringName, ShaderLanguage::DataType> > &get_functions(VS::ShaderMode p_mode);
const Set<String> &get_modes(VS::ShaderMode p_mode);
+ const Set<String> &get_types();
ShaderTypes();
};
diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp
index 40fa779170..dcc16794e7 100644
--- a/servers/visual/visual_server_canvas.cpp
+++ b/servers/visual/visual_server_canvas.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -57,10 +58,16 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor
if (!ci->visible)
return;
+ if (p_canvas_item->children_order_dirty) {
+
+ p_canvas_item->child_items.sort_custom<ItemIndexSort>();
+ p_canvas_item->children_order_dirty = false;
+ }
+
Rect2 rect = ci->get_rect();
Transform2D xform = p_transform * ci->xform;
Rect2 global_rect = xform.xform(rect);
- global_rect.pos += p_clip_rect.pos;
+ global_rect.position += p_clip_rect.position;
if (ci->use_parent_material && p_material_owner)
ci->material_owner = p_material_owner;
@@ -118,7 +125,7 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor
ci->final_transform = xform;
ci->final_modulate = Color(modulate.r * ci->self_modulate.r, modulate.g * ci->self_modulate.g, modulate.b * ci->self_modulate.b, modulate.a * ci->self_modulate.a);
ci->global_rect_cache = global_rect;
- ci->global_rect_cache.pos -= p_clip_rect.pos;
+ ci->global_rect_cache.position -= p_clip_rect.position;
ci->light_masked = false;
int zidx = p_z - VS::CANVAS_ITEM_Z_MIN;
@@ -170,6 +177,12 @@ void VisualServerCanvas::render_canvas(Canvas *p_canvas, const Transform2D &p_tr
VSG::canvas_render->canvas_begin();
+ if (p_canvas->children_order_dirty) {
+
+ p_canvas->child_items.sort();
+ p_canvas->children_order_dirty = false;
+ }
+
int l = p_canvas->child_items.size();
Canvas::ChildItem *ci = p_canvas->child_items.ptr();
@@ -230,6 +243,8 @@ void VisualServerCanvas::render_canvas(Canvas *p_canvas, const Transform2D &p_tr
}
}
}
+
+ VSG::canvas_render->canvas_end();
}
RID VisualServerCanvas::canvas_create() {
@@ -394,6 +409,86 @@ void VisualServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_from,
canvas_item->commands.push_back(line);
}
+void VisualServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) {
+
+ ERR_FAIL_COND(p_points.size() < 2);
+ Item *canvas_item = canvas_item_owner.getornull(p_item);
+ ERR_FAIL_COND(!canvas_item);
+
+ Item::CommandPolyLine *pline = memnew(Item::CommandPolyLine);
+ ERR_FAIL_COND(!pline);
+
+ pline->antialiased = p_antialiased;
+
+ if (p_width <= 1) {
+ pline->lines = p_points;
+ pline->line_colors = p_colors;
+ if (pline->line_colors.size() == 0) {
+ pline->line_colors.push_back(Color(1, 1, 1, 1));
+ } else if (pline->line_colors.size() > 1 && pline->line_colors.size() != pline->lines.size()) {
+ pline->line_colors.resize(1);
+ }
+ } else {
+ //make a trianglestrip for drawing the line...
+ Vector2 prev_t;
+ pline->triangles.resize(p_points.size() * 2);
+ if (p_antialiased) {
+ pline->lines.resize(p_points.size() * 2);
+ }
+
+ if (p_colors.size() == 0) {
+ pline->triangle_colors.push_back(Color(1, 1, 1, 1));
+ if (p_antialiased) {
+ pline->line_colors.push_back(Color(1, 1, 1, 1));
+ }
+ }
+ if (p_colors.size() == 1) {
+ pline->triangle_colors = p_colors;
+ pline->line_colors = p_colors;
+ } else {
+ pline->triangle_colors.resize(pline->triangles.size());
+ pline->line_colors.resize(pline->lines.size());
+ }
+
+ for (int i = 0; i < p_points.size(); i++) {
+
+ Vector2 t;
+ if (i == p_points.size() - 1) {
+ t = prev_t;
+ } else {
+ t = (p_points[i + 1] - p_points[i]).normalized().tangent();
+ if (i == 0) {
+ prev_t = t;
+ }
+ }
+
+ Vector2 tangent = ((t + prev_t).normalized()) * p_width * 0.5;
+
+ if (p_antialiased) {
+ pline->lines[i] = p_points[i] + tangent;
+ pline->lines[p_points.size() * 2 - i - 1] = p_points[i] - tangent;
+ if (pline->line_colors.size() > 1) {
+ pline->line_colors[i] = p_colors[i];
+ pline->line_colors[p_points.size() * 2 - i - 1] = p_colors[i];
+ }
+ }
+
+ pline->triangles[i * 2 + 0] = p_points[i] + tangent;
+ pline->triangles[i * 2 + 1] = p_points[i] - tangent;
+
+ if (pline->triangle_colors.size() > 1) {
+
+ pline->triangle_colors[i * 2 + 0] = p_colors[i];
+ pline->triangle_colors[i * 2 + 1] = p_colors[i];
+ }
+
+ prev_t = t;
+ }
+ }
+ canvas_item->rect_dirty = true;
+ canvas_item->commands.push_back(pline);
+}
+
void VisualServerCanvas::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
@@ -422,7 +517,7 @@ void VisualServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_pos,
canvas_item->commands.push_back(circle);
}
-void VisualServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose) {
+void VisualServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose, RID p_normal_map) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -453,11 +548,12 @@ void VisualServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p
SWAP(rect->rect.size.x, rect->rect.size.y);
}
rect->texture = p_texture;
+ rect->normal_map = p_normal_map;
canvas_item->rect_dirty = true;
canvas_item->commands.push_back(rect);
}
-void VisualServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose) {
+void VisualServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, RID p_normal_map, bool p_clip_uv) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -467,6 +563,7 @@ void VisualServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const R
rect->modulate = p_modulate;
rect->rect = p_rect;
rect->texture = p_texture;
+ rect->normal_map = p_normal_map;
rect->source = p_src_rect;
rect->flags = RasterizerCanvas::CANVAS_RECT_REGION;
@@ -485,12 +582,16 @@ void VisualServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const R
SWAP(rect->rect.size.x, rect->rect.size.y);
}
+ if (p_clip_uv) {
+ rect->flags |= RasterizerCanvas::CANVAS_RECT_CLIP_UV;
+ }
+
canvas_item->rect_dirty = true;
canvas_item->commands.push_back(rect);
}
-void VisualServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, VS::NinePatchAxisMode p_x_axis_mode, VS::NinePatchAxisMode p_y_axis_mode, bool p_draw_center, const Color &p_modulate) {
+void VisualServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, VS::NinePatchAxisMode p_x_axis_mode, VS::NinePatchAxisMode p_y_axis_mode, bool p_draw_center, const Color &p_modulate, RID p_normal_map) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -498,6 +599,7 @@ void VisualServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_r
Item::CommandNinePatch *style = memnew(Item::CommandNinePatch);
ERR_FAIL_COND(!style);
style->texture = p_texture;
+ style->normal_map = p_normal_map;
style->rect = p_rect;
style->source = p_source;
style->draw_center = p_draw_center;
@@ -512,7 +614,7 @@ void VisualServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_r
canvas_item->commands.push_back(style);
}
-void VisualServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width) {
+void VisualServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width, RID p_normal_map) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -520,6 +622,7 @@ void VisualServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Poin
Item::CommandPrimitive *prim = memnew(Item::CommandPrimitive);
ERR_FAIL_COND(!prim);
prim->texture = p_texture;
+ prim->normal_map = p_normal_map;
prim->points = p_points;
prim->uvs = p_uvs;
prim->colors = p_colors;
@@ -529,7 +632,7 @@ void VisualServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Poin
canvas_item->commands.push_back(prim);
}
-void VisualServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture) {
+void VisualServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, RID p_normal_map) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -552,6 +655,7 @@ void VisualServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2
Item::CommandPolygon *polygon = memnew(Item::CommandPolygon);
ERR_FAIL_COND(!polygon);
polygon->texture = p_texture;
+ polygon->normal_map = p_normal_map;
polygon->points = p_points;
polygon->uvs = p_uvs;
polygon->colors = p_colors;
@@ -562,7 +666,7 @@ void VisualServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2
canvas_item->commands.push_back(polygon);
}
-void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, int p_count) {
+void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, int p_count, RID p_normal_map) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -590,6 +694,7 @@ void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector
Item::CommandPolygon *polygon = memnew(Item::CommandPolygon);
ERR_FAIL_COND(!polygon);
polygon->texture = p_texture;
+ polygon->normal_map = p_normal_map;
polygon->points = p_points;
polygon->uvs = p_uvs;
polygon->colors = p_colors;
@@ -624,6 +729,25 @@ void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID
canvas_item->commands.push_back(m);
}
+void VisualServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal, int p_h_frames, int p_v_frames) {
+
+ Item *canvas_item = canvas_item_owner.getornull(p_item);
+ ERR_FAIL_COND(!canvas_item);
+
+ Item::CommandParticles *part = memnew(Item::CommandParticles);
+ ERR_FAIL_COND(!part);
+ part->particles = p_particles;
+ part->texture = p_texture;
+ part->normal_map = p_normal;
+ part->h_frames = p_h_frames;
+ part->v_frames = p_v_frames;
+
+ //take the chance and request processing for them, at least once until they become visible again
+ VSG::storage->particles_request_process(p_particles);
+
+ canvas_item->commands.push_back(part);
+}
+
void VisualServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_skeleton) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
@@ -913,6 +1037,13 @@ void VisualServerCanvas::canvas_light_set_shadow_color(RID p_light, const Color
clight->shadow_color = p_color;
}
+void VisualServerCanvas::canvas_light_set_shadow_smooth(RID p_light, float p_smooth) {
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+ clight->shadow_smooth = p_smooth;
+}
+
RID VisualServerCanvas::canvas_light_occluder_create() {
RasterizerCanvas::LightOccluderInstance *occluder = memnew(RasterizerCanvas::LightOccluderInstance);
@@ -1037,7 +1168,7 @@ void VisualServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occlud
PoolVector<Vector2>::Read r = p_shape.read();
for (int i = 0; i < lc; i++) {
if (i == 0)
- occluder_poly->aabb.pos = r[i];
+ occluder_poly->aabb.position = r[i];
else
occluder_poly->aabb.expand_to(r[i]);
}
diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h
index 3c2dde17d5..25d4973cb7 100644
--- a/servers/visual/visual_server_canvas.h
+++ b/servers/visual/visual_server_canvas.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -62,6 +63,14 @@ public:
}
};
+ struct ItemIndexSort {
+
+ _FORCE_INLINE_ bool operator()(const Item *p_left, const Item *p_right) const {
+
+ return p_left->index < p_right->index;
+ }
+ };
+
struct ItemPtrSort {
_FORCE_INLINE_ bool operator()(const Item *p_left, const Item *p_right) const {
@@ -162,16 +171,18 @@ public:
void canvas_item_set_draw_behind_parent(RID p_item, bool p_enable);
void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false);
+ void canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false);
void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color);
void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color);
- void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false);
- void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false);
- void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, VS::NinePatchAxisMode p_x_axis_mode = VS::NINE_PATCH_STRETCH, VS::NinePatchAxisMode p_y_axis_mode = VS::NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1));
- void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0);
- void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID());
- void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1);
+ void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID());
+ void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), bool p_clip_uv = true);
+ void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, VS::NinePatchAxisMode p_x_axis_mode = VS::NINE_PATCH_STRETCH, VS::NinePatchAxisMode p_y_axis_mode = VS::NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID());
+ void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID());
+ void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID());
+ void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID());
void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_skeleton = RID());
void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_skeleton = RID());
+ void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal, int p_h_frames, int p_v_frames);
void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform);
void canvas_item_add_clip_ignore(RID p_item, bool p_ignore);
void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable);
@@ -208,6 +219,7 @@ public:
void canvas_light_set_shadow_gradient_length(RID p_light, float p_length);
void canvas_light_set_shadow_filter(RID p_light, VS::CanvasLightShadowFilter p_filter);
void canvas_light_set_shadow_color(RID p_light, const Color &p_color);
+ void canvas_light_set_shadow_smooth(RID p_light, float p_smooth);
RID canvas_light_occluder_create();
void canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas);
diff --git a/servers/visual/visual_server_global.cpp b/servers/visual/visual_server_global.cpp
index 75506f7add..a0f118dd67 100644
--- a/servers/visual/visual_server_global.cpp
+++ b/servers/visual/visual_server_global.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/visual/visual_server_global.h b/servers/visual/visual_server_global.h
index d55059cd55..079f03f1b1 100644
--- a/servers/visual/visual_server_global.h
+++ b/servers/visual/visual_server_global.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/visual/visual_server_light_baker.cpp b/servers/visual/visual_server_light_baker.cpp
index 493eeb49ca..67048eb54e 100644
--- a/servers/visual/visual_server_light_baker.cpp
+++ b/servers/visual/visual_server_light_baker.cpp
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/visual/visual_server_light_baker.h b/servers/visual/visual_server_light_baker.h
index 82909bb082..218c42bb1b 100644
--- a/servers/visual/visual_server_light_baker.h
+++ b/servers/visual/visual_server_light_baker.h
@@ -6,6 +6,7 @@
/* 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 */
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 2666a95595..4f16ae4125 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -28,9 +29,9 @@
/*************************************************************************/
#include "visual_server_raster.h"
#include "default_mouse_cursor.xpm"
-#include "global_config.h"
#include "io/marshalls.h"
#include "os/os.h"
+#include "project_settings.h"
#include "sort.h"
#include "visual_server_canvas.h"
#include "visual_server_global.h"
@@ -38,23 +39,31 @@
// careful, these may run in different threads than the visual server
-/* CURSOR */
-void VisualServerRaster::cursor_set_rotation(float p_rotation, int p_cursor) {
-}
-void VisualServerRaster::cursor_set_texture(RID p_texture, const Point2 &p_center_offset, int p_cursor, const Rect2 &p_region) {
-}
-void VisualServerRaster::cursor_set_visible(bool p_visible, int p_cursor) {
-}
-void VisualServerRaster::cursor_set_pos(const Point2 &p_pos, int p_cursor) {
-}
+int VisualServerRaster::changes = 0;
/* BLACK BARS */
void VisualServerRaster::black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) {
+
+ black_margin[MARGIN_LEFT] = p_left;
+ black_margin[MARGIN_TOP] = p_top;
+ black_margin[MARGIN_RIGHT] = p_right;
+ black_margin[MARGIN_BOTTOM] = p_bottom;
}
+
void VisualServerRaster::black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom) {
+
+ black_image[MARGIN_LEFT] = p_left;
+ black_image[MARGIN_TOP] = p_top;
+ black_image[MARGIN_RIGHT] = p_right;
+ black_image[MARGIN_BOTTOM] = p_bottom;
}
+void VisualServerRaster::_draw_margins() {
+
+ VSG::canvas_render->draw_window_margins(black_margin, black_image);
+};
+
/* FREE */
void VisualServerRaster::free(RID p_rid) {
@@ -71,6 +80,19 @@ void VisualServerRaster::free(RID p_rid) {
/* EVENT QUEUING */
+void VisualServerRaster::request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) {
+
+ ERR_FAIL_NULL(p_where);
+ FrameDrawnCallbacks fdc;
+ fdc.object = p_where->get_instance_id();
+ fdc.method = p_method;
+ fdc.param = p_userdata;
+
+ frame_drawn_callbacks.push_back(fdc);
+
+ print_line("added callback to draw");
+}
+
void VisualServerRaster::draw() {
/*
@@ -89,6 +111,24 @@ void VisualServerRaster::draw() {
//_draw_cursors_and_margins();
VSG::rasterizer->end_frame();
//draw_extra_frame=VS:rasterizer->needs_to_draw_next_frame();
+
+ while (frame_drawn_callbacks.front()) {
+
+ Object *obj = ObjectDB::get_instance(frame_drawn_callbacks.front()->get().object);
+ if (obj) {
+ Variant::CallError ce;
+ const Variant *v = &frame_drawn_callbacks.front()->get().param;
+ obj->call(frame_drawn_callbacks.front()->get().method, &v, 1, ce);
+ if (ce.error != Variant::CallError::CALL_OK) {
+ String err = Variant::get_call_error_text(obj, frame_drawn_callbacks.front()->get().method, &v, 1, ce);
+ ERR_PRINTS("Error calling frame drawn function: " + err);
+ }
+ }
+
+ frame_drawn_callbacks.pop_front();
+ }
+
+ _draw_margins();
}
void VisualServerRaster::sync() {
}
@@ -113,12 +153,15 @@ void VisualServerRaster::finish() {
int VisualServerRaster::get_render_info(RenderInfo p_info) {
- return 0;
+ return VSG::storage->get_render_info(p_info);
}
/* TESTING */
-void VisualServerRaster::set_boot_image(const Image &p_image, const Color &p_color, bool p_scale) {
+void VisualServerRaster::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale) {
+
+ redraw_request();
+ VSG::rasterizer->set_boot_image(p_image, p_color, p_scale);
}
void VisualServerRaster::set_default_clear_color(const Color &p_color) {
}
@@ -140,6 +183,11 @@ bool VisualServerRaster::has_os_feature(const String &p_feature) const {
return VSG::storage->has_os_feature(p_feature);
}
+void VisualServerRaster::set_debug_generate_wireframes(bool p_generate) {
+
+ VSG::storage->set_debug_generate_wireframes(p_generate);
+}
+
VisualServerRaster::VisualServerRaster() {
VSG::canvas = memnew(VisualServerCanvas);
@@ -149,6 +197,9 @@ VisualServerRaster::VisualServerRaster() {
VSG::storage = VSG::rasterizer->get_storage();
VSG::canvas_render = VSG::rasterizer->get_canvas();
VSG::scene_render = VSG::rasterizer->get_scene();
+
+ for (int i = 0; i < 4; i++)
+ black_margin[i] = 0;
}
VisualServerRaster::~VisualServerRaster() {
@@ -391,33 +442,33 @@ RID VisualServerRaster::fixed_material_create() {
return rasterizer->fixed_material_create();
}
-void VisualServerRaster::fixed_material_set_flag(RID p_material, FixedSpatialMaterialFlags p_flag, bool p_enabled) {
+void VisualServerRaster::fixed_material_set_flag(RID p_material, SpatialMaterialFlags p_flag, bool p_enabled) {
rasterizer->fixed_material_set_flag(p_material,p_flag,p_enabled);
}
-bool VisualServerRaster::fixed_material_get_flag(RID p_material, FixedSpatialMaterialFlags p_flag) const {
+bool VisualServerRaster::fixed_material_get_flag(RID p_material, SpatialMaterialFlags p_flag) const {
return rasterizer->fixed_material_get_flag(p_material,p_flag);
}
-void VisualServerRaster::fixed_material_set_param(RID p_material, FixedSpatialMaterialParam p_parameter, const Variant& p_value) {
+void VisualServerRaster::fixed_material_set_param(RID p_material, SpatialMaterialParam p_parameter, const Variant& p_value) {
VS_CHANGED;
rasterizer->fixed_material_set_parameter(p_material,p_parameter,p_value);
}
-Variant VisualServerRaster::fixed_material_get_param(RID p_material,FixedSpatialMaterialParam p_parameter) const {
+Variant VisualServerRaster::fixed_material_get_param(RID p_material,SpatialMaterialParam p_parameter) const {
return rasterizer->fixed_material_get_parameter(p_material,p_parameter);
}
-void VisualServerRaster::fixed_material_set_texture(RID p_material,FixedSpatialMaterialParam p_parameter, RID p_texture) {
+void VisualServerRaster::fixed_material_set_texture(RID p_material,SpatialMaterialParam p_parameter, RID p_texture) {
VS_CHANGED;
rasterizer->fixed_material_set_texture(p_material,p_parameter,p_texture);
}
-RID VisualServerRaster::fixed_material_get_texture(RID p_material,FixedSpatialMaterialParam p_parameter) const {
+RID VisualServerRaster::fixed_material_get_texture(RID p_material,SpatialMaterialParam p_parameter) const {
return rasterizer->fixed_material_get_texture(p_material,p_parameter);
}
@@ -425,12 +476,12 @@ RID VisualServerRaster::fixed_material_get_texture(RID p_material,FixedSpatialMa
-void VisualServerRaster::fixed_material_set_texcoord_mode(RID p_material,FixedSpatialMaterialParam p_parameter, FixedSpatialMaterialTexCoordMode p_mode) {
+void VisualServerRaster::fixed_material_set_texcoord_mode(RID p_material,SpatialMaterialParam p_parameter, SpatialMaterialTexCoordMode p_mode) {
VS_CHANGED;
rasterizer->fixed_material_set_texcoord_mode(p_material,p_parameter,p_mode);
}
-VS::FixedSpatialMaterialTexCoordMode VisualServerRaster::fixed_material_get_texcoord_mode(RID p_material,FixedSpatialMaterialParam p_parameter) const {
+VS::SpatialMaterialTexCoordMode VisualServerRaster::fixed_material_get_texcoord_mode(RID p_material,SpatialMaterialParam p_parameter) const {
return rasterizer->fixed_material_get_texcoord_mode(p_material,p_parameter);
}
@@ -457,14 +508,14 @@ Transform VisualServerRaster::fixed_material_get_uv_transform(RID p_material) co
return rasterizer->fixed_material_get_uv_transform(p_material);
}
-void VisualServerRaster::fixed_material_set_light_shader(RID p_material,FixedSpatialMaterialLightShader p_shader) {
+void VisualServerRaster::fixed_material_set_light_shader(RID p_material,SpatialMaterialLightShader p_shader) {
VS_CHANGED;
rasterizer->fixed_material_set_light_shader(p_material,p_shader);
}
-VisualServerRaster::FixedSpatialMaterialLightShader VisualServerRaster::fixed_material_get_light_shader(RID p_material) const{
+VisualServerRaster::SpatialMaterialLightShader VisualServerRaster::fixed_material_get_light_shader(RID p_material) const{
return rasterizer->fixed_material_get_light_shader(p_material);
}
@@ -2586,14 +2637,14 @@ AABB VisualServerRaster::instance_get_base_aabb(RID p_instance) const {
}
-void VisualServerRaster::instance_attach_object_instance_ID(RID p_instance,uint32_t p_ID) {
+void VisualServerRaster::instance_attach_object_instance_id(RID p_instance,uint32_t p_ID) {
VS_CHANGED;
Instance *instance = instance_owner.get( p_instance );
ERR_FAIL_COND( !instance );
instance->object_ID=p_ID;
}
-uint32_t VisualServerRaster::instance_get_object_instance_ID(RID p_instance) const {
+uint32_t VisualServerRaster::instance_get_object_instance_id(RID p_instance) const {
Instance *instance = instance_owner.get( p_instance );
ERR_FAIL_COND_V( !instance, 0 );
@@ -2851,7 +2902,7 @@ Vector<RID> VisualServerRaster::instances_cull_aabb(const AABB& p_aabb, RID p_sc
int culled=0;
Instance *cull[1024];
- culled=scenario->octree.cull_AABB(p_aabb,cull,1024);
+ culled=scenario->octree.cull_aabb(p_aabb,cull,1024);
for (int i=0;i<culled;i++) {
@@ -4521,7 +4572,7 @@ void VisualServerRaster::canvas_occluder_polygon_set_cull_mode(RID p_occluder_po
RID VisualServerRaster::canvas_item_material_create() {
- Rasterizer::CanvasItemMaterial *material = memnew( Rasterizer::CanvasItemMaterial );
+ Rasterizer::ShaderMaterial *material = memnew( Rasterizer::ShaderMaterial );
return canvas_item_material_owner.make_rid(material);
}
@@ -4529,7 +4580,7 @@ RID VisualServerRaster::canvas_item_material_create() {
void VisualServerRaster::canvas_item_material_set_shader(RID p_material, RID p_shader){
VS_CHANGED;
- Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material );
+ Rasterizer::ShaderMaterial *material = canvas_item_material_owner.get( p_material );
ERR_FAIL_COND(!material);
material->shader=p_shader;
@@ -4537,7 +4588,7 @@ void VisualServerRaster::canvas_item_material_set_shader(RID p_material, RID p_s
void VisualServerRaster::canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value){
VS_CHANGED;
- Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material );
+ Rasterizer::ShaderMaterial *material = canvas_item_material_owner.get( p_material );
ERR_FAIL_COND(!material);
if (p_value.get_type()==Variant::NIL)
material->shader_param.erase(p_param);
@@ -4547,7 +4598,7 @@ void VisualServerRaster::canvas_item_material_set_shader_param(RID p_material, c
}
Variant VisualServerRaster::canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const{
- Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material );
+ Rasterizer::ShaderMaterial *material = canvas_item_material_owner.get( p_material );
ERR_FAIL_COND_V(!material,Variant());
if (!material->shader_param.has(p_param)) {
ERR_FAIL_COND_V(!material->shader.is_valid(),Variant());
@@ -4560,7 +4611,7 @@ Variant VisualServerRaster::canvas_item_material_get_shader_param(RID p_material
void VisualServerRaster::canvas_item_material_set_shading_mode(RID p_material, CanvasItemShadingMode p_mode) {
VS_CHANGED;
- Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material );
+ Rasterizer::ShaderMaterial *material = canvas_item_material_owner.get( p_material );
ERR_FAIL_COND(!material);
material->shading_mode=p_mode;
@@ -4869,7 +4920,7 @@ void VisualServerRaster::free( RID p_rid ) {
} else if (canvas_item_material_owner.owns(p_rid)) {
- Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get(p_rid);
+ Rasterizer::ShaderMaterial *material = canvas_item_material_owner.get(p_rid);
ERR_FAIL_COND(!material);
for(Set<Rasterizer::CanvasItem*>::Element *E=material->owners.front();E;E=E->next()) {
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 58e07057f2..596dd5c10e 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -56,10 +57,22 @@ class VisualServerRaster : public VisualServer {
};
- int changes;
+ static int changes;
bool draw_extra_frame;
RID test_cube;
+ int black_margin[4];
+ RID black_image[4];
+
+ struct FrameDrawnCallbacks {
+
+ ObjectID object;
+ StringName method;
+ Variant param;
+ };
+
+ List<FrameDrawnCallbacks> frame_drawn_callbacks;
+
#if 0
struct Room {
@@ -376,7 +389,7 @@ class VisualServerRaster : public VisualServer {
- mutable RID_Owner<Rasterizer::CanvasItemMaterial> canvas_item_material_owner;
+ mutable RID_Owner<Rasterizer::ShaderMaterial> canvas_item_material_owner;
@@ -574,7 +587,11 @@ class VisualServerRaster : public VisualServer {
#endif
+ void _draw_margins();
+
public:
+ _FORCE_INLINE_ static void redraw_request() { changes++; }
+
#define DISPLAY_CHANGED changes++;
#define BIND0R(m_r, m_name) \
@@ -583,6 +600,8 @@ public:
m_r m_name(m_type1 arg1) { return BINDBASE->m_name(arg1); }
#define BIND1RC(m_r, m_name, m_type1) \
m_r m_name(m_type1 arg1) const { return BINDBASE->m_name(arg1); }
+#define BIND2R(m_r, m_name, m_type1, m_type2) \
+ m_r m_name(m_type1 arg1, m_type2 arg2) { return BINDBASE->m_name(arg1, arg2); }
#define BIND2RC(m_r, m_name, m_type1, m_type2) \
m_r m_name(m_type1 arg1, m_type2 arg2) const { return BINDBASE->m_name(arg1, arg2); }
#define BIND3RC(m_r, m_name, m_type1, m_type2, m_type3) \
@@ -612,6 +631,8 @@ public:
void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); }
#define BIND10(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10) \
void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); }
+#define BIND11(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11) \
+ void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); }
//from now on, calls forwarded to this singleton
#define BINDBASE VSG::storage
@@ -620,18 +641,19 @@ public:
BIND0R(RID, texture_create)
BIND5(texture_allocate, RID, int, int, Image::Format, uint32_t)
- BIND3(texture_set_data, RID, const Image &, CubeMapSide)
- BIND2RC(Image, texture_get_data, RID, CubeMapSide)
+ BIND3(texture_set_data, RID, const Ref<Image> &, CubeMapSide)
+ BIND2RC(Ref<Image>, texture_get_data, RID, CubeMapSide)
BIND2(texture_set_flags, RID, uint32_t)
BIND1RC(uint32_t, texture_get_flags, RID)
BIND1RC(Image::Format, texture_get_format, RID)
+ BIND1RC(uint32_t, texture_get_texid, RID)
BIND1RC(uint32_t, texture_get_width, RID)
BIND1RC(uint32_t, texture_get_height, RID)
BIND3(texture_set_size_override, RID, int, int)
- BIND2RC(RID, texture_create_radiance_cubemap, RID, int)
BIND3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *)
BIND3(texture_set_detect_srgb_callback, RID, TextureDetectCallback, void *)
+ BIND3(texture_set_detect_normal_callback, RID, TextureDetectCallback, void *)
BIND2(texture_set_path, RID, const String &)
BIND1RC(String, texture_get_path, RID)
@@ -640,17 +662,14 @@ public:
BIND1(textures_keep_original, bool)
- /* SKYBOX API */
+ /* SKY API */
- BIND0R(RID, skybox_create)
- BIND3(skybox_set_texture, RID, RID, int)
+ BIND0R(RID, sky_create)
+ BIND3(sky_set_texture, RID, RID, int)
/* SHADER API */
- BIND1R(RID, shader_create, ShaderMode)
-
- BIND2(shader_set_mode, RID, ShaderMode)
- BIND1RC(ShaderMode, shader_get_mode, RID)
+ BIND0R(RID, shader_create)
BIND2(shader_set_code, RID, const String &)
BIND1RC(String, shader_get_code, RID)
@@ -671,6 +690,7 @@ public:
BIND2RC(Variant, material_get_param, RID, const StringName &)
BIND2(material_set_line_width, RID, float)
+ BIND2(material_set_next_pass, RID, RID)
/* MESH API */
@@ -829,6 +849,9 @@ public:
BIND2(gi_probe_set_bias, RID, float)
BIND1RC(float, gi_probe_get_bias, RID)
+ BIND2(gi_probe_set_normal_bias, RID, float)
+ BIND1RC(float, gi_probe_get_normal_bias, RID)
+
BIND2(gi_probe_set_propagation, RID, float)
BIND1RC(float, gi_probe_get_propagation, RID)
@@ -848,26 +871,25 @@ public:
BIND2(particles_set_emitting, RID, bool)
BIND2(particles_set_amount, RID, int)
BIND2(particles_set_lifetime, RID, float)
+ BIND2(particles_set_one_shot, RID, bool)
BIND2(particles_set_pre_process_time, RID, float)
BIND2(particles_set_explosiveness_ratio, RID, float)
BIND2(particles_set_randomness_ratio, RID, float)
BIND2(particles_set_custom_aabb, RID, const Rect3 &)
- BIND2(particles_set_gravity, RID, const Vector3 &)
+ BIND2(particles_set_speed_scale, RID, float)
BIND2(particles_set_use_local_coordinates, RID, bool)
BIND2(particles_set_process_material, RID, RID)
-
- BIND2(particles_set_emission_shape, RID, VS::ParticlesEmissionShape)
- BIND2(particles_set_emission_sphere_radius, RID, float)
- BIND2(particles_set_emission_box_extents, RID, const Vector3 &)
- BIND2(particles_set_emission_points, RID, const PoolVector<Vector3> &)
+ BIND2(particles_set_fixed_fps, RID, int)
+ BIND2(particles_set_fractional_delta, RID, bool)
+ BIND1(particles_restart, RID)
BIND2(particles_set_draw_order, RID, VS::ParticlesDrawOrder)
BIND2(particles_set_draw_passes, RID, int)
- BIND3(particles_set_draw_pass_material, RID, int, RID)
BIND3(particles_set_draw_pass_mesh, RID, int, RID)
- BIND1R(Rect3, particles_get_current_aabb, RID);
+ BIND1R(Rect3, particles_get_current_aabb, RID)
+ BIND2(particles_set_emission_transform, RID, const Transform &)
#undef BINDBASE
//from now on, calls forwarded to this singleton
@@ -891,6 +913,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)
@@ -925,6 +948,10 @@ public:
BIND3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
BIND2(viewport_set_msaa, RID, ViewportMSAA)
BIND2(viewport_set_hdr, RID, bool)
+ BIND2(viewport_set_usage, RID, ViewportUsage)
+
+ BIND2R(int, viewport_get_render_info, RID, ViewportRenderInfo)
+ BIND2(viewport_set_debug_draw, RID, ViewportDebugDraw)
/* ENVIRONMENT API */
@@ -935,24 +962,27 @@ public:
BIND0R(RID, environment_create)
BIND2(environment_set_background, RID, EnvironmentBG)
- BIND2(environment_set_skybox, RID, RID)
- BIND2(environment_set_skybox_scale, RID, float)
+ BIND2(environment_set_sky, RID, RID)
+ BIND2(environment_set_sky_scale, RID, float)
BIND2(environment_set_bg_color, RID, const Color &)
BIND2(environment_set_bg_energy, RID, float)
BIND2(environment_set_canvas_max_layer, RID, int)
BIND4(environment_set_ambient_light, RID, const Color &, float, float)
- BIND8(environment_set_ssr, RID, bool, int, float, float, float, bool, bool)
+ BIND7(environment_set_ssr, RID, bool, int, float, float, float, bool)
BIND10(environment_set_ssao, RID, bool, float, float, float, float, float, float, const Color &, bool)
BIND6(environment_set_dof_blur_near, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
BIND6(environment_set_dof_blur_far, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
BIND10(environment_set_glow, RID, bool, int, float, float, float, EnvironmentGlowBlendMode, float, float, bool)
- BIND5(environment_set_fog, RID, bool, float, float, RID)
BIND9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float)
BIND6(environment_set_adjustment, RID, bool, float, float, float, RID)
+ BIND5(environment_set_fog, RID, bool, const Color &, const Color &, float)
+ BIND6(environment_set_fog_depth, RID, bool, float, float, bool, float)
+ BIND5(environment_set_fog_height, RID, bool, float, float, float)
+
/* SCENARIO API */
#undef BINDBASE
@@ -973,7 +1003,7 @@ public:
BIND2(instance_set_scenario, RID, RID) // from can be mesh, light, poly, area and portal so far.
BIND2(instance_set_layer_mask, RID, uint32_t)
BIND2(instance_set_transform, RID, const Transform &)
- BIND2(instance_attach_object_instance_ID, RID, ObjectID)
+ BIND2(instance_attach_object_instance_id, RID, ObjectID)
BIND3(instance_set_blend_shape_weight, RID, int, float)
BIND3(instance_set_surface_material, RID, int, RID)
BIND2(instance_set_visible, RID, bool)
@@ -1022,16 +1052,18 @@ public:
BIND2(canvas_item_set_draw_behind_parent, RID, bool)
BIND6(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float, bool)
+ BIND5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool)
BIND3(canvas_item_add_rect, RID, const Rect2 &, const Color &)
BIND4(canvas_item_add_circle, RID, const Point2 &, float, const Color &)
- BIND6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool)
- BIND6(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool)
- BIND10(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &)
- BIND6(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float)
- BIND5(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID)
- BIND7(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, int)
+ BIND7(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool, RID)
+ BIND8(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, RID, bool)
+ BIND11(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &, RID)
+ BIND7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID)
+ BIND6(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID)
+ BIND8(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, int, RID)
BIND3(canvas_item_add_mesh, RID, const RID &, RID)
BIND3(canvas_item_add_multimesh, RID, RID, RID)
+ BIND6(canvas_item_add_particles, RID, RID, RID, RID, int, int)
BIND2(canvas_item_add_set_transform, RID, const Transform2D &)
BIND2(canvas_item_add_clip_ignore, RID, bool)
BIND2(canvas_item_set_sort_children_by_y, RID, bool)
@@ -1068,6 +1100,7 @@ public:
BIND2(canvas_light_set_shadow_gradient_length, RID, float)
BIND2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter)
BIND2(canvas_light_set_shadow_color, RID, const Color &)
+ BIND2(canvas_light_set_shadow_smooth, RID, float)
BIND0R(RID, canvas_light_occluder_create)
BIND2(canvas_light_occluder_attach_to_canvas, RID, RID)
@@ -1082,12 +1115,6 @@ public:
BIND2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode)
- /* CURSOR */
- virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0); // radians
- virtual void cursor_set_texture(RID p_texture, const Point2 &p_center_offset = Point2(0, 0), int p_cursor = 0, const Rect2 &p_region = Rect2());
- virtual void cursor_set_visible(bool p_visible, int p_cursor = 0);
- virtual void cursor_set_pos(const Point2 &p_pos, int p_cursor = 0);
-
/* BLACK BARS */
virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom);
@@ -1099,6 +1126,8 @@ public:
/* EVENT QUEUING */
+ virtual void request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata);
+
virtual void draw();
virtual void sync();
virtual bool has_changed() const;
@@ -1113,12 +1142,13 @@ public:
/* TESTING */
- virtual void set_boot_image(const Image &p_image, const Color &p_color, bool p_scale);
+ virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale);
virtual void set_default_clear_color(const Color &p_color);
virtual bool has_feature(Features p_feature) const;
virtual bool has_os_feature(const String &p_feature) const;
+ virtual void set_debug_generate_wireframes(bool p_generate);
VisualServerRaster();
~VisualServerRaster();
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 9b77ca9e1c..5faf0e67ca 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -29,6 +30,7 @@
#include "visual_server_scene.h"
#include "os/os.h"
#include "visual_server_global.h"
+#include "visual_server_raster.h"
/* CAMERA API */
RID VisualServerScene::camera_create() {
@@ -609,7 +611,8 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) {
} break;
case VS::INSTANCE_MESH:
case VS::INSTANCE_MULTIMESH:
- case VS::INSTANCE_IMMEDIATE: {
+ case VS::INSTANCE_IMMEDIATE:
+ case VS::INSTANCE_PARTICLES: {
InstanceGeometryData *geom = memnew(InstanceGeometryData);
instance->base_data = geom;
@@ -794,7 +797,7 @@ void VisualServerScene::instance_set_transform(RID p_instance, const Transform &
instance->transform = p_transform;
_instance_queue_update(instance, true);
}
-void VisualServerScene::instance_attach_object_instance_ID(RID p_instance, ObjectID p_ID) {
+void VisualServerScene::instance_attach_object_instance_id(RID p_instance, ObjectID p_ID) {
Instance *instance = instance_owner.get(p_instance);
ERR_FAIL_COND(!instance);
@@ -877,13 +880,13 @@ void VisualServerScene::instance_attach_skeleton(RID p_instance, RID p_skeleton)
return;
if (instance->skeleton.is_valid()) {
- VSG::storage->instance_remove_skeleton(p_skeleton, instance);
+ VSG::storage->instance_remove_skeleton(instance->skeleton, instance);
}
instance->skeleton = p_skeleton;
if (instance->skeleton.is_valid()) {
- VSG::storage->instance_add_skeleton(p_skeleton, instance);
+ VSG::storage->instance_add_skeleton(instance->skeleton, instance);
}
_instance_queue_update(instance, true);
@@ -907,7 +910,7 @@ Vector<ObjectID> VisualServerScene::instances_cull_aabb(const Rect3 &p_aabb, RID
int culled = 0;
Instance *cull[1024];
- culled = scenario->octree.cull_AABB(p_aabb, cull, 1024);
+ culled = scenario->octree.cull_aabb(p_aabb, cull, 1024);
for (int i = 0; i < culled; i++) {
@@ -975,16 +978,6 @@ void VisualServerScene::instance_geometry_set_flag(RID p_instance, VS::InstanceF
switch (p_flags) {
- case VS::INSTANCE_FLAG_BILLBOARD: {
-
- instance->billboard = p_enabled;
-
- } break;
- case VS::INSTANCE_FLAG_BILLBOARD_FIX_Y: {
-
- instance->billboard_y = p_enabled;
-
- } break;
case VS::INSTANCE_FLAG_CAST_SHADOW: {
if (p_enabled == true) {
instance->cast_shadows = VS::SHADOW_CASTING_SETTING_ON;
@@ -995,14 +988,14 @@ void VisualServerScene::instance_geometry_set_flag(RID p_instance, VS::InstanceF
instance->base_material_changed(); // to actually compute if shadows are visible or not
} break;
- case VS::INSTANCE_FLAG_DEPH_SCALE: {
+ case VS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS: {
- instance->depth_scale = p_enabled;
+ instance->visible_in_all_rooms = p_enabled;
} break;
- case VS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS: {
+ case VS::INSTANCE_FLAG_USE_BAKED_LIGHT: {
- instance->visible_in_all_rooms = p_enabled;
+ instance->baked_light = p_enabled;
} break;
}
@@ -1050,6 +1043,11 @@ void VisualServerScene::_update_instance(Instance *p_instance) {
reflection_probe->reflection_dirty = true;
}
+ if (p_instance->base_type == VS::INSTANCE_PARTICLES) {
+
+ VSG::storage->particles_set_emission_transform(p_instance->base, p_instance->transform);
+ }
+
if (p_instance->aabb.has_no_surface())
return;
@@ -1235,6 +1233,11 @@ void VisualServerScene::_update_instance_aabb(Instance *p_instance) {
new_aabb = VSG::storage->immediate_get_aabb(p_instance->base);
} break;
+ case VisualServer::INSTANCE_PARTICLES: {
+
+ new_aabb = VSG::storage->particles_get_aabb(p_instance->base);
+
+ } break;
#if 0
case VisualServer::INSTANCE_PARTICLES: {
@@ -1349,6 +1352,8 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
bool overlap = VSG::storage->light_directional_get_blend_splits(p_instance->base);
+ float first_radius = 0.0;
+
for (int i = 0; i < splits; i++) {
// setup a camera matrix for that range!
@@ -1375,9 +1380,11 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
// obtain the light frustm ranges (given endpoints)
- Vector3 x_vec = p_instance->transform.basis.get_axis(Vector3::AXIS_X).normalized();
- Vector3 y_vec = p_instance->transform.basis.get_axis(Vector3::AXIS_Y).normalized();
- Vector3 z_vec = p_instance->transform.basis.get_axis(Vector3::AXIS_Z).normalized();
+ Transform transform = p_instance->transform.orthonormalized(); //discard scale and stabilize light
+
+ Vector3 x_vec = transform.basis.get_axis(Vector3::AXIS_X).normalized();
+ Vector3 y_vec = transform.basis.get_axis(Vector3::AXIS_Y).normalized();
+ Vector3 z_vec = transform.basis.get_axis(Vector3::AXIS_Z).normalized();
//z_vec points agsint the camera, like in default opengl
float x_min, x_max;
@@ -1388,7 +1395,10 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
float y_min_cam, y_max_cam;
float z_min_cam, z_max_cam;
+ float bias_scale = 1.0;
+
//used for culling
+
for (int j = 0; j < 8; j++) {
float d_x = x_vec.dot(endpoints[j]);
@@ -1437,6 +1447,12 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
radius *= texture_size / (texture_size - 2.0); //add a texel by each side, so stepified texture will always fit
+ if (i == 0) {
+ first_radius = radius;
+ } else {
+ bias_scale = radius / first_radius;
+ }
+
x_max_cam = x_vec.dot(center) + radius;
x_min_cam = x_vec.dot(center) - radius;
y_max_cam = y_vec.dot(center) + radius;
@@ -1471,6 +1487,8 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
// a pre pass will need to be needed to determine the actual z-near to be used
+ Plane near_plane(p_instance->transform.origin, -p_instance->transform.basis.get_axis(2));
+
for (int j = 0; j < cull_count; j++) {
float min, max;
@@ -1483,6 +1501,8 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
}
instance->transformed_aabb.project_range_in_plane(Plane(z_vec, 0), min, max);
+ instance->depth = near_plane.distance_to(instance->transform.origin);
+ instance->depth_layer = 0;
if (max > z_max)
z_max = max;
}
@@ -1495,10 +1515,10 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
ortho_camera.set_orthogonal(-half_x, half_x, -half_y, half_y, 0, (z_max - z_min_cam));
Transform ortho_transform;
- ortho_transform.basis = p_instance->transform.basis;
+ ortho_transform.basis = transform.basis;
ortho_transform.origin = x_vec * (x_min_cam + half_x) + y_vec * (y_min_cam + half_y) + z_vec * z_max;
- VSG::scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, 0, distances[i + 1], i);
+ VSG::scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, 0, distances[i + 1], i, bias_scale);
}
VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
@@ -1528,6 +1548,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
planes[4] = p_instance->transform.xform(Plane(Vector3(0, -1, z).normalized(), radius));
int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
+ Plane near_plane(p_instance->transform.origin, p_instance->transform.basis.get_axis(2) * z);
for (int j = 0; j < cull_count; j++) {
@@ -1536,6 +1557,9 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
cull_count--;
SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
j--;
+ } else {
+ instance->depth = near_plane.distance_to(instance->transform.origin);
+ instance->depth_layer = 0;
}
}
@@ -1576,6 +1600,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
+ Plane near_plane(xform.origin, -xform.basis.get_axis(2));
for (int j = 0; j < cull_count; j++) {
Instance *instance = instance_shadow_cull_result[j];
@@ -1583,6 +1608,9 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
cull_count--;
SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
j--;
+ } else {
+ instance->depth = near_plane.distance_to(instance->transform.origin);
+ instance->depth_layer = 0;
}
}
@@ -1608,6 +1636,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
Vector<Plane> planes = cm.get_projection_planes(p_instance->transform);
int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
+ Plane near_plane(p_instance->transform.origin, -p_instance->transform.basis.get_axis(2));
for (int j = 0; j < cull_count; j++) {
Instance *instance = instance_shadow_cull_result[j];
@@ -1615,6 +1644,9 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
cull_count--;
SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
j--;
+ } else {
+ instance->depth = near_plane.distance_to(instance->transform.origin);
+ instance->depth_layer = 0;
}
}
@@ -1626,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);
@@ -1665,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);
@@ -1822,7 +1874,7 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
if (reflection_probe->reflection_dirty || VSG::scene_render->reflection_probe_instance_needs_redraw(reflection_probe->instance)) {
if (!reflection_probe->update_list.in_list()) {
reflection_probe->render_step = 0;
- reflection_probe_render_list.add(&reflection_probe->update_list);
+ reflection_probe_render_list.add_last(&reflection_probe->update_list);
}
reflection_probe->reflection_dirty = false;
@@ -1914,6 +1966,13 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(ins->base_data);
+ if (ins->base_type == VS::INSTANCE_PARTICLES) {
+ //particles visible? process them
+ VSG::storage->particles_request_process(ins->base);
+ //particles visible? request redraw
+ VisualServerRaster::redraw_request();
+ }
+
if (geom->lighting_dirty) {
int l = 0;
//only called when lights AABB enter/exit this geometry
@@ -2144,6 +2203,18 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
VSG::scene_render->render_scene(p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, environment, p_shadow_atlas, scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass);
}
+void VisualServerScene::render_empty_scene(RID p_scenario, RID p_shadow_atlas) {
+
+ Scenario *scenario = scenario_owner.getornull(p_scenario);
+
+ RID environment;
+ if (scenario->environment.is_valid())
+ environment = scenario->environment;
+ else
+ environment = scenario->fallback_environment;
+ VSG::scene_render->render_scene(Transform(), CameraMatrix(), true, NULL, 0, NULL, 0, NULL, 0, environment, p_shadow_atlas, scenario->reflection_atlas, RID(), 0);
+}
+
bool VisualServerScene::_render_reflection_probe_step(Instance *p_instance, int p_step) {
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data);
@@ -2574,11 +2645,11 @@ static float _get_normal_advance(const Vector3 &p_normal) {
return 1.0 / normal.dot(unorm);
}
-void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header, const GIProbeDataCell *cells, InstanceGIProbeData::LocalData *local_data, const uint32_t *leaves, int leaf_count, const InstanceGIProbeData::LightCache &light_cache, int sign) {
+void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header, const GIProbeDataCell *cells, InstanceGIProbeData::LocalData *local_data, const uint32_t *leaves, int p_leaf_count, const InstanceGIProbeData::LightCache &light_cache, int p_sign) {
- int light_r = int(light_cache.color.r * light_cache.energy * 1024.0) * sign;
- int light_g = int(light_cache.color.g * light_cache.energy * 1024.0) * sign;
- int light_b = int(light_cache.color.b * light_cache.energy * 1024.0) * sign;
+ int light_r = int(light_cache.color.r * light_cache.energy * 1024.0) * p_sign;
+ int light_g = int(light_cache.color.g * light_cache.energy * 1024.0) * p_sign;
+ int light_b = int(light_cache.color.b * light_cache.energy * 1024.0) * p_sign;
float limits[3] = { float(header->width), float(header->height), float(header->depth) };
Plane clip[3];
@@ -2614,7 +2685,7 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header, co
uint64_t us = OS::get_singleton()->get_ticks_usec();
- for (int i = 0; i < leaf_count; i++) {
+ for (int i = 0; i < p_leaf_count; i++) {
uint32_t idx = leaves[i];
@@ -2665,8 +2736,8 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header, co
success_count++;
}
}
- print_line("BAKE TIME: " + rtos((OS::get_singleton()->get_ticks_usec() - us) / 1000000.0));
- print_line("valid cells: " + itos(success_count));
+ //print_line("BAKE TIME: " + rtos((OS::get_singleton()->get_ticks_usec() - us) / 1000000.0));
+ //print_line("valid cells: " + itos(success_count));
} break;
case VS::LIGHT_OMNI:
@@ -2679,7 +2750,7 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header, co
float local_radius = light_cache.radius * light_cache.transform.basis.get_axis(2).length();
- for (int i = 0; i < leaf_count; i++) {
+ for (int i = 0; i < p_leaf_count; i++) {
uint32_t idx = leaves[i];
@@ -2771,7 +2842,7 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header, co
light->energy[2] += int32_t(light_b * att * ((cell->albedo) & 0xFF) / 255.0);
}
}
- print_line("BAKE TIME: " + rtos((OS::get_singleton()->get_ticks_usec() - us) / 1000000.0));
+ //print_line("BAKE TIME: " + rtos((OS::get_singleton()->get_ticks_usec() - us) / 1000000.0));
} break;
}
@@ -2870,7 +2941,7 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
if (stage >= probe_data->dynamic.mipmaps_3d.size())
continue; //no mipmap for this one
- print_line("generating mipmap stage: " + itos(stage));
+ //print_line("generating mipmap stage: " + itos(stage));
int level_cell_count = probe_data->dynamic.level_cell_lists[i].size();
const uint32_t *level_cells = probe_data->dynamic.level_cell_lists[i].ptr();
@@ -3305,6 +3376,38 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
} else {
can_cast_shadows = false;
}
+ } else if (p_instance->base_type == VS::INSTANCE_PARTICLES) {
+
+ bool cast_shadows = false;
+
+ int dp = VSG::storage->particles_get_draw_passes(p_instance->base);
+
+ for (int i = 0; i < dp; i++) {
+
+ RID mesh = VSG::storage->particles_get_draw_pass_mesh(p_instance->base, i);
+ if (!mesh.is_valid())
+ continue;
+
+ int sc = VSG::storage->mesh_get_surface_count(mesh);
+ for (int j = 0; j < sc; j++) {
+
+ RID mat = VSG::storage->mesh_surface_get_material(mesh, j);
+
+ if (!mat.is_valid()) {
+ cast_shadows = true;
+ break;
+ }
+
+ if (VSG::storage->material_casts_shadows(mat)) {
+ cast_shadows = true;
+ break;
+ }
+ }
+ }
+
+ if (!cast_shadows) {
+ can_cast_shadows = false;
+ }
}
}
diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h
index b02e6c820b..910e75c3e3 100644
--- a/servers/visual/visual_server_scene.h
+++ b/servers/visual/visual_server_scene.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -35,9 +36,9 @@
#include "geometry.h"
#include "octree.h"
#include "os/semaphore.h"
-#include "os/semaphore.h"
#include "os/thread.h"
#include "self_list.h"
+#include "servers/arvr/arvr_interface.h"
class VisualServerScene {
public:
@@ -117,7 +118,7 @@ public:
Camera() {
visible_layers = 0xFFFFFFFF;
- fov = 60;
+ fov = 65;
type = PERSPECTIVE;
znear = 0.1;
zfar = 100;
@@ -488,7 +489,7 @@ public:
virtual void instance_set_scenario(RID p_instance, RID p_scenario); // from can be mesh, light, poly, area and portal so far.
virtual void instance_set_layer_mask(RID p_instance, uint32_t p_mask);
virtual void instance_set_transform(RID p_instance, const Transform &p_transform);
- virtual void instance_attach_object_instance_ID(RID p_instance, ObjectID p_ID);
+ virtual void instance_attach_object_instance_id(RID p_instance, ObjectID p_ID);
virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight);
virtual void instance_set_surface_material(RID p_instance, int p_surface, RID p_material);
virtual void instance_set_visible(RID p_instance, bool p_visible);
@@ -518,8 +519,10 @@ public:
_FORCE_INLINE_ void _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario);
void _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);
+ 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
@@ -564,7 +567,7 @@ public:
_FORCE_INLINE_ uint32_t _gi_bake_find_cell(const GIProbeDataCell *cells, int x, int y, int z, int p_cell_subdiv);
void _bake_gi_downscale_light(int p_idx, int p_level, const GIProbeDataCell *p_cells, const GIProbeDataHeader *p_header, InstanceGIProbeData::LocalData *p_local_data, float p_propagate);
void _bake_gi_probe_light(const GIProbeDataHeader *header, const GIProbeDataCell *cells, InstanceGIProbeData::LocalData *local_data, const uint32_t *leaves, int p_leaf_count, const InstanceGIProbeData::LightCache &light_cache, int p_sign);
- void _bake_gi_probe(Instance *p_probe);
+ void _bake_gi_probe(Instance *p_gi_probe);
bool _check_gi_probe(Instance *p_gi_probe);
void _setup_gi_probe(Instance *p_instance);
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index 7b8a725c5a..ad9dec090a 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -27,30 +28,31 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "visual_server_viewport.h"
-#include "global_config.h"
+#include "project_settings.h"
#include "visual_server_canvas.h"
#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 */
-#if 0
- bool scenario_draw_canvas_bg=false;
- int scenario_canvas_max_layer=0;
+ /* Camera should always be BEFORE any other 3D */
- if (!p_viewport->hide_canvas && !p_viewport->disable_environment && scenario_owner.owns(p_viewport->scenario)) {
+ bool scenario_draw_canvas_bg = false; //draw canvas, or some layer of it, as BG for 3D instead of in front
+ int scenario_canvas_max_layer = 0;
- Scenario *scenario=scenario_owner.get(p_viewport->scenario);
- if (scenario->environment.is_valid()) {
- if (rasterizer->is_environment(scenario->environment)) {
- scenario_draw_canvas_bg=rasterizer->environment_get_background(scenario->environment)==VS::ENV_BG_CANVAS;
- scenario_canvas_max_layer=rasterizer->environment_get_background_param(scenario->environment,VS::ENV_BG_PARAM_CANVAS_MAX_LAYER);
- }
+ if (!p_viewport->hide_canvas && !p_viewport->disable_environment && VSG::scene->scenario_owner.owns(p_viewport->scenario)) {
+
+ VisualServerScene::Scenario *scenario = VSG::scene->scenario_owner.get(p_viewport->scenario);
+ if (VSG::scene_render->is_environment(scenario->environment)) {
+ scenario_draw_canvas_bg = VSG::scene_render->environment_get_background(scenario->environment) == VS::ENV_BG_CANVAS;
+
+ scenario_canvas_max_layer = VSG::scene_render->environment_get_canvas_max_layer(scenario->environment);
}
}
- bool can_draw_3d=!p_viewport->hide_scenario && camera_owner.owns(p_viewport->camera) && scenario_owner.owns(p_viewport->scenario);
+ bool can_draw_3d = !p_viewport->disable_3d && !p_viewport->disable_3d_by_usage && VSG::scene->camera_owner.owns(p_viewport->camera);
+#if 0
+
if (scenario_draw_canvas_bg) {
@@ -87,9 +89,14 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
}
}
- if (!p_viewport->disable_3d && p_viewport->camera.is_valid()) {
+ 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) {
@@ -132,7 +139,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
cl->texture_cache = NULL;
Transform2D scale;
scale.scale(cl->rect_cache.size);
- scale.elements[2] = cl->rect_cache.pos;
+ scale.elements[2] = cl->rect_cache.position;
cl->light_shader_xform = (cl->xform_cache * scale).affine_inverse();
cl->light_shader_pos = cl->xform_cache[2];
if (cl->shadow_buffer.is_valid()) {
@@ -198,14 +205,15 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
VSG::rasterizer->restore_render_target();
-#if 0
- if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer>scenario_canvas_max_layer) {
-
- _draw_viewport_camera(p_viewport,!can_draw_3d);
- scenario_draw_canvas_bg=false;
+ if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer > scenario_canvas_max_layer) {
+ if (can_draw_3d) {
+ VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ } else {
+ VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
+ }
+ scenario_draw_canvas_bg = false;
}
-#endif
for (Map<Viewport::CanvasKey, Viewport::CanvasData *>::Element *E = canvas_map.front(); E; E = E->next()) {
@@ -228,34 +236,48 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
VSG::canvas->render_canvas(canvas, xform, canvas_lights, lights_with_mask, clip_rect);
i++;
-#if 0
- if (scenario_draw_canvas_bg && E->key().layer>=scenario_canvas_max_layer) {
- _draw_viewport_camera(p_viewport,!can_draw_3d);
- scenario_draw_canvas_bg=false;
+
+ if (scenario_draw_canvas_bg && E->key().layer >= scenario_canvas_max_layer) {
+
+ if (can_draw_3d) {
+ VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ } else {
+ VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
+ }
+
+ scenario_draw_canvas_bg = false;
}
-#endif
}
-#if 0
+
if (scenario_draw_canvas_bg) {
- _draw_viewport_camera(p_viewport,!can_draw_3d);
- scenario_draw_canvas_bg=false;
+
+ if (can_draw_3d) {
+ VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
+ } else {
+ VSG::scene->render_empty_scene(p_viewport->scenario, p_viewport->shadow_atlas);
+ }
+
+ scenario_draw_canvas_bg = false;
}
-#endif
//VSG::canvas_render->canvas_debug_viewport_shadows(lights_with_shadow);
}
}
void VisualServerViewport::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();
+ }
- //sort viewports
-
- //draw viewports
-
- clear_color = GLOBAL_GET("rendering/viewport/default_clear_color");
+ 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];
@@ -265,23 +287,61 @@ void VisualServerViewport::draw_viewports() {
ERR_CONTINUE(!vp->render_target.is_valid());
- bool visible = vp->viewport_to_screen_rect != Rect2() || vp->update_mode == VS::VIEWPORT_UPDATE_ALWAYS || vp->update_mode == VS::VIEWPORT_UPDATE_ONCE;
+ bool visible = vp->viewport_to_screen_rect != Rect2() || vp->update_mode == VS::VIEWPORT_UPDATE_ALWAYS || vp->update_mode == VS::VIEWPORT_UPDATE_ONCE || (vp->update_mode == VS::VIEWPORT_UPDATE_WHEN_VISIBLE && VSG::storage->render_target_was_used(vp->render_target));
+ visible = visible && vp->size.x > 0 && vp->size.y > 0;
if (!visible)
continue;
- VSG::rasterizer->set_current_render_target(vp->render_target);
- _draw_viewport(vp);
+ VSG::storage->render_target_clear_used(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);
+
+ // 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);
+
+ // 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);
- 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) {
vp->update_mode = VS::VIEWPORT_UPDATE_DISABLED;
}
+ VSG::scene_render->set_debug_draw_mode(VS::VIEWPORT_DEBUG_DRAW_DISABLED);
}
}
@@ -300,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);
@@ -408,7 +475,8 @@ void VisualServerViewport::viewport_set_disable_3d(RID p_viewport, bool p_disabl
ERR_FAIL_COND(!viewport);
viewport->disable_3d = p_disable;
- VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, p_disable);
+ //VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, p_disable);
+ //this should be just for disabling rendering of 3D, to actually disable it, set usage
}
void VisualServerViewport::viewport_attach_camera(RID p_viewport, RID p_camera) {
@@ -517,6 +585,63 @@ void VisualServerViewport::viewport_set_hdr(RID p_viewport, bool p_enabled) {
VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_HDR, p_enabled);
}
+void VisualServerViewport::viewport_set_usage(RID p_viewport, VS::ViewportUsage p_usage) {
+
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ switch (p_usage) {
+ case VS::VIEWPORT_USAGE_2D: {
+
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, true);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, true);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, false);
+
+ viewport->disable_3d_by_usage = true;
+ } break;
+ case VS::VIEWPORT_USAGE_2D_NO_SAMPLING: {
+
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, true);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, true);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, true);
+ viewport->disable_3d_by_usage = true;
+ } break;
+ case VS::VIEWPORT_USAGE_3D: {
+
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, false);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, false);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, false);
+ viewport->disable_3d_by_usage = false;
+ } break;
+ case VS::VIEWPORT_USAGE_3D_NO_EFFECTS: {
+
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, false);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, true);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, false);
+ viewport->disable_3d_by_usage = false;
+ } break;
+ }
+}
+
+int VisualServerViewport::viewport_get_render_info(RID p_viewport, VS::ViewportRenderInfo p_info) {
+
+ ERR_FAIL_INDEX_V(p_info, VS::VIEWPORT_RENDER_INFO_MAX, -1);
+
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ if (!viewport)
+ return 0; //there should be a lock here..
+
+ return viewport->render_info[p_info];
+}
+
+void VisualServerViewport::viewport_set_debug_draw(RID p_viewport, VS::ViewportDebugDraw p_draw) {
+
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->debug_draw = p_draw;
+}
+
bool VisualServerViewport::free(RID p_rid) {
if (viewport_owner.owns(p_rid)) {
diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h
index 53ad6bde2b..93227d1c31 100644
--- a/servers/visual/visual_server_viewport.h
+++ b/servers/visual/visual_server_viewport.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -31,6 +32,7 @@
#include "rasterizer.h"
#include "self_list.h"
+#include "servers/arvr/arvr_interface.h"
#include "servers/visual_server.h"
class VisualServerViewport {
@@ -43,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;
@@ -58,13 +62,15 @@ public:
bool hide_canvas;
bool disable_environment;
bool disable_3d;
+ bool disable_3d_by_usage;
RID shadow_atlas;
int shadow_atlas_size;
- VS::ViewportClearMode clear_mode;
+ int render_info[VS::VIEWPORT_RENDER_INFO_MAX];
+ VS::ViewportDebugDraw debug_draw;
- bool rendered_in_prev_frame;
+ VS::ViewportClearMode clear_mode;
struct CanvasKey {
@@ -95,11 +101,16 @@ public:
Viewport() {
update_mode = VS::VIEWPORT_UPDATE_WHEN_VISIBLE;
clear_mode = VS::VIEWPORT_CLEAR_ALWAYS;
- rendered_in_prev_frame = false;
disable_environment = false;
viewport_to_screen = 0;
shadow_atlas_size = 0;
disable_3d = false;
+ disable_3d_by_usage = false;
+ debug_draw = VS::VIEWPORT_DEBUG_DRAW_DISABLED;
+ for (int i = 0; i < VS::VIEWPORT_RENDER_INFO_MAX; i++) {
+ render_info[i] = 0;
+ }
+ use_arvr = false;
}
};
@@ -124,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);
@@ -163,6 +176,10 @@ public:
void viewport_set_msaa(RID p_viewport, VS::ViewportMSAA p_msaa);
void viewport_set_hdr(RID p_viewport, bool p_enabled);
+ void viewport_set_usage(RID p_viewport, VS::ViewportUsage p_usage);
+
+ virtual int viewport_get_render_info(RID p_viewport, VS::ViewportRenderInfo p_info);
+ virtual void viewport_set_debug_draw(RID p_viewport, VS::ViewportDebugDraw p_draw);
void draw_viewports();
diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp
new file mode 100644
index 0000000000..827f47a16e
--- /dev/null
+++ b/servers/visual/visual_server_wrap_mt.cpp
@@ -0,0 +1,193 @@
+/*************************************************************************/
+/* visual_server_wrap_mt.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#include "visual_server_wrap_mt.h"
+#include "os/os.h"
+#include "project_settings.h"
+
+void VisualServerWrapMT::thread_exit() {
+
+ exit = true;
+}
+
+void VisualServerWrapMT::thread_draw() {
+
+ draw_mutex->lock();
+
+ draw_pending--;
+ bool draw = (draw_pending == 0); // only draw when no more flushes are pending
+
+ draw_mutex->unlock();
+
+ if (draw) {
+
+ visual_server->draw();
+ }
+}
+
+void VisualServerWrapMT::thread_flush() {
+
+ draw_mutex->lock();
+
+ draw_pending--;
+
+ draw_mutex->unlock();
+}
+
+void VisualServerWrapMT::_thread_callback(void *_instance) {
+
+ VisualServerWrapMT *vsmt = reinterpret_cast<VisualServerWrapMT *>(_instance);
+
+ vsmt->thread_loop();
+}
+
+void VisualServerWrapMT::thread_loop() {
+
+ server_thread = Thread::get_caller_id();
+
+ OS::get_singleton()->make_rendering_thread();
+
+ visual_server->init();
+
+ exit = false;
+ draw_thread_up = true;
+ while (!exit) {
+ // flush commands one by one, until exit is requested
+ command_queue.wait_and_flush_one();
+ }
+
+ command_queue.flush_all(); // flush all
+
+ visual_server->finish();
+}
+
+/* EVENT QUEUING */
+
+void VisualServerWrapMT::sync() {
+
+ if (create_thread) {
+
+ /* TODO: sync with the thread */
+
+ /*
+ ERR_FAIL_COND(!draw_mutex);
+ draw_mutex->lock();
+ draw_pending++; //cambiar por un saferefcount
+ draw_mutex->unlock();
+ */
+ //command_queue.push( this, &VisualServerWrapMT::thread_flush);
+ } else {
+
+ command_queue.flush_all(); //flush all pending from other threads
+ }
+}
+
+void VisualServerWrapMT::draw() {
+
+ if (create_thread) {
+
+ /* TODO: Make it draw
+ ERR_FAIL_COND(!draw_mutex);
+ draw_mutex->lock();
+ draw_pending++; //cambiar por un saferefcount
+ draw_mutex->unlock();
+
+ command_queue.push( this, &VisualServerWrapMT::thread_draw);
+ */
+ } else {
+
+ visual_server->draw();
+ }
+}
+
+void VisualServerWrapMT::init() {
+
+ if (create_thread) {
+
+ draw_mutex = Mutex::create();
+ print_line("CREATING RENDER THREAD");
+ OS::get_singleton()->release_rendering_thread();
+ if (create_thread) {
+ thread = Thread::create(_thread_callback, this);
+ print_line("STARTING RENDER THREAD");
+ }
+ while (!draw_thread_up) {
+ OS::get_singleton()->delay_usec(1000);
+ }
+ print_line("DONE RENDER THREAD");
+ } else {
+
+ visual_server->init();
+ }
+}
+
+void VisualServerWrapMT::finish() {
+
+ if (thread) {
+
+ command_queue.push(this, &VisualServerWrapMT::thread_exit);
+ Thread::wait_to_finish(thread);
+ memdelete(thread);
+
+ texture_free_cached_ids();
+ //mesh_free_cached_ids();
+
+ thread = NULL;
+ } else {
+ visual_server->finish();
+ }
+
+ if (draw_mutex)
+ memdelete(draw_mutex);
+}
+
+VisualServerWrapMT::VisualServerWrapMT(VisualServer *p_contained, bool p_create_thread)
+ : command_queue(p_create_thread) {
+
+ visual_server = p_contained;
+ create_thread = p_create_thread;
+ thread = NULL;
+ draw_mutex = NULL;
+ draw_pending = 0;
+ draw_thread_up = false;
+ alloc_mutex = Mutex::create();
+ pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
+
+ if (!p_create_thread) {
+ server_thread = Thread::get_caller_id();
+ } else {
+ server_thread = 0;
+ }
+}
+
+VisualServerWrapMT::~VisualServerWrapMT() {
+
+ memdelete(visual_server);
+ memdelete(alloc_mutex);
+ //finish();
+}
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
new file mode 100644
index 0000000000..20223f9651
--- /dev/null
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -0,0 +1,590 @@
+/*************************************************************************/
+/* visual_server_wrap_mt.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifndef VISUAL_SERVER_WRAP_MT_H
+#define VISUAL_SERVER_WRAP_MT_H
+
+#include "command_queue_mt.h"
+#include "os/thread.h"
+#include "servers/visual_server.h"
+
+/**
+ @author Juan Linietsky <reduzio@gmail.com>
+*/
+class VisualServerWrapMT : public VisualServer {
+
+ // the real visual server
+ mutable VisualServer *visual_server;
+
+ mutable CommandQueueMT command_queue;
+
+ static void _thread_callback(void *_instance);
+ void thread_loop();
+
+ Thread::ID server_thread;
+ volatile bool exit;
+ Thread *thread;
+ volatile bool draw_thread_up;
+ bool create_thread;
+
+ Mutex *draw_mutex;
+ int draw_pending;
+ void thread_draw();
+ void thread_flush();
+
+ void thread_exit();
+
+ Mutex *alloc_mutex;
+
+ int pool_max_size;
+
+//#define DEBUG_SYNC
+
+#ifdef DEBUG_SYNC
+#define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__));
+#else
+#define SYNC_DEBUG
+#endif
+
+public:
+#define ServerName VisualServer
+#define ServerNameWrapMT VisualServerWrapMT
+#define server_name visual_server
+#include "servers/server_wrap_mt_common.h"
+
+ /* EVENT QUEUING */
+ FUNCRID(texture)
+ FUNC5(texture_allocate, RID, int, int, Image::Format, uint32_t)
+ FUNC3(texture_set_data, RID, const Ref<Image> &, CubeMapSide)
+ FUNC2RC(Ref<Image>, texture_get_data, RID, CubeMapSide)
+ FUNC2(texture_set_flags, RID, uint32_t)
+ FUNC1RC(uint32_t, texture_get_flags, RID)
+ FUNC1RC(Image::Format, texture_get_format, RID)
+ FUNC1RC(uint32_t, texture_get_texid, RID)
+ FUNC1RC(uint32_t, texture_get_width, RID)
+ FUNC1RC(uint32_t, texture_get_height, RID)
+ FUNC3(texture_set_size_override, RID, int, int)
+
+ FUNC3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *)
+ FUNC3(texture_set_detect_srgb_callback, RID, TextureDetectCallback, void *)
+ FUNC3(texture_set_detect_normal_callback, RID, TextureDetectCallback, void *)
+
+ FUNC2(texture_set_path, RID, const String &)
+ FUNC1RC(String, texture_get_path, RID)
+ FUNC1(texture_set_shrink_all_x2_on_set_data, bool)
+ FUNC1(texture_debug_usage, List<TextureInfo> *)
+
+ FUNC1(textures_keep_original, bool)
+
+ /* SKY API */
+
+ FUNC0R(RID, sky_create)
+ FUNC3(sky_set_texture, RID, RID, int)
+
+ /* SHADER API */
+
+ FUNC0R(RID, shader_create)
+
+ FUNC2(shader_set_code, RID, const String &)
+ FUNC1RC(String, shader_get_code, RID)
+
+ FUNC2SC(shader_get_param_list, RID, List<PropertyInfo> *)
+
+ FUNC3(shader_set_default_texture_param, RID, const StringName &, RID)
+ FUNC2RC(RID, shader_get_default_texture_param, RID, const StringName &)
+
+ /* COMMON MATERIAL API */
+
+ FUNC0R(RID, material_create)
+
+ FUNC2(material_set_shader, RID, RID)
+ FUNC1RC(RID, material_get_shader, RID)
+
+ FUNC3(material_set_param, RID, const StringName &, const Variant &)
+ FUNC2RC(Variant, material_get_param, RID, const StringName &)
+
+ FUNC2(material_set_line_width, RID, float)
+ FUNC2(material_set_next_pass, RID, RID)
+
+ /* MESH API */
+
+ FUNC0R(RID, mesh_create)
+
+ FUNC10(mesh_add_surface, RID, uint32_t, PrimitiveType, const PoolVector<uint8_t> &, int, const PoolVector<uint8_t> &, int, const Rect3 &, const Vector<PoolVector<uint8_t> > &, const Vector<Rect3> &)
+
+ FUNC2(mesh_set_blend_shape_count, RID, int)
+ FUNC1RC(int, mesh_get_blend_shape_count, RID)
+
+ FUNC2(mesh_set_blend_shape_mode, RID, BlendShapeMode)
+ FUNC1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID)
+
+ FUNC3(mesh_surface_set_material, RID, int, RID)
+ FUNC2RC(RID, mesh_surface_get_material, RID, int)
+
+ FUNC2RC(int, mesh_surface_get_array_len, RID, int)
+ FUNC2RC(int, mesh_surface_get_array_index_len, RID, int)
+
+ FUNC2RC(PoolVector<uint8_t>, mesh_surface_get_array, RID, int)
+ FUNC2RC(PoolVector<uint8_t>, mesh_surface_get_index_array, RID, int)
+
+ FUNC2RC(uint32_t, mesh_surface_get_format, RID, int)
+ FUNC2RC(PrimitiveType, mesh_surface_get_primitive_type, RID, int)
+
+ FUNC2RC(Rect3, mesh_surface_get_aabb, RID, int)
+ FUNC2RC(Vector<PoolVector<uint8_t> >, mesh_surface_get_blend_shapes, RID, int)
+ FUNC2RC(Vector<Rect3>, mesh_surface_get_skeleton_aabb, RID, int)
+
+ FUNC2(mesh_remove_surface, RID, int)
+ FUNC1RC(int, mesh_get_surface_count, RID)
+
+ FUNC2(mesh_set_custom_aabb, RID, const Rect3 &)
+ FUNC1RC(Rect3, mesh_get_custom_aabb, RID)
+
+ FUNC1(mesh_clear, RID)
+
+ /* MULTIMESH API */
+
+ FUNC0R(RID, multimesh_create)
+
+ FUNC4(multimesh_allocate, RID, int, MultimeshTransformFormat, MultimeshColorFormat)
+ FUNC1RC(int, multimesh_get_instance_count, RID)
+
+ FUNC2(multimesh_set_mesh, RID, RID)
+ FUNC3(multimesh_instance_set_transform, RID, int, const Transform &)
+ FUNC3(multimesh_instance_set_transform_2d, RID, int, const Transform2D &)
+ FUNC3(multimesh_instance_set_color, RID, int, const Color &)
+
+ FUNC1RC(RID, multimesh_get_mesh, RID)
+ FUNC1RC(Rect3, multimesh_get_aabb, RID)
+
+ FUNC2RC(Transform, multimesh_instance_get_transform, RID, int)
+ FUNC2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int)
+ FUNC2RC(Color, multimesh_instance_get_color, RID, int)
+
+ FUNC2(multimesh_set_visible_instances, RID, int)
+ FUNC1RC(int, multimesh_get_visible_instances, RID)
+
+ /* IMMEDIATE API */
+
+ FUNC0R(RID, immediate_create)
+ FUNC3(immediate_begin, RID, PrimitiveType, RID)
+ FUNC2(immediate_vertex, RID, const Vector3 &)
+ FUNC2(immediate_normal, RID, const Vector3 &)
+ FUNC2(immediate_tangent, RID, const Plane &)
+ FUNC2(immediate_color, RID, const Color &)
+ FUNC2(immediate_uv, RID, const Vector2 &)
+ FUNC2(immediate_uv2, RID, const Vector2 &)
+ FUNC1(immediate_end, RID)
+ FUNC1(immediate_clear, RID)
+ FUNC2(immediate_set_material, RID, RID)
+ FUNC1RC(RID, immediate_get_material, RID)
+
+ /* SKELETON API */
+
+ FUNC0R(RID, skeleton_create)
+ FUNC3(skeleton_allocate, RID, int, bool)
+ FUNC1RC(int, skeleton_get_bone_count, RID)
+ FUNC3(skeleton_bone_set_transform, RID, int, const Transform &)
+ FUNC2RC(Transform, skeleton_bone_get_transform, RID, int)
+ FUNC3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &)
+ FUNC2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int)
+
+ /* Light API */
+
+ FUNC1R(RID, light_create, LightType)
+
+ FUNC2(light_set_color, RID, const Color &)
+ FUNC3(light_set_param, RID, LightParam, float)
+ FUNC2(light_set_shadow, RID, bool)
+ FUNC2(light_set_shadow_color, RID, const Color &)
+ FUNC2(light_set_projector, RID, RID)
+ FUNC2(light_set_negative, RID, bool)
+ FUNC2(light_set_cull_mask, RID, uint32_t)
+
+ FUNC2(light_omni_set_shadow_mode, RID, LightOmniShadowMode)
+ FUNC2(light_omni_set_shadow_detail, RID, LightOmniShadowDetail)
+
+ FUNC2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode)
+ FUNC2(light_directional_set_blend_splits, RID, bool)
+
+ /* PROBE API */
+
+ FUNC0R(RID, reflection_probe_create)
+
+ FUNC2(reflection_probe_set_update_mode, RID, ReflectionProbeUpdateMode)
+ FUNC2(reflection_probe_set_intensity, RID, float)
+ FUNC2(reflection_probe_set_interior_ambient, RID, const Color &)
+ FUNC2(reflection_probe_set_interior_ambient_energy, RID, float)
+ FUNC2(reflection_probe_set_interior_ambient_probe_contribution, RID, float)
+ FUNC2(reflection_probe_set_max_distance, RID, float)
+ FUNC2(reflection_probe_set_extents, RID, const Vector3 &)
+ FUNC2(reflection_probe_set_origin_offset, RID, const Vector3 &)
+ FUNC2(reflection_probe_set_as_interior, RID, bool)
+ FUNC2(reflection_probe_set_enable_box_projection, RID, bool)
+ FUNC2(reflection_probe_set_enable_shadows, RID, bool)
+ FUNC2(reflection_probe_set_cull_mask, RID, uint32_t)
+
+ /* ROOM API */
+
+ FUNC0R(RID, room_create)
+ FUNC4(room_add_bounds, RID, const PoolVector<Vector2> &, float, const Transform &)
+ FUNC1(room_clear_bounds, RID)
+
+ /* PORTAL API */
+
+ // portals are only (x/y) points, forming a convex shape, which its clockwise
+ // order points outside. (z is 0);
+
+ FUNC0R(RID, portal_create)
+ FUNC2(portal_set_shape, RID, const Vector<Point2> &)
+ FUNC2(portal_set_enabled, RID, bool)
+ FUNC2(portal_set_disable_distance, RID, float)
+ FUNC2(portal_set_disabled_color, RID, const Color &)
+
+ /* BAKED LIGHT API */
+
+ FUNC0R(RID, gi_probe_create)
+
+ FUNC2(gi_probe_set_bounds, RID, const Rect3 &)
+ FUNC1RC(Rect3, gi_probe_get_bounds, RID)
+
+ FUNC2(gi_probe_set_cell_size, RID, float)
+ FUNC1RC(float, gi_probe_get_cell_size, RID)
+
+ FUNC2(gi_probe_set_to_cell_xform, RID, const Transform &)
+ FUNC1RC(Transform, gi_probe_get_to_cell_xform, RID)
+
+ FUNC2(gi_probe_set_dynamic_range, RID, int)
+ FUNC1RC(int, gi_probe_get_dynamic_range, RID)
+
+ FUNC2(gi_probe_set_energy, RID, float)
+ FUNC1RC(float, gi_probe_get_energy, RID)
+
+ FUNC2(gi_probe_set_bias, RID, float)
+ FUNC1RC(float, gi_probe_get_bias, RID)
+
+ FUNC2(gi_probe_set_normal_bias, RID, float)
+ FUNC1RC(float, gi_probe_get_normal_bias, RID)
+
+ FUNC2(gi_probe_set_propagation, RID, float)
+ FUNC1RC(float, gi_probe_get_propagation, RID)
+
+ FUNC2(gi_probe_set_interior, RID, bool)
+ FUNC1RC(bool, gi_probe_is_interior, RID)
+
+ FUNC2(gi_probe_set_compress, RID, bool)
+ FUNC1RC(bool, gi_probe_is_compressed, RID)
+
+ FUNC2(gi_probe_set_dynamic_data, RID, const PoolVector<int> &)
+ FUNC1RC(PoolVector<int>, gi_probe_get_dynamic_data, RID)
+
+ /* PARTICLES */
+
+ FUNC0R(RID, particles_create)
+
+ FUNC2(particles_set_emitting, RID, bool)
+ FUNC2(particles_set_amount, RID, int)
+ FUNC2(particles_set_lifetime, RID, float)
+ FUNC2(particles_set_one_shot, RID, bool)
+ FUNC2(particles_set_pre_process_time, RID, float)
+ FUNC2(particles_set_explosiveness_ratio, RID, float)
+ FUNC2(particles_set_randomness_ratio, RID, float)
+ FUNC2(particles_set_custom_aabb, RID, const Rect3 &)
+ FUNC2(particles_set_speed_scale, RID, float)
+ FUNC2(particles_set_use_local_coordinates, RID, bool)
+ FUNC2(particles_set_process_material, RID, RID)
+ FUNC2(particles_set_fixed_fps, RID, int)
+ FUNC2(particles_set_fractional_delta, RID, bool)
+ FUNC1(particles_restart, RID)
+
+ FUNC2(particles_set_draw_order, RID, VS::ParticlesDrawOrder)
+
+ FUNC2(particles_set_draw_passes, RID, int)
+ FUNC3(particles_set_draw_pass_mesh, RID, int, RID)
+ FUNC2(particles_set_emission_transform, RID, const Transform &)
+
+ FUNC1R(Rect3, particles_get_current_aabb, RID)
+
+ /* CAMERA API */
+
+ FUNC0R(RID, camera_create)
+ FUNC4(camera_set_perspective, RID, float, float, float)
+ FUNC4(camera_set_orthogonal, RID, float, float, float)
+ FUNC2(camera_set_transform, RID, const Transform &)
+ FUNC2(camera_set_cull_mask, RID, uint32_t)
+ FUNC2(camera_set_environment, RID, RID)
+ FUNC2(camera_set_use_vertical_aspect, RID, bool)
+
+ /* VIEWPORT TARGET API */
+
+ FUNC0R(RID, viewport_create)
+
+ FUNC2(viewport_set_use_arvr, RID, bool)
+
+ FUNC3(viewport_set_size, RID, int, int)
+
+ FUNC2(viewport_set_active, RID, bool)
+ FUNC2(viewport_set_parent_viewport, RID, RID)
+
+ FUNC2(viewport_set_clear_mode, RID, ViewportClearMode)
+
+ FUNC3(viewport_attach_to_screen, RID, const Rect2 &, int)
+ FUNC1(viewport_detach, RID)
+
+ FUNC2(viewport_set_update_mode, RID, ViewportUpdateMode)
+ FUNC2(viewport_set_vflip, RID, bool)
+
+ FUNC1RC(RID, viewport_get_texture, RID)
+
+ FUNC2(viewport_set_hide_scenario, RID, bool)
+ FUNC2(viewport_set_hide_canvas, RID, bool)
+ FUNC2(viewport_set_disable_environment, RID, bool)
+ FUNC2(viewport_set_disable_3d, RID, bool)
+
+ FUNC2(viewport_attach_camera, RID, RID)
+ FUNC2(viewport_set_scenario, RID, RID)
+ FUNC2(viewport_attach_canvas, RID, RID)
+
+ FUNC2(viewport_remove_canvas, RID, RID)
+ FUNC3(viewport_set_canvas_transform, RID, RID, const Transform2D &)
+ FUNC2(viewport_set_transparent_background, RID, bool)
+
+ FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &)
+ FUNC3(viewport_set_canvas_layer, RID, RID, int)
+ FUNC2(viewport_set_shadow_atlas_size, RID, int)
+ FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
+ FUNC2(viewport_set_msaa, RID, ViewportMSAA)
+ FUNC2(viewport_set_hdr, RID, bool)
+ FUNC2(viewport_set_usage, RID, ViewportUsage)
+
+ //this passes directly to avoid stalling, but it's pretty dangerous, so dont call after freeing a viewport
+ virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) {
+ return visual_server->viewport_get_render_info(p_viewport, p_info);
+ }
+
+ FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw)
+
+ /* ENVIRONMENT API */
+
+ FUNC0R(RID, environment_create)
+
+ FUNC2(environment_set_background, RID, EnvironmentBG)
+ FUNC2(environment_set_sky, RID, RID)
+ FUNC2(environment_set_sky_scale, RID, float)
+ FUNC2(environment_set_bg_color, RID, const Color &)
+ FUNC2(environment_set_bg_energy, RID, float)
+ FUNC2(environment_set_canvas_max_layer, RID, int)
+ FUNC4(environment_set_ambient_light, RID, const Color &, float, float)
+ FUNC7(environment_set_ssr, RID, bool, int, float, float, float, bool)
+ FUNC10(environment_set_ssao, RID, bool, float, float, float, float, float, float, const Color &, bool)
+
+ FUNC6(environment_set_dof_blur_near, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
+ FUNC6(environment_set_dof_blur_far, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
+ FUNC10(environment_set_glow, RID, bool, int, float, float, float, EnvironmentGlowBlendMode, float, float, bool)
+
+ FUNC9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float)
+
+ FUNC6(environment_set_adjustment, RID, bool, float, float, float, RID)
+
+ FUNC5(environment_set_fog, RID, bool, const Color &, const Color &, float)
+ FUNC6(environment_set_fog_depth, RID, bool, float, float, bool, float)
+ FUNC5(environment_set_fog_height, RID, bool, float, float, float)
+
+ FUNC0R(RID, scenario_create)
+
+ FUNC2(scenario_set_debug, RID, ScenarioDebugMode)
+ FUNC2(scenario_set_environment, RID, RID)
+ FUNC3(scenario_set_reflection_atlas_size, RID, int, int)
+ FUNC2(scenario_set_fallback_environment, RID, RID)
+
+ /* INSTANCING API */
+ // from can be mesh, light, area and portal so far.
+ FUNC0R(RID, instance_create)
+
+ FUNC2(instance_set_base, RID, RID) // from can be mesh, light, poly, area and portal so far.
+ FUNC2(instance_set_scenario, RID, RID) // from can be mesh, light, poly, area and portal so far.
+ FUNC2(instance_set_layer_mask, RID, uint32_t)
+ FUNC2(instance_set_transform, RID, const Transform &)
+ FUNC2(instance_attach_object_instance_id, RID, ObjectID)
+ FUNC3(instance_set_blend_shape_weight, RID, int, float)
+ FUNC3(instance_set_surface_material, RID, int, RID)
+ FUNC2(instance_set_visible, RID, bool)
+
+ FUNC2(instance_attach_skeleton, RID, RID)
+ FUNC2(instance_set_exterior, RID, bool)
+ FUNC2(instance_set_room, RID, RID)
+
+ FUNC2(instance_set_extra_visibility_margin, RID, real_t)
+
+ // don't use these in a game!
+ FUNC2RC(Vector<ObjectID>, instances_cull_aabb, const Rect3 &, RID)
+ FUNC3RC(Vector<ObjectID>, instances_cull_ray, const Vector3 &, const Vector3 &, RID)
+ FUNC2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID)
+
+ FUNC3(instance_geometry_set_flag, RID, InstanceFlags, bool)
+ FUNC2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting)
+ FUNC2(instance_geometry_set_material_override, RID, RID)
+
+ FUNC5(instance_geometry_set_draw_range, RID, float, float, float, float)
+ FUNC2(instance_geometry_set_as_instance_lod, RID, RID)
+
+ /* CANVAS (2D) */
+
+ FUNC0R(RID, canvas_create)
+ FUNC3(canvas_set_item_mirroring, RID, RID, const Point2 &)
+ FUNC2(canvas_set_modulate, RID, const Color &)
+
+ FUNC0R(RID, canvas_item_create)
+ FUNC2(canvas_item_set_parent, RID, RID)
+
+ FUNC2(canvas_item_set_visible, RID, bool)
+ FUNC2(canvas_item_set_light_mask, RID, int)
+
+ FUNC2(canvas_item_set_transform, RID, const Transform2D &)
+ FUNC2(canvas_item_set_clip, RID, bool)
+ FUNC2(canvas_item_set_distance_field_mode, RID, bool)
+ FUNC3(canvas_item_set_custom_rect, RID, bool, const Rect2 &)
+ FUNC2(canvas_item_set_modulate, RID, const Color &)
+ FUNC2(canvas_item_set_self_modulate, RID, const Color &)
+
+ FUNC2(canvas_item_set_draw_behind_parent, RID, bool)
+
+ FUNC6(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float, bool)
+ FUNC5(canvas_item_add_polyline, RID, const Vector<Point2> &, const Vector<Color> &, float, bool)
+ FUNC3(canvas_item_add_rect, RID, const Rect2 &, const Color &)
+ FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &)
+ FUNC7(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool, RID)
+ FUNC8(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, RID, bool)
+ FUNC11(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &, RID)
+ FUNC7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID)
+ FUNC6(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID)
+ FUNC8(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, int, RID)
+ FUNC3(canvas_item_add_mesh, RID, const RID &, RID)
+ FUNC3(canvas_item_add_multimesh, RID, RID, RID)
+ FUNC6(canvas_item_add_particles, RID, RID, RID, RID, int, int)
+ FUNC2(canvas_item_add_set_transform, RID, const Transform2D &)
+ FUNC2(canvas_item_add_clip_ignore, RID, bool)
+ FUNC2(canvas_item_set_sort_children_by_y, RID, bool)
+ FUNC2(canvas_item_set_z, RID, int)
+ FUNC2(canvas_item_set_z_as_relative_to_parent, RID, bool)
+ FUNC3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &)
+
+ FUNC1(canvas_item_clear, RID)
+ FUNC2(canvas_item_set_draw_index, RID, int)
+
+ FUNC2(canvas_item_set_material, RID, RID)
+
+ FUNC2(canvas_item_set_use_parent_material, RID, bool)
+
+ FUNC0R(RID, canvas_light_create)
+ FUNC2(canvas_light_attach_to_canvas, RID, RID)
+ FUNC2(canvas_light_set_enabled, RID, bool)
+ FUNC2(canvas_light_set_scale, RID, float)
+ FUNC2(canvas_light_set_transform, RID, const Transform2D &)
+ FUNC2(canvas_light_set_texture, RID, RID)
+ FUNC2(canvas_light_set_texture_offset, RID, const Vector2 &)
+ FUNC2(canvas_light_set_color, RID, const Color &)
+ FUNC2(canvas_light_set_height, RID, float)
+ FUNC2(canvas_light_set_energy, RID, float)
+ FUNC3(canvas_light_set_z_range, RID, int, int)
+ FUNC3(canvas_light_set_layer_range, RID, int, int)
+ FUNC2(canvas_light_set_item_cull_mask, RID, int)
+ FUNC2(canvas_light_set_item_shadow_cull_mask, RID, int)
+
+ FUNC2(canvas_light_set_mode, RID, CanvasLightMode)
+
+ FUNC2(canvas_light_set_shadow_enabled, RID, bool)
+ FUNC2(canvas_light_set_shadow_buffer_size, RID, int)
+ FUNC2(canvas_light_set_shadow_gradient_length, RID, float)
+ FUNC2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter)
+ FUNC2(canvas_light_set_shadow_color, RID, const Color &)
+ FUNC2(canvas_light_set_shadow_smooth, RID, float)
+
+ FUNC0R(RID, canvas_light_occluder_create)
+ FUNC2(canvas_light_occluder_attach_to_canvas, RID, RID)
+ FUNC2(canvas_light_occluder_set_enabled, RID, bool)
+ FUNC2(canvas_light_occluder_set_polygon, RID, RID)
+ FUNC2(canvas_light_occluder_set_transform, RID, const Transform2D &)
+ FUNC2(canvas_light_occluder_set_light_mask, RID, int)
+
+ FUNC0R(RID, canvas_occluder_polygon_create)
+ FUNC3(canvas_occluder_polygon_set_shape, RID, const PoolVector<Vector2> &, bool)
+ FUNC2(canvas_occluder_polygon_set_shape_as_lines, RID, const PoolVector<Vector2> &)
+
+ FUNC2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode)
+
+ /* BLACK BARS */
+
+ FUNC4(black_bars_set_margins, int, int, int, int)
+ FUNC4(black_bars_set_images, RID, RID, RID, RID)
+
+ /* FREE */
+
+ FUNC1(free, RID)
+
+ /* EVENT QUEUING */
+
+ FUNC3(request_frame_drawn_callback, Object *, const StringName &, const Variant &)
+
+ virtual void init();
+ virtual void finish();
+ virtual void draw();
+ virtual void sync();
+ FUNC0RC(bool, has_changed)
+
+ /* RENDER INFO */
+
+ //this passes directly to avoid stalling
+ virtual int get_render_info(RenderInfo p_info) {
+ return visual_server->get_render_info(p_info);
+ }
+
+ FUNC3(set_boot_image, const Ref<Image> &, const Color &, bool)
+ FUNC1(set_default_clear_color, const Color &)
+
+ FUNC0R(RID, get_test_cube)
+
+ FUNC1(set_debug_generate_wireframes, bool)
+
+ virtual bool has_feature(Features p_feature) const { return visual_server->has_feature(p_feature); }
+ virtual bool has_os_feature(const String &p_feature) const { return visual_server->has_os_feature(p_feature); }
+
+ VisualServerWrapMT(VisualServer *p_contained, bool p_create_thread);
+ ~VisualServerWrapMT();
+
+#undef ServerName
+#undef ServerNameWrapMT
+#undef server_name
+};
+
+#ifdef DEBUG_SYNC
+#undef DEBUG_SYNC
+#endif
+#undef SYNC_DEBUG
+
+#endif
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index a28c409b97..65dd4d7661 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -6,6 +6,7 @@
/* 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 */
@@ -27,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "visual_server.h"
-#include "global_config.h"
-#include "method_bind_ext.inc"
+#include "method_bind_ext.gen.inc"
+#include "project_settings.h"
VisualServer *VisualServer::singleton = NULL;
VisualServer *(*VisualServer::create_func)() = NULL;
@@ -67,10 +68,11 @@ VisualServer *VisualServer::create() {
return NULL;
}
-RID VisualServer::texture_create_from_image(const Image &p_image, uint32_t p_flags) {
+RID VisualServer::texture_create_from_image(const Ref<Image> &p_image, uint32_t p_flags) {
+ ERR_FAIL_COND_V(!p_image.is_valid(), RID());
RID texture = texture_create();
- texture_allocate(texture, p_image.get_width(), p_image.get_height(), p_image.get_format(), p_flags); //if it has mipmaps, use, else generate
+ texture_allocate(texture, p_image->get_width(), p_image->get_height(), p_image->get_format(), p_flags); //if it has mipmaps, use, else generate
ERR_FAIL_COND_V(!texture.is_valid(), texture);
texture_set_data(texture, p_image);
@@ -119,12 +121,12 @@ RID VisualServer::get_test_texture() {
}
}
- Image data(TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, false, Image::FORMAT_RGB8, test_data);
+ Ref<Image> data = memnew(Image(TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, false, Image::FORMAT_RGB8, test_data));
test_texture = texture_create_from_image(data);
return test_texture;
-};
+}
void VisualServer::_free_internal_rids() {
@@ -134,11 +136,6 @@ void VisualServer::_free_internal_rids() {
free(white_texture);
if (test_material.is_valid())
free(test_material);
-
- for (int i = 0; i < 16; i++) {
- if (material_2d[i].is_valid())
- free(material_2d[i]);
- }
}
RID VisualServer::_make_test_cube() {
@@ -282,35 +279,6 @@ RID VisualServer::make_sphere_mesh(int p_lats, int p_lons, float p_radius) {
return mesh;
}
-RID VisualServer::material_2d_get(bool p_shaded, bool p_transparent, bool p_cut_alpha, bool p_opaque_prepass) {
-
- int version = 0;
- if (p_shaded)
- version = 1;
- if (p_transparent)
- version |= 2;
- if (p_cut_alpha)
- version |= 4;
- if (p_opaque_prepass)
- version |= 8;
- if (material_2d[version].is_valid())
- return material_2d[version];
-
- //not valid, make
-
- /* material_2d[version]=fixed_material_create();
- fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_USE_ALPHA,p_transparent);
- fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true);
- fixed_material_set_flag(material_2d[version],FIXED_MATERIAL_FLAG_DISCARD_ALPHA,p_cut_alpha);
- material_set_flag(material_2d[version],MATERIAL_FLAG_UNSHADED,!p_shaded);
- material_set_flag(material_2d[version],MATERIAL_FLAG_DOUBLE_SIDED,true);
- material_set_depth_draw_mode(material_2d[version],p_opaque_prepass?MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA:MATERIAL_DEPTH_DRAW_OPAQUE_ONLY);
- fixed_material_set_texture(material_2d[version],FIXED_MATERIAL_PARAM_DIFFUSE,get_white_texture());
- //material cut alpha?*/
-
- return material_2d[version];
-}
-
RID VisualServer::get_white_texture() {
if (white_texture.is_valid())
@@ -323,7 +291,7 @@ RID VisualServer::get_white_texture() {
for (int i = 0; i < 16 * 3; i++)
w[i] = 255;
}
- Image white(4, 4, 0, Image::FORMAT_RGB8, wt);
+ Ref<Image> white = memnew(Image(4, 4, 0, Image::FORMAT_RGB8, wt));
white_texture = texture_create();
texture_allocate(white_texture, 4, 4, Image::FORMAT_RGB8);
texture_set_data(white_texture, white);
@@ -336,8 +304,6 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_
PoolVector<uint8_t>::Write iw;
if (r_index_array.size()) {
- print_line("elements: " + itos(r_index_array.size()));
-
iw = r_index_array.write();
}
@@ -397,7 +363,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_
}
}
- r_aabb = Rect3(Vector3(aabb.pos.x, aabb.pos.y, 0), Vector3(aabb.size.x, aabb.size.y, 0));
+ r_aabb = Rect3(Vector3(aabb.position.x, aabb.position.y, 0), Vector3(aabb.size.x, aabb.size.y, 0));
} else {
PoolVector<Vector3> array = p_arrays[ai];
@@ -463,7 +429,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_
for (int i = 0; i < p_vertex_array_len; i++) {
- uint8_t vector[4] = {
+ int8_t vector[4] = {
CLAMP(src[i].x * 127, -128, 127),
CLAMP(src[i].y * 127, -128, 127),
CLAMP(src[i].z * 127, -128, 127),
@@ -768,7 +734,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_
if (bptr->size.x < 0) {
//first
bptr[idx] = Rect3();
- bptr[idx].pos = v;
+ bptr[idx].position = v;
any_valid = true;
} else {
bptr[idx].expand_to(v);
@@ -1231,11 +1197,12 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
if (p_format & ARRAY_COMPRESS_NORMAL) {
PoolVector<Vector3>::Write w = arr.write();
+ const float multiplier = 1.f / 127.f;
for (int j = 0; j < p_vertex_len; j++) {
- const uint8_t *v = (const uint8_t *)&r[j * total_elem_size + offsets[i]];
- w[j] = Vector3(float(v[0] / 255.0) * 2.0 - 1.0, float(v[1] / 255.0) * 2.0 - 1.0, float(v[2] / 255.0) * 2.0 - 1.0);
+ const int8_t *v = (const int8_t *)&r[j * total_elem_size + offsets[i]];
+ w[j] = Vector3(float(v[0]) * multiplier, float(v[1]) * multiplier, float(v[2]) * multiplier);
}
} else {
PoolVector<Vector3>::Write w = arr.write();
@@ -1259,9 +1226,9 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
for (int j = 0; j < p_vertex_len; j++) {
- const uint8_t *v = (const uint8_t *)&r[j * total_elem_size + offsets[i]];
+ const int8_t *v = (const int8_t *)&r[j * total_elem_size + offsets[i]];
for (int k = 0; k < 4; k++) {
- w[j * 4 + k] = float(v[k] / 255.0) * 2.0 - 1.0;
+ w[j * 4 + k] = float(v[k] / 127.0);
}
}
} else {
@@ -1291,7 +1258,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
for (int j = 0; j < p_vertex_len; j++) {
const uint8_t *v = (const uint8_t *)&r[j * total_elem_size + offsets[i]];
- w[j] = Color(float(v[0] / 255.0) * 2.0 - 1.0, float(v[1] / 255.0) * 2.0 - 1.0, float(v[2] / 255.0) * 2.0 - 1.0, float(v[3] / 255.0) * 2.0 - 1.0);
+ w[j] = Color(float(v[0] / 255.0), float(v[1] / 255.0), float(v[2] / 255.0), float(v[3] / 255.0));
}
} else {
PoolVector<Color>::Write w = arr.write();
@@ -1472,14 +1439,14 @@ Array VisualServer::mesh_surface_get_arrays(RID p_mesh, int p_surface) const {
void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("texture_create"), &VisualServer::texture_create);
- ClassDB::bind_method(D_METHOD("texture_create_from_image"), &VisualServer::texture_create_from_image, DEFVAL(TEXTURE_FLAGS_DEFAULT));
+ ClassDB::bind_method(D_METHOD("texture_create_from_image", "image", "flags"), &VisualServer::texture_create_from_image, DEFVAL(TEXTURE_FLAGS_DEFAULT));
//ClassDB::bind_method(D_METHOD("texture_allocate"),&VisualServer::texture_allocate,DEFVAL( TEXTURE_FLAGS_DEFAULT ) );
//ClassDB::bind_method(D_METHOD("texture_set_data"),&VisualServer::texture_blit_rect,DEFVAL( CUBEMAP_LEFT ) );
//ClassDB::bind_method(D_METHOD("texture_get_rect"),&VisualServer::texture_get_rect );
- ClassDB::bind_method(D_METHOD("texture_set_flags"), &VisualServer::texture_set_flags);
- ClassDB::bind_method(D_METHOD("texture_get_flags"), &VisualServer::texture_get_flags);
- ClassDB::bind_method(D_METHOD("texture_get_width"), &VisualServer::texture_get_width);
- ClassDB::bind_method(D_METHOD("texture_get_height"), &VisualServer::texture_get_height);
+ ClassDB::bind_method(D_METHOD("texture_set_flags", "texture", "flags"), &VisualServer::texture_set_flags);
+ ClassDB::bind_method(D_METHOD("texture_get_flags", "texture"), &VisualServer::texture_get_flags);
+ ClassDB::bind_method(D_METHOD("texture_get_width", "texture"), &VisualServer::texture_get_width);
+ ClassDB::bind_method(D_METHOD("texture_get_height", "texture"), &VisualServer::texture_get_height);
ClassDB::bind_method(D_METHOD("texture_set_shrink_all_x2_on_set_data", "shrink"), &VisualServer::texture_set_shrink_all_x2_on_set_data);
}
@@ -1564,6 +1531,39 @@ VisualServer::VisualServer() {
//ERR_FAIL_COND(singleton);
singleton = this;
+ GLOBAL_DEF("rendering/vram_compression/import_s3tc", true);
+ GLOBAL_DEF("rendering/vram_compression/import_etc", false);
+ GLOBAL_DEF("rendering/vram_compression/import_etc2", true);
+ GLOBAL_DEF("rendering/vram_compression/import_pvrtc", false);
+
+ GLOBAL_DEF("rendering/quality/directional_shadow/size", 4096);
+ GLOBAL_DEF("rendering/quality/directional_shadow/size.mobile", 2048);
+ GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096);
+ GLOBAL_DEF("rendering/quality/shadow_atlas/size.mobile", 2048);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384"));
+ GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_0_subdiv", 1);
+ GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_1_subdiv", 2);
+ GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_2_subdiv", 3);
+ GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_3_subdiv", 4);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+
+ GLOBAL_DEF("rendering/quality/shadows/filter_mode", 1);
+ GLOBAL_DEF("rendering/quality/shadows/filter_mode.mobile", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadows/filter_mode", PropertyInfo(Variant::INT, "rendering/quality/shadows/filter_mode", PROPERTY_HINT_ENUM, "Disabled,PCF5,PCF13"));
+
+ GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections", true);
+ GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections.mobile", false);
+ GLOBAL_DEF("rendering/quality/reflections/high_quality_ggx", true);
+ GLOBAL_DEF("rendering/quality/reflections/high_quality_ggx.mobile", false);
+
+ GLOBAL_DEF("rendering/quality/shading/force_vertex_shading", false);
+ GLOBAL_DEF("rendering/quality/shading/force_vertex_shading.mobile", true);
+
+ GLOBAL_DEF("rendering/quality/depth_prepass/enable", true);
+ GLOBAL_DEF("rendering/quality/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno");
}
VisualServer::~VisualServer() {
diff --git a/servers/visual_server.h b/servers/visual_server.h
index dfa253ff25..ddf32a9ea1 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -6,6 +6,7 @@
/* 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 */
@@ -31,6 +32,7 @@
#include "bsp_tree.h"
#include "geometry.h"
+#include "image.h"
#include "math_2d.h"
#include "object.h"
#include "rid.h"
@@ -58,7 +60,6 @@ protected:
RID test_texture;
RID white_texture;
RID test_material;
- RID material_2d[16];
Error _surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, PoolVector<uint8_t> &r_vertex_array, int p_vertex_array_len, PoolVector<uint8_t> &r_index_array, int p_index_array_len, Rect3 &r_aabb, Vector<Rect3> r_bone_aabb);
@@ -105,13 +106,14 @@ public:
};
virtual RID texture_create() = 0;
- RID texture_create_from_image(const Image &p_image, uint32_t p_flags = TEXTURE_FLAGS_DEFAULT); // helper
+ RID texture_create_from_image(const Ref<Image> &p_image, uint32_t p_flags = TEXTURE_FLAGS_DEFAULT); // helper
virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = TEXTURE_FLAGS_DEFAULT) = 0;
- virtual void texture_set_data(RID p_texture, const Image &p_image, CubeMapSide p_cube_side = CUBEMAP_LEFT) = 0;
- virtual Image texture_get_data(RID p_texture, CubeMapSide p_cube_side = CUBEMAP_LEFT) const = 0;
+ virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, CubeMapSide p_cube_side = CUBEMAP_LEFT) = 0;
+ virtual Ref<Image> texture_get_data(RID p_texture, CubeMapSide p_cube_side = CUBEMAP_LEFT) const = 0;
virtual void texture_set_flags(RID p_texture, uint32_t p_flags) = 0;
virtual uint32_t texture_get_flags(RID p_texture) const = 0;
virtual Image::Format texture_get_format(RID p_texture) const = 0;
+ virtual uint32_t texture_get_texid(RID p_texture) const = 0;
virtual uint32_t texture_get_width(RID p_texture) const = 0;
virtual uint32_t texture_get_height(RID p_texture) const = 0;
virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) = 0;
@@ -125,6 +127,7 @@ public:
virtual void texture_set_detect_3d_callback(RID p_texture, TextureDetectCallback p_callback, void *p_userdata) = 0;
virtual void texture_set_detect_srgb_callback(RID p_texture, TextureDetectCallback p_callback, void *p_userdata) = 0;
+ virtual void texture_set_detect_normal_callback(RID p_texture, TextureDetectCallback p_callback, void *p_userdata) = 0;
struct TextureInfo {
RID texture;
@@ -138,10 +141,10 @@ public:
virtual void textures_keep_original(bool p_enable) = 0;
- /* SKYBOX API */
+ /* SKY API */
- virtual RID skybox_create() = 0;
- virtual void skybox_set_texture(RID p_skybox, RID p_cube_map, int p_radiance_size) = 0;
+ virtual RID sky_create() = 0;
+ virtual void sky_set_texture(RID p_sky, RID p_cube_map, int p_radiance_size) = 0;
/* SHADER API */
@@ -153,10 +156,7 @@ public:
SHADER_MAX
};
- virtual RID shader_create(ShaderMode p_mode = SHADER_SPATIAL) = 0;
-
- virtual void shader_set_mode(RID p_shader, ShaderMode p_mode) = 0;
- virtual ShaderMode shader_get_mode(RID p_shader) const = 0;
+ virtual RID shader_create() = 0;
virtual void shader_set_code(RID p_shader, const String &p_code) = 0;
virtual String shader_get_code(RID p_shader) const = 0;
@@ -176,6 +176,7 @@ public:
virtual Variant material_get_param(RID p_material, const StringName &p_param) const = 0;
virtual void material_set_line_width(RID p_material, float p_width) = 0;
+ virtual void material_set_next_pass(RID p_material, RID p_next_material) = 0;
/* MESH API */
@@ -358,7 +359,6 @@ public:
LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET,
LIGHT_PARAM_SHADOW_NORMAL_BIAS,
LIGHT_PARAM_SHADOW_BIAS,
- LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE,
LIGHT_PARAM_MAX
};
@@ -462,6 +462,9 @@ public:
virtual void gi_probe_set_bias(RID p_probe, float p_range) = 0;
virtual float gi_probe_get_bias(RID p_probe) const = 0;
+ virtual void gi_probe_set_normal_bias(RID p_probe, float p_range) = 0;
+ virtual float gi_probe_get_normal_bias(RID p_probe) const = 0;
+
virtual void gi_probe_set_propagation(RID p_probe, float p_range) = 0;
virtual float gi_probe_get_propagation(RID p_probe) const = 0;
@@ -478,26 +481,17 @@ public:
virtual void particles_set_emitting(RID p_particles, bool p_emitting) = 0;
virtual void particles_set_amount(RID p_particles, int p_amount) = 0;
virtual void particles_set_lifetime(RID p_particles, float p_lifetime) = 0;
+ virtual void particles_set_one_shot(RID p_particles, bool p_one_shot) = 0;
virtual void particles_set_pre_process_time(RID p_particles, float p_time) = 0;
virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) = 0;
virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio) = 0;
virtual void particles_set_custom_aabb(RID p_particles, const Rect3 &p_aabb) = 0;
- virtual void particles_set_gravity(RID p_particles, const Vector3 &p_gravity) = 0;
+ virtual void particles_set_speed_scale(RID p_particles, float p_scale) = 0;
virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable) = 0;
virtual void particles_set_process_material(RID p_particles, RID p_material) = 0;
-
- enum ParticlesEmissionShape {
- PARTICLES_EMSSION_POINT,
- PARTICLES_EMSSION_SPHERE,
- PARTICLES_EMSSION_BOX,
- PARTICLES_EMSSION_POINTS,
- PARTICLES_EMSSION_SEGMENTS,
- };
-
- virtual void particles_set_emission_shape(RID p_particles, ParticlesEmissionShape) = 0;
- virtual void particles_set_emission_sphere_radius(RID p_particles, float p_radius) = 0;
- virtual void particles_set_emission_box_extents(RID p_particles, const Vector3 &p_extents) = 0;
- virtual void particles_set_emission_points(RID p_particles, const PoolVector<Vector3> &p_points) = 0;
+ virtual void particles_set_fixed_fps(RID p_particles, int p_fps) = 0;
+ virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) = 0;
+ virtual void particles_restart(RID p_particles) = 0;
enum ParticlesDrawOrder {
PARTICLES_DRAW_ORDER_INDEX,
@@ -507,17 +501,13 @@ public:
virtual void particles_set_draw_order(RID p_particles, ParticlesDrawOrder p_order) = 0;
- enum ParticlesDrawPassMode {
- PARTICLES_DRAW_PASS_MODE_QUAD,
- PARTICLES_DRAW_PASS_MODE_MESH
- };
-
virtual void particles_set_draw_passes(RID p_particles, int p_count) = 0;
- virtual void particles_set_draw_pass_material(RID p_particles, int p_pass, RID p_material) = 0;
virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) = 0;
virtual Rect3 particles_get_current_aabb(RID p_particles) = 0;
+ virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0; //this is only used for 2D, in 3D it's automatic
+
/* CAMERA API */
virtual RID camera_create() = 0;
@@ -541,6 +531,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;
@@ -596,7 +587,38 @@ public:
};
virtual void viewport_set_msaa(RID p_viewport, ViewportMSAA p_msaa) = 0;
+
+ enum ViewportUsage {
+ VIEWPORT_USAGE_2D,
+ VIEWPORT_USAGE_2D_NO_SAMPLING,
+ VIEWPORT_USAGE_3D,
+ VIEWPORT_USAGE_3D_NO_EFFECTS,
+ };
+
virtual void viewport_set_hdr(RID p_viewport, bool p_enabled) = 0;
+ virtual void viewport_set_usage(RID p_viewport, ViewportUsage p_usage) = 0;
+
+ enum ViewportRenderInfo {
+
+ VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME,
+ VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME,
+ VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME,
+ VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME,
+ VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME,
+ VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME,
+ VIEWPORT_RENDER_INFO_MAX
+ };
+
+ virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) = 0;
+
+ enum ViewportDebugDraw {
+ VIEWPORT_DEBUG_DRAW_DISABLED,
+ VIEWPORT_DEBUG_DRAW_UNSHADED,
+ VIEWPORT_DEBUG_DRAW_OVERDRAW,
+ VIEWPORT_DEBUG_DRAW_WIREFRAME,
+ };
+
+ virtual void viewport_set_debug_draw(RID p_viewport, ViewportDebugDraw p_draw) = 0;
/* ENVIRONMENT API */
@@ -606,19 +628,19 @@ public:
ENV_BG_CLEAR_COLOR,
ENV_BG_COLOR,
- ENV_BG_SKYBOX,
+ ENV_BG_SKY,
ENV_BG_CANVAS,
ENV_BG_KEEP,
ENV_BG_MAX
};
virtual void environment_set_background(RID p_env, EnvironmentBG p_bg) = 0;
- virtual void environment_set_skybox(RID p_env, RID p_skybox) = 0;
- virtual void environment_set_skybox_scale(RID p_env, float p_scale) = 0;
+ virtual void environment_set_sky(RID p_env, RID p_sky) = 0;
+ virtual void environment_set_sky_scale(RID p_env, float p_scale) = 0;
virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0;
virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0;
virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0;
- virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_skybox_contribution = 0.0) = 0;
+ virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_sky_contribution = 0.0) = 0;
//set default SSAO options
//set default SSR options
@@ -639,8 +661,7 @@ public:
GLOW_BLEND_MODE_SOFTLIGHT,
GLOW_BLEND_MODE_REPLACE,
};
- virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_treshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) = 0;
- virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) = 0;
+ virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) = 0;
enum EnvironmentToneMapper {
ENV_TONE_MAPPER_LINEAR,
@@ -652,9 +673,13 @@ public:
virtual void environment_set_tonemap(RID p_env, EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_grey) = 0;
virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) = 0;
- virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_accel, float p_fade, float p_depth_tolerance, bool p_smooth, bool p_roughness) = 0;
+ virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness) = 0;
virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, bool p_blur) = 0;
+ virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) = 0;
+ virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
+ virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0;
+
/* SCENARIO API */
virtual RID scenario_create() = 0;
@@ -689,7 +714,7 @@ public:
INSTANCE_MAX,
/*INSTANCE_BAKED_LIGHT_SAMPLER,*/
- INSTANCE_GEOMETRY_MASK = (1 << INSTANCE_MESH) | (1 << INSTANCE_MULTIMESH) | (1 << INSTANCE_IMMEDIATE)
+ INSTANCE_GEOMETRY_MASK = (1 << INSTANCE_MESH) | (1 << INSTANCE_MULTIMESH) | (1 << INSTANCE_IMMEDIATE) | (1 << INSTANCE_PARTICLES)
};
virtual RID instance_create2(RID p_base, RID p_scenario);
@@ -701,7 +726,7 @@ public:
virtual void instance_set_scenario(RID p_instance, RID p_scenario) = 0; // from can be mesh, light, poly, area and portal so far.
virtual void instance_set_layer_mask(RID p_instance, uint32_t p_mask) = 0;
virtual void instance_set_transform(RID p_instance, const Transform &p_transform) = 0;
- virtual void instance_attach_object_instance_ID(RID p_instance, ObjectID p_ID) = 0;
+ virtual void instance_attach_object_instance_id(RID p_instance, ObjectID p_ID) = 0;
virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) = 0;
virtual void instance_set_surface_material(RID p_instance, int p_surface, RID p_material) = 0;
virtual void instance_set_visible(RID p_instance, bool p_visible) = 0;
@@ -718,10 +743,7 @@ public:
virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario = RID()) const = 0;
enum InstanceFlags {
- INSTANCE_FLAG_BILLBOARD,
- INSTANCE_FLAG_BILLBOARD_FIX_Y,
INSTANCE_FLAG_CAST_SHADOW,
- INSTANCE_FLAG_DEPH_SCALE,
INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS,
INSTANCE_FLAG_USE_BAKED_LIGHT,
INSTANCE_FLAG_MAX
@@ -769,16 +791,18 @@ public:
};
virtual void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false) = 0;
+ virtual void canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false) = 0;
virtual void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) = 0;
virtual void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) = 0;
- virtual void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) = 0;
- virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) = 0;
- virtual void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, NinePatchAxisMode p_x_axis_mode = NINE_PATCH_STRETCH, NinePatchAxisMode p_y_axis_mode = NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1)) = 0;
- virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0) = 0;
- virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID()) = 0;
- virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1) = 0;
+ virtual void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID()) = 0;
+ virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), bool p_clip_uv = true) = 0;
+ virtual void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, NinePatchAxisMode p_x_axis_mode = NINE_PATCH_STRETCH, NinePatchAxisMode p_y_axis_mode = NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID()) = 0;
+ virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID()) = 0;
+ virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID()) = 0;
+ virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID()) = 0;
virtual void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_skeleton = RID()) = 0;
virtual void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_skeleton = RID()) = 0;
+ virtual void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, int p_h_frames, int p_v_frames) = 0;
virtual void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) = 0;
virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore) = 0;
virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) = 0;
@@ -830,6 +854,7 @@ public:
virtual void canvas_light_set_shadow_gradient_length(RID p_light, float p_length) = 0;
virtual void canvas_light_set_shadow_filter(RID p_light, CanvasLightShadowFilter p_filter) = 0;
virtual void canvas_light_set_shadow_color(RID p_light, const Color &p_color) = 0;
+ virtual void canvas_light_set_shadow_smooth(RID p_light, float p_smooth) = 0;
virtual RID canvas_light_occluder_create() = 0;
virtual void canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) = 0;
@@ -849,12 +874,6 @@ public:
};
virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, CanvasOccluderPolygonCullMode p_mode) = 0;
- /* CURSOR */
- virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0) = 0; // radians
- virtual void cursor_set_texture(RID p_texture, const Point2 &p_center_offset = Point2(0, 0), int p_cursor = 0, const Rect2 &p_region = Rect2()) = 0;
- virtual void cursor_set_visible(bool p_visible, int p_cursor = 0) = 0;
- virtual void cursor_set_pos(const Point2 &p_pos, int p_cursor = 0) = 0;
-
/* BLACK BARS */
virtual void black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) = 0;
@@ -864,6 +883,8 @@ public:
virtual void free(RID p_rid) = 0; ///< free RIDs associated with the visual server
+ virtual void request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) = 0;
+
/* EVENT QUEUING */
virtual void draw() = 0;
@@ -892,8 +913,6 @@ public:
/* Materials for 2D on 3D */
- RID material_2d_get(bool p_shaded, bool p_transparent, bool p_cut_alpha, bool p_opaque_prepass);
-
/* TESTING */
virtual RID get_test_cube() = 0;
@@ -906,7 +925,7 @@ public:
virtual void mesh_add_surface_from_mesh_data(RID p_mesh, const Geometry::MeshData &p_mesh_data);
virtual void mesh_add_surface_from_planes(RID p_mesh, const PoolVector<Plane> &p_planes);
- virtual void set_boot_image(const Image &p_image, const Color &p_color, bool p_scale) = 0;
+ virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale) = 0;
virtual void set_default_clear_color(const Color &p_color) = 0;
enum Features {
@@ -918,6 +937,8 @@ public:
virtual bool has_os_feature(const String &p_feature) const = 0;
+ virtual void set_debug_generate_wireframes(bool p_generate) = 0;
+
VisualServer();
virtual ~VisualServer();
};