summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/arvr_server.cpp6
-rw-r--r--servers/audio/audio_stream.cpp114
-rw-r--r--servers/audio/audio_stream.h57
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.cpp6
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.h2
-rw-r--r--servers/audio/effects/audio_effect_record.cpp2
-rw-r--r--servers/audio_server.cpp60
-rw-r--r--servers/audio_server.h34
-rw-r--r--servers/physics/body_pair_sw.cpp34
-rw-r--r--servers/physics/body_sw.cpp16
-rw-r--r--servers/physics/body_sw.h8
-rw-r--r--servers/physics/collision_solver_sat.cpp84
-rw-r--r--servers/physics/collision_solver_sw.cpp4
-rw-r--r--servers/physics/joints/hinge_joint_sw.cpp6
-rw-r--r--servers/physics/physics_server_sw.cpp38
-rw-r--r--servers/physics/physics_server_sw.h11
-rw-r--r--servers/physics/space_sw.cpp199
-rw-r--r--servers/physics/space_sw.h15
-rw-r--r--servers/physics/step_sw.cpp1
-rw-r--r--servers/physics_2d/body_2d_sw.cpp16
-rw-r--r--servers/physics_2d/body_2d_sw.h8
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp34
-rw-r--r--servers/physics_2d/broad_phase_2d_sw.h2
-rw-r--r--servers/physics_2d/collision_solver_2d_sat.cpp1
-rw-r--r--servers/physics_2d/collision_solver_2d_sw.cpp45
-rw-r--r--servers/physics_2d/joints_2d_sw.cpp2
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp23
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h4
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.h3
-rw-r--r--servers/physics_2d/space_2d_sw.cpp52
-rw-r--r--servers/physics_2d/space_2d_sw.h12
-rw-r--r--servers/physics_2d/step_2d_sw.cpp2
-rw-r--r--servers/physics_2d_server.cpp46
-rw-r--r--servers/physics_2d_server.h38
-rw-r--r--servers/physics_server.cpp42
-rw-r--r--servers/physics_server.h57
-rw-r--r--servers/register_server_types.cpp3
-rw-r--r--servers/server_wrap_mt_common.h7
-rw-r--r--servers/visual/rasterizer.h27
-rw-r--r--servers/visual/shader_language.cpp160
-rw-r--r--servers/visual/shader_language.h12
-rw-r--r--servers/visual/shader_types.cpp1
-rw-r--r--servers/visual/visual_server_raster.h12
-rw-r--r--servers/visual/visual_server_scene.cpp18
-rw-r--r--servers/visual/visual_server_viewport.cpp3
-rw-r--r--servers/visual/visual_server_wrap_mt.cpp6
-rw-r--r--servers/visual/visual_server_wrap_mt.h12
-rw-r--r--servers/visual_server.cpp61
-rw-r--r--servers/visual_server.h43
49 files changed, 971 insertions, 478 deletions
diff --git a/servers/arvr_server.cpp b/servers/arvr_server.cpp
index 0d1aad0dff..2040377dd4 100644
--- a/servers/arvr_server.cpp
+++ b/servers/arvr_server.cpp
@@ -178,7 +178,7 @@ void ARVRServer::remove_interface(const Ref<ARVRInterface> &p_interface) {
ERR_FAIL_COND(idx == -1);
- print_line("Removed interface" + p_interface->get_name());
+ print_verbose("ARVR: Removed interface" + p_interface->get_name());
emit_signal("interface_removed", p_interface->get_name());
interfaces.remove(idx);
@@ -320,12 +320,12 @@ Ref<ARVRInterface> ARVRServer::get_primary_interface() const {
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());
+ print_verbose("ARVR: 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");
+ print_verbose("ARVR: Clearing primary interface");
primary_interface.unref();
};
};
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index 113f23f8f2..eef8aba0c4 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "audio_stream.h"
+#include "os/os.h"
//////////////////////////////
@@ -99,6 +100,119 @@ void AudioStream::_bind_methods() {
////////////////////////////////
+Ref<AudioStreamPlayback> AudioStreamMicrophone::instance_playback() {
+ Ref<AudioStreamPlaybackMicrophone> playback;
+ playback.instance();
+
+ playbacks.insert(playback.ptr());
+
+ playback->microphone = Ref<AudioStreamMicrophone>((AudioStreamMicrophone *)this);
+ playback->active = false;
+
+ return playback;
+}
+
+String AudioStreamMicrophone::get_stream_name() const {
+
+ //if (audio_stream.is_valid()) {
+ //return "Random: " + audio_stream->get_name();
+ //}
+ return "Microphone";
+}
+
+float AudioStreamMicrophone::get_length() const {
+ return 0;
+}
+
+void AudioStreamMicrophone::_bind_methods() {
+}
+
+AudioStreamMicrophone::AudioStreamMicrophone() {
+}
+
+void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_frames) {
+
+ AudioDriver::get_singleton()->lock();
+
+ Vector<int32_t> buf = AudioDriver::get_singleton()->get_input_buffer();
+ unsigned int input_size = AudioDriver::get_singleton()->get_input_size();
+
+ // p_frames is multipled by two since an AudioFrame is stereo
+ if ((p_frames + MICROPHONE_PLAYBACK_DELAY * 2) > input_size) {
+ for (int i = 0; i < p_frames; i++) {
+ p_buffer[i] = AudioFrame(0.0f, 0.0f);
+ }
+ input_ofs = 0;
+ } else {
+ for (int i = 0; i < p_frames; i++) {
+ if (input_size >= input_ofs) {
+ float l = (buf[input_ofs++] >> 16) / 32768.f;
+ if (input_ofs >= buf.size()) {
+ input_ofs = 0;
+ }
+ float r = (buf[input_ofs++] >> 16) / 32768.f;
+ if (input_ofs >= buf.size()) {
+ input_ofs = 0;
+ }
+
+ p_buffer[i] = AudioFrame(l, r);
+ } else {
+ p_buffer[i] = AudioFrame(0.0f, 0.0f);
+ }
+ }
+ }
+
+ AudioDriver::get_singleton()->unlock();
+}
+
+void AudioStreamPlaybackMicrophone::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
+ AudioStreamPlaybackResampled::mix(p_buffer, p_rate_scale, p_frames);
+}
+
+float AudioStreamPlaybackMicrophone::get_stream_sampling_rate() {
+ return AudioDriver::get_singleton()->get_mix_rate();
+}
+
+void AudioStreamPlaybackMicrophone::start(float p_from_pos) {
+ input_ofs = 0;
+
+ AudioDriver::get_singleton()->capture_start();
+
+ active = true;
+ _begin_resample();
+}
+
+void AudioStreamPlaybackMicrophone::stop() {
+ AudioDriver::get_singleton()->capture_stop();
+ active = false;
+}
+
+bool AudioStreamPlaybackMicrophone::is_playing() const {
+ return active;
+}
+
+int AudioStreamPlaybackMicrophone::get_loop_count() const {
+ return 0;
+}
+
+float AudioStreamPlaybackMicrophone::get_playback_position() const {
+ return 0;
+}
+
+void AudioStreamPlaybackMicrophone::seek(float p_time) {
+ return; // Can't seek a microphone input
+}
+
+AudioStreamPlaybackMicrophone::~AudioStreamPlaybackMicrophone() {
+ microphone->playbacks.erase(this);
+ stop();
+}
+
+AudioStreamPlaybackMicrophone::AudioStreamPlaybackMicrophone() {
+}
+
+////////////////////////////////
+
void AudioStreamRandomPitch::set_audio_stream(const Ref<AudioStream> &p_audio_stream) {
audio_stream = p_audio_stream;
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index 3312ce1ff6..66e1b6ee2f 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -94,6 +94,63 @@ public:
virtual float get_length() const = 0; //if supported, otherwise return 0
};
+// Microphone
+
+class AudioStreamPlaybackMicrophone;
+
+class AudioStreamMicrophone : public AudioStream {
+
+ GDCLASS(AudioStreamMicrophone, AudioStream)
+ friend class AudioStreamPlaybackMicrophone;
+
+ Set<AudioStreamPlaybackMicrophone *> playbacks;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual Ref<AudioStreamPlayback> instance_playback();
+ virtual String get_stream_name() const;
+
+ virtual float get_length() const; //if supported, otherwise return 0
+
+ AudioStreamMicrophone();
+};
+
+class AudioStreamPlaybackMicrophone : public AudioStreamPlaybackResampled {
+
+ GDCLASS(AudioStreamPlaybackMicrophone, AudioStreamPlayback)
+ friend class AudioStreamMicrophone;
+
+ const int MICROPHONE_PLAYBACK_DELAY = 256;
+
+ bool active;
+ unsigned int input_ofs;
+
+ Ref<AudioStreamMicrophone> microphone;
+
+protected:
+ virtual void _mix_internal(AudioFrame *p_buffer, int p_frames);
+ virtual float get_stream_sampling_rate();
+
+public:
+ virtual void mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames);
+
+ 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_playback_position() const;
+ virtual void seek(float p_time);
+
+ ~AudioStreamPlaybackMicrophone();
+ AudioStreamPlaybackMicrophone();
+};
+
+//
+
class AudioStreamPlaybackRandomPitch;
class AudioStreamRandomPitch : public AudioStream {
diff --git a/servers/audio/effects/audio_effect_pitch_shift.cpp b/servers/audio/effects/audio_effect_pitch_shift.cpp
index ddd0a0db6b..c6d1217308 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.cpp
+++ b/servers/audio/effects/audio_effect_pitch_shift.cpp
@@ -305,9 +305,9 @@ Ref<AudioEffectInstance> AudioEffectPitchShift::instance() {
return ins;
}
-void AudioEffectPitchShift::set_pitch_scale(float p_adjust) {
-
- pitch_scale = p_adjust;
+void AudioEffectPitchShift::set_pitch_scale(float p_pitch_scale) {
+ ERR_FAIL_COND(p_pitch_scale <= 0.0);
+ pitch_scale = p_pitch_scale;
}
float AudioEffectPitchShift::get_pitch_scale() const {
diff --git a/servers/audio/effects/audio_effect_pitch_shift.h b/servers/audio/effects/audio_effect_pitch_shift.h
index f1c78d752f..78f92a0261 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.h
+++ b/servers/audio/effects/audio_effect_pitch_shift.h
@@ -100,7 +100,7 @@ protected:
public:
Ref<AudioEffectInstance> instance();
- void set_pitch_scale(float p_adjust);
+ void set_pitch_scale(float p_pitch_scale);
float get_pitch_scale() const;
AudioEffectPitchShift();
diff --git a/servers/audio/effects/audio_effect_record.cpp b/servers/audio/effects/audio_effect_record.cpp
index 74a6838d1a..78ba658ed8 100644
--- a/servers/audio/effects/audio_effect_record.cpp
+++ b/servers/audio/effects/audio_effect_record.cpp
@@ -233,7 +233,7 @@ Ref<AudioStreamSample> AudioEffectRecord::get_recording() const {
w[i * 2 + 1] = rr[i];
}
} else {
- ERR_EXPLAIN("format not implemented");
+ ERR_PRINT("Format not implemented.");
}
Ref<AudioStreamSample> sample;
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index 2eaa2ce8e7..b737f4681d 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -33,6 +33,7 @@
#include "os/file_access.h"
#include "os/os.h"
#include "project_settings.h"
+#include "scene/resources/audio_stream_sample.h"
#include "servers/audio/audio_driver_dummy.h"
#include "servers/audio/effects/audio_effect_compressor.h"
#ifdef TOOLS_ENABLED
@@ -79,6 +80,17 @@ double AudioDriver::get_mix_time() const {
return total;
}
+void AudioDriver::input_buffer_write(int32_t sample) {
+
+ input_buffer.write[input_position++] = sample;
+ if (input_position >= input_buffer.size()) {
+ input_position = 0;
+ }
+ if (input_size < input_buffer.size()) {
+ input_size++;
+ }
+}
+
AudioDriver::SpeakerMode AudioDriver::get_speaker_mode_by_total_channels(int p_channels) const {
switch (p_channels) {
case 4: return SPEAKER_SURROUND_31;
@@ -113,6 +125,14 @@ String AudioDriver::get_device() {
return "Default";
}
+Array AudioDriver::capture_get_device_list() {
+ Array list;
+
+ list.push_back("Default");
+
+ return list;
+}
+
AudioDriver::AudioDriver() {
_last_mix_time = 0;
@@ -123,14 +143,19 @@ AudioDriver::AudioDriver() {
#endif
}
-AudioDriver *AudioDriverManager::drivers[MAX_DRIVERS];
-int AudioDriverManager::driver_count = 0;
AudioDriverDummy AudioDriverManager::dummy_driver;
+AudioDriver *AudioDriverManager::drivers[MAX_DRIVERS] = {
+ &AudioDriverManager::dummy_driver,
+};
+int AudioDriverManager::driver_count = 1;
void AudioDriverManager::add_driver(AudioDriver *p_driver) {
ERR_FAIL_COND(driver_count >= MAX_DRIVERS);
- drivers[driver_count++] = p_driver;
+ drivers[driver_count - 1] = p_driver;
+
+ // Last driver is always our dummy driver
+ drivers[driver_count++] = &AudioDriverManager::dummy_driver;
}
int AudioDriverManager::get_driver_count() {
@@ -163,14 +188,6 @@ void AudioDriverManager::initialize(int p_driver) {
return;
}
}
-
- // Fallback to our dummy driver
- if (dummy_driver.init() == OK) {
- ERR_PRINT("AudioDriverManager: all drivers failed, falling back to dummy driver");
- dummy_driver.set_singleton();
- } else {
- ERR_PRINT("AudioDriverManager: dummy driver failed to init()");
- }
}
AudioDriver *AudioDriverManager::get_driver(int p_driver) {
@@ -1201,6 +1218,21 @@ void AudioServer::set_device(String device) {
AudioDriver::get_singleton()->set_device(device);
}
+Array AudioServer::capture_get_device_list() {
+
+ return AudioDriver::get_singleton()->capture_get_device_list();
+}
+
+String AudioServer::capture_get_device() {
+
+ return AudioDriver::get_singleton()->capture_get_device();
+}
+
+void AudioServer::capture_set_device(const String &p_name) {
+
+ AudioDriver::get_singleton()->capture_set_device(p_name);
+}
+
void AudioServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bus_count", "amount"), &AudioServer::set_bus_count);
@@ -1249,7 +1281,11 @@ void AudioServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_mix_rate"), &AudioServer::get_mix_rate);
ClassDB::bind_method(D_METHOD("get_device_list"), &AudioServer::get_device_list);
ClassDB::bind_method(D_METHOD("get_device"), &AudioServer::get_device);
- ClassDB::bind_method(D_METHOD("set_device"), &AudioServer::set_device);
+ ClassDB::bind_method(D_METHOD("set_device", "device"), &AudioServer::set_device);
+
+ ClassDB::bind_method(D_METHOD("capture_get_device_list"), &AudioServer::capture_get_device_list);
+ ClassDB::bind_method(D_METHOD("capture_get_device"), &AudioServer::capture_get_device);
+ ClassDB::bind_method(D_METHOD("capture_set_device", "name"), &AudioServer::capture_set_device);
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);
diff --git a/servers/audio_server.h b/servers/audio_server.h
index 258fd1d9b0..2663a0f968 100644
--- a/servers/audio_server.h
+++ b/servers/audio_server.h
@@ -38,6 +38,8 @@
#include "variant.h"
class AudioDriverDummy;
+class AudioStream;
+class AudioStreamSample;
class AudioDriver {
@@ -51,8 +53,13 @@ class AudioDriver {
#endif
protected:
+ Vector<int32_t> input_buffer;
+ unsigned int input_position;
+ unsigned int input_size;
+
void audio_server_process(int p_frames, int32_t *p_buffer, bool p_update_mix_time = true);
void update_mix_time(int p_frames);
+ void input_buffer_write(int32_t sample);
#ifdef DEBUG_ENABLED
_FORCE_INLINE_ void start_counting_ticks() { prof_ticks = OS::get_singleton()->get_ticks_usec(); }
@@ -91,11 +98,21 @@ public:
virtual void unlock() = 0;
virtual void finish() = 0;
+ virtual Error capture_start() { return FAILED; }
+ virtual Error capture_stop() { return FAILED; }
+ virtual void capture_set_device(const String &p_name) {}
+ virtual String capture_get_device() { return "Default"; }
+ virtual Array capture_get_device_list(); // TODO: convert this and get_device_list to PoolStringArray
+
virtual float get_latency() { return 0; }
SpeakerMode get_speaker_mode_by_total_channels(int p_channels) const;
int get_total_channels_by_speaker_mode(SpeakerMode) const;
+ Vector<int32_t> get_input_buffer() { return input_buffer; }
+ unsigned int get_input_position() { return input_position; }
+ unsigned int get_input_size() { return input_size; }
+
#ifdef DEBUG_ENABLED
uint64_t get_profiling_time() const { return prof_time; }
void reset_profiling_time() { prof_time = 0; }
@@ -222,6 +239,18 @@ private:
void _mix_step();
+#if 0
+ struct AudioInBlock {
+
+ Ref<AudioStreamSample> audio_stream;
+ int current_position;
+ bool loops;
+ };
+
+ Map<StringName, AudioInBlock *> audio_in_block_map;
+ Vector<AudioInBlock *> audio_in_blocks;
+#endif
+
struct CallbackItem {
AudioCallback callback;
@@ -335,8 +364,11 @@ public:
String get_device();
void set_device(String device);
- float get_output_latency() { return output_latency; }
+ Array capture_get_device_list();
+ String capture_get_device();
+ void capture_set_device(const String &p_name);
+ float get_output_latency() { return output_latency; }
AudioServer();
virtual ~AudioServer();
};
diff --git a/servers/physics/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp
index 5a41b621eb..0ce38e4486 100644
--- a/servers/physics/body_pair_sw.cpp
+++ b/servers/physics/body_pair_sw.cpp
@@ -212,41 +212,11 @@ bool BodyPairSW::_test_ccd(real_t p_step, BodySW *p_A, int p_shape_A, const Tran
}
real_t combine_bounce(BodySW *A, BodySW *B) {
- const PhysicsServer::CombineMode cm = A->get_bounce_combine_mode();
-
- switch (cm) {
- case PhysicsServer::COMBINE_MODE_INHERIT:
- if (B->get_bounce_combine_mode() != PhysicsServer::COMBINE_MODE_INHERIT)
- return combine_bounce(B, A);
- // else use MAX [This is used when the two bodies doesn't use physical material]
- case PhysicsServer::COMBINE_MODE_MAX:
- return MAX(A->get_bounce(), B->get_bounce());
- case PhysicsServer::COMBINE_MODE_MIN:
- return MIN(A->get_bounce(), B->get_bounce());
- case PhysicsServer::COMBINE_MODE_MULTIPLY:
- return A->get_bounce() * B->get_bounce();
- default: // Is always PhysicsServer::COMBINE_MODE_AVERAGE:
- return (A->get_bounce() + B->get_bounce()) / 2;
- }
+ return CLAMP(A->get_bounce() + B->get_bounce(), 0, 1);
}
real_t combine_friction(BodySW *A, BodySW *B) {
- const PhysicsServer::CombineMode cm = A->get_friction_combine_mode();
-
- switch (cm) {
- case PhysicsServer::COMBINE_MODE_INHERIT:
- if (B->get_friction_combine_mode() != PhysicsServer::COMBINE_MODE_INHERIT)
- return combine_friction(B, A);
- // else use Multiply [This is used when the two bodies doesn't use physical material]
- case PhysicsServer::COMBINE_MODE_MULTIPLY:
- return A->get_friction() * B->get_friction();
- case PhysicsServer::COMBINE_MODE_MAX:
- return MAX(A->get_friction(), B->get_friction());
- case PhysicsServer::COMBINE_MODE_MIN:
- return MIN(A->get_friction(), B->get_friction());
- default: // Is always PhysicsServer::COMBINE_MODE_AVERAGE:
- return (A->get_friction() + B->get_friction()) / 2;
- }
+ return ABS(MIN(A->get_friction(), B->get_friction()));
}
bool BodyPairSW::setup(real_t p_step) {
diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp
index 59f987fc17..cc9681193c 100644
--- a/servers/physics/body_sw.cpp
+++ b/servers/physics/body_sw.cpp
@@ -423,22 +423,6 @@ void BodySW::_compute_area_gravity_and_dampenings(const AreaSW *p_area) {
area_angular_damp += p_area->get_angular_damp();
}
-void BodySW::set_combine_mode(PhysicsServer::BodyParameter p_param, PhysicsServer::CombineMode p_mode) {
- if (p_param == PhysicsServer::BODY_PARAM_BOUNCE) {
- bounce_combine_mode = p_mode;
- } else {
- friction_combine_mode = p_mode;
- }
-}
-
-PhysicsServer::CombineMode BodySW::get_combine_mode(PhysicsServer::BodyParameter p_param) const {
- if (p_param == PhysicsServer::BODY_PARAM_BOUNCE) {
- return bounce_combine_mode;
- } else {
- return friction_combine_mode;
- }
-}
-
void BodySW::set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock) {
if (lock) {
locked_axis |= p_axis;
diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h
index 5df270f679..9d7b147fd6 100644
--- a/servers/physics/body_sw.h
+++ b/servers/physics/body_sw.h
@@ -49,8 +49,6 @@ class BodySW : public CollisionObjectSW {
real_t mass;
real_t bounce;
real_t friction;
- PhysicsServer::CombineMode bounce_combine_mode;
- PhysicsServer::CombineMode friction_combine_mode;
real_t linear_damp;
real_t angular_damp;
@@ -304,12 +302,6 @@ public:
_FORCE_INLINE_ Vector3 get_gravity() const { return gravity; }
_FORCE_INLINE_ real_t get_bounce() const { return bounce; }
- void set_combine_mode(PhysicsServer::BodyParameter p_param, PhysicsServer::CombineMode p_mode);
- PhysicsServer::CombineMode get_combine_mode(PhysicsServer::BodyParameter p_param) const;
-
- _FORCE_INLINE_ PhysicsServer::CombineMode get_bounce_combine_mode() const { return bounce_combine_mode; }
- _FORCE_INLINE_ PhysicsServer::CombineMode get_friction_combine_mode() const { return friction_combine_mode; }
-
void set_axis_lock(PhysicsServer::BodyAxis p_axis, bool lock);
bool is_axis_locked(PhysicsServer::BodyAxis p_axis) const;
diff --git a/servers/physics/collision_solver_sat.cpp b/servers/physics/collision_solver_sat.cpp
index 8f2b147460..294b1df241 100644
--- a/servers/physics/collision_solver_sat.cpp
+++ b/servers/physics/collision_solver_sat.cpp
@@ -44,12 +44,6 @@ struct _CollectorCallback {
_FORCE_INLINE_ void call(const Vector3 &p_point_A, const Vector3 &p_point_B) {
- /*
- if (normal.dot(p_point_A) >= normal.dot(p_point_B))
- return;
- print_line("** A: "+p_point_A+" B: "+p_point_B+" D: "+rtos(p_point_A.distance_to(p_point_B)));
- */
-
if (swap)
callback(p_point_B, p_point_A, userdata);
else
@@ -410,26 +404,13 @@ public:
supports_B[i] += best_axis * margin_B;
}
}
- /*
- print_line("best depth: "+rtos(best_depth));
- print_line("best axis: "+(best_axis));
- for(int i=0;i<support_count_A;i++) {
-
- print_line("A-"+itos(i)+": "+supports_A[i]);
- }
- for(int i=0;i<support_count_B;i++) {
- print_line("B-"+itos(i)+": "+supports_B[i]);
- }
-*/
callback->normal = best_axis;
if (callback->prev_axis)
*callback->prev_axis = best_axis;
_generate_contacts_from_supports(supports_A, support_count_A, supports_B, support_count_B, callback);
callback->collided = true;
- //CollisionSolverSW::CallbackResult cbk=NULL;
- //cbk(Vector3(),Vector3(),NULL);
}
_FORCE_INLINE_ SeparatorAxisTest(const ShapeA *p_shape_A, const Transform &p_transform_A, const ShapeB *p_shape_B, const Transform &p_transform_B, _CollectorCallback *p_callback, real_t p_margin_A = 0, real_t p_margin_B = 0) {
@@ -445,9 +426,6 @@ public:
};
/****** SAT TESTS *******/
-/****** SAT TESTS *******/
-/****** SAT TESTS *******/
-/****** SAT TESTS *******/
typedef void (*CollisionFunc)(const ShapeSW *, const Transform &, const ShapeSW *, const Transform &, _CollectorCallback *p_callback, real_t, real_t);
@@ -560,6 +538,12 @@ static void _collision_sphere_capsule(const ShapeSW *p_a, const Transform &p_tra
}
template <bool withMargin>
+static void _collision_sphere_cylinder(const ShapeSW *p_a, const Transform &p_transform_a, const ShapeSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
+
+ return;
+}
+
+template <bool withMargin>
static void _collision_sphere_convex_polygon(const ShapeSW *p_a, const Transform &p_transform_a, const ShapeSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
const SphereShapeSW *sphere_A = static_cast<const SphereShapeSW *>(p_a);
@@ -851,6 +835,12 @@ static void _collision_box_capsule(const ShapeSW *p_a, const Transform &p_transf
}
template <bool withMargin>
+static void _collision_box_cylinder(const ShapeSW *p_a, const Transform &p_transform_a, const ShapeSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
+
+ return;
+}
+
+template <bool withMargin>
static void _collision_box_convex_polygon(const ShapeSW *p_a, const Transform &p_transform_a, const ShapeSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
const BoxShapeSW *box_A = static_cast<const BoxShapeSW *>(p_a);
@@ -1127,6 +1117,12 @@ static void _collision_capsule_capsule(const ShapeSW *p_a, const Transform &p_tr
}
template <bool withMargin>
+static void _collision_capsule_cylinder(const ShapeSW *p_a, const Transform &p_transform_a, const ShapeSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
+
+ return;
+}
+
+template <bool withMargin>
static void _collision_capsule_convex_polygon(const ShapeSW *p_a, const Transform &p_transform_a, const ShapeSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
const CapsuleShapeSW *capsule_A = static_cast<const CapsuleShapeSW *>(p_a);
@@ -1247,6 +1243,24 @@ static void _collision_capsule_face(const ShapeSW *p_a, const Transform &p_trans
}
template <bool withMargin>
+static void _collision_cylinder_cylinder(const ShapeSW *p_a, const Transform &p_transform_a, const ShapeSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
+
+ return;
+}
+
+template <bool withMargin>
+static void _collision_cylinder_convex_polygon(const ShapeSW *p_a, const Transform &p_transform_a, const ShapeSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
+
+ return;
+}
+
+template <bool withMargin>
+static void _collision_cylinder_face(const ShapeSW *p_a, const Transform &p_transform_a, const ShapeSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
+
+ return;
+}
+
+template <bool withMargin>
static void _collision_convex_polygon_convex_polygon(const ShapeSW *p_a, const Transform &p_transform_a, const ShapeSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
const ConvexPolygonShapeSW *convex_polygon_A = static_cast<const ConvexPolygonShapeSW *>(p_a);
@@ -1475,59 +1489,81 @@ bool sat_calculate_penetration(const ShapeSW *p_shape_A, const Transform &p_tran
ERR_FAIL_COND_V(type_B == PhysicsServer::SHAPE_RAY, false);
ERR_FAIL_COND_V(p_shape_B->is_concave(), false);
- static const CollisionFunc collision_table[5][5] = {
+ static const CollisionFunc collision_table[6][6] = {
{ _collision_sphere_sphere<false>,
_collision_sphere_box<false>,
_collision_sphere_capsule<false>,
+ _collision_sphere_cylinder<false>,
_collision_sphere_convex_polygon<false>,
_collision_sphere_face<false> },
{ 0,
_collision_box_box<false>,
_collision_box_capsule<false>,
+ _collision_box_cylinder<false>,
_collision_box_convex_polygon<false>,
_collision_box_face<false> },
{ 0,
0,
_collision_capsule_capsule<false>,
+ _collision_capsule_cylinder<false>,
_collision_capsule_convex_polygon<false>,
_collision_capsule_face<false> },
{ 0,
0,
0,
+ _collision_cylinder_cylinder<false>,
+ _collision_cylinder_convex_polygon<false>,
+ _collision_cylinder_face<false> },
+ { 0,
+ 0,
+ 0,
+ 0,
_collision_convex_polygon_convex_polygon<false>,
_collision_convex_polygon_face<false> },
{ 0,
0,
0,
0,
+ 0,
0 },
};
- static const CollisionFunc collision_table_margin[5][5] = {
+ static const CollisionFunc collision_table_margin[6][6] = {
{ _collision_sphere_sphere<true>,
_collision_sphere_box<true>,
_collision_sphere_capsule<true>,
+ _collision_sphere_cylinder<true>,
_collision_sphere_convex_polygon<true>,
_collision_sphere_face<true> },
{ 0,
_collision_box_box<true>,
_collision_box_capsule<true>,
+ _collision_box_cylinder<true>,
_collision_box_convex_polygon<true>,
_collision_box_face<true> },
{ 0,
0,
_collision_capsule_capsule<true>,
+ _collision_capsule_cylinder<true>,
_collision_capsule_convex_polygon<true>,
_collision_capsule_face<true> },
{ 0,
0,
0,
+ _collision_cylinder_cylinder<true>,
+ _collision_cylinder_convex_polygon<true>,
+ _collision_cylinder_face<true> },
+ { 0,
+ 0,
+ 0,
+ 0,
_collision_convex_polygon_convex_polygon<true>,
_collision_convex_polygon_face<true> },
{ 0,
0,
0,
0,
+ 0,
0 },
};
diff --git a/servers/physics/collision_solver_sw.cpp b/servers/physics/collision_solver_sw.cpp
index 0037b9a862..2f2f6d2908 100644
--- a/servers/physics/collision_solver_sw.cpp
+++ b/servers/physics/collision_solver_sw.cpp
@@ -176,7 +176,6 @@ bool CollisionSolverSW::solve_concave(const ShapeSW *p_shape_A, const Transform
}
concave_B->cull(local_aabb, concave_callback, &cinfo);
- //print_line("COL AABB TESTS: "+itos(cinfo.aabb_tests));
return cinfo.collided;
}
@@ -364,13 +363,10 @@ bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A, const Transform
concave_B->cull(local_aabb, concave_distance_callback, &cinfo);
if (!cinfo.collided) {
- //print_line(itos(cinfo.tested));
r_point_A = cinfo.close_A;
r_point_B = cinfo.close_B;
}
- //print_line("DIST AABB TESTS: "+itos(cinfo.aabb_tests));
-
return !cinfo.collided;
} else {
diff --git a/servers/physics/joints/hinge_joint_sw.cpp b/servers/physics/joints/hinge_joint_sw.cpp
index d660eba879..368a349632 100644
--- a/servers/physics/joints/hinge_joint_sw.cpp
+++ b/servers/physics/joints/hinge_joint_sw.cpp
@@ -224,18 +224,12 @@ bool HingeJointSW::setup(real_t p_step) {
// Compute limit information
real_t hingeAngle = get_hinge_angle();
- //print_line("angle: "+rtos(hingeAngle));
//set bias, sign, clear accumulator
m_correction = real_t(0.);
m_limitSign = real_t(0.);
m_solveLimit = false;
m_accLimitImpulse = real_t(0.);
- /*if (m_useLimit) {
- print_line("low: "+rtos(m_lowerLimit));
- print_line("hi: "+rtos(m_upperLimit));
- }*/
-
//if (m_lowerLimit < m_upperLimit)
if (m_useLimit && m_lowerLimit <= m_upperLimit) {
//if (hingeAngle <= m_lowerLimit*m_limitSoftness)
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index a06942cb2a..472283833e 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -124,6 +124,13 @@ Variant PhysicsServerSW::shape_get_data(RID p_shape) const {
return shape->get_data();
};
+void PhysicsServerSW::shape_set_margin(RID p_shape, real_t p_margin) {
+}
+
+real_t PhysicsServerSW::shape_get_margin(RID p_shape) const {
+ return 0.0;
+}
+
real_t PhysicsServerSW::shape_get_custom_solver_bias(RID p_shape) const {
const ShapeSW *shape = shape_owner.get(p_shape);
@@ -292,6 +299,7 @@ void PhysicsServerSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) {
area->set_shape(p_shape_idx, shape);
}
+
void PhysicsServerSW::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform) {
AreaSW *area = area_owner.get(p_area);
@@ -701,20 +709,6 @@ real_t PhysicsServerSW::body_get_param(RID p_body, BodyParameter p_param) const
return body->get_param(p_param);
};
-void PhysicsServerSW::body_set_combine_mode(RID p_body, BodyParameter p_param, CombineMode p_mode) {
- BodySW *body = body_owner.get(p_body);
- ERR_FAIL_COND(!body);
-
- body->set_combine_mode(p_param, p_mode);
-}
-
-PhysicsServer::CombineMode PhysicsServerSW::body_get_combine_mode(RID p_body, BodyParameter p_param) const {
- BodySW *body = body_owner.get(p_body);
- ERR_FAIL_COND_V(!body, COMBINE_MODE_INHERIT);
-
- return body->get_combine_mode(p_param);
-}
-
void PhysicsServerSW::body_set_kinematic_safe_margin(RID p_body, real_t p_margin) {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
@@ -955,7 +949,19 @@ 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, bool p_infinite_inertia, MotionResult *r_result) {
+bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result, bool p_exclude_raycast_shapes) {
+
+ 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);
+
+ _update_shapes();
+
+ return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, body->get_kinematic_margin(), r_result, p_exclude_raycast_shapes);
+}
+
+int PhysicsServerSW::body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin) {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, false);
@@ -964,7 +970,7 @@ bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, cons
_update_shapes();
- return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, body->get_kinematic_margin(), r_result);
+ return body->get_space()->test_body_ray_separation(body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin);
}
PhysicsDirectBodyState *PhysicsServerSW::body_get_direct_state(RID p_body) {
diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h
index 57037fb325..4131c5e248 100644
--- a/servers/physics/physics_server_sw.h
+++ b/servers/physics/physics_server_sw.h
@@ -85,6 +85,10 @@ public:
virtual ShapeType shape_get_type(RID p_shape) const;
virtual Variant shape_get_data(RID p_shape) const;
+
+ virtual void shape_set_margin(RID p_shape, real_t p_margin);
+ virtual real_t shape_get_margin(RID p_shape) const;
+
virtual real_t shape_get_custom_solver_bias(RID p_shape) const;
/* SPACE API */
@@ -188,10 +192,6 @@ public:
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;
- /// p_param accept only Bounce and Friction
- virtual void body_set_combine_mode(RID p_body, BodyParameter p_param, CombineMode p_mode);
- virtual CombineMode body_get_combine_mode(RID p_body, BodyParameter p_param) const;
-
virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin);
virtual real_t body_get_kinematic_safe_margin(RID p_body) const;
@@ -234,7 +234,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, bool p_infinite_inertia, MotionResult *r_result = NULL);
+ virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = NULL, bool p_exclude_raycast_shapes = true);
+ virtual int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001);
// this function only works on physics process, errors and returns null otherwise
virtual PhysicsDirectBodyState *body_get_direct_state(RID p_body);
diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp
index b604e5cdf6..b2ab7bec16 100644
--- a/servers/physics/space_sw.cpp
+++ b/servers/physics/space_sw.cpp
@@ -34,12 +34,22 @@
#include "physics_server_sw.h"
#include "project_settings.h"
-_FORCE_INLINE_ static bool _can_collide_with(CollisionObjectSW *p_object, uint32_t p_collision_mask) {
+_FORCE_INLINE_ static bool _can_collide_with(CollisionObjectSW *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
- return p_object->get_collision_layer() & p_collision_mask;
+ if (!(p_object->get_collision_layer() & p_collision_mask)) {
+ return false;
+ }
+
+ if (p_object->get_type() == CollisionObjectSW::TYPE_AREA && !p_collide_with_areas)
+ return false;
+
+ if (p_object->get_type() == CollisionObjectSW::TYPE_BODY && !p_collide_with_bodies)
+ return false;
+
+ return true;
}
-int PhysicsDirectSpaceStateSW::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask) {
+int PhysicsDirectSpaceStateSW::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
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);
@@ -52,7 +62,7 @@ int PhysicsDirectSpaceStateSW::intersect_point(const Vector3 &p_point, ShapeResu
if (cc >= p_result_max)
break;
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
continue;
//area can't be picked by ray (default)
@@ -83,7 +93,7 @@ int PhysicsDirectSpaceStateSW::intersect_point(const Vector3 &p_point, ShapeResu
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_mask, bool p_pick_ray) {
+bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_ray) {
ERR_FAIL_COND_V(space->locked, false);
@@ -105,7 +115,7 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vecto
for (int i = 0; i < amount; i++) {
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
continue;
if (p_pick_ray && !(static_cast<CollisionObjectSW *>(space->intersection_query_results[i])->is_ray_pickable()))
@@ -161,7 +171,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_collision_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_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
if (p_result_max <= 0)
return 0;
@@ -182,7 +192,7 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transfo
if (cc >= p_result_max)
break;
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
continue;
//area can't be picked by ray (default)
@@ -212,7 +222,7 @@ 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_collision_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_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) {
ShapeSW *shape = static_cast<PhysicsServerSW *>(PhysicsServer::get_singleton())->shape_owner.get(p_shape);
ERR_FAIL_COND_V(!shape, false);
@@ -221,11 +231,6 @@ bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform
aabb = aabb.merge(AABB(aabb.position + p_motion, aabb.size)); //motion
aabb = aabb.grow(p_margin);
- /*
- if (p_motion!=Vector3())
- print_line(p_motion);
- */
-
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, SpaceSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
real_t best_safe = 1;
@@ -242,7 +247,7 @@ bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform
for (int i = 0; i < amount; i++) {
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
continue;
if (p_exclude.has(space->intersection_query_results[i]->get_self()))
@@ -257,7 +262,6 @@ bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform
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, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, aabb, &sep_axis)) {
- //print_line("failed motion cast (no collision)");
continue;
}
@@ -265,7 +269,6 @@ bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform
sep_axis = p_motion.normalized();
if (!CollisionSolverSW::solve_distance(shape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, aabb, &sep_axis)) {
- //print_line("failed motion cast (no collision)");
return false;
}
@@ -288,7 +291,6 @@ bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform
if (collided) {
- //print_line(itos(i)+": "+rtos(ofs));
hi = ofs;
} else {
@@ -326,7 +328,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_collision_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_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
if (p_result_max <= 0)
return 0;
@@ -356,7 +358,7 @@ bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform &p_sh
for (int i = 0; i < amount; i++) {
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
continue;
const CollisionObjectSW *col_obj = space->intersection_query_results[i];
@@ -366,9 +368,6 @@ bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform &p_sh
continue;
}
- //print_line("AGAINST: "+itos(col_obj->get_self().get_id())+":"+itos(shape_idx));
- //print_line("THE ABBB: "+(col_obj->get_transform() * col_obj->get_shape_transform(shape_idx)).xform(col_obj->get_shape(shape_idx)->get_aabb()));
-
if (CollisionSolverSW::solve_static(shape, p_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 = true;
}
@@ -405,7 +404,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_collision_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_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
ShapeSW *shape = static_cast<PhysicsServerSW *>(PhysicsServer::get_singleton())->shape_owner.get(p_shape);
ERR_FAIL_COND_V(!shape, 0);
@@ -422,7 +421,7 @@ bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_
for (int i = 0; i < amount; i++) {
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
continue;
const CollisionObjectSW *col_obj = space->intersection_query_results[i];
@@ -541,7 +540,144 @@ int SpaceSW::_cull_aabb_for_body(BodySW *p_body, const AABB &p_aabb) {
return amount;
}
-bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer::MotionResult *r_result) {
+int SpaceSW::test_body_ray_separation(BodySW *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer::SeparationResult *r_results, int p_result_max, real_t p_margin) {
+
+ AABB 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_transform.xform(p_body->get_inv_transform().xform(body_aabb));
+ body_aabb = body_aabb.grow(p_margin);
+
+ Transform body_transform = p_transform;
+
+ for (int i = 0; i < p_result_max; i++) {
+ //reset results
+ r_results[i].collision_depth = 0;
+ }
+
+ int rays_found = 0;
+
+ {
+ // raycast AND separate
+
+ const int max_results = 32;
+ int recover_attempts = 4;
+ Vector3 sr[max_results * 2];
+ PhysicsServerSW::CollCbkData cbk;
+ cbk.max = max_results;
+ PhysicsServerSW::CollCbkData *cbkptr = &cbk;
+ CollisionSolverSW::CallbackResult cbkres = PhysicsServerSW::_shape_col_cbk;
+
+ do {
+
+ Vector3 recover_motion;
+
+ bool collided = false;
+
+ int amount = _cull_aabb_for_body(p_body, body_aabb);
+ int ray_index = 0;
+
+ for (int j = 0; j < p_body->get_shape_count(); j++) {
+ if (p_body->is_shape_set_as_disabled(j))
+ continue;
+
+ ShapeSW *body_shape = p_body->get_shape(j);
+
+ if (body_shape->get_type() != PhysicsServer::SHAPE_RAY)
+ continue;
+
+ Transform body_shape_xform = body_transform * p_body->get_shape_transform(j);
+
+ for (int i = 0; i < amount; i++) {
+
+ const CollisionObjectSW *col_obj = intersection_query_results[i];
+ int shape_idx = intersection_query_subindex_results[i];
+
+ cbk.amount = 0;
+ cbk.ptr = sr;
+
+ if (CollisionObjectSW::TYPE_BODY == col_obj->get_type()) {
+ const BodySW *b = static_cast<const BodySW *>(col_obj);
+ if (p_infinite_inertia && PhysicsServer::BODY_MODE_STATIC != b->get_mode() && PhysicsServer::BODY_MODE_KINEMATIC != b->get_mode()) {
+ continue;
+ }
+ }
+
+ ShapeSW *against_shape = col_obj->get_shape(shape_idx);
+ if (CollisionSolverSW::solve_static(body_shape, body_shape_xform, against_shape, col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, NULL, p_margin)) {
+ if (cbk.amount > 0) {
+ collided = true;
+ }
+
+ if (ray_index < p_result_max) {
+ PhysicsServer::SeparationResult &result = r_results[ray_index];
+
+ for (int k = 0; k < cbk.amount; k++) {
+ Vector3 a = sr[k * 2 + 0];
+ Vector3 b = sr[k * 2 + 1];
+
+ recover_motion += (b - a) * 0.4;
+
+ float depth = a.distance_to(b);
+ if (depth > result.collision_depth) {
+
+ result.collision_depth = depth;
+ result.collision_point = b;
+ result.collision_normal = (b - a).normalized();
+ result.collision_local_shape = shape_idx;
+ result.collider = col_obj->get_self();
+ result.collider_id = col_obj->get_instance_id();
+ //result.collider_metadata = col_obj->get_shape_metadata(shape_idx);
+ if (col_obj->get_type() == CollisionObjectSW::TYPE_BODY) {
+ BodySW *body = (BodySW *)col_obj;
+
+ Vector3 rel_vec = b - body->get_transform().get_origin();
+ //result.collider_velocity = Vector3(-body->get_angular_velocity() * rel_vec.y, body->get_angular_velocity() * rel_vec.x) + body->get_linear_velocity();
+ result.collider_velocity = body->get_linear_velocity() + (body->get_angular_velocity()).cross(body->get_transform().origin - rel_vec); // * mPos);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ray_index++;
+ }
+
+ rays_found = MAX(ray_index, rays_found);
+
+ if (!collided || recover_motion == Vector3()) {
+ break;
+ }
+
+ body_transform.origin += recover_motion;
+ body_aabb.position += recover_motion;
+
+ recover_attempts--;
+ } while (recover_attempts);
+ }
+
+ //optimize results (remove non colliding)
+ for (int i = 0; i < rays_found; i++) {
+ if (r_results[i].collision_depth == 0) {
+ rays_found--;
+ SWAP(r_results[i], r_results[rays_found]);
+ }
+ }
+
+ r_recover_motion = body_transform.origin - p_transform.origin;
+ return rays_found;
+}
+
+bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer::MotionResult *r_result, bool p_exclude_raycast_shapes) {
//give me back regular physics engine logic
//this is madness
@@ -597,6 +733,10 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve
Transform body_shape_xform = body_transform * p_body->get_shape_transform(j);
ShapeSW *body_shape = p_body->get_shape(j);
+ if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer::SHAPE_RAY) {
+ continue;
+ }
+
for (int i = 0; i < amount; i++) {
const CollisionObjectSW *col_obj = intersection_query_results[i];
@@ -655,6 +795,10 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve
Transform body_shape_xform = body_transform * p_body->get_shape_transform(j);
ShapeSW *body_shape = p_body->get_shape(j);
+ if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer::SHAPE_RAY) {
+ continue;
+ }
+
Transform body_shape_xform_inv = body_shape_xform.affine_inverse();
MotionShapeSW mshape;
mshape.shape = body_shape;
@@ -677,13 +821,11 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve
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;
}
@@ -707,7 +849,6 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve
if (collided) {
- //print_line(itos(i)+": "+rtos(ofs));
hi = ofs;
} else {
diff --git a/servers/physics/space_sw.h b/servers/physics/space_sw.h
index 4d864e9a51..e7231df532 100644
--- a/servers/physics/space_sw.h
+++ b/servers/physics/space_sw.h
@@ -48,12 +48,12 @@ class PhysicsDirectSpaceStateSW : public PhysicsDirectSpaceState {
public:
SpaceSW *space;
- 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_mask = 0xFFFFFFFF);
- 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_mask = 0xFFFFFFFF, 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_mask = 0xFFFFFFFF);
- 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_mask = 0xFFFFFFFF, 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_mask = 0xFFFFFFFF);
- 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_mask = 0xFFFFFFFF);
+ 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
+ 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
+ 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
+ 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const;
PhysicsDirectSpaceStateSW();
@@ -197,7 +197,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, bool p_infinite_inertia, real_t p_margin, PhysicsServer::MotionResult *r_result);
+ int test_body_ray_separation(BodySW *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer::SeparationResult *r_results, int p_result_max, real_t p_margin);
+ bool test_body_motion(BodySW *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer::MotionResult *r_result, bool p_exclude_raycast_shapes);
SpaceSW();
~SpaceSW();
diff --git a/servers/physics/step_sw.cpp b/servers/physics/step_sw.cpp
index ad08cb6353..4128e1ec1a 100644
--- a/servers/physics/step_sw.cpp
+++ b/servers/physics/step_sw.cpp
@@ -228,7 +228,6 @@ void StepSW::step(SpaceSW *p_space, real_t p_delta, int p_iterations) {
profile_begtime = profile_endtime;
}
- //print_line("island count: "+itos(island_count)+" active count: "+itos(active_count));
/* SETUP CONSTRAINT ISLANDS */
{
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index fcd2a65ee7..aa063d6c1e 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -405,22 +405,6 @@ void Body2DSW::_compute_area_gravity_and_dampenings(const Area2DSW *p_area) {
area_angular_damp += p_area->get_angular_damp();
}
-void Body2DSW::set_combine_mode(Physics2DServer::BodyParameter p_param, Physics2DServer::CombineMode p_mode) {
- if (p_param == Physics2DServer::BODY_PARAM_BOUNCE) {
- bounce_combine_mode = p_mode;
- } else {
- friction_combine_mode = p_mode;
- }
-}
-
-Physics2DServer::CombineMode Body2DSW::get_combine_mode(Physics2DServer::BodyParameter p_param) const {
- if (p_param == Physics2DServer::BODY_PARAM_BOUNCE) {
- return bounce_combine_mode;
- } else {
- return friction_combine_mode;
- }
-}
-
void Body2DSW::integrate_forces(real_t p_step) {
if (mode == Physics2DServer::BODY_MODE_STATIC)
diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h
index fef233a72b..69184ad484 100644
--- a/servers/physics_2d/body_2d_sw.h
+++ b/servers/physics_2d/body_2d_sw.h
@@ -54,8 +54,6 @@ class Body2DSW : public CollisionObject2DSW {
real_t mass;
real_t bounce;
real_t friction;
- Physics2DServer::CombineMode bounce_combine_mode;
- Physics2DServer::CombineMode friction_combine_mode;
real_t _inv_mass;
real_t _inv_inertia;
@@ -274,12 +272,6 @@ public:
_FORCE_INLINE_ real_t get_linear_damp() const { return linear_damp; }
_FORCE_INLINE_ real_t get_angular_damp() const { return angular_damp; }
- void set_combine_mode(Physics2DServer::BodyParameter p_param, Physics2DServer::CombineMode p_mode);
- Physics2DServer::CombineMode get_combine_mode(Physics2DServer::BodyParameter p_param) const;
-
- _FORCE_INLINE_ Physics2DServer::CombineMode get_bounce_combine_mode() const { return bounce_combine_mode; }
- _FORCE_INLINE_ Physics2DServer::CombineMode get_friction_combine_mode() const { return friction_combine_mode; }
-
void integrate_forces(real_t p_step);
void integrate_velocities(real_t p_step);
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index be8dcf6fa8..2633edf7bb 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -220,41 +220,11 @@ bool BodyPair2DSW::_test_ccd(real_t p_step, Body2DSW *p_A, int p_shape_A, const
}
real_t combine_bounce(Body2DSW *A, Body2DSW *B) {
- const Physics2DServer::CombineMode cm = A->get_bounce_combine_mode();
-
- switch (cm) {
- case Physics2DServer::COMBINE_MODE_INHERIT:
- if (B->get_bounce_combine_mode() != Physics2DServer::COMBINE_MODE_INHERIT)
- return combine_bounce(B, A);
- // else use MAX [This is used when the two bodies doesn't use physical material]
- case Physics2DServer::COMBINE_MODE_MAX:
- return MAX(A->get_bounce(), B->get_bounce());
- case Physics2DServer::COMBINE_MODE_MIN:
- return MIN(A->get_bounce(), B->get_bounce());
- case Physics2DServer::COMBINE_MODE_MULTIPLY:
- return A->get_bounce() * B->get_bounce();
- default: // Is always Physics2DServer::COMBINE_MODE_AVERAGE:
- return (A->get_bounce() + B->get_bounce()) / 2;
- }
+ return CLAMP(A->get_bounce() + B->get_bounce(), 0, 1);
}
real_t combine_friction(Body2DSW *A, Body2DSW *B) {
- const Physics2DServer::CombineMode cm = A->get_friction_combine_mode();
-
- switch (cm) {
- case Physics2DServer::COMBINE_MODE_INHERIT:
- if (B->get_friction_combine_mode() != Physics2DServer::COMBINE_MODE_INHERIT)
- return combine_friction(B, A);
- // else use Multiply [This is used when the two bodies doesn't use physical material]
- case Physics2DServer::COMBINE_MODE_MULTIPLY:
- return A->get_friction() * B->get_friction();
- case Physics2DServer::COMBINE_MODE_MAX:
- return MAX(A->get_friction(), B->get_friction());
- case Physics2DServer::COMBINE_MODE_MIN:
- return MIN(A->get_friction(), B->get_friction());
- default: // Is always Physics2DServer::COMBINE_MODE_AVERAGE:
- return (A->get_friction() + B->get_friction()) / 2;
- }
+ return ABS(MIN(A->get_friction(), B->get_friction()));
}
bool BodyPair2DSW::setup(real_t p_step) {
diff --git a/servers/physics_2d/broad_phase_2d_sw.h b/servers/physics_2d/broad_phase_2d_sw.h
index 80ae970624..d7d236c4c6 100644
--- a/servers/physics_2d/broad_phase_2d_sw.h
+++ b/servers/physics_2d/broad_phase_2d_sw.h
@@ -31,8 +31,8 @@
#ifndef BROAD_PHASE_2D_SW_H
#define BROAD_PHASE_2D_SW_H
-#include "math_2d.h"
#include "math_funcs.h"
+#include "rect2.h"
class CollisionObject2DSW;
diff --git a/servers/physics_2d/collision_solver_2d_sat.cpp b/servers/physics_2d/collision_solver_2d_sat.cpp
index 0d1ffca50d..98fe4adb80 100644
--- a/servers/physics_2d/collision_solver_2d_sat.cpp
+++ b/servers/physics_2d/collision_solver_2d_sat.cpp
@@ -300,7 +300,6 @@ public:
}
}
-//print_line("test axis: "+p_axis+" depth: "+rtos(best_depth));
#ifdef DEBUG_ENABLED
best_axis_count++;
#endif
diff --git a/servers/physics_2d/collision_solver_2d_sw.cpp b/servers/physics_2d/collision_solver_2d_sw.cpp
index 6ce019f36e..b03a193d97 100644
--- a/servers/physics_2d/collision_solver_2d_sw.cpp
+++ b/servers/physics_2d/collision_solver_2d_sw.cpp
@@ -114,35 +114,6 @@ bool CollisionSolver2DSW::solve_raycast(const Shape2DSW *p_shape_A, const Vector
return true;
}
-/*
-bool CollisionSolver2DSW::solve_ray(const Shape2DSW *p_shape_A,const Matrix32& p_transform_A,const Shape2DSW *p_shape_B,const Matrix32& p_transform_B,const Matrix32& p_inverse_B,CallbackResult p_result_callback,void *p_userdata,bool p_swap_result) {
-
-
- const RayShape2DSW *ray = static_cast<const RayShape2DSW*>(p_shape_A);
-
- Vector2 from = p_transform_A.origin;
- Vector2 to = from+p_transform_A.basis.get_axis(2)*ray->get_length();
- Vector2 support_A=to;
-
- from = p_inverse_B.xform(from);
- to = p_inverse_B.xform(to);
-
- Vector2 p,n;
- if (!p_shape_B->intersect_segment(from,to,&p,&n))
- return false;
-
- Vector2 support_B=p_transform_B.xform(p);
-
- if (p_result_callback) {
- if (p_swap_result)
- p_result_callback(support_B,support_A,p_userdata);
- else
- p_result_callback(support_A,support_B,p_userdata);
- }
- return true;
-}
-*/
-
struct _ConcaveCollisionInfo2D {
const Transform2D *transform_A;
@@ -219,7 +190,6 @@ bool CollisionSolver2DSW::solve_concave(const Shape2DSW *p_shape_A, const Transf
concave_B->cull(local_aabb, concave_callback, &cinfo);
- //print_line("Rect2 TESTS: "+itos(cinfo.aabb_tests));
return cinfo.collided;
}
@@ -245,10 +215,6 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p
if (type_B == Physics2DServer::SHAPE_LINE || type_B == Physics2DServer::SHAPE_RAY) {
return false;
}
- /*
- if (type_B==Physics2DServer::SHAPE_RAY) {
- return false;
- */
if (swap) {
return solve_static_line(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true);
@@ -256,17 +222,6 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p
return solve_static_line(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false);
}
- /*} else if (type_A==Physics2DServer::SHAPE_RAY) {
-
- if (type_B==Physics2DServer::SHAPE_RAY)
- return false;
-
- if (swap) {
- return solve_ray(p_shape_B,p_transform_B,p_shape_A,p_transform_A,p_inverse_A,p_result_callback,p_userdata,true);
- } else {
- return solve_ray(p_shape_A,p_transform_A,p_shape_B,p_transform_B,p_inverse_B,p_result_callback,p_userdata,false);
- }
-*/
} else if (type_A == Physics2DServer::SHAPE_RAY) {
if (type_B == Physics2DServer::SHAPE_RAY) {
diff --git a/servers/physics_2d/joints_2d_sw.cpp b/servers/physics_2d/joints_2d_sw.cpp
index d49c1b8376..517dce0043 100644
--- a/servers/physics_2d/joints_2d_sw.cpp
+++ b/servers/physics_2d/joints_2d_sw.cpp
@@ -321,7 +321,7 @@ void GrooveJoint2DSW::solve(real_t p_step) {
Vector2 jOld = jn_acc;
j += jOld;
- jn_acc = (((clamp * j.cross(xf_normal)) > 0) ? j : xf_normal.project(j)).clamped(jn_max);
+ jn_acc = (((clamp * j.cross(xf_normal)) > 0) ? j : j.project(xf_normal)).clamped(jn_max);
j = jn_acc - jOld;
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index ba87969eea..721f21fc40 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -171,13 +171,14 @@ void Physics2DServerSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 &
}
if (cbk->valid_dir.dot((p_point_A - p_point_B).normalized()) < 0.7071) {
cbk->invalid_by_dir++;
- ;
- /* print_line("A: "+p_point_A);
+
+ /*
+ print_line("A: "+p_point_A);
print_line("B: "+p_point_B);
print_line("discard too angled "+rtos(cbk->valid_dir.dot((p_point_A-p_point_B))));
print_line("resnorm: "+(p_point_A-p_point_B).normalized());
print_line("distance: "+rtos(p_point_A.distance_to(p_point_B)));
-*/
+ */
return;
}
}
@@ -789,22 +790,6 @@ real_t Physics2DServerSW::body_get_param(RID p_body, BodyParameter p_param) cons
return body->get_param(p_param);
};
-void Physics2DServerSW::body_set_combine_mode(RID p_body, BodyParameter p_param, CombineMode p_mode) {
-
- Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND(!body);
-
- body->set_combine_mode(p_param, p_mode);
-}
-
-Physics2DServer::CombineMode Physics2DServerSW::body_get_combine_mode(RID p_body, BodyParameter p_param) const {
-
- Body2DSW *body = body_owner.get(p_body);
- ERR_FAIL_COND_V(!body, COMBINE_MODE_INHERIT);
-
- return body->get_combine_mode(p_param);
-}
-
void Physics2DServerSW::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {
Body2DSW *body = body_owner.get(p_body);
diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h
index 0b8d3f2a31..d4fc44b1d7 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -200,10 +200,6 @@ public:
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;
- /// p_param accept only Bounce and Friction
- virtual void body_set_combine_mode(RID p_body, BodyParameter p_param, CombineMode p_mode);
- virtual CombineMode body_get_combine_mode(RID p_body, BodyParameter p_param) const;
-
virtual void body_set_state(RID p_body, BodyState p_state, const Variant &p_variant);
virtual Variant body_get_state(RID p_body, BodyState p_state) const;
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h
index b9b0f80805..6b34fb9739 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.h
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.h
@@ -211,9 +211,6 @@ public:
FUNC3(body_set_param, RID, BodyParameter, real_t);
FUNC2RC(real_t, body_get_param, RID, BodyParameter);
- FUNC3(body_set_combine_mode, RID, BodyParameter, CombineMode);
- FUNC2RC(CombineMode, body_get_combine_mode, RID, BodyParameter);
-
FUNC3(body_set_state, RID, BodyState, const Variant &);
FUNC2RC(Variant, body_get_state, RID, BodyState);
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index 6e45951f42..746aa2d49b 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -34,12 +34,22 @@
#include "pair.h"
#include "physics_2d_server_sw.h"
-_FORCE_INLINE_ static bool _can_collide_with(CollisionObject2DSW *p_object, uint32_t p_collision_mask) {
+_FORCE_INLINE_ static bool _can_collide_with(CollisionObject2DSW *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
- return p_object->get_collision_layer() & p_collision_mask;
+ if (!(p_object->get_collision_layer() & p_collision_mask)) {
+ return false;
+ }
+
+ if (p_object->get_type() == CollisionObject2DSW::TYPE_AREA && !p_collide_with_areas)
+ return false;
+
+ if (p_object->get_type() == CollisionObject2DSW::TYPE_BODY && !p_collide_with_bodies)
+ return false;
+
+ return true;
}
-int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_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_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point) {
if (p_result_max <= 0)
return 0;
@@ -54,7 +64,7 @@ int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeRe
for (int i = 0; i < amount; i++) {
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
continue;
if (p_exclude.has(space->intersection_query_results[i]->get_self()))
@@ -90,7 +100,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_collision_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_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
ERR_FAIL_COND_V(space->locked, false);
@@ -112,7 +122,7 @@ bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vec
for (int i = 0; i < amount; i++) {
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
continue;
if (p_exclude.has(space->intersection_query_results[i]->get_self()))
@@ -170,7 +180,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_collision_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_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
if (p_result_max <= 0)
return 0;
@@ -190,7 +200,7 @@ int Physics2DDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Trans
if (cc >= p_result_max)
break;
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
continue;
if (p_exclude.has(space->intersection_query_results[i]->get_self()))
@@ -215,7 +225,7 @@ 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_collision_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_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
Shape2DSW *shape = Physics2DServerSW::singletonsw->shape_owner.get(p_shape);
ERR_FAIL_COND_V(!shape, false);
@@ -224,11 +234,6 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transfor
aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion
aabb = aabb.grow(p_margin);
- /*
- if (p_motion!=Vector2())
- print_line(p_motion);
- */
-
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
real_t best_safe = 1;
@@ -236,7 +241,7 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transfor
for (int i = 0; i < amount; i++) {
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
continue;
if (p_exclude.has(space->intersection_query_results[i]->get_self()))
@@ -245,15 +250,6 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transfor
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
- /*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() && p_motion.dot(body->get_one_way_collision_direction())<=CMP_EPSILON) {
- print_line("failed in motion dir");
- continue;
- }
- }*/
-
Transform2D 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 (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), NULL, NULL, NULL, p_margin)) {
@@ -299,7 +295,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_collision_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_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
if (p_result_max <= 0)
return 0;
@@ -330,7 +326,7 @@ bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &
for (int i = 0; i < amount; i++) {
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
continue;
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
@@ -388,7 +384,7 @@ 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_collision_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_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
Shape2DSW *shape = Physics2DServerSW::singletonsw->shape_owner.get(p_shape);
ERR_FAIL_COND_V(!shape, 0);
@@ -406,7 +402,7 @@ bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_sh
for (int i = 0; i < amount; i++) {
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
continue;
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h
index 1247317b03..6e2e025185 100644
--- a/servers/physics_2d/space_2d_sw.h
+++ b/servers/physics_2d/space_2d_sw.h
@@ -48,12 +48,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_collision_mask = 0xFFFFFFFF, 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_mask = 0xFFFFFFFF);
- 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_mask = 0xFFFFFFFF);
- 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_mask = 0xFFFFFFFF);
- 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_mask = 0xFFFFFFFF);
- 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_mask = 0xFFFFFFFF);
+ 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
+ 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
+ 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
+ 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
+ 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
Physics2DDirectSpaceStateSW();
};
diff --git a/servers/physics_2d/step_2d_sw.cpp b/servers/physics_2d/step_2d_sw.cpp
index 6108b885f0..d1078f1506 100644
--- a/servers/physics_2d/step_2d_sw.cpp
+++ b/servers/physics_2d/step_2d_sw.cpp
@@ -209,8 +209,6 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) {
p_space->area_remove_from_moved_list((SelfList<Area2DSW> *)aml.first()); //faster to remove here
}
- //print_line("island count: "+itos(island_count)+" active count: "+itos(active_count));
-
{ //profile
profile_endtime = OS::get_singleton()->get_ticks_usec();
p_space->set_elapsed_time(Space2DSW::ELAPSED_TIME_GENERATE_ISLANDS, profile_endtime - profile_begtime);
diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp
index 37c4bc83ad..a51b938541 100644
--- a/servers/physics_2d_server.cpp
+++ b/servers/physics_2d_server.cpp
@@ -203,6 +203,22 @@ Vector<RID> Physics2DShapeQueryParameters::get_exclude() const {
return ret;
}
+void Physics2DShapeQueryParameters::set_collide_with_bodies(bool p_enable) {
+ collide_with_bodies = p_enable;
+}
+
+bool Physics2DShapeQueryParameters::is_collide_with_bodies_enabled() const {
+ return collide_with_bodies;
+}
+
+void Physics2DShapeQueryParameters::set_collide_with_areas(bool p_enable) {
+ collide_with_areas = p_enable;
+}
+
+bool Physics2DShapeQueryParameters::is_collide_with_areas_enabled() const {
+ return collide_with_areas;
+}
+
void Physics2DShapeQueryParameters::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shape", "shape"), &Physics2DShapeQueryParameters::set_shape);
@@ -224,6 +240,12 @@ void Physics2DShapeQueryParameters::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_exclude", "exclude"), &Physics2DShapeQueryParameters::set_exclude);
ClassDB::bind_method(D_METHOD("get_exclude"), &Physics2DShapeQueryParameters::get_exclude);
+ ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &Physics2DShapeQueryParameters::set_collide_with_bodies);
+ ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &Physics2DShapeQueryParameters::is_collide_with_bodies_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_collide_with_areas", "enable"), &Physics2DShapeQueryParameters::set_collide_with_areas);
+ ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &Physics2DShapeQueryParameters::is_collide_with_areas_enabled);
+
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_NONE, itos(Variant::_RID) + ":"), "set_exclude", "get_exclude");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_margin", "get_margin");
@@ -231,22 +253,26 @@ void Physics2DShapeQueryParameters::_bind_methods() {
//ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", ""); // FIXME: Lacks a getter
ADD_PROPERTY(PropertyInfo(Variant::_RID, "shape_rid"), "set_shape_rid", "get_shape_rid");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform"), "set_transform", "get_transform");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies"), "set_collide_with_bodies", "is_collide_with_bodies_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas"), "set_collide_with_areas", "is_collide_with_areas_enabled");
}
Physics2DShapeQueryParameters::Physics2DShapeQueryParameters() {
margin = 0;
collision_mask = 0x7FFFFFFF;
+ collide_with_bodies = true;
+ collide_with_areas = false;
}
-Dictionary Physics2DDirectSpaceState::_intersect_ray(const Vector2 &p_from, const Vector2 &p_to, const Vector<RID> &p_exclude, uint32_t p_layers) {
+Dictionary Physics2DDirectSpaceState::_intersect_ray(const Vector2 &p_from, const Vector2 &p_to, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas) {
RayResult inters;
Set<RID> exclude;
for (int i = 0; i < p_exclude.size(); i++)
exclude.insert(p_exclude[i]);
- bool res = intersect_ray(p_from, p_to, inters, exclude, p_layers);
+ bool res = intersect_ray(p_from, p_to, inters, exclude, p_layers, p_collide_with_bodies, p_collide_with_areas);
if (!res)
return Dictionary();
@@ -267,7 +293,7 @@ Array Physics2DDirectSpaceState::_intersect_shape(const Ref<Physics2DShapeQueryP
Vector<ShapeResult> sr;
sr.resize(p_max_results);
- int rc = intersect_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, sr.ptrw(), sr.size(), p_shape_query->exclude, p_shape_query->collision_mask);
+ int rc = intersect_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, sr.ptrw(), sr.size(), p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
Array ret;
ret.resize(rc);
for (int i = 0; i < rc; i++) {
@@ -287,7 +313,7 @@ Array Physics2DDirectSpaceState::_intersect_shape(const Ref<Physics2DShapeQueryP
Array Physics2DDirectSpaceState::_cast_motion(const Ref<Physics2DShapeQueryParameters> &p_shape_query) {
float closest_safe, closest_unsafe;
- 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_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_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
if (!res)
return Array();
Array ret;
@@ -297,7 +323,7 @@ Array Physics2DDirectSpaceState::_cast_motion(const Ref<Physics2DShapeQueryParam
return ret;
}
-Array Physics2DDirectSpaceState::_intersect_point(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclude, uint32_t p_layers) {
+Array Physics2DDirectSpaceState::_intersect_point(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas) {
Set<RID> exclude;
for (int i = 0; i < p_exclude.size(); i++)
@@ -306,7 +332,7 @@ Array Physics2DDirectSpaceState::_intersect_point(const Vector2 &p_point, int p_
Vector<ShapeResult> ret;
ret.resize(p_max_results);
- int rc = intersect_point(p_point, ret.ptrw(), ret.size(), exclude, p_layers);
+ int rc = intersect_point(p_point, ret.ptrw(), ret.size(), exclude, p_layers, p_collide_with_bodies, p_collide_with_areas);
if (rc == 0)
return Array();
@@ -330,7 +356,7 @@ Array Physics2DDirectSpaceState::_collide_shape(const Ref<Physics2DShapeQueryPar
Vector<Vector2> ret;
ret.resize(p_max_results * 2);
int rc = 0;
- bool res = collide_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, ret.ptrw(), p_max_results, rc, p_shape_query->exclude, p_shape_query->collision_mask);
+ bool res = collide_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, ret.ptrw(), p_max_results, rc, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
if (!res)
return Array();
Array r;
@@ -343,7 +369,7 @@ Dictionary Physics2DDirectSpaceState::_get_rest_info(const Ref<Physics2DShapeQue
ShapeRestInfo sri;
- 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_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_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
Dictionary r;
if (!res)
return r;
@@ -364,8 +390,8 @@ Physics2DDirectSpaceState::Physics2DDirectSpaceState() {
void Physics2DDirectSpaceState::_bind_methods() {
- ClassDB::bind_method(D_METHOD("intersect_point", "point", "max_results", "exclude", "collision_layer"), &Physics2DDirectSpaceState::_intersect_point, DEFVAL(32), DEFVAL(Array()), DEFVAL(0x7FFFFFFF));
- ClassDB::bind_method(D_METHOD("intersect_ray", "from", "to", "exclude", "collision_layer"), &Physics2DDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF));
+ ClassDB::bind_method(D_METHOD("intersect_point", "point", "max_results", "exclude", "collision_layer", "collide_with_bodies", "collide_with_areas"), &Physics2DDirectSpaceState::_intersect_point, DEFVAL(32), DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(true), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("intersect_ray", "from", "to", "exclude", "collision_layer", "collide_with_bodies", "collide_with_areas"), &Physics2DDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(true), DEFVAL(false));
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));
diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h
index 796eec1e8e..82b4eb75d8 100644
--- a/servers/physics_2d_server.h
+++ b/servers/physics_2d_server.h
@@ -107,6 +107,9 @@ class Physics2DShapeQueryParameters : public Reference {
Set<RID> exclude;
uint32_t collision_mask;
+ bool collide_with_bodies;
+ bool collide_with_areas;
+
protected:
static void _bind_methods();
@@ -127,6 +130,12 @@ public:
void set_collision_mask(int p_collision_mask);
int get_collision_mask() const;
+ void set_collide_with_bodies(bool p_enable);
+ bool is_collide_with_bodies_enabled() const;
+
+ void set_collide_with_areas(bool p_enable);
+ bool is_collide_with_areas_enabled() const;
+
void set_exclude(const Vector<RID> &p_exclude);
Vector<RID> get_exclude() const;
@@ -137,9 +146,9 @@ class Physics2DDirectSpaceState : public Object {
GDCLASS(Physics2DDirectSpaceState, Object);
- Dictionary _intersect_ray(const Vector2 &p_from, const Vector2 &p_to, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0);
+ Dictionary _intersect_ray(const Vector2 &p_from, const Vector2 &p_to, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
- Array _intersect_point(const Vector2 &p_point, int p_max_results = 32, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0);
+ Array _intersect_point(const Vector2 &p_point, int p_max_results = 32, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
Array _intersect_shape(const Ref<Physics2DShapeQueryParameters> &p_shape_query, int p_max_results = 32);
Array _cast_motion(const Ref<Physics2DShapeQueryParameters> &p_shape_query);
Array _collide_shape(const Ref<Physics2DShapeQueryParameters> &p_shape_query, int p_max_results = 32);
@@ -160,7 +169,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_collision_layer = 0xFFFFFFFF) = 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, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
struct ShapeResult {
@@ -171,13 +180,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_collision_layer = 0xFFFFFFFF, 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, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, 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_collision_layer = 0xFFFFFFFF) = 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, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 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) = 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, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 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) = 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, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
struct ShapeRestInfo {
@@ -190,7 +199,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_collision_layer = 0xFFFFFFFF) = 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, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
Physics2DDirectSpaceState();
};
@@ -423,19 +432,6 @@ public:
virtual void body_set_param(RID p_body, BodyParameter p_param, float p_value) = 0;
virtual float body_get_param(RID p_body, BodyParameter p_param) const = 0;
- enum CombineMode {
- COMBINE_MODE_MAX,
- COMBINE_MODE_MIN,
- COMBINE_MODE_MULTIPLY,
- COMBINE_MODE_AVERAGE,
-
- COMBINE_MODE_INHERIT /// Inherit from other body or use COMBINE_MODE_MAX (Restitution) COMBINE_MODE_MULTIPLY (Friction)
- };
-
- /// p_param accept only Bounce and Friction
- virtual void body_set_combine_mode(RID p_body, BodyParameter p_param, CombineMode p_mode) = 0;
- virtual CombineMode body_get_combine_mode(RID p_body, BodyParameter p_param) const = 0;
-
//state
enum BodyState {
BODY_STATE_TRANSFORM,
diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp
index cda3856ecc..deb3cd9bbe 100644
--- a/servers/physics_server.cpp
+++ b/servers/physics_server.cpp
@@ -29,7 +29,9 @@
/*************************************************************************/
#include "physics_server.h"
+
#include "core/project_settings.h"
+#include "method_bind_ext.gen.inc"
#include "print_string.h"
PhysicsServer *PhysicsServer::singleton = NULL;
@@ -198,6 +200,22 @@ Vector<RID> PhysicsShapeQueryParameters::get_exclude() const {
return ret;
}
+void PhysicsShapeQueryParameters::set_collide_with_bodies(bool p_enable) {
+ collide_with_bodies = p_enable;
+}
+
+bool PhysicsShapeQueryParameters::is_collide_with_bodies_enabled() const {
+ return collide_with_bodies;
+}
+
+void PhysicsShapeQueryParameters::set_collide_with_areas(bool p_enable) {
+ collide_with_areas = p_enable;
+}
+
+bool PhysicsShapeQueryParameters::is_collide_with_areas_enabled() const {
+ return collide_with_areas;
+}
+
void PhysicsShapeQueryParameters::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsShapeQueryParameters::set_shape);
@@ -216,18 +234,28 @@ void PhysicsShapeQueryParameters::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_exclude", "exclude"), &PhysicsShapeQueryParameters::set_exclude);
ClassDB::bind_method(D_METHOD("get_exclude"), &PhysicsShapeQueryParameters::get_exclude);
+ ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &PhysicsShapeQueryParameters::set_collide_with_bodies);
+ ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &PhysicsShapeQueryParameters::is_collide_with_bodies_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_collide_with_areas", "enable"), &PhysicsShapeQueryParameters::set_collide_with_areas);
+ ClassDB::bind_method(D_METHOD("is_collide_with_areas_enabled"), &PhysicsShapeQueryParameters::is_collide_with_areas_enabled);
+
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_NONE, itos(Variant::_RID) + ":"), "set_exclude", "get_exclude");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "margin", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_margin", "get_margin");
//ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", ""); // FIXME: Lacks a getter
ADD_PROPERTY(PropertyInfo(Variant::_RID, "shape_rid"), "set_shape_rid", "get_shape_rid");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform"), "set_transform", "get_transform");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies"), "set_collide_with_bodies", "is_collide_with_bodies_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas"), "set_collide_with_areas", "is_collide_with_areas_enabled");
}
PhysicsShapeQueryParameters::PhysicsShapeQueryParameters() {
margin = 0;
collision_mask = 0x7FFFFFFF;
+ collide_with_bodies = true;
+ collide_with_areas = false;
}
/////////////////////////////////////
@@ -262,14 +290,14 @@ Variant PhysicsDirectSpaceState::_intersect_shape(const RID& p_shape, const Tran
}
*/
-Dictionary PhysicsDirectSpaceState::_intersect_ray(const Vector3 &p_from, const Vector3 &p_to, const Vector<RID> &p_exclude, uint32_t p_collision_mask) {
+Dictionary PhysicsDirectSpaceState::_intersect_ray(const Vector3 &p_from, const Vector3 &p_to, const Vector<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
RayResult inters;
Set<RID> exclude;
for (int i = 0; i < p_exclude.size(); i++)
exclude.insert(p_exclude[i]);
- bool res = intersect_ray(p_from, p_to, inters, exclude, p_collision_mask);
+ bool res = intersect_ray(p_from, p_to, inters, exclude, p_collision_mask, p_collide_with_bodies, p_collide_with_areas);
if (!res)
return Dictionary();
@@ -289,7 +317,7 @@ Array PhysicsDirectSpaceState::_intersect_shape(const Ref<PhysicsShapeQueryParam
Vector<ShapeResult> sr;
sr.resize(p_max_results);
- int rc = intersect_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, sr.ptrw(), sr.size(), p_shape_query->exclude, p_shape_query->collision_mask);
+ int rc = intersect_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, sr.ptrw(), sr.size(), p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
Array ret;
ret.resize(rc);
for (int i = 0; i < rc; i++) {
@@ -308,7 +336,7 @@ Array PhysicsDirectSpaceState::_intersect_shape(const Ref<PhysicsShapeQueryParam
Array PhysicsDirectSpaceState::_cast_motion(const Ref<PhysicsShapeQueryParameters> &p_shape_query, const Vector3 &p_motion) {
float closest_safe, closest_unsafe;
- 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_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_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
if (!res)
return Array();
Array ret;
@@ -322,7 +350,7 @@ Array PhysicsDirectSpaceState::_collide_shape(const Ref<PhysicsShapeQueryParamet
Vector<Vector3> ret;
ret.resize(p_max_results * 2);
int rc = 0;
- bool res = collide_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, ret.ptrw(), p_max_results, rc, p_shape_query->exclude, p_shape_query->collision_mask);
+ bool res = collide_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, ret.ptrw(), p_max_results, rc, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
if (!res)
return Array();
Array r;
@@ -335,7 +363,7 @@ Dictionary PhysicsDirectSpaceState::_get_rest_info(const Ref<PhysicsShapeQueryPa
ShapeRestInfo sri;
- 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_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_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
Dictionary r;
if (!res)
return r;
@@ -358,7 +386,7 @@ 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","shape","xform","result_max","exclude","umask"),&PhysicsDirectSpaceState::_intersect_shape,DEFVAL(Array()),DEFVAL(0));
- ClassDB::bind_method(D_METHOD("intersect_ray", "from", "to", "exclude", "collision_layer"), &PhysicsDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF));
+ ClassDB::bind_method(D_METHOD("intersect_ray", "from", "to", "exclude", "collision_mask", "collide_with_bodies", "collide_with_areas"), &PhysicsDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(true), DEFVAL(false));
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));
diff --git a/servers/physics_server.h b/servers/physics_server.h
index 294c6b6674..f2aa33a6cc 100644
--- a/servers/physics_server.h
+++ b/servers/physics_server.h
@@ -108,6 +108,9 @@ class PhysicsShapeQueryParameters : public Reference {
Set<RID> exclude;
uint32_t collision_mask;
+ bool collide_with_bodies;
+ bool collide_with_areas;
+
protected:
static void _bind_methods();
@@ -128,6 +131,12 @@ public:
void set_exclude(const Vector<RID> &p_exclude);
Vector<RID> get_exclude() const;
+ void set_collide_with_bodies(bool p_enable);
+ bool is_collide_with_bodies_enabled() const;
+
+ void set_collide_with_areas(bool p_enable);
+ bool is_collide_with_areas_enabled() const;
+
PhysicsShapeQueryParameters();
};
@@ -136,7 +145,7 @@ class PhysicsDirectSpaceState : public Object {
GDCLASS(PhysicsDirectSpaceState, Object);
private:
- Dictionary _intersect_ray(const Vector3 &p_from, const Vector3 &p_to, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_collision_mask = 0);
+ Dictionary _intersect_ray(const Vector3 &p_from, const Vector3 &p_to, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_collision_mask = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
Array _intersect_shape(const Ref<PhysicsShapeQueryParameters> &p_shape_query, int p_max_results = 32);
Array _cast_motion(const Ref<PhysicsShapeQueryParameters> &p_shape_query, const Vector3 &p_motion);
Array _collide_shape(const Ref<PhysicsShapeQueryParameters> &p_shape_query, int p_max_results = 32);
@@ -154,7 +163,7 @@ public:
int shape;
};
- 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_mask = 0xFFFFFFFF) = 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
struct RayResult {
@@ -166,9 +175,9 @@ public:
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_collision_mask = 0xFFFFFFFF, bool p_pick_ray = false) = 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, 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_mask = 0xFFFFFFFF) = 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
struct ShapeRestInfo {
@@ -180,11 +189,11 @@ 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_collision_mask = 0xFFFFFFFF, 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false, 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_mask = 0xFFFFFFFF) = 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 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_mask = 0xFFFFFFFF) = 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_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const = 0;
@@ -243,6 +252,10 @@ public:
virtual ShapeType shape_get_type(RID p_shape) const = 0;
virtual Variant shape_get_data(RID p_shape) const = 0;
+
+ virtual void shape_set_margin(RID p_shape, real_t p_margin) = 0;
+ virtual real_t shape_get_margin(RID p_shape) const = 0;
+
virtual real_t shape_get_custom_solver_bias(RID p_shape) const = 0;
/* SPACE API */
@@ -401,19 +414,6 @@ public:
virtual void body_set_param(RID p_body, BodyParameter p_param, float p_value) = 0;
virtual float body_get_param(RID p_body, BodyParameter p_param) const = 0;
- enum CombineMode {
- COMBINE_MODE_MAX,
- COMBINE_MODE_MIN,
- COMBINE_MODE_MULTIPLY,
- COMBINE_MODE_AVERAGE,
-
- COMBINE_MODE_INHERIT /// Inherit from other body or use COMBINE_MODE_MAX (Restitution) COMBINE_MODE_MULTIPLY (Friction)
- };
-
- /// p_param accept only Bounce and Friction
- virtual void body_set_combine_mode(RID p_body, BodyParameter p_param, CombineMode p_mode) = 0;
- virtual CombineMode body_get_combine_mode(RID p_body, BodyParameter p_param) const = 0;
-
virtual void body_set_kinematic_safe_margin(RID p_body, real_t p_margin) = 0;
virtual real_t body_get_kinematic_safe_margin(RID p_body) const = 0;
@@ -495,7 +495,22 @@ public:
Variant collider_metadata;
};
- virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = NULL) = 0;
+ virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = NULL, bool p_exclude_raycast_shapes = true) = 0;
+
+ struct SeparationResult {
+
+ float collision_depth;
+ 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 int body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) = 0;
/* SOFT BODY */
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index aa0e5c289b..4c764641e3 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -73,7 +73,7 @@ static void _debugger_get_resource_usage(List<ScriptDebuggerRemote::ResourceUsag
usage.vram = E->get().bytes;
usage.id = E->get().texture;
usage.type = "Texture";
- usage.format = itos(E->get().size.width) + "x" + itos(E->get().size.height) + " " + Image::get_format_name(E->get().format);
+ usage.format = itos(E->get().width) + "x" + itos(E->get().height) + " " + Image::get_format_name(E->get().format);
r_usage->push_back(usage);
}
}
@@ -104,6 +104,7 @@ void register_server_types() {
ClassDB::register_virtual_class<AudioStream>();
ClassDB::register_virtual_class<AudioStreamPlayback>();
+ ClassDB::register_class<AudioStreamMicrophone>();
ClassDB::register_class<AudioStreamRandomPitch>();
ClassDB::register_virtual_class<AudioEffect>();
ClassDB::register_class<AudioEffectEQ>();
diff --git a/servers/server_wrap_mt_common.h b/servers/server_wrap_mt_common.h
index 611e25af2a..843773e5b1 100644
--- a/servers/server_wrap_mt_common.h
+++ b/servers/server_wrap_mt_common.h
@@ -197,9 +197,10 @@
}
#define FUNC5RID(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5) \
- int m_type##allocn() { \
- for (int i = 0; i < m_type##_pool_max_size; i++) { \
- m_type##_id_pool.push_back(server_name->m_type##_create()); \
+ List<RID> m_type##_id_pool; \
+ int m_type##allocn(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \
+ for (int i = 0; i < pool_max_size; i++) { \
+ m_type##_id_pool.push_back(server_name->m_type##_create(p1, p2, p3, p4, p5)); \
} \
return 0; \
} \
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 5ce4f2b62d..49dff0d557 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -176,17 +176,34 @@ public:
/* TEXTURE API */
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 Ref<Image> &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) = 0;
- virtual void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, 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_allocate(RID p_texture,
+ int p_width,
+ int p_height,
+ int p_depth_3d,
+ Image::Format p_format,
+ VS::TextureType p_type,
+ uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT) = 0;
+
+ virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_level = 0) = 0;
+
+ virtual void texture_set_data_partial(RID p_texture,
+ const Ref<Image> &p_image,
+ int src_x, int src_y,
+ int src_w, int src_h,
+ int dst_x, int dst_y,
+ int p_dst_mip,
+ int p_level = 0) = 0;
+
+ virtual Ref<Image> texture_get_data(RID p_texture, int p_level = 0) 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 VS::TextureType texture_get_type(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;
+ virtual uint32_t texture_get_depth(RID p_texture) const = 0;
+ virtual void texture_set_size_override(RID p_texture, int p_width, int p_height, int p_depth_3d) = 0;
virtual void texture_set_path(RID p_texture, const String &p_path) = 0;
virtual String texture_get_path(RID p_texture) const = 0;
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index d4fb8d98b0..ffb130048f 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -123,6 +123,12 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"TYPE_SAMPLER2D",
"TYPE_ISAMPLER2D",
"TYPE_USAMPLER2D",
+ "TYPE_SAMPLER2DARRAY",
+ "TYPE_ISAMPLER2DARRAY",
+ "TYPE_USAMPLER2DARRAY",
+ "TYPE_SAMPLER3D",
+ "TYPE_ISAMPLER3D",
+ "TYPE_USAMPLER3D",
"TYPE_SAMPLERCUBE",
"INTERPOLATION_FLAT",
"INTERPOLATION_NO_PERSPECTIVE",
@@ -257,6 +263,12 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
{ TK_TYPE_SAMPLER2D, "sampler2D" },
{ TK_TYPE_ISAMPLER2D, "isampler2D" },
{ TK_TYPE_USAMPLER2D, "usampler2D" },
+ { TK_TYPE_SAMPLER2DARRAY, "sampler2DArray" },
+ { TK_TYPE_ISAMPLER2DARRAY, "isampler2DArray" },
+ { TK_TYPE_USAMPLER2DARRAY, "usampler2DArray" },
+ { TK_TYPE_SAMPLER3D, "sampler3D" },
+ { TK_TYPE_ISAMPLER3D, "isampler3D" },
+ { TK_TYPE_USAMPLER3D, "usampler3D" },
{ TK_TYPE_SAMPLERCUBE, "samplerCube" },
{ TK_INTERPOLATION_FLAT, "flat" },
{ TK_INTERPOLATION_NO_PERSPECTIVE, "noperspective" },
@@ -516,13 +528,14 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
bool hexa_found = false;
bool sign_found = false;
bool minus_exponent_found = false;
+ bool float_suffix_found = false;
String str;
int i = 0;
while (true) {
if (GETCHAR(i) == '.') {
- if (period_found || exponent_found)
+ if (period_found || exponent_found || hexa_found || float_suffix_found)
return _make_token(TK_ERROR, "Invalid numeric constant");
period_found = true;
} else if (GETCHAR(i) == 'x') {
@@ -530,11 +543,16 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
return _make_token(TK_ERROR, "Invalid numeric constant");
hexa_found = true;
} else if (GETCHAR(i) == 'e') {
- if (hexa_found || exponent_found)
+ if (hexa_found || exponent_found || float_suffix_found)
return _make_token(TK_ERROR, "Invalid numeric constant");
exponent_found = true;
+ } else if (GETCHAR(i) == 'f') {
+ if (hexa_found || exponent_found)
+ return _make_token(TK_ERROR, "Invalid numeric constant");
+ float_suffix_found = true;
} else if (_is_number(GETCHAR(i))) {
- //all ok
+ if (float_suffix_found)
+ return _make_token(TK_ERROR, "Invalid numeric constant");
} else if (hexa_found && _is_hex(GETCHAR(i))) {
} else if ((GETCHAR(i) == '-' || GETCHAR(i) == '+') && exponent_found) {
@@ -550,21 +568,60 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
i++;
}
- if (!_is_number(str[str.length() - 1]))
- return _make_token(TK_ERROR, "Invalid numeric constant");
+ CharType last_char = str[str.length() - 1];
+
+ if (hexa_found) {
+ //hex integers eg."0xFF" or "0x12AB", etc - NOT supported yet
+ return _make_token(TK_ERROR, "Invalid (hexadecimal) numeric constant - Not supported");
+ } else if (period_found || float_suffix_found) {
+ //floats
+ if (period_found) {
+ if (float_suffix_found) {
+ //checks for eg "1.f" or "1.99f" notations
+ if (last_char != 'f') {
+ return _make_token(TK_ERROR, "Invalid (float) numeric constant");
+ }
+ } else {
+ //checks for eg. "1." or "1.99" notations
+ if (last_char != '.' && !_is_number(last_char)) {
+ return _make_token(TK_ERROR, "Invalid (float) numeric constant");
+ }
+ }
+ } else if (float_suffix_found) {
+ // if no period found the float suffix must be the last character, like in "2f" for "2.0"
+ if (last_char != 'f') {
+ return _make_token(TK_ERROR, "Invalid (float) numeric constant");
+ }
+ }
+
+ if (float_suffix_found) {
+ //strip the suffix
+ str = str.left(str.length() - 1);
+ //compensate reading cursor position
+ char_idx += 1;
+ }
+
+ if (!str.is_valid_float()) {
+ return _make_token(TK_ERROR, "Invalid (float) numeric constant");
+ }
+ } else {
+ //integers
+ if (!_is_number(last_char)) {
+ return _make_token(TK_ERROR, "Invalid (integer) numeric constant");
+ }
+ if (!str.is_valid_integer()) {
+ return _make_token(TK_ERROR, "Invalid numeric constant");
+ }
+ }
char_idx += str.length();
Token tk;
- if (period_found || minus_exponent_found)
+ if (period_found || minus_exponent_found || float_suffix_found)
tk.type = TK_REAL_CONSTANT;
else
tk.type = TK_INT_CONSTANT;
- if (!str.is_valid_float()) {
- return _make_token(TK_ERROR, "Invalid numeric constant");
- }
-
- tk.constant = str.to_double();
+ tk.constant = str.to_double(); //wont work with hex
tk.line = tk_line;
return tk;
@@ -660,6 +717,12 @@ bool ShaderLanguage::is_token_datatype(TokenType p_type) {
p_type == TK_TYPE_SAMPLER2D ||
p_type == TK_TYPE_ISAMPLER2D ||
p_type == TK_TYPE_USAMPLER2D ||
+ p_type == TK_TYPE_SAMPLER2DARRAY ||
+ p_type == TK_TYPE_ISAMPLER2DARRAY ||
+ p_type == TK_TYPE_USAMPLER2DARRAY ||
+ p_type == TK_TYPE_SAMPLER3D ||
+ p_type == TK_TYPE_ISAMPLER3D ||
+ p_type == TK_TYPE_USAMPLER3D ||
p_type == TK_TYPE_SAMPLERCUBE);
}
@@ -731,6 +794,12 @@ String ShaderLanguage::get_datatype_name(DataType p_type) {
case TYPE_SAMPLER2D: return "sampler2D";
case TYPE_ISAMPLER2D: return "isampler2D";
case TYPE_USAMPLER2D: return "usampler2D";
+ case TYPE_SAMPLER2DARRAY: return "sampler2DArray";
+ case TYPE_ISAMPLER2DARRAY: return "isampler2DArray";
+ case TYPE_USAMPLER2DARRAY: return "usampler2DArray";
+ case TYPE_SAMPLER3D: return "sampler3D";
+ case TYPE_ISAMPLER3D: return "isampler3D";
+ case TYPE_USAMPLER3D: return "usampler3D";
case TYPE_SAMPLERCUBE: return "samplerCube";
}
@@ -1802,6 +1871,12 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "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_IVEC3, { TYPE_SAMPLER2DARRAY, TYPE_INT, TYPE_VOID } },
+ { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER2DARRAY, TYPE_INT, TYPE_VOID } },
+ { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER2DARRAY, TYPE_INT, TYPE_VOID } },
+ { "textureSize", TYPE_IVEC3, { TYPE_SAMPLER3D, TYPE_INT, TYPE_VOID } },
+ { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER3D, TYPE_INT, TYPE_VOID } },
+ { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER3D, TYPE_INT, TYPE_VOID } },
{ "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBE, TYPE_INT, TYPE_VOID } },
{ "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID } },
@@ -1813,6 +1888,24 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VOID } },
{ "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
+ { "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID } },
+ { "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
+
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID } },
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
+
+ { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID } },
+ { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
+
+ { "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VOID } },
+ { "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
+
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VOID } },
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
+
+ { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VOID } },
+ { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, 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 } },
@@ -1831,15 +1924,38 @@ 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 } },
+ { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_VOID } },
+ { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } },
+
+ { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_VOID } },
+ { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } },
+
+ { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_VOID } },
+ { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, 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_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
+ { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
+ { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
+ { "textureLod", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
+ { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
+ { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, 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 } },
{ "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID } },
{ "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID } },
+ { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID } },
+ { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID } },
+ { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID } },
+
+ { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID } },
+ { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID } },
+ { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID } },
+
{ "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
{ "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } },
@@ -1852,6 +1968,12 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
{ "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
{ "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
+ { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
+ { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
+ { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
+ { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
+ { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
+ { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
{ "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
{ "dFdx", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } },
@@ -2139,7 +2261,16 @@ bool ShaderLanguage::is_scalar_type(DataType p_type) {
bool ShaderLanguage::is_sampler_type(DataType p_type) {
- return p_type == TYPE_SAMPLER2D || p_type == TYPE_ISAMPLER2D || p_type == TYPE_USAMPLER2D || p_type == TYPE_SAMPLERCUBE;
+ return p_type == TYPE_SAMPLER2D ||
+ p_type == TYPE_ISAMPLER2D ||
+ p_type == TYPE_USAMPLER2D ||
+ p_type == TYPE_SAMPLER2DARRAY ||
+ p_type == TYPE_ISAMPLER2DARRAY ||
+ p_type == TYPE_USAMPLER2DARRAY ||
+ p_type == TYPE_SAMPLER3D ||
+ p_type == TYPE_ISAMPLER3D ||
+ p_type == TYPE_USAMPLER3D ||
+ p_type == TYPE_SAMPLERCUBE;
}
void ShaderLanguage::get_keyword_list(List<String> *r_keywords) {
@@ -2402,7 +2533,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expr = constant;
} else if (tk.type == TK_TRUE) {
- //print_line("found true");
//handle true constant
ConstantNode *constant = alloc_node<ConstantNode>();
@@ -3744,8 +3874,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
- if (!uniform && (type < TYPE_FLOAT || type > TYPE_VEC4)) {
- _set_error("Invalid type for varying, only float,vec2,vec3,vec4 allowed.");
+ if (!uniform && (type < TYPE_FLOAT || type > TYPE_MAT4)) {
+ _set_error("Invalid type for varying, only float,vec2,vec3,vec4,mat2,mat3,mat4 allowed.");
return ERR_PARSE_ERROR;
}
diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h
index b5fd567c07..d68f233b2f 100644
--- a/servers/visual/shader_language.h
+++ b/servers/visual/shader_language.h
@@ -72,6 +72,12 @@ public:
TK_TYPE_SAMPLER2D,
TK_TYPE_ISAMPLER2D,
TK_TYPE_USAMPLER2D,
+ TK_TYPE_SAMPLER2DARRAY,
+ TK_TYPE_ISAMPLER2DARRAY,
+ TK_TYPE_USAMPLER2DARRAY,
+ TK_TYPE_SAMPLER3D,
+ TK_TYPE_ISAMPLER3D,
+ TK_TYPE_USAMPLER3D,
TK_TYPE_SAMPLERCUBE,
TK_INTERPOLATION_FLAT,
TK_INTERPOLATION_NO_PERSPECTIVE,
@@ -186,6 +192,12 @@ public:
TYPE_SAMPLER2D,
TYPE_ISAMPLER2D,
TYPE_USAMPLER2D,
+ TYPE_SAMPLER2DARRAY,
+ TYPE_ISAMPLER2DARRAY,
+ TYPE_USAMPLER2DARRAY,
+ TYPE_SAMPLER3D,
+ TYPE_ISAMPLER3D,
+ TYPE_USAMPLER3D,
TYPE_SAMPLERCUBE,
};
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index 0de8676f32..caa454b98e 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -127,6 +127,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["VIEWPORT_SIZE"] = constt(ShaderLanguage::TYPE_VEC2);
+ shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4);
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["NORMAL"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["VIEW"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["LIGHT"] = constt(ShaderLanguage::TYPE_VEC3);
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index d58be21858..a00b364565 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -148,17 +148,19 @@ public:
/* TEXTURE API */
BIND0R(RID, texture_create)
- BIND5(texture_allocate, RID, int, int, Image::Format, uint32_t)
- BIND3(texture_set_data, RID, const Ref<Image> &, CubeMapSide)
- BIND10(texture_set_data_partial, RID, const Ref<Image> &, int, int, int, int, int, int, int, CubeMapSide)
- BIND2RC(Ref<Image>, texture_get_data, RID, CubeMapSide)
+ BIND7(texture_allocate, RID, int, int, int, Image::Format, TextureType, uint32_t)
+ BIND3(texture_set_data, RID, const Ref<Image> &, int)
+ BIND10(texture_set_data_partial, RID, const Ref<Image> &, int, int, int, int, int, int, int, int)
+ BIND2RC(Ref<Image>, texture_get_data, RID, int)
BIND2(texture_set_flags, RID, uint32_t)
BIND1RC(uint32_t, texture_get_flags, RID)
BIND1RC(Image::Format, texture_get_format, RID)
+ BIND1RC(TextureType, texture_get_type, 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)
+ BIND1RC(uint32_t, texture_get_depth, RID)
+ BIND4(texture_set_size_override, RID, int, int, int)
BIND3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *)
BIND3(texture_set_detect_srgb_callback, RID, TextureDetectCallback, void *)
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 213b3ad8f6..1e255591f0 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -1180,7 +1180,7 @@ _FORCE_INLINE_ static void _light_capture_sample_octree(const RasterizerStorage:
r_color = color_interp[0].linear_interpolate(color_interp[1], level_filter);
r_alpha = Math::lerp(alpha_interp[0], alpha_interp[1], level_filter);
- // print_line("pos: " + p_posf + " level " + rtos(p_level) + " down to " + itos(target_level) + "." + rtos(level_filter) + " color " + r_color + " alpha " + rtos(r_alpha));
+ //print_line("pos: " + p_posf + " level " + rtos(p_level) + " down to " + itos(target_level) + "." + rtos(level_filter) + " color " + r_color + " alpha " + rtos(r_alpha));
}
_FORCE_INLINE_ static Color _light_capture_voxel_cone_trace(const RasterizerStorage::LightmapCaptureOctree *p_octree, const Vector3 &p_pos, const Vector3 &p_dir, float p_aperture, int p_cell_subdiv) {
@@ -1799,11 +1799,12 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
//light_samplers_culled=0;
- /* print_line("OT: "+rtos( (OS::get_singleton()->get_ticks_usec()-t)/1000.0));
+ /*
+ print_line("OT: "+rtos( (OS::get_singleton()->get_ticks_usec()-t)/1000.0));
print_line("OTO: "+itos(p_scenario->octree.get_octant_count()));
- //print_line("OTE: "+itos(p_scenario->octree.get_elem_count()));
+ print_line("OTE: "+itos(p_scenario->octree.get_elem_count()));
print_line("OTP: "+itos(p_scenario->octree.get_pair_count()));
-*/
+ */
/* STEP 3 - PROCESS PORTALS, VALIDATE ROOMS */
//removed, will replace with culling
@@ -2302,7 +2303,6 @@ void VisualServerScene::_setup_gi_probe(Instance *p_instance) {
int size_divisor = 1;
if (probe->dynamic.compression == RasterizerStorage::GI_PROBE_S3TC) {
- print_line("S3TC");
size_limit = 4;
size_divisor = 4;
}
@@ -2391,7 +2391,7 @@ void VisualServerScene::_setup_gi_probe(Instance *p_instance) {
probe->dynamic.mipmaps_s3tc.resize(mipmap_count);
for (int i = 0; i < mipmap_count; i++) {
- print_line("S3TC level: " + itos(i) + " blocks: " + itos(comp_blocks[i].size()));
+ //print_line("S3TC level: " + itos(i) + " blocks: " + itos(comp_blocks[i].size()));
probe->dynamic.mipmaps_s3tc.write[i].resize(comp_blocks[i].size());
PoolVector<InstanceGIProbeData::CompBlockS3TC>::Write w = probe->dynamic.mipmaps_s3tc.write[i].write();
int block_idx = 0;
@@ -2759,7 +2759,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;
}
}
@@ -3180,7 +3180,7 @@ void VisualServerScene::render_probes() {
} break;
case GI_UPDATE_STAGE_UPLOADING: {
- // uint64_t us = OS::get_singleton()->get_ticks_usec();
+ //uint64_t us = OS::get_singleton()->get_ticks_usec();
for (int i = 0; i < (int)probe->dynamic.mipmaps_3d.size(); i++) {
@@ -3190,7 +3190,7 @@ void VisualServerScene::render_probes() {
probe->dynamic.updating_stage = GI_UPDATE_STAGE_CHECK;
- // print_line("UPLOAD TIME: " + rtos((OS::get_singleton()->get_ticks_usec() - us) / 1000000.0));
+ //print_line("UPLOAD TIME: " + rtos((OS::get_singleton()->get_ticks_usec() - us) / 1000000.0));
} break;
}
}
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index a700fcf11b..90acba306a 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -137,7 +137,6 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
}
}
- //print_line("lights: "+itos(light_count));
canvas_map[Viewport::CanvasKey(E->key(), E->get().layer)] = &E->get();
}
@@ -194,8 +193,6 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
VisualServerCanvas::Canvas *canvas = static_cast<VisualServerCanvas::Canvas *>(E->get()->canvas);
- //print_line("canvas "+itos(i)+" size: "+itos(I->get()->canvas->child_items.size()));
- //print_line("GT "+p_viewport->global_transform+". CT: "+E->get()->transform);
Transform2D xform = p_viewport->global_transform * E->get()->transform;
RasterizerCanvas::Light *canvas_lights = NULL;
diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp
index 93f3792bdc..1cafc47685 100644
--- a/servers/visual/visual_server_wrap_mt.cpp
+++ b/servers/visual/visual_server_wrap_mt.cpp
@@ -107,16 +107,16 @@ void VisualServerWrapMT::init() {
if (create_thread) {
- print_line("CREATING RENDER THREAD");
+ print_verbose("VisualServerWrapMT: Creating render thread");
OS::get_singleton()->release_rendering_thread();
if (create_thread) {
thread = Thread::create(_thread_callback, this);
- print_line("STARTING RENDER THREAD");
+ print_verbose("VisualServerWrapMT: Starting render thread");
}
while (!draw_thread_up) {
OS::get_singleton()->delay_usec(1000);
}
- print_line("DONE RENDER THREAD");
+ print_verbose("VisualServerWrapMT: Finished render thread");
} else {
visual_server->init();
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index c6af960d9f..3a4d72c793 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -82,17 +82,19 @@ public:
/* EVENT QUEUING */
FUNCRID(texture)
- FUNC5(texture_allocate, RID, int, int, Image::Format, uint32_t)
- FUNC3(texture_set_data, RID, const Ref<Image> &, CubeMapSide)
- FUNC10(texture_set_data_partial, RID, const Ref<Image> &, int, int, int, int, int, int, int, CubeMapSide)
- FUNC2RC(Ref<Image>, texture_get_data, RID, CubeMapSide)
+ FUNC7(texture_allocate, RID, int, int, int, Image::Format, TextureType, uint32_t)
+ FUNC3(texture_set_data, RID, const Ref<Image> &, int)
+ FUNC10(texture_set_data_partial, RID, const Ref<Image> &, int, int, int, int, int, int, int, int)
+ FUNC2RC(Ref<Image>, texture_get_data, RID, int)
FUNC2(texture_set_flags, RID, uint32_t)
FUNC1RC(uint32_t, texture_get_flags, RID)
FUNC1RC(Image::Format, texture_get_format, RID)
+ FUNC1RC(TextureType, texture_get_type, 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)
+ FUNC1RC(uint32_t, texture_get_depth, RID)
+ FUNC4(texture_set_size_override, RID, int, int, int)
FUNC3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *)
FUNC3(texture_set_detect_srgb_callback, RID, TextureDetectCallback, void *)
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 2e5b27510a..18a04e9a4b 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -55,7 +55,7 @@ RID VisualServer::texture_create_from_image(const Ref<Image> &p_image, uint32_t
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(), 0, p_image->get_format(), VS::TEXTURE_TYPE_2D, p_flags); //if it has mipmaps, use, else generate
ERR_FAIL_COND_V(!texture.is_valid(), texture);
texture_set_data(texture, p_image);
@@ -72,7 +72,9 @@ Array VisualServer::_texture_debug_usage_bind() {
Dictionary dict;
dict["texture"] = E->get().texture;
- dict["size"] = E->get().size;
+ dict["width"] = E->get().width;
+ dict["height"] = E->get().height;
+ dict["depth"] = E->get().depth;
dict["format"] = E->get().format;
dict["bytes"] = E->get().bytes;
dict["path"] = E->get().path;
@@ -333,7 +335,7 @@ RID VisualServer::get_white_texture() {
}
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_allocate(white_texture, 4, 4, 0, Image::FORMAT_RGB8, TEXTURE_TYPE_2D);
texture_set_data(white_texture, white);
return white_texture;
}
@@ -1658,17 +1660,19 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("texture_create"), &VisualServer::texture_create);
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", "texture", "width", "height", "format", "flags"), &VisualServer::texture_allocate, DEFVAL(TEXTURE_FLAGS_DEFAULT));
- ClassDB::bind_method(D_METHOD("texture_set_data", "texture", "image", "cube_side"), &VisualServer::texture_set_data, DEFVAL(CUBEMAP_LEFT));
- ClassDB::bind_method(D_METHOD("texture_set_data_partial", "texture", "image", "src_x", "src_y", "src_w", "src_h", "dst_x", "dst_y", "dst_mip", "cube_side"), &VisualServer::texture_set_data_partial, DEFVAL(CUBEMAP_LEFT));
+ ClassDB::bind_method(D_METHOD("texture_allocate", "texture", "width", "height", "depth_3d", "format", "type", "flags"), &VisualServer::texture_allocate, DEFVAL(TEXTURE_FLAGS_DEFAULT));
+ ClassDB::bind_method(D_METHOD("texture_set_data", "texture", "image", "layer"), &VisualServer::texture_set_data, DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("texture_set_data_partial", "texture", "image", "src_x", "src_y", "src_w", "src_h", "dst_x", "dst_y", "dst_mip", "layer"), &VisualServer::texture_set_data_partial, DEFVAL(0));
ClassDB::bind_method(D_METHOD("texture_get_data", "texture", "cube_side"), &VisualServer::texture_get_data, DEFVAL(CUBEMAP_LEFT));
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_format", "texture"), &VisualServer::texture_get_format);
+ ClassDB::bind_method(D_METHOD("texture_get_type", "texture"), &VisualServer::texture_get_type);
ClassDB::bind_method(D_METHOD("texture_get_texid", "texture"), &VisualServer::texture_get_texid);
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_size_override", "texture", "width", "height"), &VisualServer::texture_set_size_override);
+ ClassDB::bind_method(D_METHOD("texture_get_depth", "texture"), &VisualServer::texture_get_depth);
+ ClassDB::bind_method(D_METHOD("texture_set_size_override", "texture", "width", "height", "depth"), &VisualServer::texture_set_size_override);
ClassDB::bind_method(D_METHOD("texture_set_path", "texture", "path"), &VisualServer::texture_set_path);
ClassDB::bind_method(D_METHOD("texture_get_path", "texture"), &VisualServer::texture_get_path);
ClassDB::bind_method(D_METHOD("texture_set_shrink_all_x2_on_set_data", "shrink"), &VisualServer::texture_set_shrink_all_x2_on_set_data);
@@ -1802,24 +1806,24 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("gi_probe_get_bounds", "probe"), &VisualServer::gi_probe_get_bounds);
ClassDB::bind_method(D_METHOD("gi_probe_set_cell_size", "probe", "range"), &VisualServer::gi_probe_set_cell_size);
ClassDB::bind_method(D_METHOD("gi_probe_get_cell_size", "probe"), &VisualServer::gi_probe_get_cell_size);
- ClassDB::bind_method(D_METHOD("gi_probe_set_to_cell_xform", "xform"), &VisualServer::gi_probe_set_to_cell_xform);
- ClassDB::bind_method(D_METHOD("gi_probe_get_to_cell_xform"), &VisualServer::gi_probe_get_to_cell_xform);
- ClassDB::bind_method(D_METHOD("gi_probe_set_dynamic_data", "data"), &VisualServer::gi_probe_set_dynamic_data);
- ClassDB::bind_method(D_METHOD("gi_probe_get_dynamic_data"), &VisualServer::gi_probe_get_dynamic_data);
- ClassDB::bind_method(D_METHOD("gi_probe_set_dynamic_range", "range"), &VisualServer::gi_probe_set_dynamic_range);
- ClassDB::bind_method(D_METHOD("gi_probe_get_dynamic_range"), &VisualServer::gi_probe_get_dynamic_range);
- ClassDB::bind_method(D_METHOD("gi_probe_set_energy", "energy"), &VisualServer::gi_probe_set_energy);
- ClassDB::bind_method(D_METHOD("gi_probe_get_energy"), &VisualServer::gi_probe_get_energy);
- ClassDB::bind_method(D_METHOD("gi_probe_set_bias", "bias"), &VisualServer::gi_probe_set_bias);
- ClassDB::bind_method(D_METHOD("gi_probe_get_bias"), &VisualServer::gi_probe_get_bias);
- ClassDB::bind_method(D_METHOD("gi_probe_set_normal_bias", "bias"), &VisualServer::gi_probe_set_normal_bias);
- ClassDB::bind_method(D_METHOD("gi_probe_get_normal_bias"), &VisualServer::gi_probe_get_normal_bias);
- ClassDB::bind_method(D_METHOD("gi_probe_set_propagation", "propagation"), &VisualServer::gi_probe_set_propagation);
- ClassDB::bind_method(D_METHOD("gi_probe_get_propagation"), &VisualServer::gi_probe_get_propagation);
- ClassDB::bind_method(D_METHOD("gi_probe_set_interior", "enable"), &VisualServer::gi_probe_set_interior);
- ClassDB::bind_method(D_METHOD("gi_probe_is_interior"), &VisualServer::gi_probe_is_interior);
- ClassDB::bind_method(D_METHOD("gi_probe_set_compress", "enable"), &VisualServer::gi_probe_set_compress);
- ClassDB::bind_method(D_METHOD("gi_probe_is_compressed"), &VisualServer::gi_probe_is_compressed);
+ ClassDB::bind_method(D_METHOD("gi_probe_set_to_cell_xform", "probe", "xform"), &VisualServer::gi_probe_set_to_cell_xform);
+ ClassDB::bind_method(D_METHOD("gi_probe_get_to_cell_xform", "probe"), &VisualServer::gi_probe_get_to_cell_xform);
+ ClassDB::bind_method(D_METHOD("gi_probe_set_dynamic_data", "probe", "data"), &VisualServer::gi_probe_set_dynamic_data);
+ ClassDB::bind_method(D_METHOD("gi_probe_get_dynamic_data", "probe"), &VisualServer::gi_probe_get_dynamic_data);
+ ClassDB::bind_method(D_METHOD("gi_probe_set_dynamic_range", "probe", "range"), &VisualServer::gi_probe_set_dynamic_range);
+ ClassDB::bind_method(D_METHOD("gi_probe_get_dynamic_range", "probe"), &VisualServer::gi_probe_get_dynamic_range);
+ ClassDB::bind_method(D_METHOD("gi_probe_set_energy", "probe", "energy"), &VisualServer::gi_probe_set_energy);
+ ClassDB::bind_method(D_METHOD("gi_probe_get_energy", "probe"), &VisualServer::gi_probe_get_energy);
+ ClassDB::bind_method(D_METHOD("gi_probe_set_bias", "probe", "bias"), &VisualServer::gi_probe_set_bias);
+ ClassDB::bind_method(D_METHOD("gi_probe_get_bias", "probe"), &VisualServer::gi_probe_get_bias);
+ ClassDB::bind_method(D_METHOD("gi_probe_set_normal_bias", "probe", "bias"), &VisualServer::gi_probe_set_normal_bias);
+ ClassDB::bind_method(D_METHOD("gi_probe_get_normal_bias", "probe"), &VisualServer::gi_probe_get_normal_bias);
+ ClassDB::bind_method(D_METHOD("gi_probe_set_propagation", "probe", "propagation"), &VisualServer::gi_probe_set_propagation);
+ ClassDB::bind_method(D_METHOD("gi_probe_get_propagation", "probe"), &VisualServer::gi_probe_get_propagation);
+ ClassDB::bind_method(D_METHOD("gi_probe_set_interior", "probe", "enable"), &VisualServer::gi_probe_set_interior);
+ ClassDB::bind_method(D_METHOD("gi_probe_is_interior", "probe"), &VisualServer::gi_probe_is_interior);
+ ClassDB::bind_method(D_METHOD("gi_probe_set_compress", "probe", "enable"), &VisualServer::gi_probe_set_compress);
+ ClassDB::bind_method(D_METHOD("gi_probe_is_compressed", "probe"), &VisualServer::gi_probe_is_compressed);
ClassDB::bind_method(D_METHOD("lightmap_capture_create"), &VisualServer::lightmap_capture_create);
ClassDB::bind_method(D_METHOD("lightmap_capture_set_bounds", "capture", "bounds"), &VisualServer::lightmap_capture_set_bounds);
@@ -2059,13 +2063,17 @@ void VisualServer::_bind_methods() {
BIND_ENUM_CONSTANT(CUBEMAP_FRONT);
BIND_ENUM_CONSTANT(CUBEMAP_BACK);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_CUBEMAP);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D_ARRAY);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_3D);
+
BIND_ENUM_CONSTANT(TEXTURE_FLAG_MIPMAPS);
BIND_ENUM_CONSTANT(TEXTURE_FLAG_REPEAT);
BIND_ENUM_CONSTANT(TEXTURE_FLAG_FILTER);
BIND_ENUM_CONSTANT(TEXTURE_FLAG_ANISOTROPIC_FILTER);
BIND_ENUM_CONSTANT(TEXTURE_FLAG_CONVERT_TO_LINEAR);
BIND_ENUM_CONSTANT(TEXTURE_FLAG_MIRRORED_REPEAT);
- BIND_ENUM_CONSTANT(TEXTURE_FLAG_CUBEMAP);
BIND_ENUM_CONSTANT(TEXTURE_FLAG_USED_FOR_STREAMING);
BIND_ENUM_CONSTANT(TEXTURE_FLAGS_DEFAULT);
@@ -2353,6 +2361,7 @@ VisualServer::VisualServer() {
//ERR_FAIL_COND(singleton);
singleton = this;
+ GLOBAL_DEF("rendering/vram_compression/import_bptc", false);
GLOBAL_DEF("rendering/vram_compression/import_s3tc", true);
GLOBAL_DEF("rendering/vram_compression/import_etc", false);
GLOBAL_DEF("rendering/vram_compression/import_etc2", true);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 6847f6d2ae..fd7f96339e 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -34,9 +34,9 @@
#include "bsp_tree.h"
#include "geometry.h"
#include "image.h"
-#include "math_2d.h"
#include "object.h"
#include "rid.h"
+#include "transform_2d.h"
#include "variant.h"
/**
@@ -90,11 +90,17 @@ public:
TEXTURE_FLAG_ANISOTROPIC_FILTER = 8,
TEXTURE_FLAG_CONVERT_TO_LINEAR = 16,
TEXTURE_FLAG_MIRRORED_REPEAT = 32, /// Repeat texture, with alternate sections mirrored
- TEXTURE_FLAG_CUBEMAP = 2048,
- TEXTURE_FLAG_USED_FOR_STREAMING = 4096,
+ TEXTURE_FLAG_USED_FOR_STREAMING = 2048,
TEXTURE_FLAGS_DEFAULT = TEXTURE_FLAG_REPEAT | TEXTURE_FLAG_MIPMAPS | TEXTURE_FLAG_FILTER
};
+ enum TextureType {
+ TEXTURE_TYPE_2D,
+ TEXTURE_TYPE_CUBEMAP,
+ TEXTURE_TYPE_2D_ARRAY,
+ TEXTURE_TYPE_3D,
+ };
+
enum CubeMapSide {
CUBEMAP_LEFT,
@@ -107,17 +113,33 @@ public:
virtual RID texture_create() = 0;
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 Ref<Image> &p_image, CubeMapSide p_cube_side = CUBEMAP_LEFT) = 0;
- virtual void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, 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_allocate(RID p_texture,
+ int p_width,
+ int p_height,
+ int p_depth_3d,
+ Image::Format p_format,
+ TextureType p_type,
+ uint32_t p_flags = TEXTURE_FLAGS_DEFAULT) = 0;
+
+ virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) = 0;
+ virtual void texture_set_data_partial(RID p_texture,
+ const Ref<Image> &p_image,
+ int src_x, int src_y,
+ int src_w, int src_h,
+ int dst_x, int dst_y,
+ int p_dst_mip,
+ int p_layer = 0) = 0;
+
+ virtual Ref<Image> texture_get_data(RID p_texture, int p_layer = 0) 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 TextureType texture_get_type(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;
+ virtual uint32_t texture_get_depth(RID p_texture) const = 0;
+ virtual void texture_set_size_override(RID p_texture, int p_width, int p_height, int p_depth_3d) = 0;
virtual void texture_set_path(RID p_texture, const String &p_path) = 0;
virtual String texture_get_path(RID p_texture) const = 0;
@@ -132,7 +154,9 @@ public:
struct TextureInfo {
RID texture;
- Size2 size;
+ uint32_t width;
+ uint32_t height;
+ uint32_t depth;
Image::Format format;
int bytes;
String path;
@@ -1054,6 +1078,7 @@ VARIANT_ENUM_CAST(VisualServer::EnvironmentSSAOQuality);
VARIANT_ENUM_CAST(VisualServer::EnvironmentSSAOBlur);
VARIANT_ENUM_CAST(VisualServer::InstanceFlags);
VARIANT_ENUM_CAST(VisualServer::ShadowCastingSetting);
+VARIANT_ENUM_CAST(VisualServer::TextureType);
//typedef VisualServer VS; // makes it easier to use
#define VS VisualServer