diff options
Diffstat (limited to 'servers')
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(); }; |