summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/SCsub2
-rw-r--r--servers/arvr/SCsub2
-rw-r--r--servers/arvr/arvr_interface.h2
-rw-r--r--servers/arvr/arvr_positional_tracker.h2
-rw-r--r--servers/arvr_server.cpp8
-rw-r--r--servers/arvr_server.h12
-rw-r--r--servers/audio/SCsub2
-rw-r--r--servers/audio/audio_driver_dummy.cpp4
-rw-r--r--servers/audio/audio_effect.h4
-rw-r--r--servers/audio/audio_filter_sw.h2
-rw-r--r--servers/audio/audio_rb_resampler.cpp25
-rw-r--r--servers/audio/audio_rb_resampler.h4
-rw-r--r--servers/audio/audio_stream.cpp25
-rw-r--r--servers/audio/audio_stream.h6
-rw-r--r--servers/audio/effects/SCsub2
-rw-r--r--servers/audio/effects/audio_effect_chorus.cpp2
-rw-r--r--servers/audio/effects/audio_effect_delay.cpp2
-rw-r--r--servers/audio/effects/audio_effect_distortion.cpp2
-rw-r--r--servers/audio/effects/audio_effect_filter.h13
-rw-r--r--servers/audio/effects/audio_effect_phaser.cpp2
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.cpp8
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.h2
-rw-r--r--servers/audio/effects/audio_effect_record.cpp67
-rw-r--r--servers/audio/effects/audio_effect_record.h17
-rw-r--r--servers/audio/effects/eq.cpp4
-rw-r--r--servers/audio/effects/eq.h4
-rw-r--r--servers/audio/effects/reverb.cpp26
-rw-r--r--servers/audio/effects/reverb.h6
-rw-r--r--servers/audio/reverb_sw.cpp24
-rw-r--r--servers/audio/reverb_sw.h6
-rw-r--r--servers/audio/voice_rb_sw.h2
-rw-r--r--servers/audio_server.cpp86
-rw-r--r--servers/audio_server.h16
-rw-r--r--servers/physics/SCsub2
-rw-r--r--servers/physics/area_pair_sw.cpp4
-rw-r--r--servers/physics/area_sw.h2
-rw-r--r--servers/physics/body_pair_sw.cpp2
-rw-r--r--servers/physics/body_pair_sw.h1
-rw-r--r--servers/physics/body_sw.cpp8
-rw-r--r--servers/physics/body_sw.h2
-rw-r--r--servers/physics/broad_phase_basic.cpp4
-rw-r--r--servers/physics/broad_phase_basic.h2
-rw-r--r--servers/physics/broad_phase_octree.h2
-rw-r--r--servers/physics/broad_phase_sw.h4
-rw-r--r--servers/physics/collision_object_sw.h6
-rw-r--r--servers/physics/collision_solver_sat.cpp25
-rw-r--r--servers/physics/collision_solver_sw.cpp5
-rw-r--r--servers/physics/joints/SCsub2
-rw-r--r--servers/physics/joints/cone_twist_joint_sw.cpp2
-rw-r--r--servers/physics/joints/generic_6dof_joint_sw.cpp72
-rw-r--r--servers/physics/joints/generic_6dof_joint_sw.h6
-rw-r--r--servers/physics/joints/hinge_joint_sw.cpp10
-rw-r--r--servers/physics/joints/jacobian_entry_sw.h2
-rw-r--r--servers/physics/joints/slider_joint_sw.cpp4
-rw-r--r--servers/physics/physics_server_sw.cpp45
-rw-r--r--servers/physics/physics_server_sw.h14
-rw-r--r--servers/physics/shape_sw.cpp8
-rw-r--r--servers/physics/shape_sw.h4
-rw-r--r--servers/physics/space_sw.cpp228
-rw-r--r--servers/physics/space_sw.h21
-rw-r--r--servers/physics/step_sw.cpp3
-rw-r--r--servers/physics_2d/area_2d_sw.h2
-rw-r--r--servers/physics_2d/area_pair_2d_sw.cpp4
-rw-r--r--servers/physics_2d/body_2d_sw.cpp7
-rw-r--r--servers/physics_2d/body_2d_sw.h2
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp2
-rw-r--r--servers/physics_2d/broad_phase_2d_basic.h2
-rw-r--r--servers/physics_2d/broad_phase_2d_hash_grid.cpp6
-rw-r--r--servers/physics_2d/broad_phase_2d_hash_grid.h2
-rw-r--r--servers/physics_2d/broad_phase_2d_sw.h4
-rw-r--r--servers/physics_2d/collision_object_2d_sw.cpp1
-rw-r--r--servers/physics_2d/collision_object_2d_sw.h26
-rw-r--r--servers/physics_2d/collision_solver_2d_sat.cpp3
-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.cpp73
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h10
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.cpp2
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.h16
-rw-r--r--servers/physics_2d/shape_2d_sw.cpp4
-rw-r--r--servers/physics_2d/space_2d_sw.cpp257
-rw-r--r--servers/physics_2d/space_2d_sw.h21
-rw-r--r--servers/physics_2d/step_2d_sw.cpp6
-rw-r--r--servers/physics_2d_server.cpp95
-rw-r--r--servers/physics_2d_server.h48
-rw-r--r--servers/physics_server.cpp119
-rw-r--r--servers/physics_server.h62
-rw-r--r--servers/register_server_types.cpp6
-rw-r--r--servers/visual/SCsub2
-rw-r--r--servers/visual/default_mouse_cursor.xpm23
-rw-r--r--servers/visual/rasterizer.cpp4
-rw-r--r--servers/visual/rasterizer.h23
-rw-r--r--servers/visual/shader_language.cpp276
-rw-r--r--servers/visual/shader_language.h24
-rw-r--r--servers/visual/shader_types.cpp12
-rw-r--r--servers/visual/shader_types.h2
-rw-r--r--servers/visual/visual_server_canvas.cpp91
-rw-r--r--servers/visual/visual_server_canvas.h16
-rw-r--r--servers/visual/visual_server_raster.cpp12
-rw-r--r--servers/visual/visual_server_raster.h19
-rw-r--r--servers/visual/visual_server_scene.cpp139
-rw-r--r--servers/visual/visual_server_scene.h32
-rw-r--r--servers/visual/visual_server_viewport.cpp17
-rw-r--r--servers/visual/visual_server_viewport.h22
-rw-r--r--servers/visual/visual_server_wrap_mt.cpp10
-rw-r--r--servers/visual/visual_server_wrap_mt.h20
-rw-r--r--servers/visual_server.cpp63
-rw-r--r--servers/visual_server.h32
108 files changed, 1725 insertions, 822 deletions
diff --git a/servers/SCsub b/servers/SCsub
index 252a18ffd3..f4af347fe6 100644
--- a/servers/SCsub
+++ b/servers/SCsub
@@ -5,8 +5,6 @@ Import('env')
env.servers_sources = []
env.add_source_files(env.servers_sources, "*.cpp")
-Export('env')
-
SConscript('arvr/SCsub')
SConscript('physics/SCsub')
SConscript('physics_2d/SCsub')
diff --git a/servers/arvr/SCsub b/servers/arvr/SCsub
index ccc76e823f..d730144861 100644
--- a/servers/arvr/SCsub
+++ b/servers/arvr/SCsub
@@ -3,5 +3,3 @@
Import('env')
env.add_source_files(env.servers_sources, "*.cpp")
-
-Export('env')
diff --git a/servers/arvr/arvr_interface.h b/servers/arvr/arvr_interface.h
index 910b401db9..b26ee6cb1b 100644
--- a/servers/arvr/arvr_interface.h
+++ b/servers/arvr/arvr_interface.h
@@ -32,7 +32,7 @@
#define ARVR_INTERFACE_H
#include "core/math/camera_matrix.h"
-#include "os/thread_safe.h"
+#include "core/os/thread_safe.h"
#include "scene/main/viewport.h"
#include "servers/arvr_server.h"
diff --git a/servers/arvr/arvr_positional_tracker.h b/servers/arvr/arvr_positional_tracker.h
index 525e47a681..69b89f11d3 100644
--- a/servers/arvr/arvr_positional_tracker.h
+++ b/servers/arvr/arvr_positional_tracker.h
@@ -31,7 +31,7 @@
#ifndef ARVR_POSITIONAL_TRACKER_H
#define ARVR_POSITIONAL_TRACKER_H
-#include "os/thread_safe.h"
+#include "core/os/thread_safe.h"
#include "servers/arvr_server.h"
/**
diff --git a/servers/arvr_server.cpp b/servers/arvr_server.cpp
index 0d1aad0dff..55f8ea8f5b 100644
--- a/servers/arvr_server.cpp
+++ b/servers/arvr_server.cpp
@@ -31,7 +31,7 @@
#include "arvr_server.h"
#include "arvr/arvr_interface.h"
#include "arvr/arvr_positional_tracker.h"
-#include "project_settings.h"
+#include "core/project_settings.h"
ARVRServer *ARVRServer::singleton = NULL;
@@ -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/arvr_server.h b/servers/arvr_server.h
index 1f4d84fe19..a28b91c225 100644
--- a/servers/arvr_server.h
+++ b/servers/arvr_server.h
@@ -31,11 +31,11 @@
#ifndef ARVR_SERVER_H
#define ARVR_SERVER_H
-#include "os/os.h"
-#include "os/thread_safe.h"
-#include "reference.h"
-#include "rid.h"
-#include "variant.h"
+#include "core/os/os.h"
+#include "core/os/thread_safe.h"
+#include "core/reference.h"
+#include "core/rid.h"
+#include "core/variant.h"
class ARVRInterface;
class ARVRPositionalTracker;
@@ -87,7 +87,7 @@ private:
uint64_t last_process_usec; /* for frame timing, usec when we did our processing */
uint64_t last_commit_usec; /* for frame timing, usec when we finished committing both eyes */
- uint64_t last_frame_usec; /* time it took between process and commiting, we should probably average this over the last x frames */
+ uint64_t last_frame_usec; /* time it took between process and committing, we should probably average this over the last x frames */
protected:
static ARVRServer *singleton;
diff --git a/servers/audio/SCsub b/servers/audio/SCsub
index afaffcfe93..3c18c18043 100644
--- a/servers/audio/SCsub
+++ b/servers/audio/SCsub
@@ -4,6 +4,4 @@ Import('env')
env.add_source_files(env.servers_sources, "*.cpp")
-Export('env')
-
SConscript("effects/SCsub")
diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp
index be36c3b748..512ff5da7b 100644
--- a/servers/audio/audio_driver_dummy.cpp
+++ b/servers/audio/audio_driver_dummy.cpp
@@ -30,8 +30,8 @@
#include "audio_driver_dummy.h"
-#include "os/os.h"
-#include "project_settings.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
Error AudioDriverDummy::init() {
diff --git a/servers/audio/audio_effect.h b/servers/audio/audio_effect.h
index b950e824c0..bbabedbc30 100644
--- a/servers/audio/audio_effect.h
+++ b/servers/audio/audio_effect.h
@@ -31,8 +31,8 @@
#ifndef AUDIOEFFECT_H
#define AUDIOEFFECT_H
-#include "audio_frame.h"
-#include "resource.h"
+#include "core/math/audio_frame.h"
+#include "core/resource.h"
class AudioEffectInstance : public Reference {
GDCLASS(AudioEffectInstance, Reference)
diff --git a/servers/audio/audio_filter_sw.h b/servers/audio/audio_filter_sw.h
index 4174f9bd51..d137ed8ff9 100644
--- a/servers/audio/audio_filter_sw.h
+++ b/servers/audio/audio_filter_sw.h
@@ -31,7 +31,7 @@
#ifndef AUDIO_FILTER_SW_H
#define AUDIO_FILTER_SW_H
-#include "math_funcs.h"
+#include "core/math/math_funcs.h"
class AudioFilterSW {
public:
diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp
index 3414351681..d9b3579812 100644
--- a/servers/audio/audio_rb_resampler.cpp
+++ b/servers/audio/audio_rb_resampler.cpp
@@ -30,7 +30,7 @@
#include "audio_rb_resampler.h"
#include "core/math/math_funcs.h"
-#include "os/os.h"
+#include "core/os/os.h"
#include "servers/audio_server.h"
int AudioRBResampler::get_channel_count() const {
@@ -79,42 +79,27 @@ uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_i
p_dest[i] = AudioFrame(v0, v1);
}
- // For now, channels higher than stereo are almost ignored
+ // This will probably never be used, but added anyway
if (C == 4) {
float v0 = rb[(pos << 2) + 0];
float v1 = rb[(pos << 2) + 1];
- float v2 = rb[(pos << 2) + 2];
- float v3 = rb[(pos << 2) + 3];
float v0n = rb[(pos_next << 2) + 0];
float v1n = rb[(pos_next << 2) + 1];
- float v2n = rb[(pos_next << 2) + 2];
- float v3n = rb[(pos_next << 2) + 3];
-
v0 += (v0n - v0) * frac;
v1 += (v1n - v1) * frac;
- v2 += (v2n - v2) * frac;
- v3 += (v3n - v3) * frac;
p_dest[i] = AudioFrame(v0, v1);
}
if (C == 6) {
- // FIXME: Lot of unused assignments here, but it seems like intermediate calculations
- // should be done as for C == 2 (C == 4 also has some unused assignments).
float v0 = rb[(pos * 6) + 0];
float v1 = rb[(pos * 6) + 1];
- float v2 = rb[(pos * 6) + 2];
- float v3 = rb[(pos * 6) + 3];
- float v4 = rb[(pos * 6) + 4];
- float v5 = rb[(pos * 6) + 5];
float v0n = rb[(pos_next * 6) + 0];
float v1n = rb[(pos_next * 6) + 1];
- float v2n = rb[(pos_next * 6) + 2];
- float v3n = rb[(pos_next * 6) + 3];
- float v4n = rb[(pos_next * 6) + 4];
- float v5n = rb[(pos_next * 6) + 5];
+ v0 += (v0n - v0) * frac;
+ v1 += (v1n - v1) * frac;
p_dest[i] = AudioFrame(v0, v1);
}
}
@@ -153,7 +138,7 @@ bool AudioRBResampler::mix(AudioFrame *p_dest, int p_frames) {
}
// Fill zeros (silence) for the rest of frames
- for (uint32_t i = target_todo; i < p_frames; i++) {
+ for (int i = target_todo; i < p_frames; i++) {
p_dest[i] = AudioFrame(0, 0);
}
}
diff --git a/servers/audio/audio_rb_resampler.h b/servers/audio/audio_rb_resampler.h
index 6ef79c93fa..b21c480fc4 100644
--- a/servers/audio/audio_rb_resampler.h
+++ b/servers/audio/audio_rb_resampler.h
@@ -31,9 +31,9 @@
#ifndef AUDIO_RB_RESAMPLER_H
#define AUDIO_RB_RESAMPLER_H
-#include "os/memory.h"
+#include "core/os/memory.h"
+#include "core/typedefs.h"
#include "servers/audio_server.h"
-#include "typedefs.h"
struct AudioRBResampler {
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index eef8aba0c4..21073a1cd1 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -29,7 +29,8 @@
/*************************************************************************/
#include "audio_stream.h"
-#include "os/os.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
//////////////////////////////
@@ -136,16 +137,20 @@ void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_fr
Vector<int32_t> buf = AudioDriver::get_singleton()->get_input_buffer();
unsigned int input_size = AudioDriver::get_singleton()->get_input_size();
+ int mix_rate = AudioDriver::get_singleton()->get_mix_rate();
+ int playback_delay = MIN(((50 * mix_rate) / 1000) * 2, buf.size() >> 1);
+#ifdef DEBUG_ENABLED
+ unsigned int input_position = AudioDriver::get_singleton()->get_input_position();
+#endif
- // p_frames is multipled by two since an AudioFrame is stereo
- if ((p_frames + MICROPHONE_PLAYBACK_DELAY * 2) > input_size) {
+ if (playback_delay > 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) {
+ if (input_size > input_ofs) {
float l = (buf[input_ofs++] >> 16) / 32768.f;
if (input_ofs >= buf.size()) {
input_ofs = 0;
@@ -162,6 +167,12 @@ void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_fr
}
}
+#ifdef DEBUG_ENABLED
+ if (input_ofs > input_position && (input_ofs - input_position) < (p_frames * 2)) {
+ print_verbose(String(get_class_name()) + " buffer underrun: input_position=" + itos(input_position) + " input_ofs=" + itos(input_ofs) + " input_size=" + itos(input_size));
+ }
+#endif
+
AudioDriver::get_singleton()->unlock();
}
@@ -174,6 +185,12 @@ float AudioStreamPlaybackMicrophone::get_stream_sampling_rate() {
}
void AudioStreamPlaybackMicrophone::start(float p_from_pos) {
+
+ if (!GLOBAL_GET("audio/enable_audio_input")) {
+ WARN_PRINTS("Need to enable Project settings > Audio > Enable Audio Input option to use capturing.");
+ return;
+ }
+
input_ofs = 0;
AudioDriver::get_singleton()->capture_start();
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index 66e1b6ee2f..f6ed45cc9c 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -31,8 +31,8 @@
#ifndef AUDIO_STREAM_H
#define AUDIO_STREAM_H
-#include "image.h"
-#include "resource.h"
+#include "core/image.h"
+#include "core/resource.h"
#include "servers/audio/audio_filter_sw.h"
#include "servers/audio_server.h"
@@ -122,8 +122,6 @@ class AudioStreamPlaybackMicrophone : public AudioStreamPlaybackResampled {
GDCLASS(AudioStreamPlaybackMicrophone, AudioStreamPlayback)
friend class AudioStreamMicrophone;
- const int MICROPHONE_PLAYBACK_DELAY = 256;
-
bool active;
unsigned int input_ofs;
diff --git a/servers/audio/effects/SCsub b/servers/audio/effects/SCsub
index ccc76e823f..d730144861 100644
--- a/servers/audio/effects/SCsub
+++ b/servers/audio/effects/SCsub
@@ -3,5 +3,3 @@
Import('env')
env.add_source_files(env.servers_sources, "*.cpp")
-
-Export('env')
diff --git a/servers/audio/effects/audio_effect_chorus.cpp b/servers/audio/effects/audio_effect_chorus.cpp
index fd9e3311e7..3c88d050f6 100644
--- a/servers/audio/effects/audio_effect_chorus.cpp
+++ b/servers/audio/effects/audio_effect_chorus.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "audio_effect_chorus.h"
-#include "math_funcs.h"
+#include "core/math/math_funcs.h"
#include "servers/audio_server.h"
void AudioEffectChorusInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
diff --git a/servers/audio/effects/audio_effect_delay.cpp b/servers/audio/effects/audio_effect_delay.cpp
index e3af898afa..abc10ee096 100644
--- a/servers/audio/effects/audio_effect_delay.cpp
+++ b/servers/audio/effects/audio_effect_delay.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "audio_effect_delay.h"
-#include "math_funcs.h"
+#include "core/math/math_funcs.h"
#include "servers/audio_server.h"
void AudioEffectDelayInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
diff --git a/servers/audio/effects/audio_effect_distortion.cpp b/servers/audio/effects/audio_effect_distortion.cpp
index c9ac0db644..0422083363 100644
--- a/servers/audio/effects/audio_effect_distortion.cpp
+++ b/servers/audio/effects/audio_effect_distortion.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "audio_effect_distortion.h"
-#include "math_funcs.h"
+#include "core/math/math_funcs.h"
#include "servers/audio_server.h"
void AudioEffectDistortionInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
diff --git a/servers/audio/effects/audio_effect_filter.h b/servers/audio/effects/audio_effect_filter.h
index 11978882bc..e8f12e5efa 100644
--- a/servers/audio/effects/audio_effect_filter.h
+++ b/servers/audio/effects/audio_effect_filter.h
@@ -96,6 +96,11 @@ VARIANT_ENUM_CAST(AudioEffectFilter::FilterDB)
class AudioEffectLowPassFilter : public AudioEffectFilter {
GDCLASS(AudioEffectLowPassFilter, AudioEffectFilter)
+
+ void _validate_property(PropertyInfo &property) const {
+ if (property.name == "gain") property.usage = 0;
+ }
+
public:
AudioEffectLowPassFilter() :
AudioEffectFilter(AudioFilterSW::LOWPASS) {}
@@ -103,6 +108,10 @@ public:
class AudioEffectHighPassFilter : public AudioEffectFilter {
GDCLASS(AudioEffectHighPassFilter, AudioEffectFilter)
+ void _validate_property(PropertyInfo &property) const {
+ if (property.name == "gain") property.usage = 0;
+ }
+
public:
AudioEffectHighPassFilter() :
AudioEffectFilter(AudioFilterSW::HIGHPASS) {}
@@ -110,6 +119,10 @@ public:
class AudioEffectBandPassFilter : public AudioEffectFilter {
GDCLASS(AudioEffectBandPassFilter, AudioEffectFilter)
+ void _validate_property(PropertyInfo &property) const {
+ if (property.name == "gain") property.usage = 0;
+ }
+
public:
AudioEffectBandPassFilter() :
AudioEffectFilter(AudioFilterSW::BANDPASS) {}
diff --git a/servers/audio/effects/audio_effect_phaser.cpp b/servers/audio/effects/audio_effect_phaser.cpp
index c0a9bd773d..3151111ec8 100644
--- a/servers/audio/effects/audio_effect_phaser.cpp
+++ b/servers/audio/effects/audio_effect_phaser.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "audio_effect_phaser.h"
-#include "math_funcs.h"
+#include "core/math/math_funcs.h"
#include "servers/audio_server.h"
void AudioEffectPhaserInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
diff --git a/servers/audio/effects/audio_effect_pitch_shift.cpp b/servers/audio/effects/audio_effect_pitch_shift.cpp
index ddd0a0db6b..f5ca8f2da4 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.cpp
+++ b/servers/audio/effects/audio_effect_pitch_shift.cpp
@@ -30,7 +30,7 @@
#include "audio_effect_pitch_shift.h"
-#include "math_funcs.h"
+#include "core/math/math_funcs.h"
#include "servers/audio_server.h"
/* Thirdparty code, so disable clang-format with Godot style */
@@ -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..5a583243ca 100644
--- a/servers/audio/effects/audio_effect_record.cpp
+++ b/servers/audio/effects/audio_effect_record.cpp
@@ -44,20 +44,25 @@ void AudioEffectRecordInstance::process(const AudioFrame *p_src_frames, AudioFra
}
}
-bool AudioEffectRecordInstance::process_silence() {
+void AudioEffectRecordInstance::_update_buffer() {
+ //Case: Frames are remaining in the buffer
+ while (ring_buffer_read_pos < ring_buffer_pos) {
+ //Read from the buffer into recording_data
+ _io_store_buffer();
+ }
+}
+
+void AudioEffectRecordInstance::_update(void *userdata) {
+ AudioEffectRecordInstance *ins = (AudioEffectRecordInstance *)userdata;
+ ins->_update_buffer();
+}
+
+bool AudioEffectRecordInstance::process_silence() const {
return true;
}
void AudioEffectRecordInstance::_io_thread_process() {
-
- //Reset recorder status
thread_active = true;
- ring_buffer_pos = 0;
- ring_buffer_read_pos = 0;
-
- //We start a new recording
- recording_data.resize(0); //Clear data completely and reset length
- is_recording = true;
while (is_recording) {
//Check: The current recording has been requested to stop
@@ -65,13 +70,9 @@ void AudioEffectRecordInstance::_io_thread_process() {
is_recording = false;
}
- //Case: Frames are remaining in the buffer
- if (ring_buffer_read_pos < ring_buffer_pos) {
- //Read from the buffer into recording_data
- _io_store_buffer();
- }
- //Case: The buffer is empty
- else if (is_recording) {
+ _update_buffer();
+
+ if (is_recording) {
//Wait to avoid too much busy-wait
OS::get_singleton()->delay_usec(500);
}
@@ -103,7 +104,35 @@ void AudioEffectRecordInstance::_thread_callback(void *_instance) {
}
void AudioEffectRecordInstance::init() {
+ //Reset recorder status
+ ring_buffer_pos = 0;
+ ring_buffer_read_pos = 0;
+
+ //We start a new recording
+ recording_data.resize(0); //Clear data completely and reset length
+ is_recording = true;
+
+#ifdef NO_THREADS
+ AudioServer::get_singleton()->add_update_callback(&AudioEffectRecordInstance::_update, this);
+#else
io_thread = Thread::create(_thread_callback, this);
+#endif
+}
+
+void AudioEffectRecordInstance::finish() {
+
+#ifdef NO_THREADS
+ AudioServer::get_singleton()->remove_update_callback(&AudioEffectRecordInstance::_update, this);
+#else
+ if (thread_active) {
+ Thread::wait_to_finish(io_thread);
+ }
+#endif
+}
+
+AudioEffectRecordInstance::~AudioEffectRecordInstance() {
+
+ finish();
}
Ref<AudioEffectInstance> AudioEffectRecord::instance() {
@@ -145,8 +174,8 @@ Ref<AudioEffectInstance> AudioEffectRecord::instance() {
void AudioEffectRecord::ensure_thread_stopped() {
recording_active = false;
- if (current_instance != 0 && current_instance->thread_active) {
- Thread::wait_to_finish(current_instance->io_thread);
+ if (current_instance != 0) {
+ current_instance->finish();
}
}
@@ -233,7 +262,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/effects/audio_effect_record.h b/servers/audio/effects/audio_effect_record.h
index e4f5ba8a23..c5e4866f17 100644
--- a/servers/audio/effects/audio_effect_record.h
+++ b/servers/audio/effects/audio_effect_record.h
@@ -31,11 +31,11 @@
#ifndef AUDIOEFFECTRECORD_H
#define AUDIOEFFECTRECORD_H
+#include "core/io/marshalls.h"
+#include "core/os/file_access.h"
+#include "core/os/os.h"
#include "core/os/thread.h"
#include "editor/import/resource_importer_wav.h"
-#include "io/marshalls.h"
-#include "os/file_access.h"
-#include "os/os.h"
#include "scene/resources/audio_stream_sample.h"
#include "servers/audio/audio_effect.h"
#include "servers/audio_server.h"
@@ -49,7 +49,7 @@ class AudioEffectRecordInstance : public AudioEffectInstance {
bool is_recording;
Thread *io_thread;
- bool thread_active = false;
+ bool thread_active;
Vector<AudioFrame> ring_buffer;
Vector<float> recording_data;
@@ -62,11 +62,18 @@ class AudioEffectRecordInstance : public AudioEffectInstance {
void _io_store_buffer();
static void _thread_callback(void *_instance);
void _init_recording();
+ void _update_buffer();
+ static void _update(void *userdata);
public:
void init();
+ void finish();
virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count);
- virtual bool process_silence();
+ virtual bool process_silence() const;
+
+ AudioEffectRecordInstance() :
+ thread_active(false) {}
+ ~AudioEffectRecordInstance();
};
class AudioEffectRecord : public AudioEffect {
diff --git a/servers/audio/effects/eq.cpp b/servers/audio/effects/eq.cpp
index b15fc7ecf4..70ac70a5a8 100644
--- a/servers/audio/effects/eq.cpp
+++ b/servers/audio/effects/eq.cpp
@@ -31,8 +31,8 @@
// Author: reduzio@gmail.com (C) 2006
#include "eq.h"
-#include "error_macros.h"
-#include "math_funcs.h"
+#include "core/error_macros.h"
+#include "core/math/math_funcs.h"
#include <math.h>
#define POW2(v) ((v) * (v))
diff --git a/servers/audio/effects/eq.h b/servers/audio/effects/eq.h
index 5c654529c3..c06f1f8bf8 100644
--- a/servers/audio/effects/eq.h
+++ b/servers/audio/effects/eq.h
@@ -33,8 +33,8 @@
#ifndef EQ_FILTER_H
#define EQ_FILTER_H
-#include "typedefs.h"
-#include "vector.h"
+#include "core/typedefs.h"
+#include "core/vector.h"
/**
@author Juan Linietsky
diff --git a/servers/audio/effects/reverb.cpp b/servers/audio/effects/reverb.cpp
index 5e31202e58..b032c91da2 100644
--- a/servers/audio/effects/reverb.cpp
+++ b/servers/audio/effects/reverb.cpp
@@ -31,27 +31,27 @@
// Author: Juan Linietsky <reduzio@gmail.com>, (C) 2006
#include "reverb.h"
-#include "math_funcs.h"
+#include "core/math/math_funcs.h"
#include <math.h>
const float Reverb::comb_tunings[MAX_COMBS] = {
//freeverb comb tunings
- 0.025306122448979593,
- 0.026938775510204082,
- 0.028956916099773241,
- 0.03074829931972789,
- 0.032244897959183672,
- 0.03380952380952381,
- 0.035306122448979592,
- 0.036666666666666667
+ 0.025306122448979593f,
+ 0.026938775510204082f,
+ 0.028956916099773241f,
+ 0.03074829931972789f,
+ 0.032244897959183672f,
+ 0.03380952380952381f,
+ 0.035306122448979592f,
+ 0.036666666666666667f
};
const float Reverb::allpass_tunings[MAX_ALLPASS] = {
//freeverb allpass tunings
- 0.0051020408163265302,
- 0.007732426303854875,
- 0.01,
- 0.012607709750566893
+ 0.0051020408163265302f,
+ 0.007732426303854875f,
+ 0.01f,
+ 0.012607709750566893f
};
void Reverb::process(float *p_src, float *p_dst, int p_frames) {
diff --git a/servers/audio/effects/reverb.h b/servers/audio/effects/reverb.h
index c3d3873dcd..03cf197456 100644
--- a/servers/audio/effects/reverb.h
+++ b/servers/audio/effects/reverb.h
@@ -33,9 +33,9 @@
#ifndef REVERB_H
#define REVERB_H
-#include "audio_frame.h"
-#include "os/memory.h"
-#include "typedefs.h"
+#include "core/math/audio_frame.h"
+#include "core/os/memory.h"
+#include "core/typedefs.h"
class Reverb {
public:
diff --git a/servers/audio/reverb_sw.cpp b/servers/audio/reverb_sw.cpp
index 52e7699deb..d078da38b4 100644
--- a/servers/audio/reverb_sw.cpp
+++ b/servers/audio/reverb_sw.cpp
@@ -29,33 +29,21 @@
/*************************************************************************/
#include "reverb_sw.h"
-#include "print_string.h"
-#include "stdlib.h"
+
+#include "core/print_string.h"
+
+#include <stdlib.h>
+
#define SETMIN(x, y) (x) = MIN((x), (y))
+
#define rangeloop(c, min, max) \
for ((c) = (min); (c) < (max); (c)++)
#define ABSDIFF(x, y) \
(((x) < (y)) ? ((y) - (x)) : ((x) - (y)))
-#ifdef bleh_MSC_VER
-
-#if _MSC_VER >= 1400
-_FORCE_INLINE_ int32_tMULSHIFT_S32(
- int32_t Factor1,
- int32_t Factor2,
- uint8_t Bits) {
-
- return __ll_rshift(
- __emul(Factor1, Factor2),
- Bits);
-}
-#endif
-
-#else
#define MULSHIFT_S32(Factor1, Factor2, Bits) \
((int)(((int64_t)(Factor1) * (Factor2)) >> (Bits)))
-#endif
struct ReverbParamsSW {
unsigned int BufferSize; // Required buffer size
diff --git a/servers/audio/reverb_sw.h b/servers/audio/reverb_sw.h
index 15f9a43183..01977d1f61 100644
--- a/servers/audio/reverb_sw.h
+++ b/servers/audio/reverb_sw.h
@@ -31,10 +31,10 @@
#ifndef REVERB_SW_H
#define REVERB_SW_H
-#include "os/memory.h"
-#include "typedefs.h"
+#include "core/os/memory.h"
+#include "core/typedefs.h"
-class ReverbParamsSW;
+struct ReverbParamsSW;
class ReverbSW {
public:
diff --git a/servers/audio/voice_rb_sw.h b/servers/audio/voice_rb_sw.h
index 42045428a8..fc02cc1827 100644
--- a/servers/audio/voice_rb_sw.h
+++ b/servers/audio/voice_rb_sw.h
@@ -31,7 +31,7 @@
#ifndef VOICE_RB_SW_H
#define VOICE_RB_SW_H
-#include "os/os.h"
+#include "core/os/os.h"
#include "servers/audio_server.h"
class VoiceRBSW {
public:
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index 14318f282b..0073f9e149 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -29,10 +29,10 @@
/*************************************************************************/
#include "audio_server.h"
-#include "io/resource_loader.h"
-#include "os/file_access.h"
-#include "os/os.h"
-#include "project_settings.h"
+#include "core/io/resource_loader.h"
+#include "core/os/file_access.h"
+#include "core/os/os.h"
+#include "core/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"
@@ -80,6 +80,14 @@ double AudioDriver::get_mix_time() const {
return total;
}
+void AudioDriver::input_buffer_init(int driver_buffer_frames) {
+
+ const int input_buffer_channels = 2;
+ input_buffer.resize(driver_buffer_frames * input_buffer_channels * 4);
+ input_position = 0;
+ input_size = 0;
+}
+
void AudioDriver::input_buffer_write(int32_t sample) {
input_buffer.write[input_position++] = sample;
@@ -143,14 +151,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() {
@@ -159,6 +172,7 @@ int AudioDriverManager::get_driver_count() {
}
void AudioDriverManager::initialize(int p_driver) {
+ GLOBAL_DEF_RST("audio/enable_audio_input", false);
int failed_driver = -1;
// Check if there is a selected driver
@@ -180,16 +194,12 @@ void AudioDriverManager::initialize(int p_driver) {
if (drivers[i]->init() == OK) {
drivers[i]->set_singleton();
- return;
+ break;
}
}
- // 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()");
+ if (driver_count > 1 && String(AudioDriver::get_singleton()->get_name()) == "Dummy") {
+ WARN_PRINT("All audio drivers failed, falling back to the dummy driver.");
}
}
@@ -451,6 +461,14 @@ void AudioServer::_mix_step() {
to_mix = buffer_size;
}
+bool AudioServer::thread_has_channel_mix_buffer(int p_bus, int p_buffer) const {
+ if (p_bus < 0 || p_bus >= buses.size())
+ return false;
+ if (p_buffer < 0 || p_buffer >= buses[p_bus]->channels.size())
+ return false;
+ return true;
+}
+
AudioFrame *AudioServer::thread_get_channel_mix_buffer(int p_bus, int p_buffer) {
ERR_FAIL_INDEX_V(p_bus, buses.size(), NULL);
@@ -720,6 +738,12 @@ float AudioServer::get_bus_volume_db(int p_bus) const {
return buses[p_bus]->volume_db;
}
+int AudioServer::get_bus_channels(int p_bus) const {
+
+ ERR_FAIL_INDEX_V(p_bus, buses.size(), 0);
+ return buses[p_bus]->channels.size();
+}
+
void AudioServer::set_bus_send(int p_bus, const StringName &p_send) {
ERR_FAIL_INDEX(p_bus, buses.size());
@@ -925,6 +949,7 @@ void AudioServer::init() {
channel_disable_threshold_db = GLOBAL_DEF_RST("audio/channel_disable_threshold_db", -60.0);
channel_disable_frames = float(GLOBAL_DEF_RST("audio/channel_disable_time", 2.0)) * get_mix_rate();
+ ProjectSettings::get_singleton()->set_custom_property_info("audio/channel_disable_time", PropertyInfo(Variant::REAL, "audio/channel_disable_time", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"));
buffer_size = 1024; //hardcoded for now
init_channels_and_buffers();
@@ -1003,11 +1028,16 @@ void AudioServer::update() {
AudioDriver::get_singleton()->reset_profiling_time();
prof_time = 0;
#endif
+
+ for (Set<CallbackItem>::Element *E = update_callbacks.front(); E; E = E->next()) {
+
+ E->get().callback(E->get().userdata);
+ }
}
void AudioServer::load_default_bus_layout() {
- if (FileAccess::exists("res://default_bus_layout.tres")) {
+ if (ResourceLoader::exists("res://default_bus_layout.tres")) {
Ref<AudioBusLayout> default_layout = ResourceLoader::load("res://default_bus_layout.tres");
if (default_layout.is_valid()) {
set_bus_layout(default_layout);
@@ -1128,6 +1158,25 @@ void AudioServer::remove_callback(AudioCallback p_callback, void *p_userdata) {
unlock();
}
+void AudioServer::add_update_callback(AudioCallback p_callback, void *p_userdata) {
+ lock();
+ CallbackItem ci;
+ ci.callback = p_callback;
+ ci.userdata = p_userdata;
+ update_callbacks.insert(ci);
+ unlock();
+}
+
+void AudioServer::remove_update_callback(AudioCallback p_callback, void *p_userdata) {
+
+ lock();
+ CallbackItem ci;
+ ci.callback = p_callback;
+ ci.userdata = p_userdata;
+ update_callbacks.erase(ci);
+ unlock();
+}
+
void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) {
ERR_FAIL_COND(p_bus_layout.is_null() || p_bus_layout->buses.size() == 0);
@@ -1249,6 +1298,8 @@ void AudioServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_bus_name", "bus_idx"), &AudioServer::get_bus_name);
ClassDB::bind_method(D_METHOD("get_bus_index", "bus_name"), &AudioServer::get_bus_index);
+ ClassDB::bind_method(D_METHOD("get_bus_channels", "bus_idx"), &AudioServer::get_bus_channels);
+
ClassDB::bind_method(D_METHOD("set_bus_volume_db", "bus_idx", "volume_db"), &AudioServer::set_bus_volume_db);
ClassDB::bind_method(D_METHOD("get_bus_volume_db", "bus_idx"), &AudioServer::get_bus_volume_db);
@@ -1284,11 +1335,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"), &AudioServer::capture_set_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);
@@ -1296,6 +1347,7 @@ void AudioServer::_bind_methods() {
ADD_SIGNAL(MethodInfo("bus_layout_changed"));
BIND_ENUM_CONSTANT(SPEAKER_MODE_STEREO);
+ BIND_ENUM_CONSTANT(SPEAKER_SURROUND_31);
BIND_ENUM_CONSTANT(SPEAKER_SURROUND_51);
BIND_ENUM_CONSTANT(SPEAKER_SURROUND_71);
}
diff --git a/servers/audio_server.h b/servers/audio_server.h
index 2663a0f968..c389e4010f 100644
--- a/servers/audio_server.h
+++ b/servers/audio_server.h
@@ -31,11 +31,11 @@
#ifndef AUDIO_SERVER_H
#define AUDIO_SERVER_H
-#include "audio_frame.h"
-#include "object.h"
-#include "os/os.h"
+#include "core/math/audio_frame.h"
+#include "core/object.h"
+#include "core/os/os.h"
+#include "core/variant.h"
#include "servers/audio/audio_effect.h"
-#include "variant.h"
class AudioDriverDummy;
class AudioStream;
@@ -59,6 +59,7 @@ protected:
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_init(int driver_buffer_frames);
void input_buffer_write(int32_t sample);
#ifdef DEBUG_ENABLED
@@ -262,6 +263,7 @@ private:
};
Set<CallbackItem> callbacks;
+ Set<CallbackItem> update_callbacks;
friend class AudioDriver;
void _driver_process(int p_frames, int32_t *p_buffer);
@@ -281,6 +283,7 @@ public:
}
//do not use from outside audio thread
+ bool thread_has_channel_mix_buffer(int p_bus, int p_buffer) const;
AudioFrame *thread_get_channel_mix_buffer(int p_bus, int p_buffer);
int thread_get_mix_buffer_size() const;
int thread_find_bus_index(const StringName &p_name);
@@ -297,6 +300,8 @@ public:
String get_bus_name(int p_bus) const;
int get_bus_index(const StringName &p_bus_name) const;
+ int get_bus_channels(int p_bus) const;
+
void set_bus_volume_db(int p_bus, float p_volume_db);
float get_bus_volume_db(int p_bus) const;
@@ -357,6 +362,9 @@ public:
void add_callback(AudioCallback p_callback, void *p_userdata);
void remove_callback(AudioCallback p_callback, void *p_userdata);
+ void add_update_callback(AudioCallback p_callback, void *p_userdata);
+ void remove_update_callback(AudioCallback p_callback, void *p_userdata);
+
void set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout);
Ref<AudioBusLayout> generate_bus_layout() const;
diff --git a/servers/physics/SCsub b/servers/physics/SCsub
index c0ee2cc739..c5cc889112 100644
--- a/servers/physics/SCsub
+++ b/servers/physics/SCsub
@@ -4,6 +4,4 @@ Import('env')
env.add_source_files(env.servers_sources, "*.cpp")
-Export('env')
-
SConscript("joints/SCsub")
diff --git a/servers/physics/area_pair_sw.cpp b/servers/physics/area_pair_sw.cpp
index d2fef0ab77..5e295edcd1 100644
--- a/servers/physics/area_pair_sw.cpp
+++ b/servers/physics/area_pair_sw.cpp
@@ -147,10 +147,10 @@ Area2PairSW::~Area2PairSW() {
if (colliding) {
- if (area_b->has_area_monitor_callback() && area_a->is_monitorable())
+ if (area_b->has_area_monitor_callback())
area_b->remove_area_from_query(area_a, shape_a, shape_b);
- if (area_a->has_area_monitor_callback() && area_b->is_monitorable())
+ if (area_a->has_area_monitor_callback())
area_a->remove_area_from_query(area_b, shape_b, shape_a);
}
diff --git a/servers/physics/area_sw.h b/servers/physics/area_sw.h
index ae19b0e04e..63a4db5d02 100644
--- a/servers/physics/area_sw.h
+++ b/servers/physics/area_sw.h
@@ -32,7 +32,7 @@
#define AREA_SW_H
#include "collision_object_sw.h"
-#include "self_list.h"
+#include "core/self_list.h"
#include "servers/physics_server.h"
//#include "servers/physics/query_sw.h"
diff --git a/servers/physics/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp
index 0ce38e4486..357fc05355 100644
--- a/servers/physics/body_pair_sw.cpp
+++ b/servers/physics/body_pair_sw.cpp
@@ -31,7 +31,7 @@
#include "body_pair_sw.h"
#include "collision_solver_sw.h"
-#include "os/os.h"
+#include "core/os/os.h"
#include "space_sw.h"
/*
diff --git a/servers/physics/body_pair_sw.h b/servers/physics/body_pair_sw.h
index fd85d77718..17ff9d6a88 100644
--- a/servers/physics/body_pair_sw.h
+++ b/servers/physics/body_pair_sw.h
@@ -76,7 +76,6 @@ class BodyPairSW : public ConstraintSW {
Contact contacts[MAX_CONTACTS];
int contact_count;
bool collided;
- int cc;
static void _contact_added_callback(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata);
diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp
index cc9681193c..74cb724bb3 100644
--- a/servers/physics/body_sw.cpp
+++ b/servers/physics/body_sw.cpp
@@ -87,6 +87,10 @@ void BodySW::update_inertias() {
for (int i = 0; i < get_shape_count(); i++) {
+ if (is_shape_disabled(i)) {
+ continue;
+ }
+
const ShapeSW *shape = get_shape(i);
real_t area = get_shape_area(i);
@@ -755,10 +759,10 @@ void BodySW::set_kinematic_margin(real_t p_margin) {
BodySW::BodySW() :
CollisionObjectSW(TYPE_BODY),
+ locked_axis(0),
active_list(this),
inertia_update_list(this),
- direct_state_query_list(this),
- locked_axis(0) {
+ direct_state_query_list(this) {
mode = PhysicsServer::BODY_MODE_RIGID;
active = true;
diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h
index 9d7b147fd6..0f7797254e 100644
--- a/servers/physics/body_sw.h
+++ b/servers/physics/body_sw.h
@@ -33,7 +33,7 @@
#include "area_sw.h"
#include "collision_object_sw.h"
-#include "vset.h"
+#include "core/vset.h"
class ConstraintSW;
diff --git a/servers/physics/broad_phase_basic.cpp b/servers/physics/broad_phase_basic.cpp
index 52483a8b14..d55951b39a 100644
--- a/servers/physics/broad_phase_basic.cpp
+++ b/servers/physics/broad_phase_basic.cpp
@@ -29,8 +29,8 @@
/*************************************************************************/
#include "broad_phase_basic.h"
-#include "list.h"
-#include "print_string.h"
+#include "core/list.h"
+#include "core/print_string.h"
BroadPhaseSW::ID BroadPhaseBasic::create(CollisionObjectSW *p_object, int p_subindex) {
diff --git a/servers/physics/broad_phase_basic.h b/servers/physics/broad_phase_basic.h
index 47fcdb3060..500b8544a1 100644
--- a/servers/physics/broad_phase_basic.h
+++ b/servers/physics/broad_phase_basic.h
@@ -32,7 +32,7 @@
#define BROAD_PHASE_BASIC_H
#include "broad_phase_sw.h"
-#include "map.h"
+#include "core/map.h"
class BroadPhaseBasic : public BroadPhaseSW {
diff --git a/servers/physics/broad_phase_octree.h b/servers/physics/broad_phase_octree.h
index e7028eba98..c4b8ecb299 100644
--- a/servers/physics/broad_phase_octree.h
+++ b/servers/physics/broad_phase_octree.h
@@ -32,7 +32,7 @@
#define BROAD_PHASE_OCTREE_H
#include "broad_phase_sw.h"
-#include "octree.h"
+#include "core/math/octree.h"
class BroadPhaseOctree : public BroadPhaseSW {
diff --git a/servers/physics/broad_phase_sw.h b/servers/physics/broad_phase_sw.h
index 7559942cd4..2db1c1dd06 100644
--- a/servers/physics/broad_phase_sw.h
+++ b/servers/physics/broad_phase_sw.h
@@ -31,8 +31,8 @@
#ifndef BROAD_PHASE_SW_H
#define BROAD_PHASE_SW_H
-#include "aabb.h"
-#include "math_funcs.h"
+#include "core/math/aabb.h"
+#include "core/math/math_funcs.h"
class CollisionObjectSW;
diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h
index b6430b38dc..dc482baccb 100644
--- a/servers/physics/collision_object_sw.h
+++ b/servers/physics/collision_object_sw.h
@@ -32,7 +32,7 @@
#define COLLISION_OBJECT_SW_H
#include "broad_phase_sw.h"
-#include "self_list.h"
+#include "core/self_list.h"
#include "servers/physics_server.h"
#include "shape_sw.h"
@@ -122,6 +122,10 @@ public:
void set_shape(int p_index, ShapeSW *p_shape);
void set_shape_transform(int p_index, const Transform &p_transform);
_FORCE_INLINE_ int get_shape_count() const { return shapes.size(); }
+ _FORCE_INLINE_ bool is_shape_disabled(int p_index) const {
+ CRASH_BAD_INDEX(p_index, shapes.size());
+ return shapes[p_index].disabled;
+ }
_FORCE_INLINE_ ShapeSW *get_shape(int p_index) const { return shapes[p_index].shape; }
_FORCE_INLINE_ const Transform &get_shape_transform(int p_index) const { return shapes[p_index].xform; }
_FORCE_INLINE_ const Transform &get_shape_inv_transform(int p_index) const { return shapes[p_index].xform_inv; }
diff --git a/servers/physics/collision_solver_sat.cpp b/servers/physics/collision_solver_sat.cpp
index b059c20c95..f17f6f7014 100644
--- a/servers/physics/collision_solver_sat.cpp
+++ b/servers/physics/collision_solver_sat.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "collision_solver_sat.h"
-#include "geometry.h"
+#include "core/math/geometry.h"
#define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.02
@@ -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
@@ -104,7 +98,6 @@ static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_
Vector3 c = rel_A.cross(rel_B).cross(rel_B);
- //if ( Math::abs(rel_A.dot(c) )<_EDGE_IS_VALID_SUPPORT_TRESHOLD ) {
if (Math::abs(rel_A.dot(c)) < CMP_EPSILON) {
// should handle somehow..
@@ -410,26 +403,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 +425,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);
diff --git a/servers/physics/collision_solver_sw.cpp b/servers/physics/collision_solver_sw.cpp
index 0037b9a862..86ef719f6f 100644
--- a/servers/physics/collision_solver_sw.cpp
+++ b/servers/physics/collision_solver_sw.cpp
@@ -31,7 +31,6 @@
#include "collision_solver_sw.h"
#include "collision_solver_sat.h"
-#include "collision_solver_sat.h"
#include "gjk_epa.h"
#define collision_solver sat_calculate_penetration
@@ -176,7 +175,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 +362,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/SCsub b/servers/physics/joints/SCsub
index ccc76e823f..d730144861 100644
--- a/servers/physics/joints/SCsub
+++ b/servers/physics/joints/SCsub
@@ -3,5 +3,3 @@
Import('env')
env.add_source_files(env.servers_sources, "*.cpp")
-
-Export('env')
diff --git a/servers/physics/joints/cone_twist_joint_sw.cpp b/servers/physics/joints/cone_twist_joint_sw.cpp
index c06f27cc57..37fcde4b76 100644
--- a/servers/physics/joints/cone_twist_joint_sw.cpp
+++ b/servers/physics/joints/cone_twist_joint_sw.cpp
@@ -332,6 +332,7 @@ void ConeTwistJointSW::set_param(PhysicsServer::ConeTwistJointParam p_param, rea
m_relaxationFactor = p_value;
} break;
+ case PhysicsServer::CONE_TWIST_MAX: break; // Can't happen, but silences warning
}
}
@@ -358,6 +359,7 @@ real_t ConeTwistJointSW::get_param(PhysicsServer::ConeTwistJointParam p_param) c
return m_relaxationFactor;
} break;
+ case PhysicsServer::CONE_TWIST_MAX: break; // Can't happen, but silences warning
}
return 0;
diff --git a/servers/physics/joints/generic_6dof_joint_sw.cpp b/servers/physics/joints/generic_6dof_joint_sw.cpp
index c95e5cef32..3a965ff800 100644
--- a/servers/physics/joints/generic_6dof_joint_sw.cpp
+++ b/servers/physics/joints/generic_6dof_joint_sw.cpp
@@ -83,7 +83,7 @@ int G6DOFRotationalLimitMotorSW::testLimitValue(real_t test_value) {
real_t G6DOFRotationalLimitMotorSW::solveAngularLimits(
real_t timeStep, Vector3 &axis, real_t jacDiagABInv,
BodySW *body0, BodySW *body1) {
- if (needApplyTorques() == false) return 0.0f;
+ if (!needApplyTorques()) return 0.0f;
real_t target_velocity = m_targetVelocity;
real_t maxMotorForce = m_maxMotorForce;
@@ -497,6 +497,31 @@ void Generic6DOFJointSW::set_param(Vector3::Axis p_axis, PhysicsServer::G6DOFJoi
m_angularLimits[p_axis].m_maxLimitForce = p_value;
} break;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_DAMPING: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_DAMPING: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_MAX: break; // Can't happen, but silences warning
}
}
@@ -572,6 +597,31 @@ real_t Generic6DOFJointSW::get_param(Vector3::Axis p_axis, PhysicsServer::G6DOFJ
return m_angularLimits[p_axis].m_maxMotorForce;
} break;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_DAMPING: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_DAMPING: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_MAX: break; // Can't happen, but silences warning
}
return 0;
}
@@ -593,6 +643,16 @@ void Generic6DOFJointSW::set_flag(Vector3::Axis p_axis, PhysicsServer::G6DOFJoin
m_angularLimits[p_axis].m_enableMotor = p_value;
} break;
+ case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_FLAG_MAX: break; // Can't happen, but silences warning
}
}
bool Generic6DOFJointSW::get_flag(Vector3::Axis p_axis, PhysicsServer::G6DOFJointAxisFlag p_flag) const {
@@ -611,6 +671,16 @@ bool Generic6DOFJointSW::get_flag(Vector3::Axis p_axis, PhysicsServer::G6DOFJoin
return m_angularLimits[p_axis].m_enableMotor;
} break;
+ case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING: {
+ // Not implemented in GodotPhysics backend
+ } break;
+ case PhysicsServer::G6DOF_JOINT_FLAG_MAX: break; // Can't happen, but silences warning
}
return 0;
diff --git a/servers/physics/joints/generic_6dof_joint_sw.h b/servers/physics/joints/generic_6dof_joint_sw.h
index b350546c5d..035525c9e6 100644
--- a/servers/physics/joints/generic_6dof_joint_sw.h
+++ b/servers/physics/joints/generic_6dof_joint_sw.h
@@ -118,14 +118,12 @@ public:
//! Is limited
bool isLimited() {
- if (m_loLimit >= m_hiLimit) return false;
- return true;
+ return (m_loLimit < m_hiLimit);
}
//! Need apply correction
bool needApplyTorques() {
- if (m_currentLimit == 0 && m_enableMotor == false) return false;
- return true;
+ return (m_enableMotor || m_currentLimit != 0);
}
//! calculates error
diff --git a/servers/physics/joints/hinge_joint_sw.cpp b/servers/physics/joints/hinge_joint_sw.cpp
index d660eba879..50de0e871e 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)
@@ -415,6 +409,7 @@ void HingeJointSW::set_param(PhysicsServer::HingeJointParam p_param, real_t p_va
case PhysicsServer::HINGE_JOINT_LIMIT_RELAXATION: m_relaxationFactor = p_value; break;
case PhysicsServer::HINGE_JOINT_MOTOR_TARGET_VELOCITY: m_motorTargetVelocity = p_value; break;
case PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE: m_maxMotorImpulse = p_value; break;
+ case PhysicsServer::HINGE_JOINT_MAX: break; // Can't happen, but silences warning
}
}
@@ -430,6 +425,7 @@ real_t HingeJointSW::get_param(PhysicsServer::HingeJointParam p_param) const {
case PhysicsServer::HINGE_JOINT_LIMIT_RELAXATION: return m_relaxationFactor;
case PhysicsServer::HINGE_JOINT_MOTOR_TARGET_VELOCITY: return m_motorTargetVelocity;
case PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE: return m_maxMotorImpulse;
+ case PhysicsServer::HINGE_JOINT_MAX: break; // Can't happen, but silences warning
}
return 0;
@@ -440,6 +436,7 @@ void HingeJointSW::set_flag(PhysicsServer::HingeJointFlag p_flag, bool p_value)
switch (p_flag) {
case PhysicsServer::HINGE_JOINT_FLAG_USE_LIMIT: m_useLimit = p_value; break;
case PhysicsServer::HINGE_JOINT_FLAG_ENABLE_MOTOR: m_enableAngularMotor = p_value; break;
+ case PhysicsServer::HINGE_JOINT_FLAG_MAX: break; // Can't happen, but silences warning
}
}
bool HingeJointSW::get_flag(PhysicsServer::HingeJointFlag p_flag) const {
@@ -447,6 +444,7 @@ bool HingeJointSW::get_flag(PhysicsServer::HingeJointFlag p_flag) const {
switch (p_flag) {
case PhysicsServer::HINGE_JOINT_FLAG_USE_LIMIT: return m_useLimit;
case PhysicsServer::HINGE_JOINT_FLAG_ENABLE_MOTOR: return m_enableAngularMotor;
+ case PhysicsServer::HINGE_JOINT_FLAG_MAX: break; // Can't happen, but silences warning
}
return false;
diff --git a/servers/physics/joints/jacobian_entry_sw.h b/servers/physics/joints/jacobian_entry_sw.h
index 42c90c9ae9..4bc1255a9a 100644
--- a/servers/physics/joints/jacobian_entry_sw.h
+++ b/servers/physics/joints/jacobian_entry_sw.h
@@ -50,7 +50,7 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
-#include "transform.h"
+#include "core/math/transform.h"
class JacobianEntrySW {
public:
diff --git a/servers/physics/joints/slider_joint_sw.cpp b/servers/physics/joints/slider_joint_sw.cpp
index c0e9660b22..30700d45f1 100644
--- a/servers/physics/joints/slider_joint_sw.cpp
+++ b/servers/physics/joints/slider_joint_sw.cpp
@@ -404,6 +404,8 @@ void SliderJointSW::set_param(PhysicsServer::SliderJointParam p_param, real_t p_
case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: m_softnessOrthoAng = p_value; break;
case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: m_restitutionOrthoAng = p_value; break;
case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: m_dampingOrthoAng = p_value; break;
+
+ case PhysicsServer::SLIDER_JOINT_MAX: break; // Can't happen, but silences warning
}
}
@@ -433,6 +435,8 @@ real_t SliderJointSW::get_param(PhysicsServer::SliderJointParam p_param) const {
case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: return m_softnessOrthoAng;
case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: return m_restitutionOrthoAng;
case PhysicsServer::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: return m_dampingOrthoAng;
+
+ case PhysicsServer::SLIDER_JOINT_MAX: break; // Can't happen, but silences warning
}
return 0;
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index 3a32c46a9b..fddb531a4f 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -32,13 +32,19 @@
#include "broad_phase_basic.h"
#include "broad_phase_octree.h"
+#include "core/os/os.h"
+#include "core/script_language.h"
#include "joints/cone_twist_joint_sw.h"
#include "joints/generic_6dof_joint_sw.h"
#include "joints/hinge_joint_sw.h"
#include "joints/pin_joint_sw.h"
#include "joints/slider_joint_sw.h"
-#include "os/os.h"
-#include "script_language.h"
+
+#define FLUSH_QUERY_CHECK \
+ if (flushing_queries) { \
+ ERR_EXPLAIN("Can't change this state while flushing queries. Use call_deferred()/set_deferred() to change monitoring state instead"); \
+ ERR_FAIL(); \
+ }
RID PhysicsServerSW::shape_create(ShapeType p_shape) {
@@ -124,6 +130,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 +305,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);
@@ -344,6 +358,8 @@ void PhysicsServerSW::area_clear_shapes(RID p_area) {
void PhysicsServerSW::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) {
+ FLUSH_QUERY_CHECK
+
AreaSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
ERR_FAIL_INDEX(p_shape_idx, area->get_shape_count());
@@ -427,6 +443,8 @@ void PhysicsServerSW::area_set_collision_mask(RID p_area, uint32_t p_mask) {
void PhysicsServerSW::area_set_monitorable(RID p_area, bool p_monitorable) {
+ FLUSH_QUERY_CHECK
+
AreaSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
@@ -574,6 +592,8 @@ RID PhysicsServerSW::body_get_shape(RID p_body, int p_shape_idx) const {
void PhysicsServerSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) {
+ FLUSH_QUERY_CHECK
+
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
@@ -941,7 +961,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);
@@ -950,7 +982,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) {
@@ -1439,6 +1471,8 @@ void PhysicsServerSW::flush_queries() {
doing_sync = true;
+ flushing_queries = true;
+
uint64_t time_beg = OS::get_singleton()->get_ticks_usec();
for (Set<const SpaceSW *>::Element *E = active_spaces.front(); E; E = E->next()) {
@@ -1447,6 +1481,8 @@ void PhysicsServerSW::flush_queries() {
space->call_queries();
}
+ flushing_queries = false;
+
if (ScriptDebugger::get_singleton() && ScriptDebugger::get_singleton()->is_profiling()) {
uint64_t total_time[SpaceSW::ELAPSED_TIME_MAX];
@@ -1560,6 +1596,7 @@ PhysicsServerSW::PhysicsServerSW() {
collision_pairs = 0;
active = true;
+ flushing_queries = false;
};
PhysicsServerSW::~PhysicsServerSW(){
diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h
index 1c5754124d..c361d00fcc 100644
--- a/servers/physics/physics_server_sw.h
+++ b/servers/physics/physics_server_sw.h
@@ -51,6 +51,8 @@ class PhysicsServerSW : public PhysicsServer {
int active_objects;
int collision_pairs;
+ bool flushing_queries;
+
StepSW *stepper;
Set<const SpaceSW *> active_spaces;
@@ -85,6 +87,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 */
@@ -230,7 +236,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);
@@ -341,6 +348,9 @@ public:
virtual void generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag, bool p_enable);
virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag);
+ virtual void generic_6dof_joint_set_precision(RID p_joint, int precision) {}
+ virtual int generic_6dof_joint_get_precision(RID p_joint) { return 0; }
+
virtual JointType joint_get_type(RID p_joint) const;
virtual void joint_set_solver_priority(RID p_joint, int p_priority);
@@ -360,6 +370,8 @@ public:
virtual void flush_queries();
virtual void finish();
+ virtual bool is_flushing_queries() const { return flushing_queries; }
+
int get_process_info(ProcessInfo p_info);
PhysicsServerSW();
diff --git a/servers/physics/shape_sw.cpp b/servers/physics/shape_sw.cpp
index 9d2e5e846d..e7fc821c2c 100644
--- a/servers/physics/shape_sw.cpp
+++ b/servers/physics/shape_sw.cpp
@@ -30,9 +30,9 @@
#include "shape_sw.h"
-#include "geometry.h"
-#include "quick_hull.h"
-#include "sort.h"
+#include "core/math/geometry.h"
+#include "core/math/quick_hull.h"
+#include "core/sort.h"
#define _POINT_SNAP 0.001953125
#define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.0002
@@ -1047,7 +1047,7 @@ void FaceShapeSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_su
/** FIND SUPPORT VERTEX **/
int vert_support_idx = -1;
- real_t support_max;
+ real_t support_max = 0;
for (int i = 0; i < 3; i++) {
diff --git a/servers/physics/shape_sw.h b/servers/physics/shape_sw.h
index 7be818b23c..073d19e317 100644
--- a/servers/physics/shape_sw.h
+++ b/servers/physics/shape_sw.h
@@ -31,8 +31,8 @@
#ifndef SHAPE_SW_H
#define SHAPE_SW_H
-#include "bsp_tree.h"
-#include "geometry.h"
+#include "core/math/bsp_tree.h"
+#include "core/math/geometry.h"
#include "servers/physics_server.h"
/*
diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp
index b604e5cdf6..3b5344f020 100644
--- a/servers/physics/space_sw.cpp
+++ b/servers/physics/space_sw.cpp
@@ -31,15 +31,25 @@
#include "space_sw.h"
#include "collision_solver_sw.h"
+#include "core/project_settings.h"
#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);
@@ -95,7 +105,7 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vecto
int amount = space->broadphase->cull_segment(begin, end, space->intersection_query_results, SpaceSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
- //todo, create another array tha references results, compute AABBs and check closest point to ray origin, sort, and stop evaluating results when beyond first collision
+ //todo, create another array that references results, compute AABBs and check closest point to ray origin, sort, and stop evaluating results when beyond first collision
bool collided = false;
Vector3 res_point, res_normal;
@@ -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,154 @@ 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;
+
+ bool shapes_found = false;
+
+ for (int i = 0; i < p_body->get_shape_count(); i++) {
+
+ if (p_body->is_shape_set_as_disabled(i))
+ continue;
+
+ if (!shapes_found) {
+ body_aabb = p_body->get_shape_aabb(i);
+ shapes_found = true;
+ } else {
+ body_aabb = body_aabb.merge(p_body->get_shape_aabb(i));
+ }
+ }
+
+ if (!shapes_found) {
+ return 0;
+ }
+ // 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
@@ -555,13 +701,23 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve
r_result->collider_shape = 0;
}
AABB body_aabb;
+ bool shapes_found = false;
for (int i = 0; i < p_body->get_shape_count(); i++) {
- if (i == 0)
+ if (p_body->is_shape_set_as_disabled(i))
+ continue;
+
+ if (!shapes_found) {
body_aabb = p_body->get_shape_aabb(i);
- else
+ shapes_found = true;
+ } else {
body_aabb = body_aabb.merge(p_body->get_shape_aabb(i));
+ }
+ }
+
+ if (!shapes_found) {
+ return false;
}
// Undo the currently transform the physics server is aware of and apply the provided one
@@ -597,6 +753,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 +815,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 +841,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 +869,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 {
@@ -1042,6 +1203,7 @@ SpaceSW::SpaceSW() {
body_linear_velocity_sleep_threshold = GLOBAL_DEF("physics/3d/sleep_threshold_linear", 0.1);
body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/3d/sleep_threshold_angular", (8.0 / 180.0 * Math_PI));
body_time_to_sleep = GLOBAL_DEF("physics/3d/time_before_sleep", 0.5);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/time_before_sleep", PropertyInfo(Variant::REAL, "physics/3d/time_before_sleep", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"));
body_angular_velocity_damp_ratio = 10;
broadphase = BroadPhaseSW::create_func();
diff --git a/servers/physics/space_sw.h b/servers/physics/space_sw.h
index 4d864e9a51..d550b374e3 100644
--- a/servers/physics/space_sw.h
+++ b/servers/physics/space_sw.h
@@ -37,9 +37,9 @@
#include "body_sw.h"
#include "broad_phase_sw.h"
#include "collision_object_sw.h"
-#include "hash_map.h"
-#include "project_settings.h"
-#include "typedefs.h"
+#include "core/hash_map.h"
+#include "core/project_settings.h"
+#include "core/typedefs.h"
class PhysicsDirectSpaceStateSW : public PhysicsDirectSpaceState {
@@ -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..5238f24b20 100644
--- a/servers/physics/step_sw.cpp
+++ b/servers/physics/step_sw.cpp
@@ -31,7 +31,7 @@
#include "step_sw.h"
#include "joints_sw.h"
-#include "os/os.h"
+#include "core/os/os.h"
void StepSW::_populate_island(BodySW *p_body, BodySW **p_island, ConstraintSW **p_constraint_island) {
@@ -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/area_2d_sw.h b/servers/physics_2d/area_2d_sw.h
index d2058ad5af..90e30f68bc 100644
--- a/servers/physics_2d/area_2d_sw.h
+++ b/servers/physics_2d/area_2d_sw.h
@@ -32,7 +32,7 @@
#define AREA_2D_SW_H
#include "collision_object_2d_sw.h"
-#include "self_list.h"
+#include "core/self_list.h"
#include "servers/physics_2d_server.h"
//#include "servers/physics/query_sw.h"
diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp
index 9d515d2183..cdd35cf657 100644
--- a/servers/physics_2d/area_pair_2d_sw.cpp
+++ b/servers/physics_2d/area_pair_2d_sw.cpp
@@ -147,10 +147,10 @@ Area2Pair2DSW::~Area2Pair2DSW() {
if (colliding) {
- if (area_b->has_area_monitor_callback() && area_a->is_monitorable())
+ if (area_b->has_area_monitor_callback())
area_b->remove_area_from_query(area_a, shape_a, shape_b);
- if (area_a->has_area_monitor_callback() && area_b->is_monitorable())
+ if (area_a->has_area_monitor_callback())
area_a->remove_area_from_query(area_b, shape_b, shape_a);
}
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index aa063d6c1e..475c9ba977 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -61,6 +61,10 @@ void Body2DSW::update_inertias() {
for (int i = 0; i < get_shape_count(); i++) {
+ if (is_shape_disabled(i)) {
+ continue;
+ }
+
const Shape2DSW *shape = get_shape(i);
real_t area = get_shape_aabb(i).get_area();
@@ -511,8 +515,7 @@ void Body2DSW::integrate_forces(real_t p_step) {
if (continuous_cd_mode != Physics2DServer::CCD_MODE_DISABLED) {
- motion = new_transform.get_origin() - get_transform().get_origin();
- //linear_velocity*p_step;
+ motion = linear_velocity * p_step;
do_motion = true;
}
}
diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h
index 69184ad484..97dff69a20 100644
--- a/servers/physics_2d/body_2d_sw.h
+++ b/servers/physics_2d/body_2d_sw.h
@@ -33,7 +33,7 @@
#include "area_2d_sw.h"
#include "collision_object_2d_sw.h"
-#include "vset.h"
+#include "core/vset.h"
class Constraint2DSW;
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index 2633edf7bb..93a05b74ef 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -138,7 +138,7 @@ void BodyPair2DSW::_validate_contacts() {
Contact &c = contacts[i];
bool erase = false;
- if (c.reused == false) {
+ if (!c.reused) {
//was left behind in previous frame
erase = true;
} else {
diff --git a/servers/physics_2d/broad_phase_2d_basic.h b/servers/physics_2d/broad_phase_2d_basic.h
index f0f0b3df88..da5dc38b8e 100644
--- a/servers/physics_2d/broad_phase_2d_basic.h
+++ b/servers/physics_2d/broad_phase_2d_basic.h
@@ -31,7 +31,7 @@
#ifndef BROAD_PHASE_2D_BASIC_H
#define BROAD_PHASE_2D_BASIC_H
-#include "map.h"
+#include "core/map.h"
#include "space_2d_sw.h"
class BroadPhase2DBasic : public BroadPhase2DSW {
diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.cpp b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
index 1a5b2d5e3a..95195c8fff 100644
--- a/servers/physics_2d/broad_phase_2d_hash_grid.cpp
+++ b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "broad_phase_2d_hash_grid.h"
-#include "project_settings.h"
+#include "core/project_settings.h"
#define LARGE_ELEMENT_FI 1.01239812
@@ -635,11 +635,15 @@ BroadPhase2DSW *BroadPhase2DHashGrid::_create() {
BroadPhase2DHashGrid::BroadPhase2DHashGrid() {
hash_table_size = GLOBAL_DEF("physics/2d/bp_hash_table_size", 4096);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/bp_hash_table_size", PropertyInfo(Variant::INT, "physics/2d/bp_hash_table_size", PROPERTY_HINT_RANGE, "0,8192,1,or_greater"));
hash_table_size = Math::larger_prime(hash_table_size);
hash_table = memnew_arr(PosBin *, hash_table_size);
cell_size = GLOBAL_DEF("physics/2d/cell_size", 128);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/cell_size", PropertyInfo(Variant::INT, "physics/2d/cell_size", PROPERTY_HINT_RANGE, "0,512,1,or_greater"));
+
large_object_min_surface = GLOBAL_DEF("physics/2d/large_object_surface_threshold_in_cells", 512);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/large_object_surface_threshold_in_cells", PropertyInfo(Variant::INT, "physics/2d/large_object_surface_threshold_in_cells", PROPERTY_HINT_RANGE, "0,1024,1,or_greater"));
for (uint32_t i = 0; i < hash_table_size; i++)
hash_table[i] = NULL;
diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.h b/servers/physics_2d/broad_phase_2d_hash_grid.h
index 5188abc837..0ecb915a7b 100644
--- a/servers/physics_2d/broad_phase_2d_hash_grid.h
+++ b/servers/physics_2d/broad_phase_2d_hash_grid.h
@@ -32,7 +32,7 @@
#define BROAD_PHASE_2D_HASH_GRID_H
#include "broad_phase_2d_sw.h"
-#include "map.h"
+#include "core/map.h"
class BroadPhase2DHashGrid : public BroadPhase2DSW {
diff --git a/servers/physics_2d/broad_phase_2d_sw.h b/servers/physics_2d/broad_phase_2d_sw.h
index 80ae970624..5b512dac76 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 "core/math/math_funcs.h"
+#include "core/math/rect2.h"
class CollisionObject2DSW;
diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp
index 4dd5b2040f..2f5b484040 100644
--- a/servers/physics_2d/collision_object_2d_sw.cpp
+++ b/servers/physics_2d/collision_object_2d_sw.cpp
@@ -244,6 +244,7 @@ CollisionObject2DSW::CollisionObject2DSW(Type p_type) {
type = p_type;
space = NULL;
instance_id = 0;
+ canvas_instance_id = 0;
collision_mask = 1;
collision_layer = 1;
pickable = true;
diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h
index 393c4a6ed7..2bf8cba572 100644
--- a/servers/physics_2d/collision_object_2d_sw.h
+++ b/servers/physics_2d/collision_object_2d_sw.h
@@ -32,7 +32,7 @@
#define COLLISION_OBJECT_2D_SW_H
#include "broad_phase_2d_sw.h"
-#include "self_list.h"
+#include "core/self_list.h"
#include "servers/physics_2d_server.h"
#include "shape_2d_sw.h"
@@ -49,6 +49,7 @@ private:
Type type;
RID self;
ObjectID instance_id;
+ ObjectID canvas_instance_id;
bool pickable;
struct Shape {
@@ -102,6 +103,9 @@ public:
_FORCE_INLINE_ void set_instance_id(const ObjectID &p_instance_id) { instance_id = p_instance_id; }
_FORCE_INLINE_ ObjectID get_instance_id() const { return instance_id; }
+ _FORCE_INLINE_ void set_canvas_instance_id(const ObjectID &p_canvas_instance_id) { canvas_instance_id = p_canvas_instance_id; }
+ _FORCE_INLINE_ ObjectID get_canvas_instance_id() const { return canvas_instance_id; }
+
void _shape_changed();
_FORCE_INLINE_ Type get_type() const { return type; }
@@ -111,24 +115,28 @@ public:
void set_shape_metadata(int p_index, const Variant &p_metadata);
_FORCE_INLINE_ int get_shape_count() const { return shapes.size(); }
+ _FORCE_INLINE_ bool is_shape_disabled(int p_index) const {
+ CRASH_BAD_INDEX(p_index, shapes.size());
+ return shapes[p_index].disabled;
+ }
_FORCE_INLINE_ Shape2DSW *get_shape(int p_index) const {
- ERR_FAIL_INDEX_V(p_index, shapes.size(), NULL);
+ CRASH_BAD_INDEX(p_index, shapes.size());
return shapes[p_index].shape;
}
_FORCE_INLINE_ const Transform2D &get_shape_transform(int p_index) const {
- ERR_FAIL_INDEX_V(p_index, shapes.size(), Transform2D());
+ CRASH_BAD_INDEX(p_index, shapes.size());
return shapes[p_index].xform;
}
_FORCE_INLINE_ const Transform2D &get_shape_inv_transform(int p_index) const {
- ERR_FAIL_INDEX_V(p_index, shapes.size(), Transform2D());
+ CRASH_BAD_INDEX(p_index, shapes.size());
return shapes[p_index].xform_inv;
}
_FORCE_INLINE_ const Rect2 &get_shape_aabb(int p_index) const {
- ERR_FAIL_INDEX_V(p_index, shapes.size(), Rect2());
+ CRASH_BAD_INDEX(p_index, shapes.size());
return shapes[p_index].aabb_cache;
}
_FORCE_INLINE_ const Variant &get_shape_metadata(int p_index) const {
- ERR_FAIL_INDEX_V(p_index, shapes.size(), Variant());
+ CRASH_BAD_INDEX(p_index, shapes.size());
return shapes[p_index].metadata;
}
@@ -138,16 +146,16 @@ public:
void set_shape_as_disabled(int p_idx, bool p_disabled);
_FORCE_INLINE_ bool is_shape_set_as_disabled(int p_idx) const {
- ERR_FAIL_INDEX_V(p_idx, shapes.size(), false);
+ CRASH_BAD_INDEX(p_idx, shapes.size());
return shapes[p_idx].disabled;
}
_FORCE_INLINE_ void set_shape_as_one_way_collision(int p_idx, bool p_one_way_collision) {
- ERR_FAIL_INDEX(p_idx, shapes.size());
+ CRASH_BAD_INDEX(p_idx, shapes.size());
shapes.write[p_idx].one_way_collision = p_one_way_collision;
}
_FORCE_INLINE_ bool is_shape_set_as_one_way_collision(int p_idx) const {
- ERR_FAIL_INDEX_V(p_idx, shapes.size(), false);
+ CRASH_BAD_INDEX(p_idx, shapes.size());
return shapes[p_idx].one_way_collision;
}
diff --git a/servers/physics_2d/collision_solver_2d_sat.cpp b/servers/physics_2d/collision_solver_2d_sat.cpp
index 0d1ffca50d..0f32f2ec85 100644
--- a/servers/physics_2d/collision_solver_2d_sat.cpp
+++ b/servers/physics_2d/collision_solver_2d_sat.cpp
@@ -30,7 +30,7 @@
#include "collision_solver_2d_sat.h"
-#include "geometry.h"
+#include "core/math/geometry.h"
struct _CollectorCallback2D {
@@ -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 15e80bcd5e..45310ec4b3 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -32,9 +32,15 @@
#include "broad_phase_2d_basic.h"
#include "broad_phase_2d_hash_grid.h"
#include "collision_solver_2d_sw.h"
-#include "os/os.h"
-#include "project_settings.h"
-#include "script_language.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
+#include "core/script_language.h"
+
+#define FLUSH_QUERY_CHECK \
+ if (flushing_queries) { \
+ ERR_EXPLAIN("Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead"); \
+ ERR_FAIL(); \
+ }
RID Physics2DServerSW::_shape_create(ShapeType p_shape) {
@@ -169,15 +175,18 @@ void Physics2DServerSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 &
cbk->invalid_by_dir++;
return;
}
- if (cbk->valid_dir.dot((p_point_A - p_point_B).normalized()) < 0.7071) {
+ Vector2 rel_dir = (p_point_A - p_point_B).normalized();
+
+ if (cbk->valid_dir.dot(rel_dir) < 0.7071) { //sqrt(2)/2.0 - 45 degrees
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;
}
}
@@ -398,6 +407,8 @@ void Physics2DServerSW::area_set_shape_transform(RID p_area, int p_shape_idx, co
void Physics2DServerSW::area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled) {
+ FLUSH_QUERY_CHECK
+
Area2DSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
@@ -468,6 +479,27 @@ ObjectID Physics2DServerSW::area_get_object_instance_id(RID p_area) const {
return area->get_instance_id();
}
+void Physics2DServerSW::area_attach_canvas_instance_id(RID p_area, ObjectID p_ID) {
+
+ if (space_owner.owns(p_area)) {
+ Space2DSW *space = space_owner.get(p_area);
+ p_area = space->get_default_area()->get_self();
+ }
+ Area2DSW *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+ area->set_canvas_instance_id(p_ID);
+}
+ObjectID Physics2DServerSW::area_get_canvas_instance_id(RID p_area) const {
+
+ if (space_owner.owns(p_area)) {
+ Space2DSW *space = space_owner.get(p_area);
+ p_area = space->get_default_area()->get_self();
+ }
+ Area2DSW *area = area_owner.get(p_area);
+ ERR_FAIL_COND_V(!area, 0);
+ return area->get_canvas_instance_id();
+}
+
void Physics2DServerSW::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) {
if (space_owner.owns(p_area)) {
@@ -515,6 +547,8 @@ void Physics2DServerSW::area_set_pickable(RID p_area, bool p_pickable) {
void Physics2DServerSW::area_set_monitorable(RID p_area, bool p_monitorable) {
+ FLUSH_QUERY_CHECK
+
Area2DSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
@@ -593,6 +627,8 @@ RID Physics2DServerSW::body_get_space(RID p_body) const {
void Physics2DServerSW::body_set_mode(RID p_body, BodyMode p_mode) {
+ FLUSH_QUERY_CHECK
+
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
@@ -695,6 +731,8 @@ void Physics2DServerSW::body_clear_shapes(RID p_body) {
void Physics2DServerSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) {
+ FLUSH_QUERY_CHECK
+
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
@@ -743,6 +781,22 @@ uint32_t Physics2DServerSW::body_get_object_instance_id(RID p_body) const {
return body->get_instance_id();
};
+void Physics2DServerSW::body_attach_canvas_instance_id(RID p_body, uint32_t p_ID) {
+
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_canvas_instance_id(p_ID);
+};
+
+uint32_t Physics2DServerSW::body_get_canvas_instance_id(RID p_body) const {
+
+ Body2DSW *body = body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, 0);
+
+ return body->get_canvas_instance_id();
+};
+
void Physics2DServerSW::body_set_collision_layer(RID p_body, uint32_t p_layer) {
Body2DSW *body = body_owner.get(p_body);
@@ -1308,6 +1362,8 @@ void Physics2DServerSW::flush_queries() {
if (!active)
return;
+ flushing_queries = true;
+
uint64_t time_beg = OS::get_singleton()->get_ticks_usec();
for (Set<const Space2DSW *>::Element *E = active_spaces.front(); E; E = E->next()) {
@@ -1316,6 +1372,8 @@ void Physics2DServerSW::flush_queries() {
space->call_queries();
}
+ flushing_queries = false;
+
if (ScriptDebugger::get_singleton() && ScriptDebugger::get_singleton()->is_profiling()) {
uint64_t total_time[Space2DSW::ELAPSED_TIME_MAX];
@@ -1394,6 +1452,7 @@ Physics2DServerSW::Physics2DServerSW() {
active_objects = 0;
collision_pairs = 0;
using_threads = int(ProjectSettings::get_singleton()->get("physics/2d/thread_model")) == 2;
+ flushing_queries = false;
};
Physics2DServerSW::~Physics2DServerSW(){
diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h
index d4fc44b1d7..4f33873219 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -54,6 +54,8 @@ class Physics2DServerSW : public Physics2DServer {
bool using_threads;
+ bool flushing_queries;
+
Step2DSW *stepper;
Set<const Space2DSW *> active_spaces;
@@ -144,6 +146,9 @@ public:
virtual void area_attach_object_instance_id(RID p_area, ObjectID p_ID);
virtual ObjectID area_get_object_instance_id(RID p_area) const;
+ virtual void area_attach_canvas_instance_id(RID p_area, ObjectID p_ID);
+ virtual ObjectID area_get_canvas_instance_id(RID p_area) const;
+
virtual void area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value);
virtual void area_set_transform(RID p_area, const Transform2D &p_transform);
@@ -188,6 +193,9 @@ public:
virtual void body_attach_object_instance_id(RID p_body, uint32_t p_ID);
virtual uint32_t body_get_object_instance_id(RID p_body) const;
+ virtual void body_attach_canvas_instance_id(RID p_body, uint32_t p_ID);
+ virtual uint32_t body_get_canvas_instance_id(RID p_body) const;
+
virtual void body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode);
virtual CCDMode body_get_continuous_collision_detection_mode(RID p_body) const;
@@ -272,6 +280,8 @@ public:
virtual void end_sync();
virtual void finish();
+ virtual bool is_flushing_queries() const { return flushing_queries; }
+
int get_process_info(ProcessInfo p_info);
Physics2DServerSW();
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.cpp b/servers/physics_2d/physics_2d_server_wrap_mt.cpp
index 804b93ecd8..3ded4b717a 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.cpp
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.cpp
@@ -30,7 +30,7 @@
#include "physics_2d_server_wrap_mt.h"
-#include "os/os.h"
+#include "core/os/os.h"
void Physics2DServerWrapMT::thread_exit() {
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h
index 6b34fb9739..e736854077 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.h
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.h
@@ -31,9 +31,9 @@
#ifndef PHYSICS2DSERVERWRAPMT_H
#define PHYSICS2DSERVERWRAPMT_H
-#include "command_queue_mt.h"
-#include "os/thread.h"
-#include "project_settings.h"
+#include "core/command_queue_mt.h"
+#include "core/os/thread.h"
+#include "core/project_settings.h"
#include "servers/physics_2d_server.h"
#ifdef DEBUG_SYNC
@@ -154,6 +154,9 @@ public:
FUNC2(area_attach_object_instance_id, RID, ObjectID);
FUNC1RC(ObjectID, area_get_object_instance_id, RID);
+ FUNC2(area_attach_canvas_instance_id, RID, ObjectID);
+ FUNC1RC(ObjectID, area_get_canvas_instance_id, RID);
+
FUNC3(area_set_param, RID, AreaParameter, const Variant &);
FUNC2(area_set_transform, RID, const Transform2D &);
@@ -199,6 +202,9 @@ public:
FUNC2(body_attach_object_instance_id, RID, uint32_t);
FUNC1RC(uint32_t, body_get_object_instance_id, RID);
+ FUNC2(body_attach_canvas_instance_id, RID, uint32_t);
+ FUNC1RC(uint32_t, body_get_canvas_instance_id, RID);
+
FUNC2(body_set_continuous_collision_detection_mode, RID, CCDMode);
FUNC1RC(CCDMode, body_get_continuous_collision_detection_mode, RID);
@@ -306,6 +312,10 @@ public:
virtual void flush_queries();
virtual void finish();
+ virtual bool is_flushing_queries() const {
+ return physics_2d_server->is_flushing_queries();
+ }
+
int get_process_info(ProcessInfo p_info) {
return physics_2d_server->get_process_info(p_info);
}
diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp
index dc8ec23e69..94b0a0a0c7 100644
--- a/servers/physics_2d/shape_2d_sw.cpp
+++ b/servers/physics_2d/shape_2d_sw.cpp
@@ -30,8 +30,8 @@
#include "shape_2d_sw.h"
-#include "geometry.h"
-#include "sort.h"
+#include "core/math/geometry.h"
+#include "core/sort.h"
void Shape2DSW::configure(const Rect2 &p_aabb) {
aabb = p_aabb;
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index 6e45951f42..720742c198 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -31,15 +31,25 @@
#include "space_2d_sw.h"
#include "collision_solver_2d_sw.h"
-#include "pair.h"
+#include "core/os/os.h"
+#include "core/pair.h"
#include "physics_2d_server_sw.h"
+_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) {
-_FORCE_INLINE_ static bool _can_collide_with(CollisionObject2DSW *p_object, uint32_t 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 p_object->get_collision_layer() & p_collision_mask;
+ 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_impl(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, bool p_filter_by_canvas, ObjectID p_canvas_instance_id) {
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()))
@@ -65,6 +75,9 @@ int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeRe
if (p_pick_point && !col_obj->is_pickable())
continue;
+ if (p_filter_by_canvas && col_obj->get_canvas_instance_id() != p_canvas_instance_id)
+ continue;
+
int shape_idx = space->intersection_query_subindex_results[i];
Shape2DSW *shape = col_obj->get_shape(shape_idx);
@@ -90,7 +103,17 @@ 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) {
+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) {
+
+ return _intersect_point_impl(p_point, r_results, p_result_max, p_exclude, p_collision_mask, p_collide_with_bodies, p_collide_with_areas, p_pick_point);
+}
+
+int Physics2DDirectSpaceStateSW::intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_instance_id, 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) {
+
+ return _intersect_point_impl(p_point, r_results, p_result_max, p_exclude, p_collision_mask, p_collide_with_bodies, p_collide_with_areas, p_pick_point, true, p_canvas_instance_id);
+}
+
+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);
@@ -102,7 +125,7 @@ bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vec
int amount = space->broadphase->cull_segment(begin, end, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
- //todo, create another array tha references results, compute AABBs and check closest point to ray origin, sort, and stop evaluating results when beyond first collision
+ //todo, create another array that references results, compute AABBs and check closest point to ray origin, sort, and stop evaluating results when beyond first collision
bool collided = false;
Vector2 res_point, res_normal;
@@ -112,7 +135,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 +193,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 +213,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 +238,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 +247,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 +254,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 +263,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 +308,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 +339,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];
@@ -356,6 +365,8 @@ struct _RestCallbackData2D {
const CollisionObject2DSW *object;
const CollisionObject2DSW *best_object;
+ int local_shape;
+ int best_local_shape;
int shape;
int best_shape;
Vector2 best_contact;
@@ -386,9 +397,10 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B,
rd->best_normal = contact_rel / len;
rd->best_object = rd->object;
rd->best_shape = rd->shape;
+ rd->best_local_shape = rd->local_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 +418,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];
@@ -419,6 +431,7 @@ bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_sh
rcd.valid_depth = 0;
rcd.object = col_obj;
rcd.shape = shape_idx;
+ rcd.local_shape = 0;
bool sc = CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, NULL, p_margin);
if (!sc)
continue;
@@ -491,12 +504,23 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
Rect2 body_aabb;
+ bool shapes_found = false;
+
for (int i = 0; i < p_body->get_shape_count(); i++) {
- if (i == 0)
+ if (p_body->is_shape_set_as_disabled(i))
+ continue;
+
+ if (!shapes_found) {
body_aabb = p_body->get_shape_aabb(i);
- else
+ shapes_found = true;
+ } else {
body_aabb = body_aabb.merge(p_body->get_shape_aabb(i));
+ }
+ }
+
+ if (!shapes_found) {
+ return 0;
}
// Undo the currently transform the physics server is aware of and apply the provided one
@@ -559,9 +583,11 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
}
}
+ Transform2D col_obj_shape_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
+
if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
- cbk.valid_dir = body_shape_xform.get_axis(1).normalized();
+ cbk.valid_dir = col_obj_shape_xform.get_axis(1).normalized();
cbk.valid_depth = p_margin; //only valid depth is the collision margin
cbk.invalid_by_dir = 0;
@@ -572,7 +598,7 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
}
Shape2DSW *against_shape = col_obj->get_shape(shape_idx);
- if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, NULL, p_margin)) {
+ if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, NULL, p_margin)) {
if (cbk.amount > 0) {
collided = true;
}
@@ -651,12 +677,23 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
}
Rect2 body_aabb;
+ bool shapes_found = false;
+
for (int i = 0; i < p_body->get_shape_count(); i++) {
- if (i == 0)
+ if (p_body->is_shape_set_as_disabled(i))
+ continue;
+
+ if (!shapes_found) {
body_aabb = p_body->get_shape_aabb(i);
- else
+ shapes_found = true;
+ } else {
body_aabb = body_aabb.merge(p_body->get_shape_aabb(i));
+ }
+ }
+
+ if (!shapes_found) {
+ return false;
}
// Undo the currently transform the physics server is aware of and apply the provided one
@@ -667,6 +704,8 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
ExcludedShapeSW excluded_shape_pairs[max_excluded_shape_pairs];
int excluded_shape_pair_count = 0;
+ float separation_margin = MIN(p_margin, MAX(0.0, p_motion.length() - CMP_EPSILON)); //don't separate by more than the intended motion
+
Transform2D body_transform = p_from;
{
@@ -714,24 +753,42 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
}
}
+ Transform2D col_obj_shape_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
+
if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
- cbk.valid_dir = body_shape_xform.get_axis(1).normalized();
+ cbk.valid_dir = col_obj_shape_xform.get_axis(1).normalized();
+
cbk.valid_depth = p_margin; //only valid depth is the collision margin
cbk.invalid_by_dir = 0;
+ if (col_obj->get_type() == CollisionObject2DSW::TYPE_BODY) {
+ const Body2DSW *b = static_cast<const Body2DSW *>(col_obj);
+ if (b->get_mode() == Physics2DServer::BODY_MODE_KINEMATIC || b->get_mode() == Physics2DServer::BODY_MODE_RIGID) {
+ //fix for moving platforms (kinematic and dynamic), margin is increased by how much it moved in the given direction
+ Vector2 lv = b->get_linear_velocity();
+ //compute displacement from linear velocity
+ Vector2 motion = lv * Physics2DDirectBodyStateSW::singleton->step;
+ float motion_len = motion.length();
+ motion.normalize();
+ cbk.valid_depth += motion_len * MAX(motion.dot(-cbk.valid_dir), 0.0);
+ }
+ }
} else {
cbk.valid_dir = Vector2();
cbk.valid_depth = 0;
cbk.invalid_by_dir = 0;
}
+ int current_collisions = cbk.amount;
+ bool did_collide = false;
+
Shape2DSW *against_shape = col_obj->get_shape(shape_idx);
- if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), cbkres, cbkptr, NULL, p_margin)) {
- collided = cbk.amount > 0;
+ if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, NULL, separation_margin)) {
+ did_collide = cbk.amount > current_collisions;
}
- if (!collided && cbk.invalid_by_dir > 0) {
+ if (!did_collide && cbk.invalid_by_dir > 0) {
//this shape must be excluded
if (excluded_shape_pair_count < max_excluded_shape_pairs) {
ExcludedShapeSW esp;
@@ -741,6 +798,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
excluded_shape_pairs[excluded_shape_pair_count++] = esp;
}
}
+
+ if (did_collide) {
+ collided = true;
+ }
}
}
@@ -828,14 +889,14 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
continue;
}
- Transform2D col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(col_shape_idx);
+ Transform2D col_obj_shape_xform = col_obj->get_transform() * col_obj->get_shape_transform(col_shape_idx);
//test initial overlap, does it collide if going all the way?
- if (!CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion, against_shape, col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) {
+ if (!CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion, against_shape, col_obj_shape_xform, Vector2(), NULL, NULL, NULL, 0)) {
continue;
}
//test initial overlap
- if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_xform, Vector2(), NULL, NULL, NULL, 0)) {
+ if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), NULL, NULL, NULL, 0)) {
if (col_obj->is_shape_set_as_one_way_collision(col_shape_idx)) {
continue;
@@ -855,7 +916,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
real_t ofs = (low + hi) * 0.5;
Vector2 sep = mnormal; //important optimization for this to work fast enough
- bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * ofs, against_shape, col_obj_xform, Vector2(), NULL, NULL, &sep, 0);
+ bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * ofs, against_shape, col_obj_shape_xform, Vector2(), NULL, NULL, &sep, 0);
if (collided) {
@@ -873,12 +934,12 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
cbk.max = 1;
cbk.amount = 0;
cbk.ptr = cd;
- cbk.valid_dir = body_shape_xform.get_axis(1).normalized();
+ cbk.valid_dir = col_obj_shape_xform.get_axis(1).normalized();
cbk.valid_depth = 10e20;
Vector2 sep = mnormal; //important optimization for this to work fast enough
- bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * (hi + contact_max_allowed_penetration), col_obj->get_shape(col_shape_idx), col_obj_xform, Vector2(), Physics2DServerSW::_shape_col_cbk, &cbk, &sep, 0);
+ bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * (hi + contact_max_allowed_penetration), col_obj->get_shape(col_shape_idx), col_obj_shape_xform, Vector2(), Physics2DServerSW::_shape_col_cbk, &cbk, &sep, 0);
if (!collided || cbk.amount == 0) {
continue;
}
@@ -911,16 +972,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
bool collided = false;
if (safe >= 1) {
- //not collided
- collided = false;
- if (r_result) {
-
- r_result->motion = p_motion;
- r_result->remainder = Vector2();
- r_result->motion += (body_transform.get_origin() - p_from.get_origin());
- }
+ best_shape = -1; //no best shape with cast, reset to -1
+ }
- } else {
+ {
//it collided, let's get the rest info in unsafe advance
Transform2D ugt = body_transform;
@@ -931,52 +986,61 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
rcd.best_object = NULL;
rcd.best_shape = 0;
- Transform2D body_shape_xform = ugt * p_body->get_shape_transform(best_shape);
- Shape2DSW *body_shape = p_body->get_shape(best_shape);
+ //optimization
+ int from_shape = best_shape != -1 ? best_shape : 0;
+ int to_shape = best_shape != -1 ? best_shape + 1 : p_body->get_shape_count();
- body_aabb.position += p_motion * unsafe;
+ for (int j = from_shape; j < to_shape; j++) {
+ Transform2D body_shape_xform = ugt * p_body->get_shape_transform(j);
+ Shape2DSW *body_shape = p_body->get_shape(j);
- int amount = _cull_aabb_for_body(p_body, body_aabb);
+ body_aabb.position += p_motion * unsafe;
- for (int i = 0; i < amount; i++) {
+ int amount = _cull_aabb_for_body(p_body, body_aabb);
- const CollisionObject2DSW *col_obj = intersection_query_results[i];
- int shape_idx = intersection_query_subindex_results[i];
+ for (int i = 0; i < amount; i++) {
- if (CollisionObject2DSW::TYPE_BODY == col_obj->get_type()) {
- const Body2DSW *b = static_cast<const Body2DSW *>(col_obj);
- if (p_infinite_inertia && Physics2DServer::BODY_MODE_STATIC != b->get_mode() && Physics2DServer::BODY_MODE_KINEMATIC != b->get_mode()) {
- continue;
+ const CollisionObject2DSW *col_obj = intersection_query_results[i];
+ int shape_idx = intersection_query_subindex_results[i];
+
+ if (CollisionObject2DSW::TYPE_BODY == col_obj->get_type()) {
+ const Body2DSW *b = static_cast<const Body2DSW *>(col_obj);
+ if (p_infinite_inertia && Physics2DServer::BODY_MODE_STATIC != b->get_mode() && Physics2DServer::BODY_MODE_KINEMATIC != b->get_mode()) {
+ continue;
+ }
}
- }
- Shape2DSW *against_shape = col_obj->get_shape(shape_idx);
+ Shape2DSW *against_shape = col_obj->get_shape(shape_idx);
- bool excluded = false;
- for (int k = 0; k < excluded_shape_pair_count; k++) {
+ bool excluded = false;
+ for (int k = 0; k < excluded_shape_pair_count; k++) {
- if (excluded_shape_pairs[k].local_shape == body_shape && excluded_shape_pairs[k].against_object == col_obj && excluded_shape_pairs[k].against_shape_index == shape_idx) {
- excluded = true;
- break;
+ if (excluded_shape_pairs[k].local_shape == body_shape && excluded_shape_pairs[k].against_object == col_obj && excluded_shape_pairs[k].against_shape_index == shape_idx) {
+ excluded = true;
+ break;
+ }
}
- }
- if (excluded)
- continue;
+ if (excluded)
+ continue;
- if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
+ Transform2D col_obj_shape_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
- rcd.valid_dir = body_shape_xform.get_axis(1).normalized();
- rcd.valid_depth = 10e20;
- } else {
- rcd.valid_dir = Vector2();
- rcd.valid_depth = 0;
- }
+ if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
- rcd.object = col_obj;
- rcd.shape = shape_idx;
- bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, NULL, p_margin);
- if (!sc)
- continue;
+ rcd.valid_dir = col_obj_shape_xform.get_axis(1).normalized();
+ rcd.valid_depth = 10e20;
+ } else {
+ rcd.valid_dir = Vector2();
+ rcd.valid_depth = 0;
+ }
+
+ rcd.object = col_obj;
+ rcd.shape = shape_idx;
+ rcd.local_shape = j;
+ bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), _rest_cbk_result, &rcd, NULL, p_margin);
+ if (!sc)
+ continue;
+ }
}
if (rcd.best_len != 0) {
@@ -985,7 +1049,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
r_result->collider = rcd.best_object->get_self();
r_result->collider_id = rcd.best_object->get_instance_id();
r_result->collider_shape = rcd.best_shape;
- r_result->collision_local_shape = best_shape;
+ r_result->collision_local_shape = rcd.best_local_shape;
r_result->collision_normal = rcd.best_normal;
r_result->collision_point = rcd.best_contact;
r_result->collider_metadata = rcd.best_object->get_shape_metadata(rcd.best_shape);
@@ -1000,16 +1064,14 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
}
collided = true;
- } else {
- if (r_result) {
+ }
+ }
- r_result->motion = p_motion;
- r_result->remainder = Vector2();
- r_result->motion += (body_transform.get_origin() - p_from.get_origin());
- }
+ if (!collided && r_result) {
- collided = false;
- }
+ r_result->motion = p_motion;
+ r_result->remainder = Vector2();
+ r_result->motion += (body_transform.get_origin() - p_from.get_origin());
}
return collided;
@@ -1237,6 +1299,7 @@ Space2DSW::Space2DSW() {
body_linear_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_linear", 2.0);
body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_angular", (8.0 / 180.0 * Math_PI));
body_time_to_sleep = GLOBAL_DEF("physics/2d/time_before_sleep", 0.5);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/time_before_sleep", PropertyInfo(Variant::REAL, "physics/2d/time_before_sleep", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"));
broadphase = BroadPhase2DSW::create_func();
broadphase->set_pair_callback(_broadphase_pair, this);
diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h
index 1247317b03..bf4ea12eb5 100644
--- a/servers/physics_2d/space_2d_sw.h
+++ b/servers/physics_2d/space_2d_sw.h
@@ -37,23 +37,26 @@
#include "body_pair_2d_sw.h"
#include "broad_phase_2d_sw.h"
#include "collision_object_2d_sw.h"
-#include "hash_map.h"
-#include "project_settings.h"
-#include "typedefs.h"
+#include "core/hash_map.h"
+#include "core/project_settings.h"
+#include "core/typedefs.h"
class Physics2DDirectSpaceStateSW : public Physics2DDirectSpaceState {
GDCLASS(Physics2DDirectSpaceStateSW, Physics2DDirectSpaceState);
+ int _intersect_point_impl(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, bool p_filter_by_canvas = false, ObjectID p_canvas_instance_id = 0);
+
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 int intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_instance_id, 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..e4e1b03623 100644
--- a/servers/physics_2d/step_2d_sw.cpp
+++ b/servers/physics_2d/step_2d_sw.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "step_2d_sw.h"
-#include "os/os.h"
+#include "core/os/os.h"
void Step2DSW::_populate_island(Body2DSW *p_body, Body2DSW **p_island, Constraint2DSW **p_constraint_island) {
@@ -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);
@@ -224,7 +222,7 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) {
Constraint2DSW *prev_ci = NULL;
while (ci) {
- if (_setup_island(ci, p_delta) == true) {
+ if (_setup_island(ci, p_delta)) {
//removed the root from the island graph because it is not to be processed
diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp
index 37c4bc83ad..2ed8a4c478 100644
--- a/servers/physics_2d_server.cpp
+++ b/servers/physics_2d_server.cpp
@@ -29,9 +29,10 @@
/*************************************************************************/
#include "physics_2d_server.h"
+
#include "core/method_bind_ext.gen.inc"
+#include "core/print_string.h"
#include "core/project_settings.h"
-#include "print_string.h"
Physics2DServer *Physics2DServer::singleton = NULL;
@@ -203,6 +204,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 +241,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 +254,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();
@@ -265,9 +292,11 @@ Dictionary Physics2DDirectSpaceState::_intersect_ray(const Vector2 &p_from, cons
Array Physics2DDirectSpaceState::_intersect_shape(const Ref<Physics2DShapeQueryParameters> &p_shape_query, int p_max_results) {
+ ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
+
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++) {
@@ -286,8 +315,10 @@ Array Physics2DDirectSpaceState::_intersect_shape(const Ref<Physics2DShapeQueryP
Array Physics2DDirectSpaceState::_cast_motion(const Ref<Physics2DShapeQueryParameters> &p_shape_query) {
+ ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
+
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 +328,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_impl(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, bool p_filter_by_canvas, ObjectID p_canvas_instance_id) {
Set<RID> exclude;
for (int i = 0; i < p_exclude.size(); i++)
@@ -306,7 +337,12 @@ 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;
+ if (p_filter_by_canvas)
+ rc = intersect_point(p_point, ret.ptrw(), ret.size(), exclude, p_layers, p_collide_with_bodies, p_collide_with_areas);
+ else
+ rc = intersect_point_on_canvas(p_point, p_canvas_instance_id, ret.ptrw(), ret.size(), exclude, p_layers, p_collide_with_bodies, p_collide_with_areas);
+
if (rc == 0)
return Array();
@@ -325,12 +361,24 @@ Array Physics2DDirectSpaceState::_intersect_point(const Vector2 &p_point, int p_
return r;
}
+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) {
+
+ return _intersect_point_impl(p_point, p_max_results, p_exclude, p_layers, p_collide_with_bodies, p_collide_with_areas);
+}
+
+Array Physics2DDirectSpaceState::_intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_intance_id, int p_max_results, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas) {
+
+ return _intersect_point_impl(p_point, p_max_results, p_exclude, p_layers, p_collide_with_bodies, p_collide_with_areas, true, p_canvas_intance_id);
+}
+
Array Physics2DDirectSpaceState::_collide_shape(const Ref<Physics2DShapeQueryParameters> &p_shape_query, int p_max_results) {
+ ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
+
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;
@@ -341,9 +389,11 @@ Array Physics2DDirectSpaceState::_collide_shape(const Ref<Physics2DShapeQueryPar
}
Dictionary Physics2DDirectSpaceState::_get_rest_info(const Ref<Physics2DShapeQueryParameters> &p_shape_query) {
+ ERR_FAIL_COND_V(!p_shape_query.is_valid(), Dictionary());
+
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,13 +414,13 @@ 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_point_on_canvas", "point", "canvas_instance_id", "max_results", "exclude", "collision_layer", "collide_with_bodies", "collide_with_areas"), &Physics2DDirectSpaceState::_intersect_point_on_canvas, 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));
ClassDB::bind_method(D_METHOD("get_rest_info", "shape"), &Physics2DDirectSpaceState::_get_rest_info);
- //ClassDB::bind_method(D_METHOD("cast_motion","shape","xform","motion","exclude","umask"),&Physics2DDirectSpaceState::_intersect_shape,DEFVAL(Array()),DEFVAL(0));
}
int Physics2DShapeQueryResult::get_result_count() const {
@@ -408,10 +458,6 @@ void Physics2DShapeQueryResult::_bind_methods() {
///////////////////////////////
-/*bool Physics2DTestMotionResult::is_colliding() const {
-
- return colliding;
-}*/
Vector2 Physics2DTestMotionResult::get_motion() const {
return result.motion;
@@ -453,7 +499,6 @@ int Physics2DTestMotionResult::get_collider_shape() const {
void Physics2DTestMotionResult::_bind_methods() {
- //ClassDB::bind_method(D_METHOD("is_colliding"),&Physics2DTestMotionResult::is_colliding);
ClassDB::bind_method(D_METHOD("get_motion"), &Physics2DTestMotionResult::get_motion);
ClassDB::bind_method(D_METHOD("get_motion_remainder"), &Physics2DTestMotionResult::get_motion_remainder);
ClassDB::bind_method(D_METHOD("get_collision_point"), &Physics2DTestMotionResult::get_collision_point);
@@ -546,6 +591,9 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("area_attach_object_instance_id", "area", "id"), &Physics2DServer::area_attach_object_instance_id);
ClassDB::bind_method(D_METHOD("area_get_object_instance_id", "area"), &Physics2DServer::area_get_object_instance_id);
+ ClassDB::bind_method(D_METHOD("area_attach_canvas_instance_id", "area", "id"), &Physics2DServer::area_attach_canvas_instance_id);
+ ClassDB::bind_method(D_METHOD("area_get_canvas_instance_id", "area"), &Physics2DServer::area_get_canvas_instance_id);
+
ClassDB::bind_method(D_METHOD("area_set_monitor_callback", "area", "receiver", "method"), &Physics2DServer::area_set_monitor_callback);
ClassDB::bind_method(D_METHOD("area_set_area_monitor_callback", "area", "receiver", "method"), &Physics2DServer::area_set_area_monitor_callback);
ClassDB::bind_method(D_METHOD("area_set_monitorable", "area", "monitorable"), &Physics2DServer::area_set_monitorable);
@@ -577,6 +625,9 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_attach_object_instance_id", "body", "id"), &Physics2DServer::body_attach_object_instance_id);
ClassDB::bind_method(D_METHOD("body_get_object_instance_id", "body"), &Physics2DServer::body_get_object_instance_id);
+ ClassDB::bind_method(D_METHOD("body_attach_canvas_instance_id", "body", "id"), &Physics2DServer::body_attach_canvas_instance_id);
+ ClassDB::bind_method(D_METHOD("body_get_canvas_instance_id", "body"), &Physics2DServer::body_get_canvas_instance_id);
+
ClassDB::bind_method(D_METHOD("body_set_continuous_collision_detection_mode", "body", "mode"), &Physics2DServer::body_set_continuous_collision_detection_mode);
ClassDB::bind_method(D_METHOD("body_get_continuous_collision_detection_mode", "body"), &Physics2DServer::body_get_continuous_collision_detection_mode);
@@ -602,7 +653,6 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_add_collision_exception", "body", "excepted_body"), &Physics2DServer::body_add_collision_exception);
ClassDB::bind_method(D_METHOD("body_remove_collision_exception", "body", "excepted_body"), &Physics2DServer::body_remove_collision_exception);
- //virtual void body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions)=0;
ClassDB::bind_method(D_METHOD("body_set_max_contacts_reported", "body", "amount"), &Physics2DServer::body_set_max_contacts_reported);
ClassDB::bind_method(D_METHOD("body_get_max_contacts_reported", "body"), &Physics2DServer::body_get_max_contacts_reported);
@@ -636,11 +686,6 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_process_info", "process_info"), &Physics2DServer::get_process_info);
- //ClassDB::bind_method(D_METHOD("init"),&Physics2DServer::init);
- //ClassDB::bind_method(D_METHOD("step"),&Physics2DServer::step);
- //ClassDB::bind_method(D_METHOD("sync"),&Physics2DServer::sync);
- //ClassDB::bind_method(D_METHOD("flush_queries"),&Physics2DServer::flush_queries);
-
BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_RECYCLE_RADIUS);
BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_MAX_SEPARATION);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION);
@@ -710,9 +755,6 @@ void Physics2DServer::_bind_methods() {
BIND_ENUM_CONSTANT(CCD_MODE_CAST_RAY);
BIND_ENUM_CONSTANT(CCD_MODE_CAST_SHAPE);
- //BIND_ENUM_CONSTANT( TYPE_BODY );
- //BIND_ENUM_CONSTANT( TYPE_AREA );
-
BIND_ENUM_CONSTANT(AREA_BODY_ADDED);
BIND_ENUM_CONSTANT(AREA_BODY_REMOVED);
@@ -723,7 +765,6 @@ void Physics2DServer::_bind_methods() {
Physics2DServer::Physics2DServer() {
- //ERR_FAIL_COND( singleton!=NULL );
singleton = this;
}
diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h
index f42d9868f0..32e1dd1a08 100644
--- a/servers/physics_2d_server.h
+++ b/servers/physics_2d_server.h
@@ -31,9 +31,9 @@
#ifndef PHYSICS_2D_SERVER_H
#define PHYSICS_2D_SERVER_H
-#include "object.h"
-#include "reference.h"
-#include "resource.h"
+#include "core/object.h"
+#include "core/reference.h"
+#include "core/resource.h"
class Physics2DDirectSpaceState;
@@ -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,10 @@ 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);
-
- Array _intersect_point(const Vector2 &p_point, int p_max_results = 32, 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, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
+ Array _intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_intance_id, 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_point_impl(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclud, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_filter_by_canvas = false, ObjectID p_canvas_instance_id = 0);
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 +170,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 +181,14 @@ 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_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_instance_id, 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 +201,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();
};
@@ -339,6 +350,9 @@ public:
virtual void area_attach_object_instance_id(RID p_area, ObjectID p_ID) = 0;
virtual ObjectID area_get_object_instance_id(RID p_area) const = 0;
+ virtual void area_attach_canvas_instance_id(RID p_area, ObjectID p_ID) = 0;
+ virtual ObjectID area_get_canvas_instance_id(RID p_area) const = 0;
+
virtual void area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) = 0;
virtual void area_set_transform(RID p_area, const Transform2D &p_transform) = 0;
@@ -363,7 +377,6 @@ public:
BODY_MODE_KINEMATIC,
BODY_MODE_RIGID,
BODY_MODE_CHARACTER
- //BODY_MODE_SOFT ??
};
virtual RID body_create() = 0;
@@ -393,6 +406,9 @@ public:
virtual void body_attach_object_instance_id(RID p_body, uint32_t p_ID) = 0;
virtual uint32_t body_get_object_instance_id(RID p_body) const = 0;
+ virtual void body_attach_canvas_instance_id(RID p_body, uint32_t p_ID) = 0;
+ virtual uint32_t body_get_canvas_instance_id(RID p_body) const = 0;
+
enum CCDMode {
CCD_MODE_DISABLED,
CCD_MODE_CAST_RAY,
@@ -568,13 +584,13 @@ public:
virtual void end_sync() = 0;
virtual void finish() = 0;
+ virtual bool is_flushing_queries() const = 0;
+
enum ProcessInfo {
INFO_ACTIVE_OBJECTS,
INFO_COLLISION_PAIRS,
- INFO_ISLAND_COUNT,
- INFO_STEP_TIME,
- INFO_BROAD_PHASE_TIME
+ INFO_ISLAND_COUNT
};
virtual int get_process_info(ProcessInfo p_info) = 0;
diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp
index cda3856ecc..888e16e0c3 100644
--- a/servers/physics_server.cpp
+++ b/servers/physics_server.cpp
@@ -29,8 +29,10 @@
/*************************************************************************/
#include "physics_server.h"
+
+#include "core/method_bind_ext.gen.inc"
+#include "core/print_string.h"
#include "core/project_settings.h"
-#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,60 +234,40 @@ 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;
}
/////////////////////////////////////
-/*
-Variant PhysicsDirectSpaceState::_intersect_shape(const RID& p_shape, const Transform& p_xform,int p_result_max,const Vector<RID>& p_exclude,uint32_t p_collision_mask) {
-
-
-
- ERR_FAIL_INDEX_V(p_result_max,4096,Variant());
- if (p_result_max<=0)
- return Variant();
-
- Set<RID> exclude;
- for(int i=0;i<p_exclude.size();i++)
- exclude.insert(p_exclude[i]);
-
- ShapeResult *res=(ShapeResult*)alloca(p_result_max*sizeof(ShapeResult));
-
- int rc = intersect_shape(p_shape,p_xform,0,res,p_result_max,exclude);
-
- if (rc==0)
- return Variant();
-
- Ref<PhysicsShapeQueryResult> result = memnew( PhysicsShapeQueryResult );
- result->result.resize(rc);
- for(int i=0;i<rc;i++)
- result->result[i]=res[i];
-
- return result;
-
-}
-*/
-
-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();
@@ -287,9 +285,11 @@ Dictionary PhysicsDirectSpaceState::_intersect_ray(const Vector3 &p_from, const
Array PhysicsDirectSpaceState::_intersect_shape(const Ref<PhysicsShapeQueryParameters> &p_shape_query, int p_max_results) {
+ ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
+
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++) {
@@ -307,8 +307,10 @@ Array PhysicsDirectSpaceState::_intersect_shape(const Ref<PhysicsShapeQueryParam
Array PhysicsDirectSpaceState::_cast_motion(const Ref<PhysicsShapeQueryParameters> &p_shape_query, const Vector3 &p_motion) {
+ ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
+
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;
@@ -319,10 +321,12 @@ Array PhysicsDirectSpaceState::_cast_motion(const Ref<PhysicsShapeQueryParameter
}
Array PhysicsDirectSpaceState::_collide_shape(const Ref<PhysicsShapeQueryParameters> &p_shape_query, int p_max_results) {
+ ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
+
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;
@@ -333,9 +337,11 @@ Array PhysicsDirectSpaceState::_collide_shape(const Ref<PhysicsShapeQueryParamet
}
Dictionary PhysicsDirectSpaceState::_get_rest_info(const Ref<PhysicsShapeQueryParameters> &p_shape_query) {
+ ERR_FAIL_COND_V(!p_shape_query.is_valid(), Dictionary());
+
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;
@@ -355,10 +361,7 @@ PhysicsDirectSpaceState::PhysicsDirectSpaceState() {
void PhysicsDirectSpaceState::_bind_methods() {
- //ClassDB::bind_method(D_METHOD("intersect_ray","from","to","exclude","umask"),&PhysicsDirectSpaceState::_intersect_ray,DEFVAL(Array()),DEFVAL(0));
- //ClassDB::bind_method(D_METHOD("intersect_shape","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));
@@ -485,9 +488,6 @@ void PhysicsServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_set_enable_continuous_collision_detection", "body", "enable"), &PhysicsServer::body_set_enable_continuous_collision_detection);
ClassDB::bind_method(D_METHOD("body_is_continuous_collision_detection_enabled", "body"), &PhysicsServer::body_is_continuous_collision_detection_enabled);
- //ClassDB::bind_method(D_METHOD("body_set_user_flags","flags""),&PhysicsServer::body_set_shape,DEFVAL(Transform));
- //ClassDB::bind_method(D_METHOD("body_get_user_flags","body","shape_idx","shape"),&PhysicsServer::body_get_shape);
-
ClassDB::bind_method(D_METHOD("body_set_param", "body", "param", "value"), &PhysicsServer::body_set_param);
ClassDB::bind_method(D_METHOD("body_get_param", "body", "param"), &PhysicsServer::body_get_param);
@@ -511,7 +511,6 @@ void PhysicsServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_add_collision_exception", "body", "excepted_body"), &PhysicsServer::body_add_collision_exception);
ClassDB::bind_method(D_METHOD("body_remove_collision_exception", "body", "excepted_body"), &PhysicsServer::body_remove_collision_exception);
- //virtual void body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions)=0;
ClassDB::bind_method(D_METHOD("body_set_max_contacts_reported", "body", "amount"), &PhysicsServer::body_set_max_contacts_reported);
ClassDB::bind_method(D_METHOD("body_get_max_contacts_reported", "body"), &PhysicsServer::body_get_max_contacts_reported);
@@ -644,28 +643,10 @@ void PhysicsServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("generic_6dof_joint_set_flag", "joint", "axis", "flag", "enable"), &PhysicsServer::generic_6dof_joint_set_flag);
ClassDB::bind_method(D_METHOD("generic_6dof_joint_get_flag", "joint", "axis", "flag"), &PhysicsServer::generic_6dof_joint_get_flag);
- /*
- ClassDB::bind_method(D_METHOD("joint_set_param","joint","param","value"),&PhysicsServer::joint_set_param);
- ClassDB::bind_method(D_METHOD("joint_get_param","joint","param"),&PhysicsServer::joint_get_param);
-
- ClassDB::bind_method(D_METHOD("pin_joint_create","anchor","body_a","body_b"),&PhysicsServer::pin_joint_create,DEFVAL(RID()));
- ClassDB::bind_method(D_METHOD("groove_joint_create","groove1_a","groove2_a","anchor_b","body_a","body_b"),&PhysicsServer::groove_joint_create,DEFVAL(RID()),DEFVAL(RID()));
- ClassDB::bind_method(D_METHOD("damped_spring_joint_create","anchor_a","anchor_b","body_a","body_b"),&PhysicsServer::damped_spring_joint_create,DEFVAL(RID()));
-
- ClassDB::bind_method(D_METHOD("damped_string_joint_set_param","joint","param","value"),&PhysicsServer::damped_string_joint_set_param,DEFVAL(RID()));
- ClassDB::bind_method(D_METHOD("damped_string_joint_get_param","joint","param"),&PhysicsServer::damped_string_joint_get_param);
-
- ClassDB::bind_method(D_METHOD("joint_get_type","joint"),&PhysicsServer::joint_get_type);
-*/
ClassDB::bind_method(D_METHOD("free_rid", "rid"), &PhysicsServer::free);
ClassDB::bind_method(D_METHOD("set_active", "active"), &PhysicsServer::set_active);
- //ClassDB::bind_method(D_METHOD("init"),&PhysicsServer::init);
- //ClassDB::bind_method(D_METHOD("step"),&PhysicsServer::step);
- //ClassDB::bind_method(D_METHOD("sync"),&PhysicsServer::sync);
- //ClassDB::bind_method(D_METHOD("flush_queries"),&PhysicsServer::flush_queries);
-
ClassDB::bind_method(D_METHOD("get_process_info", "process_info"), &PhysicsServer::get_process_info);
BIND_ENUM_CONSTANT(SHAPE_PLANE);
@@ -697,7 +678,6 @@ void PhysicsServer::_bind_methods() {
BIND_ENUM_CONSTANT(BODY_MODE_STATIC);
BIND_ENUM_CONSTANT(BODY_MODE_KINEMATIC);
BIND_ENUM_CONSTANT(BODY_MODE_RIGID);
- BIND_ENUM_CONSTANT(BODY_MODE_SOFT);
BIND_ENUM_CONSTANT(BODY_MODE_CHARACTER);
BIND_ENUM_CONSTANT(BODY_PARAM_BOUNCE);
@@ -713,17 +693,6 @@ void PhysicsServer::_bind_methods() {
BIND_ENUM_CONSTANT(BODY_STATE_ANGULAR_VELOCITY);
BIND_ENUM_CONSTANT(BODY_STATE_SLEEPING);
BIND_ENUM_CONSTANT(BODY_STATE_CAN_SLEEP);
- /*
- BIND_ENUM_CONSTANT( JOINT_PIN );
- BIND_ENUM_CONSTANT( JOINT_GROOVE );
- BIND_ENUM_CONSTANT( JOINT_DAMPED_SPRING );
-
- BIND_ENUM_CONSTANT( DAMPED_STRING_REST_LENGTH );
- BIND_ENUM_CONSTANT( DAMPED_STRING_STIFFNESS );
- BIND_ENUM_CONSTANT( DAMPED_STRING_DAMPING );
-*/
- //BIND_ENUM_CONSTANT( TYPE_BODY );
- //BIND_ENUM_CONSTANT( TYPE_AREA );
BIND_ENUM_CONSTANT(AREA_BODY_ADDED);
BIND_ENUM_CONSTANT(AREA_BODY_REMOVED);
diff --git a/servers/physics_server.h b/servers/physics_server.h
index 948aec1a2d..9fb5e958c3 100644
--- a/servers/physics_server.h
+++ b/servers/physics_server.h
@@ -31,8 +31,8 @@
#ifndef PHYSICS_SERVER_H
#define PHYSICS_SERVER_H
-#include "object.h"
-#include "resource.h"
+#include "core/object.h"
+#include "core/resource.h"
class PhysicsDirectSpaceState;
@@ -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 */
@@ -347,7 +360,6 @@ public:
BODY_MODE_STATIC,
BODY_MODE_KINEMATIC,
BODY_MODE_RIGID,
- BODY_MODE_SOFT,
BODY_MODE_CHARACTER
};
@@ -482,7 +494,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 */
@@ -670,6 +697,9 @@ public:
G6DOF_JOINT_LINEAR_DAMPING,
G6DOF_JOINT_LINEAR_MOTOR_TARGET_VELOCITY,
G6DOF_JOINT_LINEAR_MOTOR_FORCE_LIMIT,
+ G6DOF_JOINT_LINEAR_SPRING_STIFFNESS,
+ G6DOF_JOINT_LINEAR_SPRING_DAMPING,
+ G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT,
G6DOF_JOINT_ANGULAR_LOWER_LIMIT,
G6DOF_JOINT_ANGULAR_UPPER_LIMIT,
G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS,
@@ -679,6 +709,9 @@ public:
G6DOF_JOINT_ANGULAR_ERP,
G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY,
G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT,
+ G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS,
+ G6DOF_JOINT_ANGULAR_SPRING_DAMPING,
+ G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT,
G6DOF_JOINT_MAX
};
@@ -686,6 +719,8 @@ public:
G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT,
G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT,
+ G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING,
+ G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING,
G6DOF_JOINT_FLAG_ENABLE_MOTOR,
G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR,
G6DOF_JOINT_FLAG_MAX
@@ -699,6 +734,9 @@ public:
virtual void generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag, bool p_enable) = 0;
virtual bool generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis, G6DOFJointAxisFlag p_flag) = 0;
+ virtual void generic_6dof_joint_set_precision(RID p_joint, int precision) = 0;
+ virtual int generic_6dof_joint_get_precision(RID p_joint) = 0;
+
/* QUERY API */
enum AreaBodyStatus {
@@ -717,6 +755,8 @@ public:
virtual void flush_queries() = 0;
virtual void finish() = 0;
+ virtual bool is_flushing_queries() const = 0;
+
enum ProcessInfo {
INFO_ACTIVE_OBJECTS,
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 4c764641e3..7deeec676b 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -29,8 +29,8 @@
/*************************************************************************/
#include "register_server_types.h"
-#include "engine.h"
-#include "project_settings.h"
+#include "core/engine.h"
+#include "core/project_settings.h"
#include "arvr/arvr_interface.h"
#include "arvr/arvr_positional_tracker.h"
@@ -52,12 +52,12 @@
#include "audio/effects/audio_effect_reverb.h"
#include "audio/effects/audio_effect_stereo_enhance.h"
#include "audio_server.h"
+#include "core/script_debugger_remote.h"
#include "physics/physics_server_sw.h"
#include "physics_2d/physics_2d_server_sw.h"
#include "physics_2d/physics_2d_server_wrap_mt.h"
#include "physics_2d_server.h"
#include "physics_server.h"
-#include "script_debugger_remote.h"
#include "visual/shader_types.h"
#include "visual_server.h"
diff --git a/servers/visual/SCsub b/servers/visual/SCsub
index ccc76e823f..d730144861 100644
--- a/servers/visual/SCsub
+++ b/servers/visual/SCsub
@@ -3,5 +3,3 @@
Import('env')
env.add_source_files(env.servers_sources, "*.cpp")
-
-Export('env')
diff --git a/servers/visual/default_mouse_cursor.xpm b/servers/visual/default_mouse_cursor.xpm
deleted file mode 100644
index 37d437dd15..0000000000
--- a/servers/visual/default_mouse_cursor.xpm
+++ /dev/null
@@ -1,23 +0,0 @@
-/* XPM */
-static const char * default_mouse_cursor_xpm[] = {
-"16 16 4 1",
-" c None",
-". c #000000",
-"+ c #FF00FF",
-"@ c #FFFFFF",
-"...+++++++++++++",
-".@...+++++++++++",
-".@@@...+++++++++",
-".@@@@@....++++++",
-".@@@@@@@@...++++",
-".@@@@@@@@@@...++",
-".@@@@@@@@@@@@..+",
-".@@@@@@@@@@@@@..",
-".@@@@@@@@@@@@..+",
-".@@@@@@@@@@@..++",
-".@@@@@@@@@...+++",
-".@@@.....@@..+++",
-".....+++.@@@..++",
-"++++++++..@@@..+",
-"+++++++++..@@@.+",
-"++++++++++.....+"};
diff --git a/servers/visual/rasterizer.cpp b/servers/visual/rasterizer.cpp
index be46690e55..6c04d1de63 100644
--- a/servers/visual/rasterizer.cpp
+++ b/servers/visual/rasterizer.cpp
@@ -30,8 +30,8 @@
#include "rasterizer.h"
-#include "os/os.h"
-#include "print_string.h"
+#include "core/os/os.h"
+#include "core/print_string.h"
Rasterizer *(*Rasterizer::_create_func)() = NULL;
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 49dff0d557..f78b4aaf5f 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -31,10 +31,10 @@
#ifndef RASTERIZER_H
#define RASTERIZER_H
-#include "camera_matrix.h"
+#include "core/math/camera_matrix.h"
#include "servers/visual_server.h"
-#include "self_list.h"
+#include "core/self_list.h"
class RasterizerScene {
public:
@@ -62,7 +62,7 @@ public:
virtual void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) = 0;
virtual void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) = 0;
- virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) = 0;
+ virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale) = 0;
virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) = 0;
virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance, bool p_roughness) = 0;
@@ -73,7 +73,7 @@ public:
virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) = 0;
virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) = 0;
- virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
+ virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0;
virtual bool is_environment(RID p_env) = 0;
@@ -120,9 +120,7 @@ public:
Vector<Color> lightmap_capture_data; //in a array (12 values) to avoid wasting space if unused. Alpha is unused, but needed to send to shader
virtual void base_removed() = 0;
- virtual void base_changed() = 0;
- virtual void base_material_changed() = 0;
-
+ virtual void base_changed(bool p_aabb, bool p_materials) = 0;
InstanceBase() :
dependency_item(this) {
@@ -249,6 +247,7 @@ public:
virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) = 0;
virtual Variant material_get_param(RID p_material, const StringName &p_param) const = 0;
+ virtual Variant material_get_param_default(RID p_material, const StringName &p_param) const = 0;
virtual void material_set_line_width(RID p_material, float p_width) = 0;
@@ -396,6 +395,7 @@ public:
virtual RID reflection_probe_create() = 0;
virtual void reflection_probe_set_update_mode(RID p_probe, VS::ReflectionProbeUpdateMode p_mode) = 0;
+ virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) = 0;
virtual void reflection_probe_set_intensity(RID p_probe, float p_intensity) = 0;
virtual void reflection_probe_set_interior_ambient(RID p_probe, const Color &p_ambient) = 0;
virtual void reflection_probe_set_interior_ambient_energy(RID p_probe, float p_energy) = 0;
@@ -518,6 +518,8 @@ public:
virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) = 0;
virtual void particles_restart(RID p_particles) = 0;
+ virtual bool particles_is_inactive(RID p_particles) const = 0;
+
virtual void particles_set_draw_order(RID p_particles, VS::ParticlesDrawOrder p_order) = 0;
virtual void particles_set_draw_passes(RID p_particles, int p_count) = 0;
@@ -798,8 +800,6 @@ public:
RID particles;
RID texture;
RID normal_map;
- int h_frames;
- int v_frames;
CommandParticles() { type = TYPE_PARTICLES; }
};
@@ -836,6 +836,7 @@ public:
bool clip;
bool visible;
bool behind;
+ bool update_when_visible;
//VS::MaterialBlendMode blend_mode;
int light_mask;
Vector<Command *> commands;
@@ -1037,6 +1038,7 @@ public:
copy_back_buffer = NULL;
distance_field = false;
light_masked = false;
+ update_when_visible = false;
}
virtual ~Item() {
clear();
@@ -1100,9 +1102,12 @@ public:
virtual void restore_render_target() = 0;
virtual void clear_render_target(const Color &p_color) = 0;
virtual void blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen = 0) = 0;
+ virtual void output_lens_distorted_to_screen(RID p_render_target, const Rect2 &p_screen_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) = 0;
virtual void end_frame(bool p_swap_buffers) = 0;
virtual void finalize() = 0;
+ virtual bool is_low_end() const = 0;
+
virtual ~Rasterizer() {}
};
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index ca50d0d049..1acec7ccaf 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -29,8 +29,8 @@
/*************************************************************************/
#include "shader_language.h"
-#include "os/os.h"
-#include "print_string.h"
+#include "core/os/os.h"
+#include "core/print_string.h"
static bool _is_text_char(CharType c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
@@ -131,7 +131,6 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"TYPE_USAMPLER3D",
"TYPE_SAMPLERCUBE",
"INTERPOLATION_FLAT",
- "INTERPOLATION_NO_PERSPECTIVE",
"INTERPOLATION_SMOOTH",
"PRECISION_LOW",
"PRECISION_MID",
@@ -271,7 +270,6 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
{ TK_TYPE_USAMPLER3D, "usampler3D" },
{ TK_TYPE_SAMPLERCUBE, "samplerCube" },
{ TK_INTERPOLATION_FLAT, "flat" },
- { TK_INTERPOLATION_NO_PERSPECTIVE, "noperspective" },
{ TK_INTERPOLATION_SMOOTH, "smooth" },
{ TK_PRECISION_LOW, "lowp" },
{ TK_PRECISION_MID, "mediump" },
@@ -691,6 +689,30 @@ String ShaderLanguage::token_debug(const String &p_code) {
return output;
}
+bool ShaderLanguage::is_token_variable_datatype(TokenType p_type) {
+ return (
+ p_type == TK_TYPE_VOID ||
+ p_type == TK_TYPE_BOOL ||
+ p_type == TK_TYPE_BVEC2 ||
+ p_type == TK_TYPE_BVEC3 ||
+ p_type == TK_TYPE_BVEC4 ||
+ p_type == TK_TYPE_INT ||
+ p_type == TK_TYPE_IVEC2 ||
+ p_type == TK_TYPE_IVEC3 ||
+ p_type == TK_TYPE_IVEC4 ||
+ p_type == TK_TYPE_UINT ||
+ p_type == TK_TYPE_UVEC2 ||
+ p_type == TK_TYPE_UVEC3 ||
+ p_type == TK_TYPE_UVEC4 ||
+ p_type == TK_TYPE_FLOAT ||
+ p_type == TK_TYPE_VEC2 ||
+ p_type == TK_TYPE_VEC3 ||
+ p_type == TK_TYPE_VEC4 ||
+ p_type == TK_TYPE_MAT2 ||
+ p_type == TK_TYPE_MAT3 ||
+ p_type == TK_TYPE_MAT4);
+}
+
bool ShaderLanguage::is_token_datatype(TokenType p_type) {
return (
@@ -735,7 +757,6 @@ bool ShaderLanguage::is_token_interpolation(TokenType p_type) {
return (
p_type == TK_INTERPOLATION_FLAT ||
- p_type == TK_INTERPOLATION_NO_PERSPECTIVE ||
p_type == TK_INTERPOLATION_SMOOTH);
}
@@ -743,8 +764,6 @@ ShaderLanguage::DataInterpolation ShaderLanguage::get_token_interpolation(TokenT
if (p_type == TK_INTERPOLATION_FLAT)
return INTERPOLATION_FLAT;
- else if (p_type == TK_INTERPOLATION_NO_PERSPECTIVE)
- return INTERPOLATION_NO_PERSPECTIVE;
else
return INTERPOLATION_SMOOTH;
}
@@ -1196,6 +1215,15 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
} else if (p_op->op == OP_ASSIGN_MUL && na == TYPE_MAT4 && nb == TYPE_VEC4) {
valid = true;
ret_type = TYPE_MAT4;
+ } else if (p_op->op == OP_ASSIGN_MUL && na == TYPE_VEC2 && nb == TYPE_MAT2) {
+ valid = true;
+ ret_type = TYPE_VEC2;
+ } else if (p_op->op == OP_ASSIGN_MUL && na == TYPE_VEC3 && nb == TYPE_MAT3) {
+ valid = true;
+ ret_type = TYPE_VEC3;
+ } else if (p_op->op == OP_ASSIGN_MUL && na == TYPE_VEC4 && nb == TYPE_MAT4) {
+ valid = true;
+ ret_type = TYPE_VEC4;
}
} break;
case OP_ASSIGN_BIT_AND:
@@ -1622,33 +1650,51 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "min", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
{ "min", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
+ { "min", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
{ "min", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
+ { "min", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
{ "min", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
+ { "min", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } },
{ "min", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_VOID } },
{ "min", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID } },
+ { "min", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_VOID } },
{ "min", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID } },
+ { "min", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_VOID } },
{ "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID } },
+ { "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID } },
{ "min", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID } },
{ "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID } },
+ { "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID } },
{ "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID } },
+ { "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID } },
{ "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID } },
+ { "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID } },
{ "max", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
{ "max", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
+ { "max", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } },
{ "max", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } },
+ { "max", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } },
{ "max", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } },
+ { "max", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } },
{ "max", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_VOID } },
{ "max", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID } },
+ { "max", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_VOID } },
{ "max", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID } },
+ { "max", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_VOID } },
{ "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID } },
+ { "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID } },
{ "max", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID } },
{ "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID } },
+ { "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID } },
{ "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID } },
+ { "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID } },
{ "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID } },
+ { "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID } },
{ "clamp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } },
{ "clamp", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } },
@@ -1995,6 +2041,12 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
};
+const ShaderLanguage::BuiltinFuncOutArgs ShaderLanguage::builtin_func_out_args[] = {
+ //constructors
+ { "modf", 1 },
+ { NULL, 0 }
+};
+
bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p_func, DataType *r_ret_type) {
ERR_FAIL_COND_V(p_func->op != OP_CALL && p_func->op != OP_CONSTRUCT, NULL);
@@ -2005,10 +2057,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p
StringName name = static_cast<VariableNode *>(p_func->arguments[0])->name.operator String();
- bool all_const = true;
for (int i = 1; i < p_func->arguments.size(); i++) {
- if (p_func->arguments[i]->type != Node::TYPE_CONSTANT)
- all_const = false;
args.push_back(p_func->arguments[i]->get_datatype());
}
@@ -2041,6 +2090,41 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p
if (!fail) {
+ //make sure its not an out argument used in the wrong way
+ int outarg_idx = 0;
+ while (builtin_func_out_args[outarg_idx].name) {
+
+ if (String(name) == builtin_func_out_args[outarg_idx].name) {
+ int arg_idx = builtin_func_out_args[outarg_idx].argument;
+
+ if (arg_idx < argcount) {
+
+ if (p_func->arguments[arg_idx + 1]->type != Node::TYPE_VARIABLE) {
+ _set_error("Argument " + itos(arg_idx + 1) + " of function '" + String(name) + "' is not a variable");
+ return false;
+ }
+ StringName var_name = static_cast<const VariableNode *>(p_func->arguments[arg_idx + 1])->name;
+
+ const BlockNode *b = p_block;
+ bool valid = false;
+ while (b) {
+ if (b->variables.has(var_name)) {
+ valid = true;
+ break;
+ }
+ b = b->parent_block;
+ }
+
+ if (!valid) {
+ _set_error("Argument " + itos(arg_idx + 1) + " of function '" + String(name) + "' can only take a local variable");
+ return false;
+ }
+ }
+ }
+
+ outarg_idx++;
+ }
+
if (r_ret_type)
*r_ret_type = builtin_func_defs[idx].rettype;
@@ -2273,6 +2357,109 @@ bool ShaderLanguage::is_sampler_type(DataType p_type) {
p_type == TYPE_SAMPLERCUBE;
}
+Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, ShaderLanguage::ShaderNode::Uniform::Hint p_hint) {
+ if (p_value.size() > 0) {
+ Variant value;
+ switch (p_type) {
+ case ShaderLanguage::TYPE_BOOL:
+ value = Variant(p_value[0].boolean);
+ break;
+ case ShaderLanguage::TYPE_BVEC2:
+ case ShaderLanguage::TYPE_BVEC3:
+ case ShaderLanguage::TYPE_BVEC4:
+ case ShaderLanguage::TYPE_INT:
+ value = Variant(p_value[0].sint);
+ break;
+ case ShaderLanguage::TYPE_IVEC2:
+ value = Variant(Vector2(p_value[0].sint, p_value[1].sint));
+ break;
+ case ShaderLanguage::TYPE_IVEC3:
+ value = Variant(Vector3(p_value[0].sint, p_value[1].sint, p_value[2].sint));
+ break;
+ case ShaderLanguage::TYPE_IVEC4:
+ value = Variant(Plane(p_value[0].sint, p_value[1].sint, p_value[2].sint, p_value[3].sint));
+ break;
+ case ShaderLanguage::TYPE_UINT:
+ value = Variant(p_value[0].uint);
+ break;
+ case ShaderLanguage::TYPE_UVEC2:
+ value = Variant(Vector2(p_value[0].uint, p_value[1].uint));
+ break;
+ case ShaderLanguage::TYPE_UVEC3:
+ value = Variant(Vector3(p_value[0].uint, p_value[1].uint, p_value[2].uint));
+ break;
+ case ShaderLanguage::TYPE_UVEC4:
+ value = Variant(Plane(p_value[0].uint, p_value[1].uint, p_value[2].uint, p_value[3].uint));
+ break;
+ case ShaderLanguage::TYPE_FLOAT:
+ value = Variant(p_value[0].real);
+ break;
+ case ShaderLanguage::TYPE_VEC2:
+ value = Variant(Vector2(p_value[0].real, p_value[1].real));
+ break;
+ case ShaderLanguage::TYPE_VEC3:
+ value = Variant(Vector3(p_value[0].real, p_value[1].real, p_value[2].real));
+ break;
+ case ShaderLanguage::TYPE_VEC4:
+ if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+ value = Variant(Color(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
+ } else {
+ value = Variant(Plane(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
+ }
+ break;
+ case ShaderLanguage::TYPE_MAT2:
+ value = Variant(Transform2D(p_value[0].real, p_value[2].real, p_value[1].real, p_value[3].real, 0.0, 0.0));
+ break;
+ case ShaderLanguage::TYPE_MAT3: {
+ Basis p;
+ p[0][0] = p_value[0].real;
+ p[0][1] = p_value[1].real;
+ p[0][2] = p_value[2].real;
+ p[1][0] = p_value[3].real;
+ p[1][1] = p_value[4].real;
+ p[1][2] = p_value[5].real;
+ p[2][0] = p_value[6].real;
+ p[2][1] = p_value[7].real;
+ p[2][2] = p_value[8].real;
+ value = Variant(p);
+ break;
+ }
+ case ShaderLanguage::TYPE_MAT4: {
+ Basis p;
+ p[0][0] = p_value[0].real;
+ p[0][1] = p_value[1].real;
+ p[0][2] = p_value[2].real;
+ p[1][0] = p_value[4].real;
+ p[1][1] = p_value[5].real;
+ p[1][2] = p_value[6].real;
+ p[2][0] = p_value[8].real;
+ p[2][1] = p_value[9].real;
+ p[2][2] = p_value[10].real;
+ Transform t = Transform(p, Vector3(p_value[3].real, p_value[7].real, p_value[11].real));
+ value = Variant(t);
+ break;
+ }
+ case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_ISAMPLER2D:
+ case ShaderLanguage::TYPE_ISAMPLER3D:
+ case ShaderLanguage::TYPE_SAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_SAMPLER2D:
+ case ShaderLanguage::TYPE_SAMPLER3D:
+ case ShaderLanguage::TYPE_USAMPLER2DARRAY:
+ case ShaderLanguage::TYPE_USAMPLER2D:
+ case ShaderLanguage::TYPE_USAMPLER3D:
+ case ShaderLanguage::TYPE_SAMPLERCUBE: {
+ // Texture types, likely not relevant here.
+ break;
+ }
+ case ShaderLanguage::TYPE_VOID:
+ break;
+ }
+ return value;
+ }
+ return Variant();
+}
+
void ShaderLanguage::get_keyword_list(List<String> *r_keywords) {
Set<String> kws;
@@ -2368,9 +2555,9 @@ int ShaderLanguage::get_cardinality(DataType p_type) {
2,
3,
4,
- 2,
- 3,
4,
+ 9,
+ 16,
1,
1,
1,
@@ -2384,7 +2571,7 @@ bool ShaderLanguage::_get_completable_identifier(BlockNode *p_block, CompletionT
identifier = StringName();
- TkPos pos;
+ TkPos pos = { 0, 0 };
Token tk = _get_token();
@@ -2533,7 +2720,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>();
@@ -2907,6 +3093,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
case TYPE_IVEC2: member_type = TYPE_INT; break;
case TYPE_UVEC2: member_type = TYPE_UINT; break;
case TYPE_MAT2: member_type = TYPE_VEC2; break;
+ default: break;
}
break;
@@ -2932,6 +3119,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
case TYPE_IVEC3: member_type = TYPE_INT; break;
case TYPE_UVEC3: member_type = TYPE_UINT; break;
case TYPE_MAT3: member_type = TYPE_VEC3; break;
+ default: break;
}
break;
case TYPE_BVEC4:
@@ -2956,6 +3144,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
case TYPE_IVEC4: member_type = TYPE_INT; break;
case TYPE_UVEC4: member_type = TYPE_UINT; break;
case TYPE_MAT4: member_type = TYPE_VEC4; break;
+ default: break;
}
break;
default: {
@@ -3308,7 +3497,9 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
ERR_FAIL_COND_V(op->arguments[0]->type != Node::TYPE_VARIABLE, p_node);
- DataType base = get_scalar_type(op->get_datatype());
+ DataType type = op->get_datatype();
+ DataType base = get_scalar_type(type);
+ int cardinality = get_cardinality(type);
Vector<ConstantNode::Value> values;
@@ -3319,19 +3510,9 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[i]);
if (get_scalar_type(cn->datatype) == base) {
-
- int cardinality = get_cardinality(op->arguments[i]->get_datatype());
- if (cn->values.size() == cardinality) {
-
- for (int j = 0; j < cn->values.size(); j++) {
- values.push_back(cn->values[j]);
- }
- } else if (cn->values.size() == 1) {
-
- for (int j = 0; j < cardinality; j++) {
- values.push_back(cn->values[0]);
- }
- } // else: should be filtered by the parser as it's an invalid constructor
+ for (int j = 0; j < cn->values.size(); j++) {
+ values.push_back(cn->values[j]);
+ }
} else if (get_scalar_type(cn->datatype) == cn->datatype) {
ConstantNode::Value v;
@@ -3348,6 +3529,30 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
}
}
+ if (values.size() == 1) {
+ if (type >= TYPE_MAT2 && type <= TYPE_MAT4) {
+ ConstantNode::Value value = values[0];
+ ConstantNode::Value zero;
+ zero.real = 0.0f;
+ int size = 2 + (type - TYPE_MAT2);
+
+ values.clear();
+ for (int i = 0; i < size; i++) {
+ for (int j = 0; j < size; j++) {
+ values.push_back(i == j ? value : zero);
+ }
+ }
+ } else {
+ ConstantNode::Value value = values[0];
+ for (int i = 1; i < cardinality; i++) {
+ values.push_back(value);
+ }
+ }
+ } else if (values.size() != cardinality) {
+ ERR_PRINT("Failed to reduce expression, values and cardinality mismatch.");
+ return p_node;
+ }
+
ConstantNode *cn = alloc_node<ConstantNode>();
cn->datatype = op->get_datatype();
cn->values = values;
@@ -3374,6 +3579,7 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
nv.sint = -cn->values[i].sint;
} break;
case TYPE_UINT: {
+ // FIXME: This can't work on uint
nv.uint = -cn->values[i].uint;
} break;
case TYPE_FLOAT: {
@@ -3430,6 +3636,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
}
}
+ if (!is_token_variable_datatype(tk.type)) {
+ _set_error("Invalid data type for variable (samplers not allowed)");
+ return ERR_PARSE_ERROR;
+ }
+
DataType type = get_token_datatype(tk.type);
tk = _get_token();
@@ -3875,8 +4086,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;
}
@@ -4085,6 +4296,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
+ if (!is_token_variable_datatype(tk.type)) {
+ _set_error("Invalid data type for function return (samplers not allowed)");
+ return ERR_PARSE_ERROR;
+ }
+
type = get_token_datatype(tk.type);
_get_completable_identifier(NULL, COMPLETION_MAIN_FUNCTION, name);
diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h
index d68f233b2f..2d1851928e 100644
--- a/servers/visual/shader_language.h
+++ b/servers/visual/shader_language.h
@@ -31,12 +31,12 @@
#ifndef SHADER_LANGUAGE_H
#define SHADER_LANGUAGE_H
-#include "list.h"
-#include "map.h"
-#include "string_db.h"
-#include "typedefs.h"
-#include "ustring.h"
-#include "variant.h"
+#include "core/list.h"
+#include "core/map.h"
+#include "core/string_db.h"
+#include "core/typedefs.h"
+#include "core/ustring.h"
+#include "core/variant.h"
class ShaderLanguage {
@@ -80,7 +80,6 @@ public:
TK_TYPE_USAMPLER3D,
TK_TYPE_SAMPLERCUBE,
TK_INTERPOLATION_FLAT,
- TK_INTERPOLATION_NO_PERSPECTIVE,
TK_INTERPOLATION_SMOOTH,
TK_PRECISION_LOW,
TK_PRECISION_MID,
@@ -210,7 +209,6 @@ public:
enum DataInterpolation {
INTERPOLATION_FLAT,
- INTERPOLATION_NO_PERSPECTIVE,
INTERPOLATION_SMOOTH,
};
@@ -333,6 +331,7 @@ public:
virtual DataType get_datatype() const { return datatype_cache; }
VariableNode() {
+
type = TYPE_VARIABLE;
datatype_cache = TYPE_VOID;
}
@@ -534,6 +533,7 @@ public:
static String get_token_text(Token p_token);
static bool is_token_datatype(TokenType p_type);
+ static bool is_token_variable_datatype(TokenType p_type);
static DataType get_token_datatype(TokenType p_type);
static bool is_token_interpolation(TokenType p_type);
static DataInterpolation get_token_interpolation(TokenType p_type);
@@ -548,6 +548,7 @@ public:
static int get_cardinality(DataType p_type);
static bool is_scalar_type(DataType p_type);
static bool is_sampler_type(DataType p_type);
+ static Variant constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, ShaderLanguage::ShaderNode::Uniform::Hint p_hint = ShaderLanguage::ShaderNode::Uniform::HINT_NONE);
static void get_keyword_list(List<String> *r_keywords);
static void get_builtin_funcs(List<String> *r_keywords);
@@ -641,6 +642,12 @@ private:
const DataType args[MAX_ARGS];
};
+ struct BuiltinFuncOutArgs { //arguments used as out in built in funcions
+
+ const char *name;
+ int argument;
+ };
+
CompletionType completion_type;
int completion_line;
BlockNode *completion_block;
@@ -651,6 +658,7 @@ private:
bool _get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier);
static const BuiltinFuncDef builtin_func_defs[];
+ static const BuiltinFuncOutArgs builtin_func_out_args[];
bool _validate_function_call(BlockNode *p_block, OperatorNode *p_func, DataType *r_ret_type);
bool _parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg = NULL);
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index 0de8676f32..b5e03b4826 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -78,6 +78,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["INV_PROJECTION_MATRIX"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["VIEWPORT_SIZE"] = constt(ShaderLanguage::TYPE_VEC2);
+ shader_modes[VS::SHADER_SPATIAL].functions["vertex"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL);
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["VERTEX"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4);
@@ -85,6 +86,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["TANGENT"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["BINORMAL"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEW"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMALMAP"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["NORMALMAP_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["UV"] = constt(ShaderLanguage::TYPE_VEC2);
@@ -108,12 +110,16 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["EMISSION"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["SCREEN_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["DEPTH_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["DEPTH"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ALPHA_SCISSOR"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL);
+
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["WORLD_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
@@ -122,11 +128,13 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["WORLD_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["INV_CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
+ shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["CAMERA_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["INV_PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
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);
@@ -137,6 +145,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["ROUGHNESS"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["DIFFUSE_LIGHT"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["SPECULAR_LIGHT"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["light"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL);
shader_modes[VS::SHADER_SPATIAL].functions["light"].can_discard = true;
@@ -193,6 +202,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["INSTANCE_CUSTOM"] = constt(ShaderLanguage::TYPE_VEC4);
shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["AT_LIGHT_PASS"] = constt(ShaderLanguage::TYPE_BOOL);
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["TEXTURE_PIXEL_SIZE"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"].can_discard = false;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4);
@@ -222,7 +232,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_VEC"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_HEIGHT"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_COLOR"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_UV"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_UV"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["SHADOW_COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["POINT_COORD"] = constt(ShaderLanguage::TYPE_VEC2);
diff --git a/servers/visual/shader_types.h b/servers/visual/shader_types.h
index 0680ec8242..e195b6ea20 100644
--- a/servers/visual/shader_types.h
+++ b/servers/visual/shader_types.h
@@ -31,7 +31,7 @@
#ifndef SHADERTYPES_H
#define SHADERTYPES_H
-#include "ordered_hash_map.h"
+#include "core/ordered_hash_map.h"
#include "servers/visual_server.h"
#include "shader_language.h"
diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp
index 0b4bbffddf..26fb3cc493 100644
--- a/servers/visual/visual_server_canvas.cpp
+++ b/servers/visual/visual_server_canvas.cpp
@@ -30,6 +30,7 @@
#include "visual_server_canvas.h"
#include "visual_server_global.h"
+#include "visual_server_raster.h"
#include "visual_server_viewport.h"
void VisualServerCanvas::_render_canvas_item_tree(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights) {
@@ -50,6 +51,23 @@ void VisualServerCanvas::_render_canvas_item_tree(Item *p_canvas_item, const Tra
}
}
+void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2D p_transform, VisualServerCanvas::Item **r_items, int &r_index) {
+ int child_item_count = p_canvas_item->child_items.size();
+ VisualServerCanvas::Item **child_items = p_canvas_item->child_items.ptrw();
+ for (int i = 0; i < child_item_count; i++) {
+ if (r_items) {
+ r_items[r_index] = child_items[i];
+ child_items[i]->ysort_xform = p_transform;
+ child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.elements[2]);
+ }
+
+ r_index++;
+
+ if (child_items[i]->sort_y)
+ _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, r_items, r_index);
+ }
+}
+
void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner) {
Item *ci = p_canvas_item;
@@ -57,10 +75,10 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor
if (!ci->visible)
return;
- if (p_canvas_item->children_order_dirty) {
+ if (ci->children_order_dirty) {
- p_canvas_item->child_items.sort_custom<ItemIndexSort>();
- p_canvas_item->children_order_dirty = false;
+ ci->child_items.sort_custom<ItemIndexSort>();
+ ci->children_order_dirty = false;
}
Rect2 rect = ci->get_rect();
@@ -81,8 +99,7 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor
return;
int child_item_count = ci->child_items.size();
- Item **child_items = (Item **)alloca(child_item_count * sizeof(Item *));
- copymem(child_items, ci->child_items.ptr(), child_item_count * sizeof(Item *));
+ Item **child_items = ci->child_items.ptrw();
if (ci->clip) {
if (p_canvas_clip != NULL) {
@@ -98,6 +115,17 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor
if (ci->sort_y) {
+ if (ci->ysort_children_count == -1) {
+ ci->ysort_children_count = 0;
+ _collect_ysort_children(ci, Transform2D(), NULL, ci->ysort_children_count);
+ }
+
+ child_item_count = ci->ysort_children_count;
+ child_items = (Item **)alloca(child_item_count * sizeof(Item *));
+
+ int i = 0;
+ _collect_ysort_children(ci, Transform2D(), child_items, i);
+
SortArray<Item *, ItemPtrSort> sorter;
sorter.sort(child_items, child_item_count);
}
@@ -109,9 +137,13 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor
for (int i = 0; i < child_item_count; i++) {
- if (!child_items[i]->behind)
+ if (!child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y))
continue;
- _render_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
+ if (ci->sort_y) {
+ _render_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
+ } else {
+ _render_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
+ }
}
if (ci->copy_back_buffer) {
@@ -119,6 +151,10 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor
ci->copy_back_buffer->screen_rect = xform.xform(ci->copy_back_buffer->rect).clip(p_clip_rect);
}
+ if (ci->update_when_visible) {
+ VisualServerRaster::redraw_request();
+ }
+
if ((!ci->commands.empty() && p_clip_rect.intersects(global_rect)) || ci->vp_render || ci->copy_back_buffer) {
//something to draw?
ci->final_transform = xform;
@@ -143,9 +179,13 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor
for (int i = 0; i < child_item_count; i++) {
- if (child_items[i]->behind)
+ if (child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y))
continue;
- _render_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
+ if (ci->sort_y) {
+ _render_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
+ } else {
+ _render_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner);
+ }
}
}
@@ -295,6 +335,12 @@ void VisualServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) {
Item *item_owner = canvas_item_owner.get(canvas_item->parent);
item_owner->child_items.erase(canvas_item);
+
+ Item *ysort_owner = item_owner;
+ while (ysort_owner && ysort_owner->sort_y) {
+ item_owner->ysort_children_count = -1;
+ ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : NULL;
+ }
}
canvas_item->parent = RID();
@@ -314,6 +360,12 @@ void VisualServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) {
item_owner->child_items.push_back(canvas_item);
item_owner->children_order_dirty = true;
+ Item *ysort_owner = item_owner;
+ while (ysort_owner && ysort_owner->sort_y) {
+ item_owner->ysort_children_count = -1;
+ ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : NULL;
+ }
+
} else {
ERR_EXPLAIN("Invalid parent");
@@ -390,6 +442,14 @@ void VisualServerCanvas::canvas_item_set_draw_behind_parent(RID p_item, bool p_e
canvas_item->behind = p_enable;
}
+void VisualServerCanvas::canvas_item_set_update_when_visible(RID p_item, bool p_update) {
+
+ Item *canvas_item = canvas_item_owner.getornull(p_item);
+ ERR_FAIL_COND(!canvas_item);
+
+ canvas_item->update_when_visible = p_update;
+}
+
void VisualServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width, bool p_antialiased) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
@@ -676,7 +736,7 @@ void VisualServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2
if (indices.empty()) {
ERR_EXPLAIN("Bad Polygon!");
- ERR_FAIL_V();
+ ERR_FAIL();
}
Item::CommandPolygon *polygon = memnew(Item::CommandPolygon);
@@ -763,7 +823,7 @@ void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID
canvas_item->commands.push_back(m);
}
-void VisualServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal, int p_h_frames, int p_v_frames) {
+void VisualServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -773,8 +833,6 @@ void VisualServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles,
part->particles = p_particles;
part->texture = p_texture;
part->normal_map = p_normal;
- part->h_frames = p_h_frames;
- part->v_frames = p_v_frames;
//take the chance and request processing for them, at least once until they become visible again
VSG::storage->particles_request_process(p_particles);
@@ -815,6 +873,7 @@ void VisualServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool p_e
ERR_FAIL_COND(!canvas_item);
canvas_item->sort_y = p_enable;
+ canvas_item->ysort_children_count = -1;
}
void VisualServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) {
@@ -1291,6 +1350,12 @@ bool VisualServerCanvas::free(RID p_rid) {
Item *item_owner = canvas_item_owner.get(canvas_item->parent);
item_owner->child_items.erase(canvas_item);
+
+ Item *ysort_owner = item_owner;
+ while (ysort_owner && ysort_owner->sort_y) {
+ item_owner->ysort_children_count = -1;
+ ysort_owner = canvas_item_owner.owns(ysort_owner->parent) ? canvas_item_owner.getornull(ysort_owner->parent) : NULL;
+ }
}
}
diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h
index 4d9398a17e..4b7422b15a 100644
--- a/servers/visual/visual_server_canvas.h
+++ b/servers/visual/visual_server_canvas.h
@@ -48,6 +48,9 @@ public:
bool use_parent_material;
int index;
bool children_order_dirty;
+ int ysort_children_count;
+ Transform2D ysort_xform;
+ Vector2 ysort_pos;
Vector<Item *> child_items;
@@ -61,6 +64,9 @@ public:
use_parent_material = false;
z_relative = true;
index = 0;
+ ysort_children_count = -1;
+ ysort_xform = Transform2D();
+ ysort_pos = Vector2();
}
};
@@ -76,10 +82,10 @@ public:
_FORCE_INLINE_ bool operator()(const Item *p_left, const Item *p_right) const {
- if (Math::abs(p_left->xform.elements[2].y - p_right->xform.elements[2].y) < CMP_EPSILON)
- return p_left->xform.elements[2].x < p_right->xform.elements[2].x;
+ if (Math::abs(p_left->ysort_pos.y - p_right->ysort_pos.y) < CMP_EPSILON)
+ return p_left->ysort_pos.x < p_right->ysort_pos.x;
else
- return p_left->xform.elements[2].y < p_right->xform.elements[2].y;
+ return p_left->ysort_pos.y < p_right->ysort_pos.y;
}
};
@@ -171,6 +177,8 @@ public:
void canvas_item_set_draw_behind_parent(RID p_item, bool p_enable);
+ void canvas_item_set_update_when_visible(RID p_item, bool p_update);
+
void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false);
void canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false);
void canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false);
@@ -184,7 +192,7 @@ public:
void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID());
void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture = RID(), RID p_normal_map = RID());
void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID());
- void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal, int p_h_frames, int p_v_frames);
+ void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal);
void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform);
void canvas_item_add_clip_ignore(RID p_item, bool p_ignore);
void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable);
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index c7d33ec43c..677c323216 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -30,11 +30,10 @@
#include "visual_server_raster.h"
-#include "default_mouse_cursor.xpm"
-#include "io/marshalls.h"
-#include "os/os.h"
-#include "project_settings.h"
-#include "sort.h"
+#include "core/io/marshalls.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
+#include "core/sort.h"
#include "visual_server_canvas.h"
#include "visual_server_global.h"
#include "visual_server_scene.h"
@@ -190,6 +189,9 @@ void VisualServerRaster::call_set_use_vsync(bool p_enable) {
OS::get_singleton()->_set_use_vsync(p_enable);
}
+bool VisualServerRaster::is_low_end() const {
+ return VSG::rasterizer->is_low_end();
+}
VisualServerRaster::VisualServerRaster() {
VSG::canvas = memnew(VisualServerCanvas);
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index a00b364565..f3a442be99 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -31,8 +31,8 @@
#ifndef VISUAL_SERVER_RASTER_H
#define VISUAL_SERVER_RASTER_H
-#include "allocators.h"
-#include "octree.h"
+#include "core/allocators.h"
+#include "core/math/octree.h"
#include "servers/visual/rasterizer.h"
#include "servers/visual_server.h"
#include "visual_server_canvas.h"
@@ -59,7 +59,6 @@ class VisualServerRaster : public VisualServer {
};
static int changes;
- bool draw_extra_frame;
RID test_cube;
int black_margin[4];
@@ -203,6 +202,7 @@ public:
BIND3(material_set_param, RID, const StringName &, const Variant &)
BIND2RC(Variant, material_get_param, RID, const StringName &)
+ BIND2RC(Variant, material_get_param_default, RID, const StringName &)
BIND2(material_set_render_priority, RID, int)
BIND2(material_set_line_width, RID, float)
@@ -336,6 +336,7 @@ public:
BIND2(reflection_probe_set_enable_box_projection, RID, bool)
BIND2(reflection_probe_set_enable_shadows, RID, bool)
BIND2(reflection_probe_set_cull_mask, RID, uint32_t)
+ BIND2(reflection_probe_set_resolution, RID, int)
/* BAKED LIGHT API */
@@ -473,7 +474,7 @@ public:
BIND2(viewport_set_transparent_background, RID, bool)
BIND2(viewport_set_global_canvas_transform, RID, const Transform2D &)
- BIND3(viewport_set_canvas_layer, RID, RID, int)
+ BIND4(viewport_set_canvas_stacking, RID, RID, int, int)
BIND2(viewport_set_shadow_atlas_size, RID, int)
BIND3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
BIND2(viewport_set_msaa, RID, ViewportMSAA)
@@ -503,14 +504,14 @@ public:
BIND6(environment_set_dof_blur_near, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
BIND6(environment_set_dof_blur_far, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
- BIND10(environment_set_glow, RID, bool, int, float, float, float, EnvironmentGlowBlendMode, float, float, bool)
+ BIND11(environment_set_glow, RID, bool, int, float, float, float, EnvironmentGlowBlendMode, float, float, float, bool)
BIND9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float)
BIND6(environment_set_adjustment, RID, bool, float, float, float, RID)
BIND5(environment_set_fog, RID, bool, const Color &, const Color &, float)
- BIND6(environment_set_fog_depth, RID, bool, float, float, bool, float)
+ BIND7(environment_set_fog_depth, RID, bool, float, float, float, bool, float)
BIND5(environment_set_fog_height, RID, bool, float, float, float)
/* SCENARIO API */
@@ -574,6 +575,8 @@ public:
BIND2(canvas_item_set_visible, RID, bool)
BIND2(canvas_item_set_light_mask, RID, int)
+ BIND2(canvas_item_set_update_when_visible, RID, bool)
+
BIND2(canvas_item_set_transform, RID, const Transform2D &)
BIND2(canvas_item_set_clip, RID, bool)
BIND2(canvas_item_set_distance_field_mode, RID, bool)
@@ -596,7 +599,7 @@ public:
BIND10(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID)
BIND4(canvas_item_add_mesh, RID, const RID &, RID, RID)
BIND4(canvas_item_add_multimesh, RID, RID, RID, RID)
- BIND6(canvas_item_add_particles, RID, RID, RID, RID, int, int)
+ BIND4(canvas_item_add_particles, RID, RID, RID, RID)
BIND2(canvas_item_add_set_transform, RID, const Transform2D &)
BIND2(canvas_item_add_clip_ignore, RID, bool)
BIND2(canvas_item_set_sort_children_by_y, RID, bool)
@@ -686,6 +689,8 @@ public:
virtual void call_set_use_vsync(bool p_enable);
+ virtual bool is_low_end() const;
+
VisualServerRaster();
~VisualServerRaster();
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 213b3ad8f6..1deca7bc66 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "visual_server_scene.h"
-#include "os/os.h"
+#include "core/os/os.h"
#include "visual_server_global.h"
#include "visual_server_raster.h"
/* CAMERA API */
@@ -398,6 +398,7 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) {
VSG::scene_render->free(gi_probe->probe_instance);
} break;
+ default: {}
}
if (instance->base_data) {
@@ -471,6 +472,7 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) {
gi_probe->probe_instance = VSG::scene_render->gi_probe_instance_create();
} break;
+ default: {}
}
VSG::storage->instance_add_dependency(p_base, instance);
@@ -518,6 +520,7 @@ void VisualServerScene::instance_set_scenario(RID p_instance, RID p_scenario) {
gi_probe_update_list.remove(&gi_probe->update_element);
}
} break;
+ default: {}
}
instance->scenario = NULL;
@@ -549,6 +552,7 @@ void VisualServerScene::instance_set_scenario(RID p_instance, RID p_scenario) {
gi_probe_update_list.add(&gi_probe->update_element);
}
} break;
+ default: {}
}
_instance_queue_update(instance, true, true);
@@ -597,8 +601,9 @@ void VisualServerScene::instance_set_surface_material(RID p_instance, int p_surf
Instance *instance = instance_owner.get(p_instance);
ERR_FAIL_COND(!instance);
- if (instance->update_item.in_list()) {
- _update_dirty_instance(instance);
+ if (instance->base_type == VS::INSTANCE_MESH) {
+ //may not have been updated yet
+ instance->materials.resize(VSG::storage->mesh_get_surface_count(instance->base));
}
ERR_FAIL_INDEX(p_surface, instance->materials.size());
@@ -607,7 +612,7 @@ void VisualServerScene::instance_set_surface_material(RID p_instance, int p_surf
VSG::storage->material_remove_instance_owner(instance->materials[p_surface], instance);
}
instance->materials.write[p_surface] = p_material;
- instance->base_material_changed();
+ instance->base_changed(false, true);
if (instance->materials[p_surface].is_valid()) {
VSG::storage->material_add_instance_owner(instance->materials[p_surface], instance);
@@ -649,6 +654,7 @@ void VisualServerScene::instance_set_visible(RID p_instance, bool p_visible) {
}
} break;
+ default: {}
}
}
inline bool is_geometry_instance(VisualServer::InstanceType p_type) {
@@ -825,6 +831,7 @@ void VisualServerScene::instance_geometry_set_flag(RID p_instance, VS::InstanceF
instance->redraw_if_visible = p_enabled;
} break;
+ default: {}
}
}
void VisualServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, VS::ShadowCastingSetting p_shadow_casting_setting) {
@@ -833,7 +840,7 @@ void VisualServerScene::instance_geometry_set_cast_shadows_setting(RID p_instanc
ERR_FAIL_COND(!instance);
instance->cast_shadows = p_shadow_casting_setting;
- instance->base_material_changed(); // to actually compute if shadows are visible or not
+ instance->base_changed(false, true); // to actually compute if shadows are visible or not
}
void VisualServerScene::instance_geometry_set_material_override(RID p_instance, RID p_material) {
@@ -844,7 +851,7 @@ void VisualServerScene::instance_geometry_set_material_override(RID p_instance,
VSG::storage->material_remove_instance_owner(instance->material_override, instance);
}
instance->material_override = p_material;
- instance->base_material_changed();
+ instance->base_changed(false, true);
if (instance->material_override.is_valid()) {
VSG::storage->material_add_instance_owner(instance->material_override, instance);
@@ -902,7 +909,7 @@ void VisualServerScene::_update_instance(Instance *p_instance) {
_update_instance_lightmap_captures(p_instance);
} else {
if (!p_instance->lightmap_capture_data.empty()) {
- !p_instance->lightmap_capture_data.resize(0); //not in use, clear capture data
+ p_instance->lightmap_capture_data.resize(0); //not in use, clear capture data
}
}
}
@@ -1016,7 +1023,6 @@ void VisualServerScene::_update_instance_aabb(Instance *p_instance) {
new_aabb = VSG::storage->lightmap_capture_get_bounds(p_instance->base);
} break;
-
default: {}
}
@@ -1180,7 +1186,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) {
@@ -1258,13 +1264,15 @@ void VisualServerScene::_update_instance_lightmap_captures(Instance *p_instance)
}
}
-void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario) {
+bool VisualServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario) {
InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
Transform light_transform = p_instance->transform;
light_transform.orthonormalize(); //scale does not count on lights
+ bool animated_material_found = false;
+
switch (VSG::storage->light_get_type(p_instance->base)) {
case VS::LIGHT_DIRECTIONAL: {
@@ -1297,6 +1305,10 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
continue;
}
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
+ }
+
float max, min;
instance->transformed_aabb.project_range_in_plane(base, min, max);
@@ -1378,9 +1390,12 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
float y_min = 0.f, y_max = 0.f;
float z_min = 0.f, z_max = 0.f;
+ // FIXME: z_max_cam is defined, computed, but not used below when setting up
+ // ortho_camera. Commented out for now to fix warnings but should be investigated.
float x_min_cam = 0.f, x_max_cam = 0.f;
float y_min_cam = 0.f, y_max_cam = 0.f;
- float z_min_cam = 0.f, z_max_cam = 0.f;
+ float z_min_cam = 0.f;
+ //float z_max_cam = 0.f;
float bias_scale = 1.0;
@@ -1442,7 +1457,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
x_min_cam = x_vec.dot(center) - radius;
y_max_cam = y_vec.dot(center) + radius;
y_min_cam = y_vec.dot(center) - radius;
- z_max_cam = z_vec.dot(center) + radius;
+ //z_max_cam = z_vec.dot(center) + radius;
z_min_cam = z_vec.dot(center) - radius;
if (depth_range_mode == VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE) {
@@ -1549,6 +1564,10 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
j--;
} else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
+ }
+
instance->depth = near_plane.distance_to(instance->transform.origin);
instance->depth_layer = 0;
}
@@ -1600,6 +1619,9 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
j--;
} else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
+ }
instance->depth = near_plane.distance_to(instance->transform.origin);
instance->depth_layer = 0;
}
@@ -1636,6 +1658,9 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
j--;
} else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
+ }
instance->depth = near_plane.distance_to(instance->transform.origin);
instance->depth_layer = 0;
}
@@ -1646,6 +1671,8 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
} break;
}
+
+ return animated_material_found;
}
void VisualServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas) {
@@ -1799,11 +1826,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
@@ -1884,9 +1912,14 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
if (ins->base_type == VS::INSTANCE_PARTICLES) {
//particles visible? process them
- VSG::storage->particles_request_process(ins->base);
- //particles visible? request redraw
- VisualServerRaster::redraw_request();
+ if (VSG::storage->particles_is_inactive(ins->base)) {
+ //but if nothing is going on, don't do it.
+ keep = false;
+ } else {
+ VSG::storage->particles_request_process(ins->base);
+ //particles visible? request redraw
+ VisualServerRaster::redraw_request();
+ }
}
if (geom->lighting_dirty) {
@@ -2086,7 +2119,7 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
if (redraw) {
//must redraw!
- _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_shadow_atlas, scenario);
+ light->shadow_dirty = _light_instance_update_shadow(ins, p_cam_transform, p_cam_projection, p_cam_orthogonal, p_shadow_atlas, scenario);
}
}
}
@@ -2132,6 +2165,8 @@ bool VisualServerScene::_render_reflection_probe_step(Instance *p_instance, int
Scenario *scenario = p_instance->scenario;
ERR_FAIL_COND_V(!scenario, true);
+ VisualServerRaster::redraw_request(); //update, so it updates in editor
+
if (p_step == 0) {
if (!VSG::scene_render->reflection_probe_instance_begin_render(reflection_probe->instance, scenario->reflection_atlas)) {
@@ -2302,7 +2337,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 +2425,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 +2793,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;
}
}
@@ -2821,7 +2855,7 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
RID rid = E->key();
const InstanceGIProbeData::LightCache &lc = E->get();
- if ((!probe_data->dynamic.light_cache_changes.has(rid) || !(probe_data->dynamic.light_cache_changes[rid] == lc)) && lc.visible) {
+ if ((!probe_data->dynamic.light_cache_changes.has(rid) || probe_data->dynamic.light_cache_changes[rid] != lc) && lc.visible) {
//erase light data
_bake_gi_probe_light(header, cells, local_data, leaves, leaf_count, lc, -1);
@@ -2834,7 +2868,7 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
RID rid = E->key();
const InstanceGIProbeData::LightCache &lc = E->get();
- if ((!probe_data->dynamic.light_cache.has(rid) || !(probe_data->dynamic.light_cache[rid] == lc)) && lc.visible) {
+ if ((!probe_data->dynamic.light_cache.has(rid) || probe_data->dynamic.light_cache[rid] != lc) && lc.visible) {
//add light data
_bake_gi_probe_light(header, cells, local_data, leaves, leaf_count, lc, 1);
@@ -3051,7 +3085,7 @@ bool VisualServerScene::_check_gi_probe(Instance *p_gi_probe) {
lc.transform = probe_data->dynamic.light_to_cell_xform * E->get()->transform;
lc.visible = E->get()->visible;
- if (!probe_data->dynamic.light_cache.has(E->get()->self) || !(probe_data->dynamic.light_cache[E->get()->self] == lc)) {
+ if (!probe_data->dynamic.light_cache.has(E->get()->self) || probe_data->dynamic.light_cache[E->get()->self] != lc) {
all_equal = false;
}
@@ -3071,7 +3105,7 @@ bool VisualServerScene::_check_gi_probe(Instance *p_gi_probe) {
lc.transform = probe_data->dynamic.light_to_cell_xform * E->get()->transform;
lc.visible = E->get()->visible;
- if (!probe_data->dynamic.light_cache.has(E->get()->self) || !(probe_data->dynamic.light_cache[E->get()->self] == lc)) {
+ if (!probe_data->dynamic.light_cache.has(E->get()->self) || probe_data->dynamic.light_cache[E->get()->self] != lc) {
all_equal = false;
}
@@ -3154,7 +3188,7 @@ void VisualServerScene::render_probes() {
force_lighting = true;
}
- if (probe->invalid == false && probe->dynamic.enabled) {
+ if (!probe->invalid && probe->dynamic.enabled) {
switch (probe->dynamic.updating_stage) {
case GI_UPDATE_STAGE_CHECK: {
@@ -3180,7 +3214,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 +3224,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;
}
}
@@ -3233,11 +3267,13 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
bool can_cast_shadows = true;
+ bool is_animated = false;
if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_OFF) {
can_cast_shadows = false;
} else if (p_instance->material_override.is_valid()) {
can_cast_shadows = VSG::storage->material_casts_shadows(p_instance->material_override);
+ is_animated = VSG::storage->material_is_animated(p_instance->material_override);
} else {
if (p_instance->base_type == VS::INSTANCE_MESH) {
@@ -3252,12 +3288,15 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
if (!mat.is_valid()) {
cast_shadows = true;
- break;
- }
+ } else {
- if (VSG::storage->material_casts_shadows(mat)) {
- cast_shadows = true;
- break;
+ if (VSG::storage->material_casts_shadows(mat)) {
+ cast_shadows = true;
+ }
+
+ if (VSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
}
}
@@ -3279,12 +3318,15 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
if (!mat.is_valid()) {
cast_shadows = true;
- break;
- }
- if (VSG::storage->material_casts_shadows(mat)) {
- cast_shadows = true;
- break;
+ } else {
+
+ if (VSG::storage->material_casts_shadows(mat)) {
+ cast_shadows = true;
+ }
+ if (VSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
}
}
@@ -3301,6 +3343,10 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
} else {
can_cast_shadows = false;
}
+
+ if (mat.is_valid() && VSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
} else if (p_instance->base_type == VS::INSTANCE_PARTICLES) {
bool cast_shadows = false;
@@ -3320,12 +3366,15 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
if (!mat.is_valid()) {
cast_shadows = true;
- break;
- }
+ } else {
- if (VSG::storage->material_casts_shadows(mat)) {
- cast_shadows = true;
- break;
+ if (VSG::storage->material_casts_shadows(mat)) {
+ cast_shadows = true;
+ }
+
+ if (VSG::storage->material_is_animated(mat)) {
+ is_animated = true;
+ }
}
}
}
@@ -3345,6 +3394,8 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
geom->can_cast_shadows = can_cast_shadows;
}
+
+ geom->material_is_animated = is_animated;
}
}
diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h
index 12d732724a..38c5258116 100644
--- a/servers/visual/visual_server_scene.h
+++ b/servers/visual/visual_server_scene.h
@@ -33,12 +33,12 @@
#include "servers/visual/rasterizer.h"
-#include "allocators.h"
-#include "geometry.h"
-#include "octree.h"
-#include "os/semaphore.h"
-#include "os/thread.h"
-#include "self_list.h"
+#include "core/allocators.h"
+#include "core/math/geometry.h"
+#include "core/math/octree.h"
+#include "core/os/semaphore.h"
+#include "core/os/thread.h"
+#include "core/self_list.h"
#include "servers/arvr/arvr_interface.h"
class VisualServerScene {
@@ -192,14 +192,9 @@ public:
singleton->instance_set_base(self, RID());
}
- virtual void base_changed() {
+ virtual void base_changed(bool p_aabb, bool p_materials) {
- singleton->_instance_queue_update(this, true, true);
- }
-
- virtual void base_material_changed() {
-
- singleton->_instance_queue_update(this, false, true);
+ singleton->_instance_queue_update(this, p_aabb, p_materials);
}
Instance() :
@@ -247,6 +242,7 @@ public:
List<Instance *> lighting;
bool lighting_dirty;
bool can_cast_shadows;
+ bool material_is_animated;
List<Instance *> reflection_probes;
bool reflection_dirty;
@@ -261,6 +257,7 @@ public:
lighting_dirty = false;
reflection_dirty = true;
can_cast_shadows = true;
+ material_is_animated = true;
gi_probes_dirty = true;
}
};
@@ -355,6 +352,11 @@ public:
visible == p_cache.visible);
}
+ bool operator!=(const LightCache &p_cache) {
+
+ return !operator==(p_cache);
+ }
+
LightCache() {
type = VS::LIGHT_DIRECTIONAL;
@@ -483,7 +485,7 @@ public:
_FORCE_INLINE_ void _update_dirty_instance(Instance *p_instance);
_FORCE_INLINE_ void _update_instance_lightmap_captures(Instance *p_instance);
- _FORCE_INLINE_ void _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario);
+ _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_shadow_atlas, Scenario *p_scenario);
void _prepare_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe);
void _render_scene(const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
@@ -544,7 +546,7 @@ public:
bool free(RID p_rid);
VisualServerScene();
- ~VisualServerScene();
+ virtual ~VisualServerScene();
};
#endif // VISUALSERVERSCENE_H
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index a700fcf11b..571b71db85 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -30,7 +30,7 @@
#include "visual_server_viewport.h"
-#include "project_settings.h"
+#include "core/project_settings.h"
#include "visual_server_canvas.h"
#include "visual_server_global.h"
#include "visual_server_scene.h"
@@ -137,8 +137,7 @@ 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();
+ canvas_map[Viewport::CanvasKey(E->key(), E->get().layer, E->get().sublayer)] = &E->get();
}
if (lights_with_shadow) {
@@ -177,7 +176,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
VSG::rasterizer->restore_render_target();
- if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().layer > scenario_canvas_max_layer) {
+ if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().get_layer() > scenario_canvas_max_layer) {
Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
if (!can_draw_3d) {
@@ -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;
@@ -212,7 +209,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E
VSG::canvas->render_canvas(canvas, xform, canvas_lights, lights_with_mask, clip_rect);
i++;
- if (scenario_draw_canvas_bg && E->key().layer >= scenario_canvas_max_layer) {
+ if (scenario_draw_canvas_bg && E->key().get_layer() >= scenario_canvas_max_layer) {
Ref<ARVRInterface> arvr_interface = ARVRServer::get_singleton()->get_primary_interface();
if (!can_draw_3d) {
@@ -297,7 +294,7 @@ void VisualServerViewport::draw_viewports() {
arvr_interface->commit_for_eye(ARVRInterface::EYE_RIGHT, vp->render_target, vp->viewport_to_screen_rect);
}
- // and for our frame timing, mark when we've finished commiting our eyes
+ // and for our frame timing, mark when we've finished committing our eyes
ARVRServer::get_singleton()->_mark_commit();
} else {
VSG::rasterizer->set_current_render_target(vp->render_target);
@@ -499,6 +496,7 @@ void VisualServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas)
canvas->viewports.insert(p_viewport);
viewport->canvas_map[p_canvas] = Viewport::CanvasData();
viewport->canvas_map[p_canvas].layer = 0;
+ viewport->canvas_map[p_canvas].sublayer = 0;
viewport->canvas_map[p_canvas].canvas = canvas;
}
@@ -537,13 +535,14 @@ void VisualServerViewport::viewport_set_global_canvas_transform(RID p_viewport,
viewport->global_transform = p_transform;
}
-void VisualServerViewport::viewport_set_canvas_layer(RID p_viewport, RID p_canvas, int p_layer) {
+void VisualServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
ERR_FAIL_COND(!viewport->canvas_map.has(p_canvas));
viewport->canvas_map[p_canvas].layer = p_layer;
+ viewport->canvas_map[p_canvas].sublayer = p_sublayer;
}
void VisualServerViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) {
diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h
index f915e26b81..66baa48458 100644
--- a/servers/visual/visual_server_viewport.h
+++ b/servers/visual/visual_server_viewport.h
@@ -31,8 +31,8 @@
#ifndef VISUALSERVERVIEWPORT_H
#define VISUALSERVERVIEWPORT_H
+#include "core/self_list.h"
#include "rasterizer.h"
-#include "self_list.h"
#include "servers/arvr/arvr_interface.h"
#include "servers/visual_server.h"
@@ -78,17 +78,21 @@ public:
struct CanvasKey {
- int layer;
+ int64_t stacking;
RID canvas;
bool operator<(const CanvasKey &p_canvas) const {
- if (layer == p_canvas.layer) return canvas < p_canvas.canvas;
- return layer < p_canvas.layer;
+ if (stacking == p_canvas.stacking)
+ return canvas < p_canvas.canvas;
+ return stacking < p_canvas.stacking;
+ }
+ CanvasKey() {
+ stacking = 0;
}
- CanvasKey() { layer = 0; }
- CanvasKey(const RID &p_canvas, int p_layer) {
+ CanvasKey(const RID &p_canvas, int p_layer, int p_sublayer) {
canvas = p_canvas;
- layer = p_layer;
+ stacking = ((int64_t)p_layer << 32) + p_sublayer;
}
+ int get_layer() const { return stacking >> 32; }
};
struct CanvasData {
@@ -96,6 +100,7 @@ public:
CanvasBase *canvas;
Transform2D transform;
int layer;
+ int sublayer;
};
Transform2D global_transform;
@@ -176,7 +181,7 @@ public:
void viewport_set_transparent_background(RID p_viewport, bool p_enabled);
void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform);
- void viewport_set_canvas_layer(RID p_viewport, RID p_canvas, int p_layer);
+ void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer);
void viewport_set_shadow_atlas_size(RID p_viewport, int p_size);
void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv);
@@ -194,6 +199,7 @@ public:
bool free(RID p_rid);
VisualServerViewport();
+ virtual ~VisualServerViewport() {}
};
#endif // VISUALSERVERVIEWPORT_H
diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp
index 93f3792bdc..f59d8af9cb 100644
--- a/servers/visual/visual_server_wrap_mt.cpp
+++ b/servers/visual/visual_server_wrap_mt.cpp
@@ -29,8 +29,8 @@
/*************************************************************************/
#include "visual_server_wrap_mt.h"
-#include "os/os.h"
-#include "project_settings.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
void VisualServerWrapMT::thread_exit() {
@@ -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 3a4d72c793..37f6323b8f 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -31,8 +31,8 @@
#ifndef VISUAL_SERVER_WRAP_MT_H
#define VISUAL_SERVER_WRAP_MT_H
-#include "command_queue_mt.h"
-#include "os/thread.h"
+#include "core/command_queue_mt.h"
+#include "core/os/thread.h"
#include "servers/visual_server.h"
/**
@@ -137,6 +137,7 @@ public:
FUNC3(material_set_param, RID, const StringName &, const Variant &)
FUNC2RC(Variant, material_get_param, RID, const StringName &)
+ FUNC2RC(Variant, material_get_param_default, RID, const StringName &)
FUNC2(material_set_render_priority, RID, int)
FUNC2(material_set_line_width, RID, float)
@@ -270,6 +271,7 @@ public:
FUNC2(reflection_probe_set_enable_box_projection, RID, bool)
FUNC2(reflection_probe_set_enable_shadows, RID, bool)
FUNC2(reflection_probe_set_cull_mask, RID, uint32_t)
+ FUNC2(reflection_probe_set_resolution, RID, int)
/* BAKED LIGHT API */
@@ -398,7 +400,7 @@ public:
FUNC2(viewport_set_transparent_background, RID, bool)
FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &)
- FUNC3(viewport_set_canvas_layer, RID, RID, int)
+ FUNC4(viewport_set_canvas_stacking, RID, RID, int, int)
FUNC2(viewport_set_shadow_atlas_size, RID, int)
FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
FUNC2(viewport_set_msaa, RID, ViewportMSAA)
@@ -428,14 +430,14 @@ public:
FUNC6(environment_set_dof_blur_near, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
FUNC6(environment_set_dof_blur_far, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
- FUNC10(environment_set_glow, RID, bool, int, float, float, float, EnvironmentGlowBlendMode, float, float, bool)
+ FUNC11(environment_set_glow, RID, bool, int, float, float, float, EnvironmentGlowBlendMode, float, float, float, bool)
FUNC9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float)
FUNC6(environment_set_adjustment, RID, bool, float, float, float, RID)
FUNC5(environment_set_fog, RID, bool, const Color &, const Color &, float)
- FUNC6(environment_set_fog_depth, RID, bool, float, float, bool, float)
+ FUNC7(environment_set_fog_depth, RID, bool, float, float, float, bool, float)
FUNC5(environment_set_fog_height, RID, bool, float, float, float)
FUNCRID(scenario)
@@ -490,6 +492,8 @@ public:
FUNC2(canvas_item_set_visible, RID, bool)
FUNC2(canvas_item_set_light_mask, RID, int)
+ FUNC2(canvas_item_set_update_when_visible, RID, bool)
+
FUNC2(canvas_item_set_transform, RID, const Transform2D &)
FUNC2(canvas_item_set_clip, RID, bool)
FUNC2(canvas_item_set_distance_field_mode, RID, bool)
@@ -512,7 +516,7 @@ public:
FUNC10(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, const Vector<int> &, const Vector<float> &, RID, int, RID)
FUNC4(canvas_item_add_mesh, RID, const RID &, RID, RID)
FUNC4(canvas_item_add_multimesh, RID, RID, RID, RID)
- FUNC6(canvas_item_add_particles, RID, RID, RID, RID, int, int)
+ FUNC4(canvas_item_add_particles, RID, RID, RID, RID)
FUNC2(canvas_item_add_set_transform, RID, const Transform2D &)
FUNC2(canvas_item_add_clip_ignore, RID, bool)
FUNC2(canvas_item_set_sort_children_by_y, RID, bool)
@@ -605,6 +609,10 @@ public:
static void set_use_vsync_callback(bool p_enable);
+ virtual bool is_low_end() const {
+ return visual_server->is_low_end();
+ }
+
VisualServerWrapMT(VisualServer *p_contained, bool p_create_thread);
~VisualServerWrapMT();
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index bc9e9042ec..34cc1cbd66 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -30,8 +30,8 @@
#include "visual_server.h"
-#include "method_bind_ext.gen.inc"
-#include "project_settings.h"
+#include "core/method_bind_ext.gen.inc"
+#include "core/project_settings.h"
VisualServer *VisualServer::singleton = NULL;
VisualServer *(*VisualServer::create_func)() = NULL;
@@ -343,7 +343,7 @@ RID VisualServer::get_white_texture() {
#define SMALL_VEC2 Vector2(0.00001, 0.00001)
#define SMALL_VEC3 Vector3(0.00001, 0.00001, 0.00001)
-Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, PoolVector<uint8_t> &r_vertex_array, int p_vertex_array_len, PoolVector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> r_bone_aabb) {
+Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, PoolVector<uint8_t> &r_vertex_array, int p_vertex_array_len, PoolVector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb) {
PoolVector<uint8_t>::Write vw = r_vertex_array.write();
@@ -1695,6 +1695,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("material_get_shader", "shader_material"), &VisualServer::material_get_shader);
ClassDB::bind_method(D_METHOD("material_set_param", "material", "parameter", "value"), &VisualServer::material_set_param);
ClassDB::bind_method(D_METHOD("material_get_param", "material", "parameter"), &VisualServer::material_get_param);
+ ClassDB::bind_method(D_METHOD("material_get_param_default", "material", "parameter"), &VisualServer::material_get_param_default);
ClassDB::bind_method(D_METHOD("material_set_render_priority", "material", "priority"), &VisualServer::material_set_render_priority);
ClassDB::bind_method(D_METHOD("material_set_line_width", "material", "width"), &VisualServer::material_set_line_width);
ClassDB::bind_method(D_METHOD("material_set_next_pass", "material", "next_material"), &VisualServer::material_set_next_pass);
@@ -1806,24 +1807,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);
@@ -1889,7 +1890,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("viewport_set_canvas_transform", "viewport", "canvas", "offset"), &VisualServer::viewport_set_canvas_transform);
ClassDB::bind_method(D_METHOD("viewport_set_transparent_background", "viewport", "enabled"), &VisualServer::viewport_set_transparent_background);
ClassDB::bind_method(D_METHOD("viewport_set_global_canvas_transform", "viewport", "transform"), &VisualServer::viewport_set_global_canvas_transform);
- ClassDB::bind_method(D_METHOD("viewport_set_canvas_layer", "viewport", "canvas", "layer"), &VisualServer::viewport_set_canvas_layer);
+ ClassDB::bind_method(D_METHOD("viewport_set_canvas_stacking", "viewport", "canvas", "layer", "sublayer"), &VisualServer::viewport_set_canvas_stacking);
ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size"), &VisualServer::viewport_set_shadow_atlas_size);
ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_quadrant_subdivision", "viewport", "quadrant", "subdivision"), &VisualServer::viewport_set_shadow_atlas_quadrant_subdivision);
ClassDB::bind_method(D_METHOD("viewport_set_msaa", "viewport", "msaa"), &VisualServer::viewport_set_msaa);
@@ -1908,13 +1909,15 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("environment_set_ambient_light", "env", "color", "energy", "sky_contibution"), &VisualServer::environment_set_ambient_light, DEFVAL(1.0), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("environment_set_dof_blur_near", "env", "enable", "distance", "transition", "far_amount", "quality"), &VisualServer::environment_set_dof_blur_near);
ClassDB::bind_method(D_METHOD("environment_set_dof_blur_far", "env", "enable", "distance", "transition", "far_amount", "quality"), &VisualServer::environment_set_dof_blur_far);
- ClassDB::bind_method(D_METHOD("environment_set_glow", "env", "enable", "level_flags", "intensity", "strength", "bloom_threshold", "blend_mode", "hdr_bleed_threshold", "hdr_bleed_scale", "bicubic_upscale"), &VisualServer::environment_set_glow);
+ ClassDB::bind_method(D_METHOD("environment_set_glow", "env", "enable", "level_flags", "intensity", "strength", "bloom_threshold", "blend_mode", "hdr_bleed_threshold", "hdr_bleed_scale", "hdr_luminance_cap", "bicubic_upscale"), &VisualServer::environment_set_glow);
ClassDB::bind_method(D_METHOD("environment_set_tonemap", "env", "tone_mapper", "exposure", "white", "auto_exposure", "min_luminance", "max_luminance", "auto_exp_speed", "auto_exp_grey"), &VisualServer::environment_set_tonemap);
ClassDB::bind_method(D_METHOD("environment_set_adjustment", "env", "enable", "brightness", "contrast", "saturation", "ramp"), &VisualServer::environment_set_adjustment);
ClassDB::bind_method(D_METHOD("environment_set_ssr", "env", "enable", "max_steps", "fade_in", "fade_out", "depth_tolerance", "roughness"), &VisualServer::environment_set_ssr);
ClassDB::bind_method(D_METHOD("environment_set_ssao", "env", "enable", "radius", "intensity", "radius2", "intensity2", "bias", "light_affect", "ao_channel_affect", "color", "quality", "blur", "bilateral_sharpness"), &VisualServer::environment_set_ssao);
ClassDB::bind_method(D_METHOD("environment_set_fog", "env", "enable", "color", "sun_color", "sun_amount"), &VisualServer::environment_set_fog);
- ClassDB::bind_method(D_METHOD("environment_set_fog_depth", "env", "enable", "depth_begin", "depth_curve", "transmit", "transmit_curve"), &VisualServer::environment_set_fog_depth);
+
+ ClassDB::bind_method(D_METHOD("environment_set_fog_depth", "env", "enable", "depth_begin", "depth_end", "depth_curve", "transmit", "transmit_curve"), &VisualServer::environment_set_fog_depth);
+
ClassDB::bind_method(D_METHOD("environment_set_fog_height", "env", "enable", "min_height", "max_height", "height_curve"), &VisualServer::environment_set_fog_height);
ClassDB::bind_method(D_METHOD("scenario_create"), &VisualServer::scenario_create);
@@ -1977,7 +1980,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("canvas_item_add_triangle_array", "item", "indices", "points", "colors", "uvs", "bones", "weights", "texture", "count", "normal_map"), &VisualServer::canvas_item_add_triangle_array, DEFVAL(Vector<Point2>()), DEFVAL(Vector<int>()), DEFVAL(Vector<float>()), DEFVAL(RID()), DEFVAL(-1), DEFVAL(RID()));
ClassDB::bind_method(D_METHOD("canvas_item_add_mesh", "item", "mesh", "texture", "normal_map"), &VisualServer::canvas_item_add_mesh, DEFVAL(RID()));
ClassDB::bind_method(D_METHOD("canvas_item_add_multimesh", "item", "mesh", "texture", "normal_map"), &VisualServer::canvas_item_add_multimesh, DEFVAL(RID()));
- ClassDB::bind_method(D_METHOD("canvas_item_add_particles", "item", "particles", "texture", "normal_map", "h_frames", "v_frames"), &VisualServer::canvas_item_add_particles);
+ ClassDB::bind_method(D_METHOD("canvas_item_add_particles", "item", "particles", "texture", "normal_map"), &VisualServer::canvas_item_add_particles);
ClassDB::bind_method(D_METHOD("canvas_item_add_set_transform", "item", "transform"), &VisualServer::canvas_item_add_set_transform);
ClassDB::bind_method(D_METHOD("canvas_item_add_clip_ignore", "item", "ignore"), &VisualServer::canvas_item_add_clip_ignore);
ClassDB::bind_method(D_METHOD("canvas_item_set_sort_children_by_y", "item", "enabled"), &VisualServer::canvas_item_set_sort_children_by_y);
@@ -2282,7 +2285,7 @@ void VisualServer::_bind_methods() {
BIND_ENUM_CONSTANT(GLOW_BLEND_MODE_REPLACE);
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_LINEAR);
- BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_REINHARDT);
+ BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_REINHARD);
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_FILMIC);
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_ACES);
@@ -2361,6 +2364,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);
@@ -2368,6 +2372,7 @@ VisualServer::VisualServer() {
GLOBAL_DEF("rendering/quality/directional_shadow/size", 4096);
GLOBAL_DEF("rendering/quality/directional_shadow/size.mobile", 2048);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/directional_shadow/size", PropertyInfo(Variant::INT, "rendering/quality/directional_shadow/size", PROPERTY_HINT_RANGE, "256,16384"));
GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096);
GLOBAL_DEF("rendering/quality/shadow_atlas/size.mobile", 2048);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384"));
@@ -2391,9 +2396,15 @@ VisualServer::VisualServer() {
GLOBAL_DEF("rendering/quality/shading/force_vertex_shading", false);
GLOBAL_DEF("rendering/quality/shading/force_vertex_shading.mobile", true);
+ GLOBAL_DEF("rendering/quality/shading/force_lambert_over_burley", false);
+ GLOBAL_DEF("rendering/quality/shading/force_lambert_over_burley.mobile", true);
+ GLOBAL_DEF("rendering/quality/shading/force_blinn_over_ggx", false);
+ GLOBAL_DEF("rendering/quality/shading/force_blinn_over_ggx.mobile", true);
GLOBAL_DEF("rendering/quality/depth_prepass/enable", true);
GLOBAL_DEF("rendering/quality/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno");
+
+ GLOBAL_DEF("rendering/quality/filters/use_nearest_mipmap_filter", false);
}
VisualServer::~VisualServer() {
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 0ec902c18c..ad2819a95a 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -31,13 +31,13 @@
#ifndef VISUAL_SERVER_H
#define VISUAL_SERVER_H
-#include "bsp_tree.h"
-#include "geometry.h"
-#include "image.h"
-#include "math_2d.h"
-#include "object.h"
-#include "rid.h"
-#include "variant.h"
+#include "core/image.h"
+#include "core/math/bsp_tree.h"
+#include "core/math/geometry.h"
+#include "core/math/transform_2d.h"
+#include "core/object.h"
+#include "core/rid.h"
+#include "core/variant.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
@@ -61,7 +61,7 @@ protected:
RID white_texture;
RID test_material;
- Error _surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, PoolVector<uint8_t> &r_vertex_array, int p_vertex_array_len, PoolVector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> r_bone_aabb);
+ Error _surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, PoolVector<uint8_t> &r_vertex_array, int p_vertex_array_len, PoolVector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb);
static VisualServer *(*create_func)();
static void _bind_methods();
@@ -209,6 +209,7 @@ public:
virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) = 0;
virtual Variant material_get_param(RID p_material, const StringName &p_param) const = 0;
+ virtual Variant material_get_param_default(RID p_material, const StringName &p_param) const = 0;
virtual void material_set_render_priority(RID p_material, int priority) = 0;
@@ -489,6 +490,7 @@ public:
virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) = 0;
virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) = 0;
virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) = 0;
+ virtual void reflection_probe_set_resolution(RID p_probe, int p_resolution) = 0;
/* GI PROBE API */
@@ -642,7 +644,7 @@ public:
virtual void viewport_set_transparent_background(RID p_viewport, bool p_enabled) = 0;
virtual void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform) = 0;
- virtual void viewport_set_canvas_layer(RID p_viewport, RID p_canvas, int p_layer) = 0;
+ virtual void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) = 0;
virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size) = 0;
virtual void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) = 0;
@@ -731,11 +733,11 @@ public:
GLOW_BLEND_MODE_SOFTLIGHT,
GLOW_BLEND_MODE_REPLACE,
};
- virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) = 0;
+ virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale) = 0;
enum EnvironmentToneMapper {
ENV_TONE_MAPPER_LINEAR,
- ENV_TONE_MAPPER_REINHARDT,
+ ENV_TONE_MAPPER_REINHARD,
ENV_TONE_MAPPER_FILMIC,
ENV_TONE_MAPPER_ACES
};
@@ -761,7 +763,7 @@ public:
virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, float p_ao_channel_affect, const Color &p_color, EnvironmentSSAOQuality p_quality, EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0;
virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) = 0;
- virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
+ virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0;
/* SCENARIO API */
@@ -863,6 +865,8 @@ public:
virtual void canvas_item_set_visible(RID p_item, bool p_visible) = 0;
virtual void canvas_item_set_light_mask(RID p_item, int p_mask) = 0;
+ virtual void canvas_item_set_update_when_visible(RID p_item, bool p_update) = 0;
+
virtual void canvas_item_set_transform(RID p_item, const Transform2D &p_transform) = 0;
virtual void canvas_item_set_clip(RID p_item, bool p_clip) = 0;
virtual void canvas_item_set_distance_field_mode(RID p_item, bool p_enable) = 0;
@@ -891,7 +895,7 @@ public:
virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID()) = 0;
virtual void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture = RID(), RID p_normal_map = RID()) = 0;
virtual void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID()) = 0;
- virtual void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, int p_h_frames, int p_v_frames) = 0;
+ virtual void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map) = 0;
virtual void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) = 0;
virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore) = 0;
virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) = 0;
@@ -1033,6 +1037,8 @@ public:
virtual void call_set_use_vsync(bool p_enable) = 0;
+ virtual bool is_low_end() const = 0;
+
VisualServer();
virtual ~VisualServer();
};